gpt4 book ai didi

linker - CMake 自定义链接可执行命令,如何提取链接器选项?

转载 作者:行者123 更新时间:2023-12-04 03:30:27 27 4
gpt4 key购买 nike

我需要在我的 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 中提取链接器标志?

最佳答案

把我的评论变成答案

问题

我们来看看 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

但是您不希望这些链接器标志混入 LINK_LIBRARIES因为您的 Synopsys VCS GCC 包装器希望它们带有 -LDFLAGS前缀/组。

你是对的,“库和标志不能相互分离。看起来生成 LINK_LIBRARIES 的函数是 cmLocalGenerator::OutputLinkLibraries 。不幸的是,它将所有标志和库放入单个 std::string 中。”

可能的解决方案

我看到五个选项(或它们的某种组合):
  • 用 VCS 匹配前缀/替换普通的 gcc/ld 标志
  • 解析链接器 -Wl,中间脚本中的选项
  • 不要使用扩展规则,而是使用 CMake 变量/生成器表达式
  • 定义您自己的链接器语言
  • 比动态链接库更喜欢静态库

  • 所以 - 在选项 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)

    这会给
    CXXFLAGS: 
    LINK_FLAGS: -Wl,-rpath,[... my binary path ...]/lib
    LINK_LIBRARIES: libslib.a lib/libdlib.so
    OBJECTS: CMakeFiles/main.dir/main.cpp.o

    主要问题是您是否真的需要 -rdynamic-Wl,-rpath选项。

    第一个可以跳过,见 Linux-GNU.cmake :

    # 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,也可以跳过后者。系统路径中的共享库,参见例如 Wikipedia rpath :

    Specifically it encodes a path to shared libraries into the header of an executable (or another shared library). This RPATH header value (so named in the Executable and Linkable Format header standards) may either override or supplement the system default dynamic linking search paths.



    引用文献
  • 目标属性(property) SKIP_BUILD_RPATH , 或者全局变量 CMAKE_SKIP_RPATH
  • CMake: Suppressing -rdynamic
  • 关于linker - CMake 自定义链接可执行命令,如何提取链接器选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37368434/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com