我需要在我的CMake脚本中支持自定义可执行链接命令,即Synopsys VCS。 VCS是GCC的包装器,但它使用特殊语法来传递LD选项:
vcs -LDFLAGS "<LINK_FLAGS>" <LINK_LIBRARIES> <OBJECTS>
链接可执行文件的规则存在于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> ")
当我建立项目时,我得到了:
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
因此所有链接器标志和库都在LINK_LIBRARIES
中如何从LINK_LIBRARIES中提取链接器标志?
答案 0 :(得分:3)
将我的评论转化为答案
让我们来看看CMAKE_CXX_LINK_EXECUTABLE
中定义的Linux / GNU / GCC / CXX特定链接:
<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS>
<OBJECTS> -o <TARGET> <LINK_LIBRARIES>
由于问题在于LINK_LIBRARIES
扩展规则,让我们仔细研究一下(以您的示例为例)了解其内容在cmLocalGenerator::OutputLinkLibraries()
中的生成方式:
但是您不希望这些链接器标记混合到LINK_LIBRARIES
中,因为您的Synopsys VCS GCC包装器希望它们具有-LDFLAGS
前缀/组。
你是对的“库和标志彼此不可分离。看起来生成LINK_LIBRARIES
的函数是cmLocalGenerator::OutputLinkLibraries
。不幸的是,它将所有标志和库放入单{{ {1}}“。
我看到五个选项(或它们的某种组合):
std::string
选项所以 - 在选项3的变体中 - 你需要知道为什么你在-Wl,
中看到的链接器选项存在,以及如何在其他地方抑制然后重新生成它们。
以下是我成功测试的一个示例:
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)
主要问题是,如果您确实需要CXXFLAGS:
LINK_FLAGS: -Wl,-rpath,[... my binary path ...]/lib
LINK_LIBRARIES: libslib.a lib/libdlib.so
OBJECTS: CMakeFiles/main.dir/main.cpp.o
和-rdynamic
选项。
可以跳过第一个,请参阅Linux-GNU.cmake
:
-Wl,-rpath
如果系统路径中有# 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")
个共享库,也可以跳过后者,例如, Wikipedia rpath
:
具体来说,它将共享库的路径编码到可执行文件(或其他共享库)的标头中。此RPATH标头值(在可执行文件和可链接格式标头标准中命名)可以覆盖或补充系统默认动态链接搜索路径。
<强>参考强>