From d4f2d8914fab7c79e426e40ade3603f4b9364d8c Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 19 Nov 2023 15:30:45 +0100 Subject: [PATCH 1/8] Add split-dwarf to improve linker resource consumption in incremental build --- CMakeLists.txt | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68c3607c58..53a7da07b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,27 @@ string(APPEND CMAKE_CXX_FLAGS_RELEASE "") option(CMAKE_VISIBILITY_INLINES_HIDDEN "Hide inlined functions from the DSO table (default ON)" ON) +include(CheckCXXCompilerFlag) + +# Handle memory issues with linking +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " -gsplit-dwarf") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -gsplit-dwarf") + set(LINKER_FLAGS_SAVE ${CMAKE_EXE_LINKER_FLAGS}) + + # See LLVM_USE_SPLIT_DWARF in LLVM + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gdb-index") + cmake_policy(PUSH) + cmake_policy(SET CMP0056 NEW) + check_cxx_compiler_flag("" GDB_INDEX_SUPPORTED) + cmake_policy(POP) + set(CMAKE_EXE_LINKER_FLAGS ${LINKER_FLAGS_SAVE}) + + if(GDB_INDEX_SUPPORTED) + link_libraries(debug "-Wl,--gdb-index") + endif() +endif() + # march=native # NOTE: Use gcc -march=native -Q --help=target | grep -- '-march=' | cut -f3 @@ -87,7 +108,6 @@ elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Release") endif() if (NOT "${PHASAR_TARGET_ARCH_INTERNAL}" STREQUAL "") - include(CheckCXXCompilerFlag) check_cxx_compiler_flag("-march=${PHASAR_TARGET_ARCH_INTERNAL}" MARCH_SUPPORTED) if (MARCH_SUPPORTED) message(STATUS "Target architecture '${PHASAR_TARGET_ARCH_INTERNAL}' enabled") From 04c79c47d53587fadefaf2ff5bb7f1dc27095ba1 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 19 Nov 2023 15:38:32 +0100 Subject: [PATCH 2/8] More target-oriented cmake + verify that llvm small libs exist when not using the fat lib --- CMakeLists.txt | 36 +++++++++++++++++++++++++++++------- cmake/phasar_macros.cmake | 27 +++++++++++++++------------ 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53a7da07b7..382cc74d98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,6 +224,17 @@ else() set(PHASAR_CONFIG_INSTALL_DIR "${PHASAR_CUSTOM_CONFIG_INSTALL_DIR}") endif() + +# Headers + +add_library(phasar_interface INTERFACE) +target_include_directories(phasar_interface + INTERFACE + $ # The regular include folder + $ # The location of phasar-config.h + $ # The installed include folder +) + ### Adding external libraries # Threads @@ -280,7 +291,6 @@ option(USE_LLVM_FAT_LIB "Link against libLLVM.so instead of the individual LLVM if (NOT PHASAR_IN_TREE) # Only search for LLVM if we build out of tree find_package(LLVM 14 REQUIRED CONFIG) - find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) if(USE_LLVM_FAT_LIB AND ${LLVM_LIBRARY} STREQUAL "LLVM_LIBRARY-NOTFOUND") @@ -290,6 +300,23 @@ if (NOT PHASAR_IN_TREE) message(STATUS "Found consolidated shared LLVM lib ${LLVM_LIBRARY} that will be linked against.") set(USE_LLVM_FAT_LIB ON) endif() + + if (NOT USE_LLVM_FAT_LIB) + set(LLVM_REQUIRED_LIBRARIES + Core + Support + BitWriter + Analysis + Passes + Demangle + Analysis + IRReader + Linker + ) + foreach(lib ${LLVM_REQUIRED_LIBRARIES}) + find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH REQUIRED) + endforeach() + endif() endif() if(NOT LLVM_ENABLE_RTTI AND NOT PHASAR_IN_TREE) @@ -335,7 +362,7 @@ if(BUILD_PHASAR_CLANG) if (PHASAR_IN_TREE) # Phasar needs clang headers, specificaly some that are generated by clangs table-gen - include_directories(SYSTEM + set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIR} ${PHASAR_SRC_DIR}/../clang/include ${PROJECT_BINARY_DIR}/tools/clang/include @@ -355,13 +382,8 @@ endif () # Library Dependency Dirs if(NOT PHASAR_IN_TREE) - include_directories(${LLVM_INCLUDE_DIRS}) - link_directories(${LLVM_LIB_PATH} ${LLVM_LIBRARY_DIRS}) separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) add_definitions(${LLVM_DEFINITIONS_LIST}) - if (BUILD_PHASAR_CLANG) - link_directories(${CLANG_LIB_PATH}) - endif() endif() # Installed config diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 4e7b2a901e..0b83f6c681 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -192,22 +192,25 @@ function(add_phasar_library name) target_link_libraries(${name} PUBLIC ${PHASAR_LIB_LINKS}) endif() - target_link_libraries(${name} PUBLIC ${PHASAR_LIB_LINK_PUBLIC}) + target_link_libraries(${name} PUBLIC phasar_interface ${PHASAR_LIB_LINK_PUBLIC}) target_link_libraries(${name} PRIVATE ${PHASAR_LIB_LINK_PRIVATE}) phasar_link_llvm(${name} ${PHASAR_LIB_LLVM_LINK_COMPONENTS}) - target_include_directories(${name} - PUBLIC - $ # The regular include folder - $ # The location of phasar-config.h - ) - - # Set the target property such that installed PhASAR knows where to find its includes (must be relative paths in this case in contrast to non-installed PhASAR!) - set_property(TARGET ${name} APPEND - PROPERTY INTERFACE_INCLUDE_DIRECTORIES - $ - ) + # Library Dependency Dirs + if(NOT PHASAR_IN_TREE) + target_include_directories(${name} PUBLIC + ${LLVM_INCLUDE_DIRS} + ) + target_link_directories(${name} PUBLIC + ${LLVM_LIB_PATH} ${LLVM_LIBRARY_DIRS} + ) + if (BUILD_PHASAR_CLANG) + target_link_directories(${name} PUBLIC + ${CLANG_LIB_PATH} + ) + endif() + endif() if(MSVC) get_target_property(cflag ${name} COMPILE_FLAGS) From 60cd53498602089c24a55d6673d764ead4fd7f68 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 19 Nov 2023 15:39:26 +0100 Subject: [PATCH 3/8] Single export set + rename install components --- CMakeLists.txt | 28 +++++++++--- Config.cmake.in | 43 ++++++++++--------- cmake/phasar_macros.cmake | 26 +++++------ examples/use-phasar-as-library/CMakeLists.txt | 4 +- 4 files changed, 57 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 382cc74d98..54fbf05e40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,7 +361,7 @@ if(BUILD_PHASAR_CLANG) endif() if (PHASAR_IN_TREE) - # Phasar needs clang headers, specificaly some that are generated by clangs table-gen + # Phasar needs clang headers, specificaly some that are generated by clangs table-gen set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIR} ${PHASAR_SRC_DIR}/../clang/include @@ -455,17 +455,31 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/phasar/Config/ PATTERN "*.h" ) -# Install the header only json container +if(NOT PHASAR_IN_TREE) + install(TARGETS phasar_interface + EXPORT PhasarExports + ) + + # Install the export-set containing all the phasar targets + install(EXPORT PhasarExports + FILE PhasarExports.cmake + NAMESPACE phasar:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/phasar" + ) +else() + install(TARGETS phasar_interface + EXPORT LLVMExports + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ) +endif() + +# Install the header only json container ### TODO Fix this! install(DIRECTORY external/json/single_include/ DESTINATION include FILES_MATCHING PATTERN "*.hpp" ) -# Install the gtest header files (TODO this installation dependency should be eliminated) -install(DIRECTORY external/googletest/googletest/include/gtest/ - DESTINATION include/gtest -) - # Install Phasar utils helper scripts install(DIRECTORY utils/ DESTINATION bin diff --git a/Config.cmake.in b/Config.cmake.in index 98d5c07c78..5828af35ee 100644 --- a/Config.cmake.in +++ b/Config.cmake.in @@ -14,8 +14,6 @@ find_package(LLVM 14 REQUIRED CONFIG) set(PHASAR_USE_LLVM_FAT_LIB @USE_LLVM_FAT_LIB@) set(PHASAR_BUILD_DYNLIB @PHASAR_BUILD_DYNLIB@) -# TODO: The order seems to be important in the include'ing loop below. Fix this! - set(PHASAR_COMPONENTS utils passes @@ -40,30 +38,35 @@ set(PHASAR_COMPONENTS list(REMOVE_DUPLICATES phasar_FIND_COMPONENTS) +set(PHASAR_NEEDED_LIBS) + +include("${CMAKE_CURRENT_LIST_DIR}/PhasarExports.cmake") + foreach(component ${phasar_FIND_COMPONENTS}) if(NOT ${component} IN_LIST PHASAR_COMPONENTS) set(phasar_FOUND false) - set(phasar_NOT_FOUND_MESSAGE "Unsupported component: ${component}. valid components are: ${PHASAR_COMPONENTS}") + set(phasar_NOT_FOUND_MESSAGE "Unsupported component: ${component}. Valid components are: ${PHASAR_COMPONENTS}") endif() -endforeach() -foreach(component ${PHASAR_COMPONENTS}) - include("${CMAKE_CURRENT_LIST_DIR}/phasar_${component}-targets.cmake") + list(APPEND PHASAR_NEEDED_LIBS phasar::${component}) endforeach() -include("${CMAKE_CURRENT_LIST_DIR}/phasar-targets.cmake") -if (NOT phasar_FIND_COMPONENTS) - list(APPEND PHASAR_NEEDED_LIBS phasar::phasar) - set(phasar_FIND_COMPONENTS ${PHASAR_NEEDED_LIBS}) -endif() +if (phasar_FOUND) + foreach(component ${phasar_FIND_COMPONENTS}) + # For backwards compatibility -- will be removed with next release + add_library(phasar::phasar_${component} ALIAS phasar::${component}) + endforeach() -foreach(component ${phasar_FIND_COMPONENTS}) - list(APPEND PHASAR_NEEDED_LIBS phasar::phasar_${component}) -endforeach() + if (NOT phasar_FIND_COMPONENTS) + list(APPEND PHASAR_NEEDED_LIBS phasar::phasar) + # Default target + add_library(phasar ALIAS phasar::phasar) + endif() -function(phasar_config executable) - target_link_libraries(${executable} - PUBLIC - ${PHASAR_NEEDED_LIBS} - ) -endfunction() + function(phasar_config executable) + target_link_libraries(${executable} + PUBLIC + ${PHASAR_NEEDED_LIBS} + ) + endfunction() +endif() diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index 0b83f6c681..fc3e528a7d 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -179,8 +179,14 @@ function(add_phasar_library name) set(libkind STATIC) endif() + # cut off prefix phasar_ for convenient component names + string(REGEX REPLACE phasar_ "" component_name ${name}) + add_library(${name} ${libkind} ${srcs}) - add_library(phasar::${name} ALIAS ${name}) + add_library(phasar::${component_name} ALIAS ${name}) + set_target_properties(${name} PROPERTIES + EXPORT_NAME ${component_name} + ) if(LLVM_COMMON_DEPENDS) add_dependencies(${name} ${LLVM_COMMON_DEPENDS}) @@ -223,31 +229,19 @@ function(add_phasar_library name) set_target_properties(${name} PROPERTIES COMPILE_FLAGS ${cflag}) endif(MSVC) - # cut off prefix phasar_ for convenient component names - string(REGEX REPLACE phasar_ "" component_name ${name}) - if(PHASAR_IN_TREE) install(TARGETS ${name} EXPORT LLVMExports LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} + ) else() install(TARGETS ${name} - EXPORT ${name}-targets - COMPONENT ${component_name} - - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + EXPORT PhasarExports # NOTE: Library, archive and runtime destination are automatically set by # GNUInstallDirs which is included in the top-level CMakeLists.txt ) - install(EXPORT ${name}-targets - FILE ${name}-targets.cmake - NAMESPACE phasar:: - DESTINATION lib/cmake/phasar - COMPONENT ${component_name} - ) endif() set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) diff --git a/examples/use-phasar-as-library/CMakeLists.txt b/examples/use-phasar-as-library/CMakeLists.txt index de0f50fd16..a7bfaa8d96 100644 --- a/examples/use-phasar-as-library/CMakeLists.txt +++ b/examples/use-phasar-as-library/CMakeLists.txt @@ -21,10 +21,12 @@ add_executable(myphasartool # phasar_config(myphasartool) # New way using target_link_libraries: -target_link_libraries(myphasartool phasar::phasar_llvm_ifdside) +target_link_libraries(myphasartool phasar::llvm_ifdside) # If find_package did not specify components: # target_link_libraries(myphasartool phasar::phasar) +# alternatively using the default target: +# target_link_libraries(myphasartool phasar) install(TARGETS myphasartool RUNTIME DESTINATION bin From ad55a1fa43594c7d9c90f45298e4ab682f87cebe Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Sun, 19 Nov 2023 15:45:40 +0100 Subject: [PATCH 4/8] minor fix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54fbf05e40..02188b047c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,7 +314,7 @@ if (NOT PHASAR_IN_TREE) Linker ) foreach(lib ${LLVM_REQUIRED_LIBRARIES}) - find_library(LLVM_LIBRARY NAMES LLVM PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH REQUIRED) + find_library(LLVM_SMALL_LIB NAMES LLVM${lib} PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH REQUIRED) endforeach() endif() endif() From c5176fc6d7f803c59051e85c5db141596463af25 Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 20 Nov 2023 18:03:00 +0100 Subject: [PATCH 5/8] Auto-detect whether we should link against the fat LLVM lib --- CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02188b047c..6f36f084a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,7 @@ if (NOT PHASAR_IN_TREE) endif() if (NOT USE_LLVM_FAT_LIB) + message(STATUS "Link against individual LLVM modules") set(LLVM_REQUIRED_LIBRARIES Core Support @@ -314,10 +315,22 @@ if (NOT PHASAR_IN_TREE) Linker ) foreach(lib ${LLVM_REQUIRED_LIBRARIES}) - find_library(LLVM_SMALL_LIB NAMES LLVM${lib} PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH REQUIRED) + find_library(LLVM_SMALL_LIB NAMES LLVM${lib} PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) + if(LLVM_SMALL_LIB STREQUAL "LLVM_SMALL_LIB-NOTFOUND") + list(APPEND LLVM_SMALL_LIB_NOTFOUND "LLVM${lib}") + endif() endforeach() - endif() -endif() + + if(DEFINED LLVM_SMALL_LIB_NOTFOUND) + if(${LLVM_LIBRARY} STREQUAL "LLVM_LIBRARY-NOTFOUND") + message(FATAL_ERROR "Did not find a complete version of LLVM: Did not find the fat lib libLLVM.so, but also did not find the individual modules ${LLVM_SMALL_LIB_NOTFOUND}.") + else() + set(USE_LLVM_FAT_LIB ON) + message(WARNING "Did not find the LLVM modules ${LLVM_SMALL_LIB_NOTFOUND}. Fallback to link against ${LLVM_LIBRARY}. To silence this warning, set -DUSE_LLVM_FAT_LIB=ON in the cmake invocation.") + endif() + endif(DEFINED LLVM_SMALL_LIB_NOTFOUND) + endif(NOT USE_LLVM_FAT_LIB) +endif(NOT PHASAR_IN_TREE) if(NOT LLVM_ENABLE_RTTI AND NOT PHASAR_IN_TREE) message(FATAL_ERROR "PhASAR requires a LLVM version that is built with RTTI") From cb7fd9c7b0cb6c79a9162be3dd400ac6b1a03a6c Mon Sep 17 00:00:00 2001 From: Fabian Schiebel Date: Mon, 20 Nov 2023 18:41:45 +0100 Subject: [PATCH 6/8] Fix in-tree build --- CMakeLists.txt | 7 +++---- cmake/phasar_macros.cmake | 5 ----- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f36f084a2..ffab0ea44e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -374,8 +374,8 @@ if(BUILD_PHASAR_CLANG) endif() if (PHASAR_IN_TREE) - # Phasar needs clang headers, specificaly some that are generated by clangs table-gen - set(CLANG_INCLUDE_DIRS + # Phasar needs clang headers, specificaly some that are generated by clangs table-gen + include_directories( ${CLANG_INCLUDE_DIR} ${PHASAR_SRC_DIR}/../clang/include ${PROJECT_BINARY_DIR}/tools/clang/include @@ -482,9 +482,8 @@ if(NOT PHASAR_IN_TREE) else() install(TARGETS phasar_interface EXPORT LLVMExports - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} ) + set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS phasar_interface) endif() # Install the header only json container ### TODO Fix this! diff --git a/cmake/phasar_macros.cmake b/cmake/phasar_macros.cmake index fc3e528a7d..2c9decf9a9 100644 --- a/cmake/phasar_macros.cmake +++ b/cmake/phasar_macros.cmake @@ -211,11 +211,6 @@ function(add_phasar_library name) target_link_directories(${name} PUBLIC ${LLVM_LIB_PATH} ${LLVM_LIBRARY_DIRS} ) - if (BUILD_PHASAR_CLANG) - target_link_directories(${name} PUBLIC - ${CLANG_LIB_PATH} - ) - endif() endif() if(MSVC) From c975b40bd557ba066f259414c8aa2288c0ff2f09 Mon Sep 17 00:00:00 2001 From: Martin Mory Date: Fri, 24 Nov 2023 10:20:07 +0100 Subject: [PATCH 7/8] fix llvm small library search --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ffab0ea44e..94a2b32454 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,8 +315,8 @@ if (NOT PHASAR_IN_TREE) Linker ) foreach(lib ${LLVM_REQUIRED_LIBRARIES}) - find_library(LLVM_SMALL_LIB NAMES LLVM${lib} PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) - if(LLVM_SMALL_LIB STREQUAL "LLVM_SMALL_LIB-NOTFOUND") + find_library(LLVM_SMALL_LIB${lib} NAMES LLVM${lib} PATHS ${LLVM_LIBRARY_DIRS} NO_DEFAULT_PATH) + if(LLVM_SMALL_LIB${lib} MATCHES "NOTFOUND$") list(APPEND LLVM_SMALL_LIB_NOTFOUND "LLVM${lib}") endif() endforeach() From 877257c7cd34d50dbde9352fc9a81daeedca3897 Mon Sep 17 00:00:00 2001 From: Martin Mory Date: Fri, 24 Nov 2023 10:20:29 +0100 Subject: [PATCH 8/8] make output of non-found small llvm libs pretty --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94a2b32454..a32ac2bc24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,7 +326,8 @@ if (NOT PHASAR_IN_TREE) message(FATAL_ERROR "Did not find a complete version of LLVM: Did not find the fat lib libLLVM.so, but also did not find the individual modules ${LLVM_SMALL_LIB_NOTFOUND}.") else() set(USE_LLVM_FAT_LIB ON) - message(WARNING "Did not find the LLVM modules ${LLVM_SMALL_LIB_NOTFOUND}. Fallback to link against ${LLVM_LIBRARY}. To silence this warning, set -DUSE_LLVM_FAT_LIB=ON in the cmake invocation.") + list(JOIN LLVM_SMALL_LIB_NOTFOUND ", " LLVM_SMALL_LIB_NOTFOUND_PRETTY) + message(WARNING "Did not find the LLVM modules ${LLVM_SMALL_LIB_NOTFOUND_PRETTY}. Fallback to link against ${LLVM_LIBRARY}. To silence this warning, set -DUSE_LLVM_FAT_LIB=ON in the cmake invocation.") endif() endif(DEFINED LLVM_SMALL_LIB_NOTFOUND) endif(NOT USE_LLVM_FAT_LIB)