1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
include(SwiftAddCustomCommandTarget)
include(SwiftSetIfArchBitness)
# Create a target to process single gyb source with the 'gyb' tool.
#
# handle_gyb_source_single(
# dependency_out_var_name
# SOURCE src_gyb
# OUTPUT output
# [FLAGS [flags ...]])
# [DEPENDS [depends ...]]
# [COMMENT comment])
#
# dependency_out_var_name
# The name of a variable, to be set in the parent scope to be the target
# target that invoke gyb.
#
# src_gyb
# .gyb suffixed source file
#
# output
# Output filename to be generated
#
# flags ...
# gyb flags in addition to ${SWIFT_GYB_FLAGS}.
#
# depends ...
# gyb flags in addition to 'src_gyb' and sources of gyb itself.
#
# comment
# Additional comment.
function(handle_gyb_source_single dependency_out_var_name)
set(options)
set(single_value_args SOURCE OUTPUT COMMENT)
set(multi_value_args FLAGS DEPENDS)
cmake_parse_arguments(
GYB_SINGLE # prefix
"${options}" "${single_value_args}" "${multi_value_args}" ${ARGN})
set(gyb_tool "${SWIFT_SOURCE_DIR}/utils/gyb")
set(gyb_tool_source "${gyb_tool}" "${gyb_tool}.py")
get_filename_component(dir "${GYB_SINGLE_OUTPUT}" DIRECTORY)
get_filename_component(basename "${GYB_SINGLE_OUTPUT}" NAME)
# Handle foo.gyb in pattern ``gyb.expand('foo.gyb'`` as a dependency
set(gyb_expand_deps "")
file(READ "${GYB_SINGLE_SOURCE}" gyb_file)
string(REGEX MATCHALL "\\\$\{[\r\n\t ]*gyb.expand\\\([\r\n\t ]*[\'\"]([^\'\"]*)[\'\"]" gyb_expand_matches "${gyb_file}")
foreach(match ${gyb_expand_matches})
string(REGEX MATCH "[\'\"]\([^\'\"]*\)[\'\"]" gyb_dep "${match}")
list(APPEND gyb_expand_deps "${CMAKE_MATCH_1}")
endforeach()
list(REMOVE_DUPLICATES gyb_expand_deps)
add_custom_command_target(
dependency_target
COMMAND
"${CMAKE_COMMAND}" -E make_directory "${dir}"
COMMAND
"${CMAKE_COMMAND}" -E env "$<TARGET_FILE:Python3::Interpreter>" "${gyb_tool}" ${SWIFT_GYB_FLAGS} ${GYB_SINGLE_FLAGS} -o "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_SOURCE}"
COMMAND
"${CMAKE_COMMAND}" -E copy_if_different "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_OUTPUT}"
COMMAND
"${CMAKE_COMMAND}" -E remove "${GYB_SINGLE_OUTPUT}.tmp"
OUTPUT "${GYB_SINGLE_OUTPUT}"
DEPENDS "${gyb_tool_source}" "${GYB_SINGLE_DEPENDS}" "${GYB_SINGLE_SOURCE}" "${gyb_expand_deps}"
COMMENT "Generating ${basename} from ${GYB_SINGLE_SOURCE} ${GYB_SINGLE_COMMENT}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
SOURCES "${GYB_SINGLE_SOURCE}"
IDEMPOTENT)
set("${dependency_out_var_name}" "${dependency_target}" PARENT_SCOPE)
endfunction()
# Create a target to process .gyb files with the 'gyb' tool.
#
# handle_gyb_sources(
# dependency_out_var_name
# sources_var_name
# [ARCH arch]
# [DEPENDS [depends ...]])
#
# Replace, in ${sources_var_name}, the given .gyb-suffixed sources with
# their un-suffixed intermediate files, which will be generated by processing
# the .gyb files with gyb.
#
# dependency_out_var_name
# The name of a variable, to be set in the parent scope to the list of
# targets that invoke gyb. Every target that depends on the generated
# sources should depend on ${dependency_out_var_name} targets.
#
# arch
# The architecture that the files will be compiled for. If this is
# false, the files are architecture-independent and will be emitted
# into ${CMAKE_CURRENT_BINARY_DIR} instead of an architecture-specific
# destination; this is useful for generated include files.
#
# depends
# Additional file dependencies beyond the standard dependencies that all gyb
# invocations get.
function(handle_gyb_sources dependency_out_var_name sources_var_name)
set(options)
set(single_value_args ARCH)
set(multi_value_args DEPENDS)
cmake_parse_arguments(GYB
"${options}" "${single_value_args}" "${multi_value_args}" ${ARGN})
set(extra_gyb_flags "")
if (GYB_ARCH)
set_if_arch_bitness(ptr_size
ARCH "${GYB_ARCH}"
CASE_32_BIT "4"
CASE_64_BIT "8")
set(extra_gyb_flags "-DCMAKE_SIZEOF_VOID_P=${ptr_size}")
endif()
set(dependency_targets)
set(de_gybbed_sources)
set(gyb_extra_sources
"${SWIFT_SOURCE_DIR}/utils/GYBUnicodeDataUtils.py"
"${SWIFT_SOURCE_DIR}/utils/SwiftIntTypes.py"
"${SWIFT_SOURCE_DIR}/utils/SwiftFloatingPointTypes.py"
"${SWIFT_SOURCE_DIR}/utils/UnicodeData/GraphemeBreakProperty.txt"
"${SWIFT_SOURCE_DIR}/utils/UnicodeData/GraphemeBreakTest.txt"
"${SWIFT_SOURCE_DIR}/utils/gyb_stdlib_support.py")
foreach (src ${${sources_var_name}})
# On Windows (using Visual Studio), the generated project files assume that the
# generated GYB files will be in the source, not binary directory.
# We can work around this by modifying the root directory when generating VS projects.
if ("${CMAKE_GENERATOR_PLATFORM}" MATCHES "Visual Studio")
set(dir_root ${CMAKE_CURRENT_SOURCE_DIR})
else()
set(dir_root ${CMAKE_CURRENT_BINARY_DIR})
endif()
if (GYB_ARCH)
set(dir "${dir_root}/${ptr_size}")
else()
set(dir "${dir_root}")
endif()
# get_filename_component(src_sans_gyb ${src} NAME_WLE)
string(REGEX REPLACE "\.gyb$" "" src_sans_gyb ${src})
set(output_file_name "${dir}/${src_sans_gyb}")
list(APPEND de_gybbed_sources "${output_file_name}")
handle_gyb_source_single(dependency_target
SOURCE "${src}"
OUTPUT "${output_file_name}"
FLAGS ${extra_gyb_flags}
DEPENDS "${GYB_DEPENDS}" "${gyb_extra_sources}"
COMMENT "with ptr size = ${ptr_size}")
list(APPEND dependency_targets "${dependency_target}")
endforeach()
set("${dependency_out_var_name}" "${dependency_targets}" PARENT_SCOPE)
set("${sources_var_name}" "${de_gybbed_sources}" PARENT_SCOPE)
endfunction()
function(add_gyb_target target sources)
handle_gyb_sources(gyb_sources_depends sources ${ARGN})
add_custom_target(${target}
DEPENDS "${gyb_sources_depends}")
endfunction()
|