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

2019-09-20 08:23:55 +08:00
 dangyuluo

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

具体需求是这样,我们公司需要使用 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 生成的最终编译命令中源代码所在的位置呢?谢谢。

6112 次点击
所在节点    C
11 条回复
ppzbreeze
2019-09-20 09:42:06 +08:00
看来精通这方面的老哥不多啊,都不见回答
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
2019-09-20 09:57:26 +08:00
qza1212
2019-09-20 10:14:00 +08:00
1. 使用 Xlinker "-("-lz -lxxx"-)" 通过-( )- 强制 repeat
2. 添加"-Wl,--no-as-needed"到 LDFLAGS
3. 使用 libc++.a (我不确定有没有静态库)
waruqi
2019-09-20 10:19:00 +08:00
改用 xmake 吧,顺序添加就行了,add_syslinks("c++", "c++abi", "m", "c", "gcc_s", "gcc")
dangyuluo
2019-09-20 11:23:48 +08:00
@ppzbreeze CMAKE 确实挺难的。。

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


@waruqi 公司决策不是我能决定的。
@qza1212 我研究一下
xylophone21
2019-09-20 20:46:45 +08:00
@dangyuluo 其实不要以为这里把顺序调整对了就好了,你会发现后面还有别的顺序问题。只有 group 最可靠
dangyuluo
2019-09-20 23:11:02 +08:00
@xylophone21 可以详细说明一下么?谢谢
wutiantong
2019-10-06 05:06:01 +08:00
你这 CMakeLists 写成啥样了?
dangyuluo
2019-10-06 05:15:15 +08:00
@wutiantong 你是问我怎么解决的么?
wutiantong
2019-10-06 05:20:14 +08:00
@dangyuluo 不是的,解决了就好

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/602363

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX