gpt4 book ai didi

c - 如何在 C 中正确链接以阻止符号被剥离?

转载 作者:太空狗 更新时间:2023-10-29 15:24:57 25 4
gpt4 key购买 nike

我在正确链接 C 语言库时遇到了一些问题。

我确定这是我不完全理解的神秘 C 链接规则之一,但我想不出来。

我有 libn,我将其编译成静态库 libn.a

nm libn 显示:

doug@ninja:~/projects/libnw/build$ nm ../../libn/build/libn.a |grep nIndex
00000034 T nIndex
00000000 D nIndex_
00000026 T nIndex_finalize
00000013 T nIndex_init
00000000 T nIndex_map

我还有libnw,依赖libn。 libnw 上的 nm 显示:

doug@ninja:~/projects/libnw/build$ nm libnw.a |grep Index
U nIndex

但是,当我编译针对 libnw 和 libn 的编程链接时,我得到:

doug@ninja:~/projects/libnw/build$ make
[ 70%] Built target nw
[ 80%] Built target test-template
Scanning dependencies of target test-Core
[ 85%] Building C object tests/nw/mvc/Core/CMakeFiles/test-Core.dir/Tests.c.o
[ 90%] Building C object tests/nw/mvc/Core/CMakeFiles/test-Core.dir/test.c.o
Linking C executable test-Core
../../../../libnw.a(Impl.c.o): In function `nwCore__Impl_init':
/home/doug/projects/libnw/src/nw/mvc/Core/Impl.c:76: undefined reference to `nIndex'
collect2: ld returned 1 exit status
make[2]: *** [tests/nw/mvc/Core/test-Core] Error 1
make[1]: *** [tests/nw/mvc/Core/CMakeFiles/test-Core.dir/all] Error 2
make: *** [all] Error 2

原因很明确。当 Tests.c --> Tests.c.o 时,它没有选择 nIndex 作为它需要保留的符号:

doug@ninja:~/projects/libnw/build$ nm tests/nw/mvc/Core/CMakeFiles/test-Core.dir/Tests.c.o 
U MyController
000005a4 T Tests
00000000 D Tests_
00000125 T Tests_can_attach_controller
00000080 T Tests_can_create_core
000003d3 T Tests_can_handle_native_event
000001c8 T Tests_can_set_controller
00000322 T Tests_can_update
00000000 t Tests_core_factory
0000056c T Tests_finalize
000005c0 T Tests_getType
0000048c T Tests_init
U nFactory
U nTest
U nType_nalloc
U nType_nfree
U nwCore
U nwDummyContext_getType
U nwDummyEvents_getType
U nwDummyRender_getType
U nwIContext_getType
U nwIEvents_getType
U nwIRender_getType

(注意测试对象文件中完全没有 U nIndex)。

因此,我可以通过在我的测试脚本中添加对 nIndex() 的调用来轻松解决此问题,但这并没有解决基本问题:

程序依赖于 liba 依赖于 libb,liba 缺少需要解析的 libb 中的符号,但程序没有对这些符号的引用,因此它们似乎被剥离了。

我做错了什么?

(是的,我正在使用 cmake 构建并依赖于 libn 和 libnw 的静态构建版本)。

编辑:

现在有了链接器行:

/usr/bin/gcc  -std=c99 -g   CMakeFiles/test-Core.dir/Tests.c.o \
CMakeFiles/test-Core.dir/test.c.o \
CMakeFiles/test-Core.dir/helpers/MyController.c.o \
CMakeFiles/test-Core.dir/helpers/MyModel.c.o \
-o test-Core -rdynamic \
/home/doug/projects/tapspin-android/source/deps/libn/build/libn.a \
../../../../libnw.a

最佳答案

我没有看到您的链接行,所以我很难确定,但这似乎是一个订购问题

如果libb需要的所有符号都在liba中,那么你应该先列出libb,这样它们就被列出了作为要解析的符号,当访问 libb 时,它们将被解析。这本身并不是剥离,它只是不包括(即它是遗漏而不是主动去除,我是不是在吹毛求疵?也许吧)

此外,有时如果存在循环依赖(liba 需要来自 libb 的一些符号,而 libb 需要来自 liba 的一些符号) 必须多次列出库(这不是 cmake 的答案,因为我不使用 cmake,但多年来一直使用链接器,这是一个常见错误)。

请注意,与库中的符号不​​同,目标文件中的所有符号都是链接的

首先尝试的最简单的解决方法是交换两个库的顺序

关于c - 如何在 C 中正确链接以阻止符号被剥离?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7624194/

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