V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dangyuluo
V2EX  ›  C

CMake 如何控制生成的 Makefile 中链接顺序 (-la -lc -lb)

  •  
  •   dangyuluo · 2019-09-20 08:23:55 +08:00 · 6298 次点击
    这是一个创建于 1890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近遇到这么一个问题,想了很久没有解决办法,请各位帮忙看看应该怎么办。

    具体需求是这样,我们公司需要使用 GNU 编译器+LLVM LibC++来编译产品。在 LLVM 官网上可以看到,用以下命令可以用 GCC+LLVM LibC++编译:LLVM Link

    $ g++ -nostdinc++ -I<libcxx-install-prefix>/include/c++/v1 \
           test.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc
    

    这里由于没有使用 GNU LibstdC++,因此需要手动链接 libc++。另外注意test.cpp的顺序是在-lc++-lc++abi之前的,这样 linker 由左至右(存疑)扫文件的时候才可以正确链接。Stackoverflow 解释

    如果将test.cpp挪到-lc++abi之后,编译器会报找不到operator new(unsigned long),原因看上述链接。这里的结论就是源代码必须出现在 libc++之前

    问题就在于,我们用 CMake 来编译,生成的最终编译命令类似:

    /usr/bin/c++ \
    -nostdinc++ \
    -nodefaultlibs \
    -I/usr/include/c++/v1 \
    -lc++ \
    -lc++abi \
    -lc \
    -lgcc_s \
    -lgcc \
    -lm \
    -frecord-gcc-switches \
    -Wall \
    -Werror=format-security \
    -Werror=implicit-function-declaration \
    -Wextra \
    -Wno-unused \
    -Wcast-align \
    -Wunused-result \
    -Wno-error=deprecated-declarations \
    -Woverloaded-virtual \
    -Wlogical-op \
    -Wno-noexcept-type \
    -Wno-duplicated-branches \
    -O2 \
    -g \
    -DNDEBUG \
    -ftree-vectorize \
    -Wpedantic \
    -Werror \
    -std=gnu++14 \
    -o \
    test_runner \
    /home/xx.xxxx/gc/xxx_ws/main.cpp
    

    CMake 生成的命令中源代码在最后,因此链接器在扫过libc++.so之后就扔掉了里面所有的内容(因为 unresolved symbol table 这时候还是空),然后在遇到main.cpp.o的时候就找不到operator new了。

    有什么办法能改变 CMake 生成的最终编译命令中源代码所在的位置呢?谢谢。

    11 条回复    2019-10-06 05:20:14 +08:00
    ppzbreeze
        1
    ppzbreeze  
       2019-09-20 09:42:06 +08:00
    看来精通这方面的老哥不多啊,都不见回答
    xylophone21
        2
    xylophone21  
       2019-09-20 09:53:20 +08:00
    target_link_libraries(main
    -Wl,--start-group
    c++
    c++abi
    m
    c
    gcc_s
    -Wl,--end-group
    )
    AaronLiang
        3
    AaronLiang  
       2019-09-20 09:57:26 +08:00
    qza1212
        4
    qza1212  
       2019-09-20 10:14:00 +08:00
    1. 使用 Xlinker "-("-lz -lxxx"-)" 通过-( )- 强制 repeat
    2. 添加"-Wl,--no-as-needed"到 LDFLAGS
    3. 使用 libc++.a (我不确定有没有静态库)
    waruqi
        5
    waruqi  
       2019-09-20 10:19:00 +08:00
    改用 xmake 吧,顺序添加就行了,add_syslinks("c++", "c++abi", "m", "c", "gcc_s", "gcc")
    dangyuluo
        6
    dangyuluo  
    OP
       2019-09-20 11:23:48 +08:00
    @ppzbreeze CMAKE 确实挺难的。。

    @AaronLiang
    @xylophone21 几百个包,还有第三方的代码,没办法一个个修改,只能用 toolchain 来全剧定义


    @waruqi 公司决策不是我能决定的。
    @qza1212 我研究一下
    xylophone21
        7
    xylophone21  
       2019-09-20 20:46:45 +08:00
    @dangyuluo 其实不要以为这里把顺序调整对了就好了,你会发现后面还有别的顺序问题。只有 group 最可靠
    dangyuluo
        8
    dangyuluo  
    OP
       2019-09-20 23:11:02 +08:00
    @xylophone21 可以详细说明一下么?谢谢
    wutiantong
        9
    wutiantong  
       2019-10-06 05:06:01 +08:00 via iPhone
    你这 CMakeLists 写成啥样了?
    dangyuluo
        10
    dangyuluo  
    OP
       2019-10-06 05:15:15 +08:00
    @wutiantong 你是问我怎么解决的么?
    wutiantong
        11
    wutiantong  
       2019-10-06 05:20:14 +08:00 via iPhone
    @dangyuluo 不是的,解决了就好
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   903 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 21:50 · PVG 05:50 · LAX 13:50 · JFK 16:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.