add standard libraries to RPATH for build tree exe

2019-08-25 07:46发布

问题:

In my work setup, my "compiler" is a shell script that sets a few environment variables and calls the actual compiler (clang-wrapper):

#!/bin/sh
export PATH=/path_to_clang_install/bin:/path_to_gcc_install/bin${PATH:+:$PATH}
export LD_LIBRARY_PATH=/path_to_clang_install/lib64:/path_to_gcc_install/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
exec /path_to_clang_install/bin/clang++ --gcc-toolchain=/path_to_gcc_install "$@"

As far as I understand, cmake and ctest add all link directories to the RPATH of linked executables in the build directory and removes the RPATH for the install directory. (at the moment I don't care about the install directory, and with objdump -x I see that directories of libraries I add with target_link_libraries appear in the RPATH).

However, the directories of the compiler's standard libraries (/path_to_clang_install/lib64) does not get added to the RPATH.

As minimum working example, I have

CMakeLists.txt

add_executable(foo foo.cc)
enable_testing()
add_test(NAME foo COMMAND foo)

foo.cc

#include <string>
int main(int, char** argv) {
  return std::string(argv[0]).length();
}

which I then build with

cmake .. -DCMAKE_CXX_COMPILER=clang-wrapper -DCMAKE_C_COMPILER=clang-wrapper
cmake --build .
ctest

The test usually fails

UpdateCTestConfiguration  from :<buildpath>/DartConfiguration.tcl
UpdateCTestConfiguration  from :<buildpath>/DartConfiguration.tcl
Test project <buildpath>
Constructing a list of tests
Done constructing a list of tests
Updating test list for fixtures
Added 0 tests to meet fixture requirements
Checking test dependency graph...
Checking test dependency graph end
test 1
    Start 1: foo

1: Test command: <buildpath>/foo
1: Test timeout computed to be: 10000000
1: <buildpath>/foo: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by <buildpath>/foo)
1/1 Test #1: foo ..............................***Failed    0.02 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.13 sec

The following tests FAILED:
          1 - foo (Failed)
Errors while running CTest

(the linker gets called with /path_to_clang_wrapper/clang-wrapper -rdynamic CMakeFiles/foo.dir/foo.o -o foo.)

I tried spelling out the standard libraries with

enable_testing()
link_directories(/path_to_gcc/lib64)
add_executable(foo foo.cc)
target_link_libraries(foo /path_to_gcc/lib64/libstdc++.so)

but that only added -lstdc++ to the linker call. I verified that if I link against some non-compiler library, the linker call receives an extra -L/path_to_random_lib/lib -Wl,-rpath,/path_to_random_lib/lib -lrandomlib.

So my question: how can I add compiler standard libraries to the RPATH with cmake? I appreciate that the executables and ctests in the build tree are otherwise pretty independent of environment variables (LD_LIBRARY_PATH).

标签: cmake rpath