使用NetBeans从Linux静态库中缺少符号

时间:2017-12-27 04:51:06

标签: c gcc netbeans-8

我正在开发一个最终将成为开源的C静态库,所以我在Windows和Ubuntu上进行交叉编译以支持任何可移植性问题。

我遇到的问题是Linux构建中省略了其中一个目标文件的符号。当我在Windows上使用VS2015构建库时,所有符号都存在。

我主要习惯于为Windows开发,所以我很喜欢在大多数构建场景中使用IDE。在Ubuntu上,我使用的是NetBeans,我不确定问题是否与我对gcc的理解有关,或者我是否没有正确设置NetBeans。

详情

Ubuntu 16.04LTS使用gcc(Ubuntu)5.4.0

NetBeans IDE 8.1 C / C ++

该库由3个源文件和2个头文件组成:

queue.c  --> queue implementation
memutil.c  --> memory utilities
mylib.c  --> main library implementation

queue.h  --> included by queue.c and mylib.c
mylib.h  --> header file for the static library

mylib.h标头包含memutil.c源文件的标头信息,包含在一个条件中,该条件取决于命令行上的MEMCHECK符号。同样,对于memutil.c源文件中的代码。在构建库时定义了MEMCHECK符号,但是当我在Linux构建之后在nm上运行libmylib.a时,没有为memutil.o目标文件列出符号。当我查看Windows上的mylib.lib文件时,会列出memutil.obj的所有符号。

现在,如果我添加一个仅包含mylib.h标头的存根源文件,则所有符号都会出现在libmylib.a库中。我猜测有一些头文件交互故障正在进行,但我不知道在哪里找出它是什么或如何解决它。我已经用尽可能多的不同的措辞谷歌了解了这一点,但没有快乐。

这是NetBeans构建输出,减去所有目录噪声:

gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/queue.o.d" -o build/queue.o queue.c
gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/memutil.o.d" -o build/memutil.o memutil.c
gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/mylib.o.d" -o build/mylib.o mylib.c

ar -rv dist/Debug/GNU-Linux/libmylib.a build/queue.o build/memutil.o build/mylib.o 
ar: creating dist/Debug/GNU-Linux/libmylib.a
a - build/queue.o
a - build/memutil.o
a - build/mylib.o
ranlib dist/Debug/GNU-Linux/libmylib.a

BUILD SUCCESSFUL (total time: 3s)

在头文件中包含stubbing不能解决这个问题,可以吗?它有效,但看起来非常粗糙。此外,我不能相信它是必要的,使用gcc而不是VS2015。

1 个答案:

答案 0 :(得分:0)

好吧,我找到了解决方案,但我并没有将此标记为已接受的答案,因为我不确定为什么这是解决方案。

我注意到编译器行上的-Mxx标志:

gcc    -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/...

所以我回到Google找到了这个网站:Auto-Dependency Generation,其中包含让Make处理构建依赖关系的生成和跟踪。

然后我开始梳理NetBeans中的每个菜单项,直到找到这个:

  

工具 - >选项 - > C / C ++ - > [开/关]在生成的makefile中启用依赖项检查

我清除了那个开关,所有缺失的符号出现在库中。但是,-Mxx标志仍然存在于构建输出中的编译器行中。现在,NetBeans的makefile生成使用大约5个单独的makefile模板和3或4个不同的XML配置文件,根据构建配置和目标在构建时生成makefile。我无法弄清楚是否通过翻转该开关使自动依赖标志变为惰性。

但是,如果我正确地阅读上述网站上的信息,那些-Mxx标志实际上是由gcc用于支持Make,所以我不确定它们会如何基于NetBeans所做的事情有不同的解释。虽然,那些makefile模板中有很多替换,并且我不是一个Autoconfig / Make向导,但我可能只是错过了它。

所以,显然,因为没有源文件实际上包含了内存实用程序的函数原型 - 因为它们包含在库头文件中,没有任何库源文件包含(它意味着包含在客户端代码中) ) - NetBeans依赖检查器确定库中不需要这些功能。