diff --git a/atdna/CMakeLists.txt b/atdna/CMakeLists.txt index e0f5321..3d5510d 100644 --- a/atdna/CMakeLists.txt +++ b/atdna/CMakeLists.txt @@ -180,80 +180,6 @@ add_test(NAME test-dna COMMAND $ -o test.cpp endif() -####################### -# In-tree atdna macro # -####################### - -# Super handy macro for adding atdna target -function(atdna out incdirs cdefs) - # Ninja wants invocations in root binary dir for DEPFILE application - file(RELATIVE_PATH out_rel ${CMAKE_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/${out}") - - # Make input files source-relative - unset(ins) - unset(ins_impdeps) - foreach(arg ${ARGN}) - list(APPEND ins ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) - list(APPEND ins_impdeps CXX) - list(APPEND ins_impdeps ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) - endforeach() - - # MS extra - unset(extraargs) - if(MSVC) - list(APPEND extraargs -fms-compatibility -fexceptions) - if(MSVC_VERSION EQUAL 1800) - list(APPEND extraargs -fms-compatibility-version=18.00) - elseif(MSVC_VERSION EQUAL 1900) - list(APPEND extraargs -fms-compatibility-version=19.00) - elseif(MSVC_VERSION EQUAL 1910) - list(APPEND extraargs -fms-compatibility-version=19.10) - elseif(MSVC_VERSION EQUAL 1911) - list(APPEND extraargs -fms-compatibility-version=19.11) - endif() - - # OSX Extra - elseif(APPLE) - get_filename_component(COMPILER_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) - if (NOT EXISTS "${CMAKE_OSX_SYSROOT}") - message(FATAL_ERROR "CMAKE_OSX_SYSROOT not set") - endif() - list(APPEND extraargs - -I ${COMPILER_DIR}/../include/c++/v1 - -isysroot ${CMAKE_OSX_SYSROOT}) - endif() - - # Make target - if(${CMAKE_GENERATOR} STREQUAL "Ninja") - # Use Ninja's DEPFILE parser in cooperation with atdna - add_custom_command(OUTPUT ${out} COMMAND $ - ARGS ${extraargs} -o ${out_rel} -MD -MT ${out_rel} -MF ${out_rel}.d - "$<$:-I$>" - "$<$:-D$>" - "-I${athena_SOURCE_DIR}/include" -isystem "${CLANG_INCLUDE_DIR}" ${ins} - DEPENDS atdna ${ins} IMPLICIT_DEPENDS ${ins_impdeps} - DEPFILE "${CMAKE_CURRENT_BINARY_DIR}/${out}.d" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating DNA ${out_rel}" - COMMAND_EXPAND_LISTS) - else() - # Use CMake's built-in dependency scanner for makefile targets - add_custom_command(OUTPUT ${out} COMMAND $ - ARGS ${extraargs} -o ${out_rel} - "$<$:-I$>" - "$<$:-D$>" - "-I${athena_SOURCE_DIR}/include" -isystem "${CLANG_INCLUDE_DIR}" ${ins} - DEPENDS atdna ${ins} IMPLICIT_DEPENDS ${ins_impdeps} - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Generating DNA ${out_rel}" - COMMAND_EXPAND_LISTS) - endif() -endfunction() - -function(target_atdna target out) - atdna(${out} "$" - "$" ${ARGN}) - target_sources(${target} PRIVATE ${out} ${ARGN}) -endfunction() +include(atdnaHelpers.cmake) endif() diff --git a/atdna/atdnaHelpers.cmake b/atdna/atdnaHelpers.cmake new file mode 100644 index 0000000..a86cb88 --- /dev/null +++ b/atdna/atdnaHelpers.cmake @@ -0,0 +1,147 @@ +# +# gather_include_directories recursively builds a list of include directories +# across all dependencies. +# + +function(_atdna_gather_include_directories_impl target_name) + get_target_property(target_dependencies ${target_name} INTERFACE_LINK_LIBRARIES) + foreach(dep ${target_dependencies}) + if(TARGET ${dep}) + get_target_property(dep_includes ${dep} INTERFACE_INCLUDE_DIRECTORIES) + if(dep_includes) + list(APPEND target_includes ${dep_includes}) + endif() + _atdna_gather_include_directories_impl(${dep}) + endif() + endforeach() + set(target_includes ${target_includes} PARENT_SCOPE) +endfunction() + +function(atdna_gather_include_directories var target_name) + unset(target_includes) + get_directory_property(dir_includes INCLUDE_DIRECTORIES) + if(dir_includes) + list(APPEND target_includes ${dir_includes}) + endif() + get_target_property(target_includes1 ${target_name} INCLUDE_DIRECTORIES) + if(target_includes1) + list(APPEND target_includes ${target_includes1}) + endif() + get_target_property(target_includes2 ${target_name} INTERFACE_INCLUDE_DIRECTORIES) + if(target_includes2) + list(APPEND target_includes ${target_includes2}) + endif() + _atdna_gather_include_directories_impl(${target_name}) + list(REMOVE_DUPLICATES target_includes) + set(${var} ${target_includes} PARENT_SCOPE) +endfunction() + +function(_atdna_gather_compile_definitions_impl target_name) + get_target_property(target_dependencies ${target_name} INTERFACE_LINK_LIBRARIES) + foreach(dep ${target_dependencies}) + if(TARGET ${dep}) + get_target_property(dep_defines ${dep} INTERFACE_COMPILE_DEFINITIONS) + if(dep_defines) + list(APPEND target_defines ${dep_defines}) + endif() + _atdna_gather_compile_definitions_impl(${dep}) + endif() + endforeach() + set(target_defines ${target_defines} PARENT_SCOPE) +endfunction() + +function(atdna_gather_compile_definitions var target_name) + unset(target_defines) + get_directory_property(dir_defines COMPILE_DEFINITIONS) + if(dir_defines) + list(APPEND target_defines ${dir_defines}) + endif() + get_target_property(target_defines1 ${target_name} COMPILE_DEFINITIONS) + if(target_defines1) + list(APPEND target_defines ${target_defines1}) + endif() + get_target_property(target_defines2 ${target_name} INTERFACE_COMPILE_DEFINITIONS) + if(target_defines2) + list(APPEND target_defines ${target_defines2}) + endif() + _atdna_gather_compile_definitions_impl(${target_name}) + list(REMOVE_DUPLICATES target_defines) + set(${var} ${target_defines} PARENT_SCOPE) +endfunction() + +####################### +# In-tree atdna macro # +####################### + +# Super handy macro for adding atdna target +function(atdna out incdirs cdefs) + # Ninja wants invocations in root binary dir for DEPFILE application + file(RELATIVE_PATH out_rel ${CMAKE_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/${out}") + + # Make input files source-relative + unset(ins) + unset(ins_impdeps) + foreach(arg ${ARGN}) + list(APPEND ins ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) + list(APPEND ins_impdeps CXX) + list(APPEND ins_impdeps ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) + endforeach() + + # MS extra + unset(extraargs) + if(MSVC) + list(APPEND extraargs -fms-compatibility -fexceptions) + if(MSVC_VERSION EQUAL 1800) + list(APPEND extraargs -fms-compatibility-version=18.00) + elseif(MSVC_VERSION EQUAL 1900) + list(APPEND extraargs -fms-compatibility-version=19.00) + elseif(MSVC_VERSION EQUAL 1910) + list(APPEND extraargs -fms-compatibility-version=19.10) + elseif(MSVC_VERSION EQUAL 1911) + list(APPEND extraargs -fms-compatibility-version=19.11) + endif() + + # OSX Extra + elseif(APPLE) + get_filename_component(COMPILER_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) + if (NOT EXISTS "${CMAKE_OSX_SYSROOT}") + message(FATAL_ERROR "CMAKE_OSX_SYSROOT not set") + endif() + list(APPEND extraargs + -I ${COMPILER_DIR}/../include/c++/v1 + -isysroot ${CMAKE_OSX_SYSROOT}) + endif() + + # Make target + if(${CMAKE_GENERATOR} STREQUAL "Ninja") + # Use Ninja's DEPFILE parser in cooperation with atdna + add_custom_command(OUTPUT ${out} COMMAND $ + ARGS ${extraargs} -o ${out_rel} -MD -MT ${out_rel} -MF ${out_rel}.d + "$<$:-I$>" + "$<$:-D$>" + "-I${athena_SOURCE_DIR}/include" -isystem "${CLANG_INCLUDE_DIR}" ${ins} + DEPENDS atdna ${ins} IMPLICIT_DEPENDS ${ins_impdeps} + DEPFILE "${CMAKE_CURRENT_BINARY_DIR}/${out}.d" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating DNA ${out_rel}" + COMMAND_EXPAND_LISTS) + else() + # Use CMake's built-in dependency scanner for makefile targets + add_custom_command(OUTPUT ${out} COMMAND $ + ARGS ${extraargs} -o ${out_rel} + "$<$:-I$>" + "$<$:-D$>" + "-I${athena_SOURCE_DIR}/include" -isystem "${CLANG_INCLUDE_DIR}" ${ins} + DEPENDS atdna ${ins} IMPLICIT_DEPENDS ${ins_impdeps} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating DNA ${out_rel}" + COMMAND_EXPAND_LISTS) + endif() +endfunction() + +function(target_atdna target out) + atdna_gather_include_directories(include_list ${target}) + atdna_gather_compile_definitions(define_list ${target}) + atdna(${out} "${include_list}" "${define_list}" ${ARGN}) + target_sources(${target} PRIVATE ${out} ${ARGN}) +endfunction()