Skip to content

Commit

Permalink
Fix Build (#684)
Browse files Browse the repository at this point in the history
* Add split-dwarf to improve linker resource consumption in incremental build

* More target-oriented cmake + verify that llvm small libs exist when not using the fat lib

* Single export set + rename install components

* minor fix

* Auto-detect whether we should link against the fat LLVM lib

* Fix in-tree build

* fix llvm small library search

* make output of non-found small llvm libs pretty

---------

Co-authored-by: Martin Mory <[email protected]>
  • Loading branch information
fabianbs96 and Martin Mory authored Nov 25, 2023
1 parent ae8c161 commit 4c04ed3
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 64 deletions.
99 changes: 84 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand Down Expand Up @@ -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
$<BUILD_INTERFACE:${PHASAR_SRC_DIR}/include/> # The regular include folder
$<BUILD_INTERFACE:${PHASAR_BINARY_DIR}/include/> # The location of phasar-config.h
$<INSTALL_INTERFACE:include/> # The installed include folder
)

### Adding external libraries

# Threads
Expand Down Expand Up @@ -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")
Expand All @@ -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")
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
43 changes: 23 additions & 20 deletions Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
48 changes: 20 additions & 28 deletions cmake/phasar_macros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand All @@ -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
$<BUILD_INTERFACE:${PHASAR_SRC_DIR}/include/> # The regular include folder
$<BUILD_INTERFACE:${PHASAR_BINARY_DIR}/include/> # 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
$<INSTALL_INTERFACE:include/>
)
# 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)
Expand All @@ -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})
Expand Down
4 changes: 3 additions & 1 deletion examples/use-phasar-as-library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 4c04ed3

Please sign in to comment.