|
| 1 | + |
| 2 | +include(CMakeParseArguments) |
| 3 | + |
| 4 | +# Creates an output file map give a target and its list of sources at |
| 5 | +# output_path |
| 6 | +# |
| 7 | +# Usage: |
| 8 | +# create_output_file_map(target sources output_path) |
| 9 | +function(create_output_file_map target sources output_path) |
| 10 | + set(output_list) |
| 11 | + set(output_file_map "{\n") |
| 12 | + foreach(source ${sources}) |
| 13 | + get_filename_component(name ${source} NAME) |
| 14 | + |
| 15 | + set(obj ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}${CMAKE_C_OUTPUT_EXTENSION}) |
| 16 | + set(deps ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.d) |
| 17 | + set(swiftdeps ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.swiftdeps) |
| 18 | + set(dia ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${name}.dia) |
| 19 | + set(output_entry "\"${source}\": {\n\ |
| 20 | + \"object\": \"${obj}\",\n\ |
| 21 | + \"dependencies\": \"${deps}\",\n\ |
| 22 | + \"swift-dependencies\": \"${swiftdeps}\",\n\ |
| 23 | + \"diagnostics\": \"${dia}\"\n\ |
| 24 | +},\n") |
| 25 | + string(APPEND output_file_map ${output_entry}) |
| 26 | + endforeach() |
| 27 | + set(master_deps ${CMAKE_CURRENT_BINARY_DIR}/${target}.swiftdeps) |
| 28 | + string(APPEND output_file_map "\"\": {\n\ |
| 29 | + \"swift-dependencies\": \"${master_deps}\"\n\ |
| 30 | + }\n") |
| 31 | + string(APPEND output_file_map "}\n") |
| 32 | + file(WRITE ${output_path} ${output_file_map}) |
| 33 | +endfunction() |
| 34 | + |
| 35 | +function(add_swift_target target) |
| 36 | + set(options LIBRARY;SHARED;STATIC) |
| 37 | + set(single_value_options MODULE_NAME;MODULE_LINK_NAME;MODULE_PATH;MODULE_CACHE_PATH;OUTPUT;TARGET) |
| 38 | + set(multiple_value_options CFLAGS;DEPENDS;LINK_FLAGS;RESOURCES;SOURCES;SWIFT_FLAGS) |
| 39 | + |
| 40 | + cmake_parse_arguments(AST "${options}" "${single_value_options}" "${multiple_value_options}" ${ARGN}) |
| 41 | + |
| 42 | + set(compile_flags ${CMAKE_SWIFT_FLAGS}) |
| 43 | + set(link_flags) |
| 44 | + |
| 45 | + list(APPEND compile_flags -incremental) |
| 46 | + if(AST_TARGET) |
| 47 | + list(APPEND compile_flags -target;${AST_TARGET}) |
| 48 | + list(APPEND link_flags -target;${AST_TARGET}) |
| 49 | + endif() |
| 50 | + if(AST_MODULE_NAME) |
| 51 | + list(APPEND compile_flags -module-name;${AST_MODULE_NAME}) |
| 52 | + else() |
| 53 | + list(APPEND compile_flags -module-name;${target}) |
| 54 | + endif() |
| 55 | + if(AST_MODULE_LINK_NAME) |
| 56 | + list(APPEND compile_flags -module-link-name;${AST_MODULE_LINK_NAME}) |
| 57 | + endif() |
| 58 | + if(AST_MODULE_CACHE_PATH) |
| 59 | + list(APPEND compile_flags -module-cache-path;${AST_MODULE_CACHE_PATH}) |
| 60 | + endif() |
| 61 | + if(AST_MODULE_PATH) |
| 62 | + get_filename_component(module_location ${AST_MODULE_PATH} PATH) |
| 63 | + file(MAKE_DIRECTORY "${module_location}") |
| 64 | + list(APPEND compile_flags "-emit-module-path;${AST_MODULE_PATH}") |
| 65 | + endif() |
| 66 | + if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) |
| 67 | + list(APPEND compile_flags -g) |
| 68 | + endif() |
| 69 | + if(AST_SWIFT_FLAGS) |
| 70 | + foreach(flag ${AST_SWIFT_FLAGS}) |
| 71 | + list(APPEND compile_flags ${flag}) |
| 72 | + endforeach() |
| 73 | + endif() |
| 74 | + if(AST_CFLAGS) |
| 75 | + foreach(flag ${AST_CFLAGS}) |
| 76 | + list(APPEND compile_flags -Xcc;${flag}) |
| 77 | + endforeach() |
| 78 | + endif() |
| 79 | + if(AST_LINK_FLAGS) |
| 80 | + foreach(flag ${AST_LINK_FLAGS}) |
| 81 | + list(APPEND link_flags ${flag}) |
| 82 | + endforeach() |
| 83 | + endif() |
| 84 | + if(AST_LIBRARY) |
| 85 | + if(AST_STATIC AND AST_SHARED) |
| 86 | + message(SEND_ERROR "add_swift_target asked to create library as STATIC and SHARED") |
| 87 | + elseif(AST_STATIC OR NOT BUILD_SHARED_LIBS) |
| 88 | + set(library_kind STATIC) |
| 89 | + elseif(AST_SHARED OR BUILD_SHARED_LIBS) |
| 90 | + set(library_kind SHARED) |
| 91 | + endif() |
| 92 | + else() |
| 93 | + if(AST_STATIC OR AST_SHARED) |
| 94 | + message(SEND_ERROR "add_swift_target asked to create executable as STATIC or SHARED") |
| 95 | + endif() |
| 96 | + endif() |
| 97 | + if(NOT AST_OUTPUT) |
| 98 | + if(AST_LIBRARY) |
| 99 | + if(AST_SHARED OR BUILD_SHARED_LIBS) |
| 100 | + set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX}) |
| 101 | + else() |
| 102 | + set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${CMAKE_STATIC_LIBRARY_PREFIX}${target}${CMAKE_STATIC_LIBRARY_SUFFIX}) |
| 103 | + endif() |
| 104 | + else() |
| 105 | + set(AST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${target}${CMAKE_EXECUTABLE_SUFFIX}) |
| 106 | + endif() |
| 107 | + endif() |
| 108 | + if(CMAKE_SYSTEM_NAME STREQUAL Windows) |
| 109 | + if(AST_SHARED OR BUILD_SHARED_LIBS) |
| 110 | + set(IMPORT_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${CMAKE_IMPORT_LIBRARY_PREFIX}${target}${CMAKE_IMPORT_LIBRARY_SUFFIX}) |
| 111 | + endif() |
| 112 | + endif() |
| 113 | + |
| 114 | + set(sources) |
| 115 | + set(rsp_text) |
| 116 | + foreach(source ${AST_SOURCES}) |
| 117 | + get_filename_component(location ${source} PATH) |
| 118 | + if(IS_ABSOLUTE ${location}) |
| 119 | + list(APPEND sources ${source}) |
| 120 | + string(APPEND rsp_text "${source} ") |
| 121 | + else() |
| 122 | + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/${source}) |
| 123 | + string(APPEND rsp_text "${CMAKE_CURRENT_SOURCE_DIR}/${source} ") |
| 124 | + endif() |
| 125 | + endforeach() |
| 126 | + |
| 127 | + set(output_map_path ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/output-file-map.json) |
| 128 | + create_output_file_map(${target} "${sources}" ${output_map_path}) |
| 129 | + list(APPEND compile_flags -output-file-map;${output_map_path}) |
| 130 | + |
| 131 | + string(LENGTH sources source_length) |
| 132 | + set(rsp_file ${CMAKE_CURRENT_BINARY_DIR}/${target}.dir/${target}.rsp) |
| 133 | + file(WRITE ${rsp_file} ${rsp_text}) |
| 134 | + |
| 135 | + if(AST_LIBRARY) |
| 136 | + set(emit_library -emit-library) |
| 137 | + endif() |
| 138 | + if(NOT AST_LIBRARY OR library_kind STREQUAL SHARED) |
| 139 | + add_custom_command(OUTPUT |
| 140 | + ${AST_OUTPUT} |
| 141 | + DEPENDS |
| 142 | + ${sources} |
| 143 | + ${AST_DEPENDS} |
| 144 | + COMMAND |
| 145 | + ${CMAKE_SWIFT_COMPILER} ${emit_library} ${compile_flags} ${link_flags} -o ${AST_OUTPUT} @${rsp_file}) |
| 146 | + add_custom_target(${target} |
| 147 | + ALL |
| 148 | + DEPENDS |
| 149 | + ${AST_OUTPUT} |
| 150 | + ${module} |
| 151 | + ${documentation}) |
| 152 | + else() |
| 153 | + add_library(${target}-static STATIC ${sources}) |
| 154 | + if(AST_DEPENDS) |
| 155 | + add_dependencies(${target}-static ${AST_DEPENDS}) |
| 156 | + endif() |
| 157 | + get_filename_component(ast_output_bn ${AST_OUTPUT} NAME) |
| 158 | + if(NOT CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "") |
| 159 | + string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}" "" ast_output_bn ${ast_output_bn}) |
| 160 | + endif() |
| 161 | + if(NOT CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL "") |
| 162 | + string(REGEX REPLACE "${CMAKE_STATIC_LIBRARY_SUFFIX}$" "" ast_output_bn ${ast_output_bn}) |
| 163 | + endif() |
| 164 | + get_filename_component(ast_output_dn ${AST_OUTPUT} DIRECTORY) |
| 165 | + set_target_properties(${target}-static |
| 166 | + PROPERTIES |
| 167 | + LINKER_LANGUAGE C |
| 168 | + ARCHIVE_OUTPUT_DIRECTORY ${ast_output_dn} |
| 169 | + OUTPUT_DIRECTORY ${ast_output_dn} |
| 170 | + OUTPUT_NAME ${ast_output_bn}) |
| 171 | + add_custom_target(${target} |
| 172 | + ALL |
| 173 | + DEPENDS |
| 174 | + ${target}-static |
| 175 | + ${module} |
| 176 | + ${documentation}) |
| 177 | + endif() |
| 178 | + |
| 179 | + if(AST_RESOURCES) |
| 180 | + if(CMAKE_SYSTEM_NAME STREQUAL Windows) |
| 181 | + set(resources_dir ${target}.resources) |
| 182 | + else() |
| 183 | + set(resources_dir Resources) |
| 184 | + endif() |
| 185 | + add_custom_command(TARGET |
| 186 | + ${target} |
| 187 | + POST_BUILD |
| 188 | + COMMAND |
| 189 | + ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${target} |
| 190 | + COMMAND |
| 191 | + ${CMAKE_COMMAND} -E copy ${AST_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${target} |
| 192 | + COMMAND |
| 193 | + ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${target}/${resources_dir}) |
| 194 | + foreach(resource ${AST_RESOURCES}) |
| 195 | + add_custom_command(TARGET |
| 196 | + ${target} |
| 197 | + POST_BUILD |
| 198 | + COMMAND |
| 199 | + ${CMAKE_COMMAND} -E copy ${resource} ${CMAKE_CURRENT_BINARY_DIR}/${target}/${resources_dir}/) |
| 200 | + endforeach() |
| 201 | + else() |
| 202 | + add_custom_command(TARGET |
| 203 | + ${target} |
| 204 | + POST_BUILD |
| 205 | + COMMAND |
| 206 | + ${CMAKE_COMMAND} -E copy ${AST_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}) |
| 207 | + if(CMAKE_SYSTEM_NAME STREQUAL Windows) |
| 208 | + if(AST_SHARED OR BUILD_SHARED_LIBS) |
| 209 | + add_custom_command(TARGET |
| 210 | + ${target} |
| 211 | + POST_BUILD |
| 212 | + COMMAND |
| 213 | + ${CMAKE_COMMAND} -E copy ${IMPORT_LIBRARY} ${CMAKE_CURRENT_BINARY_DIR}) |
| 214 | + endif() |
| 215 | + endif() |
| 216 | + endif() |
| 217 | +endfunction() |
| 218 | + |
| 219 | +function(add_swift_library library) |
| 220 | + add_swift_target(${library} LIBRARY ${ARGN}) |
| 221 | +endfunction() |
| 222 | + |
| 223 | +function(add_swift_executable executable) |
| 224 | + add_swift_target(${executable} ${ARGN}) |
| 225 | +endfunction() |
| 226 | + |
| 227 | +# Returns the current achitecture name in a variable |
| 228 | +# |
| 229 | +# Usage: |
| 230 | +# get_swift_host_arch(result_var_name) |
| 231 | +# |
| 232 | +# If the current architecture is supported by Swift, sets ${result_var_name} |
| 233 | +# with the sanitized host architecture name derived from CMAKE_SYSTEM_PROCESSOR. |
| 234 | +function(get_swift_host_arch result_var_name) |
| 235 | + if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") |
| 236 | + set("${result_var_name}" "x86_64" PARENT_SCOPE) |
| 237 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") |
| 238 | + set("${result_var_name}" "aarch64" PARENT_SCOPE) |
| 239 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64") |
| 240 | + set("${result_var_name}" "powerpc64" PARENT_SCOPE) |
| 241 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le") |
| 242 | + set("${result_var_name}" "powerpc64le" PARENT_SCOPE) |
| 243 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x") |
| 244 | + set("${result_var_name}" "s390x" PARENT_SCOPE) |
| 245 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l") |
| 246 | + set("${result_var_name}" "armv6" PARENT_SCOPE) |
| 247 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") |
| 248 | + set("${result_var_name}" "armv7" PARENT_SCOPE) |
| 249 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") |
| 250 | + set("${result_var_name}" "x86_64" PARENT_SCOPE) |
| 251 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64") |
| 252 | + set("${result_var_name}" "itanium" PARENT_SCOPE) |
| 253 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86") |
| 254 | + set("${result_var_name}" "i686" PARENT_SCOPE) |
| 255 | + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") |
| 256 | + set("${result_var_name}" "i686" PARENT_SCOPE) |
| 257 | + else() |
| 258 | + message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}") |
| 259 | + endif() |
| 260 | +endfunction() |
0 commit comments