我需要在我的 CMake 脚本中支持自定义可执行链接命令,即 Synopsys VCS。VCS 是 GCC 的包装器,但它使用特殊语法来传递 LD 选项:
vcs -LDFLAGS "<LINK_FLAGS>" <LINK_LIBRARIES> <OBJECTS>
Run Code Online (Sandbox Code Playgroud)
链接可执行文件的规则存在于CMAKE_CXX_LINK_EXECUTABLE变量中,所以我尝试使用它:
set(CMAKE_CXX_LINK_EXECUTABLE "echo CXXFLAGS: <CMAKE_CXX_LINK_FLAGS> LINK_FLAGS: <LINKER_FLAGS> LINK_LIBRARIES: <LINK_LIBRARIES> OBJECTS: <OBJECTS> ")
Run Code Online (Sandbox Code Playgroud)
当我构建项目时,我得到:
CXXFLAGS:
LINK_FLAGS:
LINK_LIBRARIES: -rdynamic ../slib/libslib.a ../dlib/libdlib.so -Wl,-rpath,/home/ripopov/proj_cmake/build/dlib
OBJECTS: CMakeFiles/sim.dir/sc_main.cpp.o
Run Code Online (Sandbox Code Playgroud)
所以所有链接器标志和库都在 LINK_LIBRARIES
如何从中提取链接器标志LINK_LIBRARIES?
把我的评论变成答案
我们来看看定义在 Linux/GNU/GCC/CXX 中的特定链接行CMAKE_CXX_LINK_EXECUTABLE:
<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS>
<OBJECTS> -o <TARGET> <LINK_LIBRARIES>
Run Code Online (Sandbox Code Playgroud)
由于您的问题在于LINK_LIBRARIES扩展规则,让我们仔细看看(以您的示例为例)其内容是如何在 中生成的cmLocalGenerator::OutputLinkLibraries():
但是您不希望这些链接器标志混入,LINK_LIBRARIES因为您的 Synopsys VCS GCC 包装器希望它们带有-LDFLAGS前缀/组。
你是对的,“库和标志不能相互分离。看起来生成的函数LINK_LIBRARIES是cmLocalGenerator::OutputLinkLibraries。不幸的是,它将所有标志和库放入单个std::string.”
我看到五个选项(或它们的某种组合):
-Wl,中间脚本中的链接器选项所以 - 在选项 3 的变体中。 - 您需要知道为什么您看到的链接器选项在LINK_LIBRARIES那里,以及如何抑制然后在其他地方重新生成它们。
这是我成功测试的示例:
cmake_minimum_required(VERSION 2.8)
project(LinkerVCS CXX)
file(WRITE foo.h "void foo();\n")
file(WRITE foo.cpp "void foo() {};\n")
file(WRITE bar.h "void bar();\n")
file(WRITE bar.cpp "void bar() {};\n")
file(
WRITE main.cpp
"#include \"foo.h\"\n"
"#include \"bar.h\"\n"
"int main() { foo(); bar(); return 0; }\n"
)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 0)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
# remove the '-rdynamic'
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# define my own search path for shared libraries
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${CMAKE_BINARY_DIR}/lib")
set(CMAKE_CXX_LINK_EXECUTABLE "echo CXXFLAGS: ${CMAKE_CXX_FLAGS} LINK_FLAGS: <LINK_FLAGS> LINK_LIBRARIES: <LINK_LIBRARIES> OBJECTS: <OBJECTS>")
add_library(slib STATIC foo.cpp)
add_library(dlib SHARED bar.cpp)
add_executable(main main.cpp)
target_link_libraries(main slib dlib)
# remove the CMake generated '-Wl,-rpath'
set_target_properties(main PROPERTIES SKIP_BUILD_RPATH 1)
Run Code Online (Sandbox Code Playgroud)
这会给
CXXFLAGS:
LINK_FLAGS: -Wl,-rpath,[... my binary path ...]/lib
LINK_LIBRARIES: libslib.a lib/libdlib.so
OBJECTS: CMakeFiles/main.dir/main.cpp.o
Run Code Online (Sandbox Code Playgroud)
主要问题是您是否真的需要-rdynamic和-Wl,-rpath选项。
第一个可以跳过,见Linux-GNU.cmake:
Run Code Online (Sandbox Code Playgroud)# We pass this for historical reasons. Projects may have # executables that use dlopen but do not set ENABLE_EXPORTS. set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
如果.so系统路径中有共享库,也可以跳过后者,例如Wikipediarpath:
具体来说,它将共享库的路径编码到可执行文件(或另一个共享库)的头文件中。此 RPATH 标头值(在可执行和可链接格式标头标准中如此命名)可以覆盖或补充系统默认动态链接搜索路径。
参考
| 归档时间: |
|
| 查看次数: |
6116 次 |
| 最近记录: |