Skip to content

Commit

Permalink
Account for components available only in LLVM shared library
Browse files Browse the repository at this point in the history
LLVM components may be built as individual libraries/archives, included
in the LLVM shared library or both. Some distros such as Ubuntu (at
least 20.04) does both, others such as Arch ships only the shared
library. The latter causes issues when trying to link Mull against
components such as clangTooling and clangCodeGen as they are not
available on the system.

LLVM allows for checking whether the shared lib was built at all
through LLVM_LINK_LLVM_DYLIB and, if it were, which components were
included in it through LLVM_DYLIB_COMPONENTS. This commit attempts to
leverage these variables in order to select the appropriate library
to link against.

If the component in question is included in the shared library, linking
against the latter is always preferred. If the component is not included
in the shared library, or if the library doesn't exist at all, linking
is done against the individual component lib/archive.
  • Loading branch information
vengaer authored and AlexDenisov committed Jan 14, 2023
1 parent 527d4b8 commit caddc5d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 deletions.
46 changes: 46 additions & 0 deletions cmake/functions.cmake
Expand Up @@ -28,3 +28,49 @@ macro(add_mull_executable)
RUNTIME DESTINATION bin
)
endmacro()

function(determine_clang_component_lib lib_out component)
# Assume the component comes as a separate lib
# until otherwise proven
set(${lib_out} ${component} PARENT_SCOPE)

# Check whether the LLVM shared library was built
if("${LLVM_LINK_LLVM_DYLIB}" STREQUAL "ON" AND NOT "${LLVM_DYLIB_COMPONENTS}" STREQUAL "")
# The LLVM_DYLIB_COMPONENTS variable lists the components included in the
# shared library. According to https://llvm.org/docs/BuildingADistribution.html,
# it is a list of semi-colon separated names of LLVM components or special
# purpose names. The latter are
#
# 1. all - All available LLVM component libraries included
# 2. Native - The LLVM target for the native system
# 3. AllTargetsAsmParsers - All included target ASM parser libraries
# 4. AllTargetsDescs - All included target description libraries
# 5. AllTargetsDisassemblers - All included target dissassembler libraries
# 6. AllTargetsInfos - All included target info libraries
#
# I can't find any relevant reference to Native in the LLVM source tree
# so we leave that out for now
if("${LLVM_DYLIB_COMPONENTS}" STREQUAL "all")
# Dylib includes all components, linking against it is a safe bet
set(${lib_out} clang-cpp PARENT_SCOPE)
elseif(${component} IN_LIST LLVM_DYLIB_COMPONENTS)
# Component listed in DYLIB_COMPONENTS, included
set(${lib_out} clang-cpp PARENT_SCOPE)
else()
# Look through remaining special purpose names. Based on llvm/cmake/modules/LLVM-Config.cmake
# in the LLVM repo, the targets correspond to the following
#
# AllTargetsAsmParsers - All components ending in AsmParser
# AllTargetsDescs - All components ending in Desc
# AllTargetsDisassemblers - All components ending in Disassembler
# AllTargetsInfos - All components ending in Info
set(suffixes AsmParser Desc Disassembler Info)

foreach(s ${suffixes})
if(${component} MATCHES ".*${s}$" AND "${LLVM_DYLIB_COMPONENTS}" STREQUAL "AllTargets${s}s")
set(${lib_out} clang-cpp PARENT_SCOPE)
endif()
endforeach()
endif()
endif()
endfunction()
4 changes: 3 additions & 1 deletion lib/CMakeLists.txt
Expand Up @@ -115,10 +115,12 @@ set_source_files_properties(${mull_header_dirs} PROPERTIES HEADER_FILE_ONLY ON)
find_package(Threads REQUIRED)
find_package(SQLite3 REQUIRED)

determine_clang_component_lib(clang_tooling_lib clangTooling)

target_link_libraries(mull
LLVM
SQLite::SQLite3
clangTooling
"${clang_tooling_lib}"
Threads::Threads
irm
mull-cxx-mutators
Expand Down
5 changes: 4 additions & 1 deletion tests/CMakeLists.txt
Expand Up @@ -45,11 +45,14 @@ get_filename_component(factory_include_dir ${FACTORY_HEADER} DIRECTORY)

add_executable(mull-tests EXCLUDE_FROM_ALL ${mull_unittests_sources})
gtest_discover_tests(mull-tests)

determine_clang_component_lib(clang_codegen_lib clangCodeGen)

target_link_libraries(mull-tests
mull
google-test
json11
clangCodeGen
"${clang_codegen_lib}"
)

target_include_directories(mull-tests PUBLIC
Expand Down

0 comments on commit caddc5d

Please sign in to comment.