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

Dou*_*oug 4 c gcc

我在与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
Run Code Online (Sandbox Code Playgroud)

我也有libnw,这取决于libn.libnw上的nm显示:

doug@ninja:~/projects/libnw/build$ nm libnw.a |grep Index
         U nIndex
Run Code Online (Sandbox Code Playgroud)

但是,当我编译一个针对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
Run Code Online (Sandbox Code Playgroud)

原因很清楚.当Tests.c - > Tests.co时,它并没有选择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
Run Code Online (Sandbox Code Playgroud)

(注意测试对象文件中完全没有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 
Run Code Online (Sandbox Code Playgroud)

nhe*_*hed 5

我没有看到你链接线,所以我很难确定,但这似乎可能是一个订购问题

如果所需的所有符号libb都在liba,则应libb首先列出,以便将它们列为要解析的符号,并且在libb访问它们时将解析它们.这不是剥离本身,它只是不包括(即它是遗漏不是主动删除,我分裂头发?也许)

此外,有时如果存在循环依赖(liba需要一些符号libb并且libb需要一些符号liba),则必须多次列出库(这不是cmake我不使用的答案cmake,但是使用了多年的连接器,这里是一个常见的错误).

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

最简单的尝试首先尝试只是交换两个库的顺序