[llvm] [offload] Fix link issues when LLVM_LINK_LLVM_DYLIB on (PR #106583)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 30 08:39:07 PDT 2024


https://github.com/macurtis-amd updated https://github.com/llvm/llvm-project/pull/106583

>From d493dc59411a59ae8a1c9ef1fa83b30331156369 Mon Sep 17 00:00:00 2001
From: Matthew Curtis <macurtis at amd.com>
Date: Thu, 29 Aug 2024 10:43:31 -0500
Subject: [PATCH] [offload] Fix link issues when LLVM_LINK_LLVM_DYLIB on

When LLVM_LINK_LLVM_DYLIB is on, link against LLVM (shared library) rather than
individual (static) libraries. Otherwise, global initializers may get called
multiple times as multiple copies of LLVM libraries are loaded.

This typically results in a runtime error such as:

  Error: CommandLine Error: Option ... registered more than once

See related commit ea8bb4d633683f5cbfd82491620be3056f347a02
---
 offload/plugins-nextgen/amdgpu/CMakeLists.txt | 10 ++-
 offload/plugins-nextgen/common/CMakeLists.txt |  6 +-
 offload/src/CMakeLists.txt                    | 62 +++++++++++++++++++
 3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/offload/plugins-nextgen/amdgpu/CMakeLists.txt b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
index b40c62d43226f4..ca88fe7614d888 100644
--- a/offload/plugins-nextgen/amdgpu/CMakeLists.txt
+++ b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
@@ -8,14 +8,20 @@ target_sources(omptarget.rtl.amdgpu PRIVATE src/rtl.cpp)
 target_include_directories(omptarget.rtl.amdgpu PRIVATE
                            ${CMAKE_CURRENT_SOURCE_DIR}/utils)
 
+if (LLVM_LINK_LLVM_DYLIB)
+  set(llvm_libs LLVM)                      
+else()                      
+  set(llvm_libs LLVMFrontendOffloading)
+endif()
+
 if(hsa-runtime64_FOUND AND NOT "amdgpu" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
   message(STATUS "Building AMDGPU plugin linked against libhsa")
-  target_link_libraries(omptarget.rtl.amdgpu PRIVATE hsa-runtime64::hsa-runtime64 LLVMFrontendOffloading)
+  target_link_libraries(omptarget.rtl.amdgpu PRIVATE hsa-runtime64::hsa-runtime64 ${llvm_libs})
 else()
   message(STATUS "Building AMDGPU plugin for dlopened libhsa")
   target_include_directories(omptarget.rtl.amdgpu PRIVATE dynamic_hsa)
   target_sources(omptarget.rtl.amdgpu PRIVATE dynamic_hsa/hsa.cpp)
-  target_link_libraries(omptarget.rtl.amdgpu PRIVATE LLVMFrontendOffloading)
+  target_link_libraries(omptarget.rtl.amdgpu PRIVATE ${llvm_libs})
 endif()
 
 # Configure testing for the AMDGPU plugin. We will build tests if we could a
diff --git a/offload/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt
index 4dca5422087bba..6342e6f4090e72 100644
--- a/offload/plugins-nextgen/common/CMakeLists.txt
+++ b/offload/plugins-nextgen/common/CMakeLists.txt
@@ -52,7 +52,11 @@ target_compile_definitions(PluginCommon PRIVATE
 
 target_compile_options(PluginCommon PUBLIC ${offload_compile_flags})
 target_link_options(PluginCommon PUBLIC ${offload_link_flags})
-target_link_libraries(PluginCommon PRIVATE LLVMProfileData)
+if (LLVM_LINK_LLVM_DYLIB)
+  target_link_libraries(PluginCommon PRIVATE LLVM)
+else()
+  target_link_libraries(PluginCommon PRIVATE LLVMProfileData)
+endif()
 
 target_include_directories(PluginCommon PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/include
diff --git a/offload/src/CMakeLists.txt b/offload/src/CMakeLists.txt
index c5f5d902fad14c..c34148adf8cdf8 100644
--- a/offload/src/CMakeLists.txt
+++ b/offload/src/CMakeLists.txt
@@ -69,3 +69,65 @@ set_target_properties(omptarget PROPERTIES
                       INSTALL_RPATH "$ORIGIN"
                       BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
 install(TARGETS omptarget LIBRARY COMPONENT omptarget DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
+
+#===============================================================================
+# Ensure that omptarget does not contain a mixture of static and dynamically
+# linked LLVM libs.
+#===============================================================================
+if (LLVM_LINK_LLVM_DYLIB)
+  if(LLVM_AVAILABLE_LIBS)
+    set(llvm_libs ${LLVM_AVAILABLE_LIBS})
+  else()
+    # Inside LLVM itself available libs are in a global property.
+    get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS)
+  endif()
+
+  #-----------------------------------------------------------------------------
+  # Helper function to recursively get the llvm targets that 'tgt' links against
+  #-----------------------------------------------------------------------------
+  function(get_llvm_link_targets var tgt visited)
+    if(${tgt} IN_LIST visited)
+      return()
+    endif()
+    list(APPEND visited ${tgt})
+
+    get_target_property(link_libs ${tgt} LINK_LIBRARIES)
+    if(NOT link_libs)
+      set(link_libs "")
+    endif()
+    get_target_property(i_link_libs ${tgt} INTERFACE_LINK_LIBRARIES)
+    if(i_link_libs)
+      list(APPEND link_libs ${i_link_libs})
+    endif()
+    if(NOT link_libs)
+      return()
+    endif()
+    list(REMOVE_DUPLICATES link_libs)
+
+    foreach(lib ${link_libs})
+      if(${lib} IN_LIST llvm_libs)
+        list(APPEND rv ${lib})
+      endif()
+      if(TARGET ${lib})
+        get_llvm_link_targets(indirect ${lib} visited)
+        list(APPEND rv ${indirect})
+        list(REMOVE_DUPLICATES rv)
+      endif()
+    endforeach()
+
+    set(${var} ${rv} PARENT_SCOPE)
+  endfunction()
+
+  #-----------------------------------------------------------------------------
+  # Check for extraneous libs
+  #-----------------------------------------------------------------------------
+  get_llvm_link_targets(llvm_link_targets omptarget "")
+  list(REMOVE_ITEM llvm_link_targets "LLVM")
+  if(llvm_link_targets)
+    list(JOIN llvm_link_targets " " pp_list)
+    message(
+      FATAL_ERROR
+      "'omptarget' should only link against 'LLVM' when 'LLVM_LINK_LLVM_DYLIB' "
+      "is on. Extraneous LLVM Libraries: ${pp_list}")
+  endif()
+endif()



More information about the llvm-commits mailing list