llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.92k stars 11.53k forks source link

Incorrect position of generated simple_version_script.map when using Ninja Multi-Config #63800

Open ur4t opened 1 year ago

ur4t commented 1 year ago

When using multi-config generator like cmake -G "Ninja Multi-Config" to build libLLVM.so, lld complains error: cannot find version script /home/builder/llvm-project/build/Debug/lib/tools/llvm-shlib/simple_version_script.map.

Actually generated simple_version_script.map is /home/builder/llvm-project/build/${CONFIGURATION}/lib/tools/llvm-shlib/simple_version_script.map.

Contents of generated ${CONFIGURATION} directory:

${CONFIGURATION}
└── lib
    ├── Debug
    ├── Release
    ├── RelWithDebInfo
    └── tools
        └── llvm-shlib
            └── simple_version_script.map
ur4t commented 1 year ago

This patch can emplace simple_version_script.map in the right position.

diff --git i/llvm/tools/llvm-shlib/CMakeLists.txt w/llvm/tools/llvm-shlib/CMakeLists.txt
index 4f6a2cbfbba3..93c1aa65b995 100644
--- i/llvm/tools/llvm-shlib/CMakeLists.txt
+++ w/llvm/tools/llvm-shlib/CMakeLists.txt
@@ -41,9 +41,20 @@ if(LLVM_BUILD_LLVM_DYLIB)
      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
      OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")) # FIXME: It should be "GNU ld for elf"
-    configure_file(
-    ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in
-    ${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map)
+
+    if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
+      foreach(BUILD_MODE ${CMAKE_CONFIGURATION_TYPES})
+        # Replace the special string with a per config directory.
+        string(REPLACE ${CMAKE_CFG_INTDIR} ${BUILD_MODE} PER_CONF_LIBRARY_DIR ${LLVM_LIBRARY_DIR})
+        configure_file(
+        ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in
+        ${PER_CONF_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map)
+      endforeach()
+    else()
+      configure_file(
+      ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in
+      ${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map)
+    endif()

     # GNU ld doesn't resolve symbols in the version script.
     set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive)
ur4t commented 1 year ago

However, with the patch applyed, there is still a ${CONFIGURATION} directory, which contains libbenchmark.a and libbenchmark_main.a.

Contents of generated ${CONFIGURATION} directory after a successful Debug build:

${CONFIGURATION}
└── lib
    ├── Debug
    │   ├── libbenchmark.a
    │   └── libbenchmark_main.a
    ├── Release
    └── RelWithDebInfo

Corresponding partial contents of third_party/benchmark/build after a standalone Debug build with Ninja Multi-Config:

build
└── src
    ├── Debug
    │   ├── libbenchmark.a
    │   └── libbenchmark_main.a
    ├── Release
    └── RelWithDebInfo