diff --git a/CMakeLists.txt b/CMakeLists.txt index 68c3607c58..a32ac2bc24 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") @@ -204,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 @@ -260,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") @@ -270,7 +300,38 @@ 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() -endif() + + if (NOT USE_LLVM_FAT_LIB) + message(STATUS "Link against individual LLVM modules") + set(LLVM_REQUIRED_LIBRARIES + Core + Support + BitWriter + Analysis + Passes + Demangle + Analysis + IRReader + Linker + ) + foreach(lib ${LLVM_REQUIRED_LIBRARIES}) + 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() + + 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) + 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) +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") @@ -315,7 +376,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 + include_directories( ${CLANG_INCLUDE_DIR} ${PHASAR_SRC_DIR}/../clang/include ${PROJECT_BINARY_DIR}/tools/clang/include @@ -335,13 +396,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 @@ -413,17 +469,30 @@ 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 + ) + set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS phasar_interface) +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 4e7b2a901e..2c9decf9a9 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}) @@ -192,22 +198,20 @@ 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} + ) + endif() if(MSVC) get_target_property(cflag ${name} COMPILE_FLAGS) @@ -220,31 +224,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