1set(OBJECT_LIBRARY_TARGET_TYPE "OBJECT_LIBRARY") 2 3function(_get_common_compile_options output_var flags) 4 list(FIND flags ${FMA_OPT_FLAG} fma) 5 if(${fma} LESS 0) 6 list(FIND flags "${FMA_OPT_FLAG}__ONLY" fma) 7 endif() 8 if((${fma} GREATER -1) AND (LIBC_CPU_FEATURES MATCHES "FMA")) 9 set(ADD_FMA_FLAG TRUE) 10 endif() 11 12 set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${ARGN}) 13 if(NOT ${LIBC_TARGET_OS} STREQUAL "windows") 14 set(compile_options ${compile_options} -fpie -ffreestanding -fno-builtin) 15 endif() 16 if(LLVM_COMPILER_IS_GCC_COMPATIBLE) 17 list(APPEND compile_options "-fno-exceptions") 18 list(APPEND compile_options "-fno-unwind-tables") 19 list(APPEND compile_options "-fno-asynchronous-unwind-tables") 20 list(APPEND compile_options "-fno-rtti") 21 if(ADD_FMA_FLAG) 22 list(APPEND compile_options "-mfma") 23 endif() 24 elseif(MSVC) 25 list(APPEND compile_options "/EHs-c-") 26 list(APPEND compile_options "/GR-") 27 if(ADD_FMA_FLAG) 28 list(APPEND compile_options "/arch:AVX2") 29 endif() 30 endif() 31 set(${output_var} ${compile_options} PARENT_SCOPE) 32endfunction() 33 34# Rule which is essentially a wrapper over add_library to compile a set of 35# sources to object files. 36# Usage: 37# add_object_library( 38# <target_name> 39# HDRS <list of header files> 40# SRCS <list of source files> 41# DEPENDS <list of dependencies> 42# COMPILE_OPTIONS <optional list of special compile options for this target> 43# FLAGS <optional list of flags> 44function(create_object_library fq_target_name) 45 cmake_parse_arguments( 46 "ADD_OBJECT" 47 "" # No optional arguments 48 "CXX_STANDARD" # Single value arguments 49 "SRCS;HDRS;COMPILE_OPTIONS;DEPENDS;FLAGS" # Multivalue arguments 50 ${ARGN} 51 ) 52 53 if(NOT ADD_OBJECT_SRCS) 54 message(FATAL_ERROR "'add_object_library' rule requires SRCS to be specified.") 55 endif() 56 57 add_library( 58 ${fq_target_name} 59 EXCLUDE_FROM_ALL 60 OBJECT 61 ${ADD_OBJECT_SRCS} 62 ${ADD_OBJECT_HDRS} 63 ) 64 target_include_directories( 65 ${fq_target_name} 66 PRIVATE 67 ${LIBC_BUILD_DIR}/include 68 ${LIBC_SOURCE_DIR} 69 ${LIBC_BUILD_DIR} 70 ) 71 _get_common_compile_options( 72 compile_options 73 "${ADD_OBJECT_FLAGS}" 74 ${ADD_OBJECT_COMPILE_OPTIONS} 75 ) 76 target_compile_options(${fq_target_name} PRIVATE ${compile_options}) 77 78 get_fq_deps_list(fq_deps_list ${ADD_OBJECT_DEPENDS}) 79 80 if(SHOW_INTERMEDIATE_OBJECTS) 81 message(STATUS "Adding object library ${fq_target_name}") 82 if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS") 83 foreach(dep IN LISTS ADD_OBJECT_DEPENDS) 84 message(STATUS " ${fq_target_name} depends on ${dep}") 85 endforeach() 86 endif() 87 endif() 88 89 if(fq_deps_list) 90 add_dependencies(${fq_target_name} ${fq_deps_list}) 91 endif() 92 93 if(NOT ADD_OBJECT_CXX_STANDARD) 94 set(ADD_OBJECT_CXX_STANDARD ${CMAKE_CXX_STANDARD}) 95 endif() 96 97 set_target_properties( 98 ${fq_target_name} 99 PROPERTIES 100 TARGET_TYPE ${OBJECT_LIBRARY_TARGET_TYPE} 101 OBJECT_FILES "$<TARGET_OBJECTS:${fq_target_name}>" 102 CXX_STANDARD ${ADD_OBJECT_CXX_STANDARD} 103 DEPS "${fq_deps_list}" 104 FLAGS "${ADD_OBJECT_FLAGS}" 105 ) 106endfunction(create_object_library) 107 108# Internal function, used by `add_object_library`. 109function(expand_flags_for_object_library target_name flags) 110 cmake_parse_arguments( 111 "EXPAND_FLAGS" 112 "IGNORE_MARKER" # Optional arguments 113 "" # Single-value arguments 114 "DEPENDS;FLAGS" # Multi-value arguments 115 ${ARGN} 116 ) 117 118 list(LENGTH flags nflags) 119 if(NOT ${nflags}) 120 create_object_library( 121 ${target_name} 122 DEPENDS ${EXPAND_FLAGS_DEPENDS} 123 FLAGS ${EXPAND_FLAGS_FLAGS} 124 ${EXPAND_FLAGS_UNPARSED_ARGUMENTS} 125 ) 126 return() 127 endif() 128 129 list(GET flags 0 flag) 130 list(REMOVE_AT flags 0) 131 extract_flag_modifier(${flag} real_flag modifier) 132 133 if(NOT "${modifier}" STREQUAL "NO") 134 expand_flags_for_object_library( 135 ${target_name} 136 "${flags}" 137 DEPENDS "${EXPAND_FLAGS_DEPENDS}" IGNORE_MARKER 138 FLAGS "${EXPAND_FLAGS_FLAGS}" IGNORE_MARKER 139 "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}" 140 ) 141 endif() 142 143 if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY") 144 return() 145 endif() 146 147 set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS}) 148 list(REMOVE_ITEM NEW_FLAGS ${flag}) 149 get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS}) 150 151 # Only target with `flag` has `.__NO_flag` target, `flag__NO` and 152 # `flag__ONLY` do not. 153 if(NOT "${modifier}") 154 set(TARGET_NAME "${target_name}.__NO_${flag}") 155 else() 156 set(TARGET_NAME "${target_name}") 157 endif() 158 159 expand_flags_for_object_library( 160 ${TARGET_NAME} 161 "${flags}" 162 DEPENDS "${NEW_DEPS}" IGNORE_MARKER 163 FLAGS "${NEW_FLAGS}" IGNORE_MARKER 164 "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}" 165 ) 166endfunction(expand_flags_for_object_library) 167 168function(add_object_library target_name) 169 cmake_parse_arguments( 170 "ADD_TO_EXPAND" 171 "" # Optional arguments 172 "" # Single value arguments 173 "DEPENDS;FLAGS" # Multi-value arguments 174 ${ARGN} 175 ) 176 177 get_fq_target_name(${target_name} fq_target_name) 178 179 if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS")) 180 message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}") 181 endif() 182 183 get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS}) 184 get_flags_from_dep_list(deps_flag_list ${fq_deps_list}) 185 186 list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list}) 187 remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags) 188 list(SORT flags) 189 190 if(SHOW_INTERMEDIATE_OBJECTS AND flags) 191 message(STATUS "Object library ${fq_target_name} has FLAGS: ${flags}") 192 endif() 193 194 expand_flags_for_object_library( 195 ${fq_target_name} 196 "${flags}" 197 DEPENDS "${fq_deps_list}" IGNORE_MARKER 198 FLAGS "${flags}" IGNORE_MARKER 199 ${ADD_TO_EXPAND_UNPARSED_ARGUMENTS} 200 ) 201endfunction(add_object_library) 202 203set(ENTRYPOINT_OBJ_TARGET_TYPE "ENTRYPOINT_OBJ") 204 205# A rule for entrypoint object targets. 206# Usage: 207# add_entrypoint_object( 208# <target_name> 209# [ALIAS|REDIRECTED] # Specified if the entrypoint is redirected or an alias. 210# [NAME] <the C name of the entrypoint if different from target_name> 211# SRCS <list of .cpp files> 212# HDRS <list of .h files> 213# DEPENDS <list of dependencies> 214# COMPILE_OPTIONS <optional list of special compile options for this target> 215# SPECIAL_OBJECTS <optional list of special object targets added by the rule `add_object`> 216# FLAGS <optional list of flags> 217# ) 218function(create_entrypoint_object fq_target_name) 219 cmake_parse_arguments( 220 "ADD_ENTRYPOINT_OBJ" 221 "ALIAS;REDIRECTED" # Optional argument 222 "NAME;CXX_STANDARD" # Single value arguments 223 "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;FLAGS" # Multi value arguments 224 ${ARGN} 225 ) 226 227 list(FIND TARGET_ENTRYPOINT_NAME_LIST ${ADD_ENTRYPOINT_OBJ_NAME} entrypoint_name_index) 228 if(${entrypoint_name_index} EQUAL -1) 229 add_custom_target(${fq_target_name}) 230 set_target_properties( 231 ${fq_target_name} 232 PROPERTIES 233 "ENTRYPOINT_NAME" ${ADD_ENTRYPOINT_OBJ_NAME} 234 "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE} 235 "OBJECT_FILE" "" 236 "OBJECT_FILE_RAW" "" 237 "DEPS" "" 238 "SKIPPED" "YES" 239 ) 240 message(STATUS "Skipping libc entrypoint ${fq_target_name}.") 241 return() 242 endif() 243 244 if(ADD_ENTRYPOINT_OBJ_ALIAS) 245 # Alias targets help one add aliases to other entrypoint object targets. 246 # One can use alias targets setup OS/machine independent entrypoint targets. 247 list(LENGTH ADD_ENTRYPOINT_OBJ_DEPENDS deps_size) 248 if(NOT (${deps_size} EQUAL "1")) 249 message(FATAL_ERROR "An entrypoint alias should have exactly one dependency.") 250 endif() 251 list(GET ADD_ENTRYPOINT_OBJ_DEPENDS 0 dep_target) 252 get_fq_dep_name(fq_dep_name ${dep_target}) 253 254 if(SHOW_INTERMEDIATE_OBJECTS) 255 message(STATUS "Adding entrypoint object ${fq_target_name} as an alias of" 256 " ${fq_dep_name}") 257 endif() 258 259 if(NOT TARGET ${fq_dep_name}) 260 message(WARNING "Aliasee ${fq_dep_name} for entrypoint alias ${target_name} missing; " 261 "Target ${target_name} will be ignored.") 262 return() 263 endif() 264 265 get_target_property(obj_type ${fq_dep_name} "TARGET_TYPE") 266 if((NOT obj_type) OR (NOT (${obj_type} STREQUAL ${ENTRYPOINT_OBJ_TARGET_TYPE}))) 267 message(FATAL_ERROR "The aliasee of an entrypoint alias should be an entrypoint.") 268 endif() 269 270 add_custom_target(${fq_target_name}) 271 add_dependencies(${fq_target_name} ${fq_dep_name}) 272 get_target_property(object_file ${fq_dep_name} "OBJECT_FILE") 273 get_target_property(object_file_raw ${fq_dep_name} "OBJECT_FILE_RAW") 274 set_target_properties( 275 ${fq_target_name} 276 PROPERTIES 277 ENTRYPOINT_NAME ${ADD_ENTRYPOINT_OBJ_NAME} 278 TARGET_TYPE ${ENTRYPOINT_OBJ_TARGET_TYPE} 279 IS_ALIAS "YES" 280 OBJECT_FILE "" 281 OBJECT_FILE_RAW "" 282 DEPS "${fq_dep_name}" 283 FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}" 284 ) 285 return() 286 endif() 287 288 if(NOT ADD_ENTRYPOINT_OBJ_SRCS) 289 message(FATAL_ERROR "`add_entrypoint_object` rule requires SRCS to be specified.") 290 endif() 291 if(NOT ADD_ENTRYPOINT_OBJ_HDRS) 292 message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.") 293 endif() 294 if(NOT ADD_ENTRYPOINT_OBJ_CXX_STANDARD) 295 set(ADD_ENTRYPOINT_OBJ_CXX_STANDARD ${CMAKE_CXX_STANDARD}) 296 endif() 297 298 _get_common_compile_options( 299 common_compile_options 300 "${ADD_ENTRYPOINT_OBJ_FLAGS}" 301 ${ADD_ENTRYPOINT_OBJ_COMPILE_OPTIONS} 302 ) 303 set(internal_target_name ${fq_target_name}.__internal__) 304 set(include_dirs ${LIBC_BUILD_DIR}/include ${LIBC_SOURCE_DIR} ${LIBC_BUILD_DIR}) 305 get_fq_deps_list(fq_deps_list ${ADD_ENTRYPOINT_OBJ_DEPENDS}) 306 set(full_deps_list ${fq_deps_list} libc.src.__support.common) 307 308 if(SHOW_INTERMEDIATE_OBJECTS) 309 message(STATUS "Adding entrypoint object ${fq_target_name}") 310 if(${SHOW_INTERMEDIATE_OBJECTS} STREQUAL "DEPS") 311 foreach(dep IN LISTS ADD_OBJECT_DEPENDS) 312 message(STATUS " ${fq_target_name} depends on ${dep}") 313 endforeach() 314 endif() 315 endif() 316 317 add_library( 318 ${internal_target_name} 319 # TODO: We don't need an object library for internal consumption. 320 # A future change should switch this to a normal static library. 321 EXCLUDE_FROM_ALL 322 OBJECT 323 ${ADD_ENTRYPOINT_OBJ_SRCS} 324 ${ADD_ENTRYPOINT_OBJ_HDRS} 325 ) 326 target_compile_options(${internal_target_name} BEFORE PRIVATE ${common_compile_options}) 327 target_include_directories(${internal_target_name} PRIVATE ${include_dirs}) 328 add_dependencies(${internal_target_name} ${full_deps_list}) 329 set_target_properties( 330 ${internal_target_name} 331 PROPERTIES 332 CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD} 333 FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}" 334 ) 335 336 add_library( 337 ${fq_target_name} 338 # We want an object library as the objects will eventually get packaged into 339 # an archive (like libc.a). 340 EXCLUDE_FROM_ALL 341 OBJECT 342 ${ADD_ENTRYPOINT_OBJ_SRCS} 343 ${ADD_ENTRYPOINT_OBJ_HDRS} 344 ) 345 target_compile_options(${fq_target_name} BEFORE PRIVATE ${common_compile_options} -DLLVM_LIBC_PUBLIC_PACKAGING) 346 target_include_directories(${fq_target_name} PRIVATE ${include_dirs}) 347 add_dependencies(${fq_target_name} ${full_deps_list}) 348 349 set_target_properties( 350 ${fq_target_name} 351 PROPERTIES 352 ENTRYPOINT_NAME ${ADD_ENTRYPOINT_OBJ_NAME} 353 TARGET_TYPE ${ENTRYPOINT_OBJ_TARGET_TYPE} 354 OBJECT_FILE "$<TARGET_OBJECTS:${fq_target_name}>" 355 # TODO: We don't need to list internal object files if the internal 356 # target is a normal static library. 357 OBJECT_FILE_RAW "$<TARGET_OBJECTS:${internal_target_name}>" 358 CXX_STANDARD ${ADD_ENTRYPOINT_OBJ_CXX_STANDARD} 359 DEPS "${fq_deps_list}" 360 FLAGS "${ADD_ENTRYPOINT_OBJ_FLAGS}" 361 ) 362 363 if(LLVM_LIBC_ENABLE_LINTING) 364 if(NOT LLVM_LIBC_CLANG_TIDY) 365 message(FATAL_ERROR "Something is wrong! LLVM_LIBC_ENABLE_LINTING is " 366 "ON but LLVM_LIBC_CLANG_TIDY is not set.") 367 endif() 368 369 # We only want a second invocation of clang-tidy to run 370 # restrict-system-libc-headers if the compiler-resource-dir was set in 371 # order to prevent false-positives due to a mismatch between the host 372 # compiler and the compiled clang-tidy. 373 if(COMPILER_RESOURCE_DIR) 374 # We run restrict-system-libc-headers with --system-headers to prevent 375 # transitive inclusion through compler provided headers. 376 set(restrict_system_headers_check_invocation 377 COMMAND ${LLVM_LIBC_CLANG_TIDY} --system-headers 378 --checks="-*,llvmlibc-restrict-system-libc-headers" 379 # We explicitly set the resource dir here to match the 380 # resource dir of the host compiler. 381 "--extra-arg=-resource-dir=${COMPILER_RESOURCE_DIR}" 382 --quiet 383 -p ${PROJECT_BINARY_DIR} 384 ${ADD_ENTRYPOINT_OBJ_SRCS} 385 ) 386 else() 387 set(restrict_system_headers_check_invocation 388 COMMAND ${CMAKE_COMMAND} -E echo "Header file check skipped") 389 endif() 390 391 set(lint_timestamp "${CMAKE_CURRENT_BINARY_DIR}/.${target_name}.__lint_timestamp__") 392 add_custom_command( 393 OUTPUT ${lint_timestamp} 394 # --quiet is used to surpress warning statistics from clang-tidy like: 395 # Suppressed X warnings (X in non-user code). 396 # There seems to be a bug in clang-tidy where by even with --quiet some 397 # messages from clang's own diagnostics engine leak through: 398 # X warnings generated. 399 # Until this is fixed upstream, we use -fno-caret-diagnostics to surpress 400 # these. 401 COMMAND ${LLVM_LIBC_CLANG_TIDY} 402 "--extra-arg=-fno-caret-diagnostics" --quiet 403 # Path to directory containing compile_commands.json 404 -p ${PROJECT_BINARY_DIR} 405 ${ADD_ENTRYPOINT_OBJ_SRCS} 406 # See above: this might be a second invocation of clang-tidy depending on 407 # the conditions above. 408 ${restrict_system_headers_check_invocation} 409 # We have two options for running commands, add_custom_command and 410 # add_custom_target. We don't want to run the linter unless source files 411 # have changed. add_custom_target explicitly runs everytime therefore we 412 # use add_custom_command. This function requires an output file and since 413 # linting doesn't produce a file, we create a dummy file using a 414 # crossplatform touch. 415 COMMAND "${CMAKE_COMMAND}" -E touch ${lint_timestamp} 416 COMMENT "Linting... ${target_name}" 417 DEPENDS clang-tidy ${internal_target_name} ${ADD_ENTRYPOINT_OBJ_SRCS} 418 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 419 ) 420 endif() 421 422endfunction(create_entrypoint_object) 423 424# Internal function, used by `add_entrypoint_object`. 425function(expand_flags_for_entrypoint_object target_name flags) 426 cmake_parse_arguments( 427 "EXPAND_FLAGS" 428 "IGNORE_MARKER" # Optional arguments 429 "" # Single-value arguments 430 "DEPENDS;FLAGS" # Multi-value arguments 431 ${ARGN} 432 ) 433 434 list(LENGTH flags nflags) 435 if(NOT ${nflags}) 436 create_entrypoint_object( 437 ${target_name} 438 DEPENDS ${EXPAND_FLAGS_DEPENDS} 439 FLAGS ${EXPAND_FLAGS_FLAGS} 440 ${EXPAND_FLAGS_UNPARSED_ARGUMENTS} 441 ) 442 return() 443 endif() 444 445 list(GET flags 0 flag) 446 list(REMOVE_AT flags 0) 447 extract_flag_modifier(${flag} real_flag modifier) 448 449 if(NOT "${modifier}" STREQUAL "NO") 450 expand_flags_for_entrypoint_object( 451 ${target_name} 452 "${flags}" 453 DEPENDS "${EXPAND_FLAGS_DEPENDS}" IGNORE_MARKER 454 FLAGS "${EXPAND_FLAGS_FLAGS}" IGNORE_MARKER 455 "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}" 456 ) 457 endif() 458 459 if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY") 460 return() 461 endif() 462 463 set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS}) 464 list(REMOVE_ITEM NEW_FLAGS ${flag}) 465 get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS}) 466 467 # Only target with `flag` has `.__NO_flag` target, `flag__NO` and 468 # `flag__ONLY` do not. 469 if(NOT "${modifier}") 470 set(TARGET_NAME "${target_name}.__NO_${flag}") 471 else() 472 set(TARGET_NAME "${target_name}") 473 endif() 474 475 expand_flags_for_entrypoint_object( 476 ${TARGET_NAME} 477 "${flags}" 478 DEPENDS "${NEW_DEPS}" IGNORE_MARKER 479 FLAGS "${NEW_FLAGS}" IGNORE_MARKER 480 "${EXPAND_FLAGS_UNPARSED_ARGUMENTS}" 481 ) 482endfunction(expand_flags_for_entrypoint_object) 483 484function(add_entrypoint_object target_name) 485 cmake_parse_arguments( 486 "ADD_TO_EXPAND" 487 "" # Optional arguments 488 "NAME" # Single value arguments 489 "DEPENDS;FLAGS" # Multi-value arguments 490 ${ARGN} 491 ) 492 493 get_fq_target_name(${target_name} fq_target_name) 494 495 if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS")) 496 message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}") 497 endif() 498 499 get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS}) 500 get_flags_from_dep_list(deps_flag_list ${fq_deps_list}) 501 502 list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list}) 503 remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags) 504 list(SORT flags) 505 506 if(SHOW_INTERMEDIATE_OBJECTS AND flags) 507 message(STATUS "Object library ${fq_target_name} has FLAGS: ${flags}") 508 endif() 509 510 if(NOT ADD_TO_EXPAND_NAME) 511 set(ADD_TO_EXPAND_NAME ${target_name}) 512 endif() 513 514 expand_flags_for_entrypoint_object( 515 ${fq_target_name} 516 "${flags}" 517 NAME ${ADD_TO_EXPAND_NAME} IGNORE_MARKER 518 DEPENDS "${fq_deps_list}" IGNORE_MARKER 519 FLAGS "${flags}" IGNORE_MARKER 520 ${ADD_TO_EXPAND_UNPARSED_ARGUMENTS} 521 ) 522endfunction(add_entrypoint_object) 523 524set(ENTRYPOINT_EXT_TARGET_TYPE "ENTRYPOINT_EXT") 525 526# A rule for external entrypoint targets. 527# Usage: 528# add_entrypoint_external( 529# <target_name> 530# DEPENDS <list of dependencies> 531# ) 532function(add_entrypoint_external target_name) 533 cmake_parse_arguments( 534 "ADD_ENTRYPOINT_EXT" 535 "" # No optional arguments 536 "" # No single value arguments 537 "DEPENDS" # Multi value arguments 538 ${ARGN} 539 ) 540 get_fq_target_name(${target_name} fq_target_name) 541 set(entrypoint_name ${target_name}) 542 543 add_custom_target(${fq_target_name}) 544 set_target_properties( 545 ${fq_target_name} 546 PROPERTIES 547 "ENTRYPOINT_NAME" ${entrypoint_name} 548 "TARGET_TYPE" ${ENTRYPOINT_EXT_TARGET_TYPE} 549 "DEPS" "${ADD_ENTRYPOINT_EXT_DEPENDS}" 550 ) 551 552endfunction(add_entrypoint_external) 553 554# Rule build a redirector object file. 555function(add_redirector_object target_name) 556 cmake_parse_arguments( 557 "REDIRECTOR_OBJECT" 558 "" # No optional arguments 559 "SRC" # The cpp file in which the redirector is defined. 560 "" # No multivalue arguments 561 ${ARGN} 562 ) 563 if(NOT REDIRECTOR_OBJECT_SRC) 564 message(FATAL_ERROR "'add_redirector_object' rule requires SRC option listing one source file.") 565 endif() 566 567 add_library( 568 ${target_name} 569 EXCLUDE_FROM_ALL 570 OBJECT 571 ${REDIRECTOR_OBJECT_SRC} 572 ) 573 target_compile_options( 574 ${target_name} 575 BEFORE PRIVATE -fPIC ${LIBC_COMPILE_OPTIONS_DEFAULT} 576 ) 577endfunction(add_redirector_object) 578