From 9f5aa8578c8a5793b1ad8dc39c8327e24ad7b53c Mon Sep 17 00:00:00 2001 From: Nils Wentzell Date: Tue, 24 Sep 2019 15:17:47 -0400 Subject: [PATCH] [cmake] Provide extract_flags macro in share/cmake directory, simplify creation of docs_cpp2rst target --- doc/CMakeLists.txt | 23 +++-------- share/cmake/extract_flags.cmake | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 share/cmake/extract_flags.cmake diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 0d26b4a9..c8bbd4d5 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -4,23 +4,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in ${CMAKE_CURRENT_BINARY_DIR # ----------------------------------------------------------------------------- # Create an optional target that allows us to regenerate the C++ doc with c++2rst # ----------------------------------------------------------------------------- -foreach(t app4triqs_c triqs) - get_property(INCLUDE_DIRS TARGET ${t} PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - get_property(SYSTEM_INCLUDE_DIRS TARGET ${t} PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) - if(SYTEM_INCLUDE_DIRS) - list(REMOVE_ITEM INCLUDE_DIRS ${SYSTEM_INCLUDE_DIRS}) - endif() - foreach(DIR ${INCLUDE_DIRS}) - set(CPP2RST_INCLUDE_FLAGS ${CPP2RST_INCLUDE_FLAGS} -I${DIR}) - endforeach() - foreach(DIR ${SYSTEM_INCLUDE_DIRS}) - set(CPP2RST_INCLUDE_FLAGS ${CPP2RST_INCLUDE_FLAGS} -isystem=${DIR}) - endforeach() - get_property(COMPILE_OPTIONS TARGET ${t} PROPERTY INTERFACE_COMPILE_OPTIONS) - set(CPP2RST_CXXFLAGS ${CPP2RST_CXXFLAGS} ${COMPILE_OPTIONS}) -endforeach() - add_custom_target(docs_cpp2rst) +include(${PROJECT_SOURCE_DIR}/share/cmake/extract_flags.cmake) +extract_flags(app4triqs_c) +separate_arguments(app4triqs_c_CXXFLAGS) macro(generate_docs header_file) add_custom_command( TARGET docs_cpp2rst @@ -30,8 +17,8 @@ macro(generate_docs header_file) ${header_file} -N app4triqs --output_directory ${CMAKE_CURRENT_SOURCE_DIR}/cpp2rst_generated - --cxxflags="${CPP2RST_CXXFLAGS}" - ${CPP2RST_INCLUDE_FLAGS} + -I${PROJECT_SOURCE_DIR}/c++ + --cxxflags="${app4triqs_c_CXXFLAGS}" ) endmacro(generate_docs) diff --git a/share/cmake/extract_flags.cmake b/share/cmake/extract_flags.cmake new file mode 100644 index 00000000..d71f31f1 --- /dev/null +++ b/share/cmake/extract_flags.cmake @@ -0,0 +1,67 @@ +# Recursively fetch all targets that the interface of a target depends upon +macro(get_all_interface_targets name target) + get_property(TARGET_LINK_LIBRARIES TARGET ${target} PROPERTY INTERFACE_LINK_LIBRARIES) + foreach(lib IN LISTS TARGET_LINK_LIBRARIES) + if(TARGET ${lib}) + # Append to list + list(APPEND ${name}_INTERFACE_TARGETS ${lib}) + # Recure into target dependencies + get_all_interface_targets(${name} ${lib}) + endif() + endforeach() +endmacro() + +# Extract the property from the target and recursively from all targets it depends upon +macro(get_property_recursive) + cmake_parse_arguments(get_property_recursive "" "TARGET" "PROPERTY" ${ARGN}) + set(target ${get_property_recursive_TARGET}) + set(property ${get_property_recursive_PROPERTY}) + get_all_interface_targets(${target} ${target}) + foreach(t IN LISTS ${target}_INTERFACE_TARGETS ITEMS ${target}) + get_property(p TARGET ${t} PROPERTY ${property}) + list(APPEND ${ARGV0} ${p}) + endforeach() + # Clean duplicates and any occurance of '/usr/include' dirs + if(${ARGV0}) + list(REMOVE_DUPLICATES ${ARGV0}) + list(REMOVE_ITEM ${ARGV0} /usr/include) + endif() +endmacro() + +# Recursively fetch all compiler flags attached to the interface of a target +macro(extract_flags target) + + get_property_recursive(opts TARGET ${target} PROPERTY INTERFACE_COMPILE_OPTIONS) + foreach(opt ${opts}) + set(${target}_LDFLAGS "${${target}_LDFLAGS} ${opt}") + set(${target}_CXXFLAGS "${${target}_CXXFLAGS} ${opt}") + endforeach() + + get_property_recursive(defs TARGET ${target} PROPERTY INTERFACE_COMPILE_DEFINITIONS) + foreach(def ${defs}) + set(${target}_CXXFLAGS "${${target}_CXXFLAGS} -D${def}") + endforeach() + + get_property_recursive(inc_dirs TARGET ${target} PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + get_property_recursive(sys_inc_dirs TARGET ${target} PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + list(REMOVE_ITEM inc_dirs ${sys_inc_dirs}) + foreach(dir ${inc_dirs}) + set(${target}_CXXFLAGS "${${target}_CXXFLAGS} -I${dir}") + endforeach() + foreach(dir ${sys_inc_dirs}) + set(${target}_CXXFLAGS "${${target}_CXXFLAGS} -isystem${dir}") + endforeach() + + get_property_recursive(libs TARGET ${target} PROPERTY INTERFACE_LINK_LIBRARIES) + foreach(lib ${libs}) + if(NOT TARGET ${lib}) + set(${target}_LDFLAGS "${${target}_LDFLAGS} ${lib}") + endif() + endforeach() + + # We have to replace generator expressions explicitly + string(REGEX REPLACE "\\$" "\\1" ${target}_LDFLAGS "${${target}_LDFLAGS}") + string(REGEX REPLACE "\\$" "\\1" ${target}_CXXFLAGS "${${target}_CXXFLAGS}") + string(REGEX REPLACE " [^ ]*\\$<[^ ]*:[^ ]*>" "" ${target}_LDFLAGS "${${target}_LDFLAGS}") + string(REGEX REPLACE " [^ ]*\\$<[^ ]*:[^ ]*>" "" ${target}_CXXFLAGS "${${target}_CXXFLAGS}") +endmacro()