diff options
-rw-r--r-- | cmake/find_llvm.cmake | 69 |
1 files changed, 60 insertions, 9 deletions
diff --git a/cmake/find_llvm.cmake b/cmake/find_llvm.cmake index 60d7b3e4..b1d3dc27 100644 --- a/cmake/find_llvm.cmake +++ b/cmake/find_llvm.cmake @@ -149,18 +149,69 @@ else() string_to_list("${_llvm_libs}" _llvm_libs_list) # Now find the system libs that are needed. - # FIXME: This is a hack. We should really create imported - # targets for the LLVM libraries and have them depend - # on the necessary system libraries. _run_llvm_config(_system_libs "--ldflags") string_to_list("${_system_libs}" _system_libs_list) - set(_filtered_system_libs_list "") - foreach (l ${_system_libs_list}) - # Filter out `-L<path>`. - if ("${l}" MATCHES "^-l") - list(APPEND _filtered_system_libs_list "${l}") + + # Create an imported target for each LLVM library + # if it doesn't already exist. We need to do this + # so we can tell CMake that these libraries depend + # on the necessary libraries so that CMake + # can get the link order right. + set(targets_to_return "") + set(created_targets "") + foreach (llvm_lib ${_llvm_libs_list}) + get_filename_component(llvm_lib_file_name "${llvm_lib}" NAME) + string(REGEX REPLACE "^(lib)?(LLVM[a-zA-Z0-9]+)\\..+$" "\\2" target_name "${llvm_lib_file_name}") + list(APPEND targets_to_return "${target_name}") + if (NOT TARGET "${target_name}") + # DEBUG: message(STATUS "Creating imported target \"${target_name}\"" " for \"${llvm_lib}\"") + list(APPEND created_targets "${target_name}") + + set(import_library_type "STATIC") + if ("${llvm_lib_file_name}" MATCHES "(so|dylib|dll)$") + set(import_library_type "SHARED") + endif() + # Create an imported target for the library + add_library("${target_name}" "${import_library_type}" IMPORTED GLOBAL) + set_property(TARGET "${target_name}" PROPERTY + IMPORTED_LOCATION "${llvm_lib}" + ) endif() endforeach() - set(${OUTPUT_VAR} ${_llvm_libs_list} ${_system_libs} PARENT_SCOPE) + + # Now state the dependencies of the created imported targets which we + # assume to be for each imported target the libraries which appear after + # the library in `{_llvm_libs_list}` and then finally the system libs. + # It is **essential** that we do this otherwise CMake will get the + # link order of the imported targets wrong. + list(LENGTH targets_to_return length_targets_to_return) + if ("${length_targets_to_return}" GREATER 0) + math(EXPR targets_to_return_last_index "${length_targets_to_return} -1") + foreach (llvm_target_lib ${created_targets}) + # DEBUG: message(STATUS "Adding deps for target ${llvm_target_lib}") + # Find position in `targets_to_return` + list(FIND targets_to_return "${llvm_target_lib}" position) + if ("${position}" EQUAL "-1") + message(FATAL_ERROR "couldn't find \"${llvm_target_lib}\" in list of targets") + endif() + if ("${position}" LESS "${targets_to_return_last_index}") + math(EXPR position_plus_one "${position} + 1") + foreach (index RANGE ${position_plus_one} ${targets_to_return_last_index}) + # Get the target for this index + list(GET targets_to_return ${index} target_for_index) + # DEBUG: message(STATUS "${llvm_target_libs} depends on ${target_for_index}") + set_property(TARGET "${llvm_target_lib}" APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "${target_for_index}" + ) + endforeach() + endif() + # Now finally add the system library dependencies. These must be last. + set_property(TARGET "${target_name}" APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "${_system_libs_list}" + ) + endforeach() + endif() + + set(${OUTPUT_VAR} ${targets_to_return} PARENT_SCOPE) endfunction() endif() |