[英]Symbols missing from Linux static library using NetBeans
我正在开发一个最终将成为开源的 C 静态库,因此我正在 Windows 和 Ubuntu 上进行交叉编译,以支持任何可移植性问题。
我遇到的问题是 Linux 构建中省略了来自目标文件之一的符号。 当我在 Windows 上使用 VS2015 构建库时,所有符号都存在。
我主要习惯于为 Windows 开发,所以我非常喜欢在大多数构建场景中使用 IDE。 在 Ubuntu 上,我使用的是 NetBeans ,我不确定问题是我对 gcc 的理解还是我没有正确设置 NetBeans。
细节
使用 gcc(Ubuntu) 5.4.0 的 Ubuntu 16.04LTS
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
源文件中的代码也是memutil.c
。 MEMCHECK
符号是在构建库时定义的,但是当我在 Linux 构建后在libmylib.a
上运行nm
时,没有为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)
在头文件包含中存根不能解决这个问题,是吗? 它有效,但看起来非常粗糙。 此外,我真的不能相信 gcc 是必需的,而 VS2015 则不是必需的。
好吧,我找到了解决方案,但我没有将其标记为已接受的答案,因为我不确定为什么它是解决方案。
我注意到编译器行上的-Mxx
标志:
gcc -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/...
所以我回到谷歌,找到了这个站点: Auto-Dependency Generation ,它涵盖了让Make
处理构建依赖项的生成和跟踪。
然后我开始梳理 NetBeans 中的每个菜单项,直到找到这个:
Tools->Options->C/C++->[on/off] 在生成的 makefile 中启用依赖项检查
我清除了那个开关,所有丢失的符号都出现在库中。 但是, -Mxx
标志仍然出现在构建输出的编译器行上。 现在,NetBeans 的生成文件使用大约 5 个单独的生成文件模板和 3 或 4 个不同的 XML 配置文件在生成时根据生成配置和目标生成生成文件。 我无法确定是否通过翻转该开关使自动依赖标志变得惰性。
但是,如果我正确阅读了上述网站上的信息,那些-Mxx
标志实际上是由 gcc 使用来支持Make
,所以我不确定它们如何根据 NetBeans 所做的事情有不同的解释. 虽然,在这些 makefile 模板中有很多替换,而且由于我不是 Autoconfig/Make 向导,我可能只是错过了它。
所以,显然,因为没有一个源文件实际上包含内存实用程序的函数原型——因为它们包含在库头文件中,没有一个库源文件包含其中(它意味着包含在客户端代码中)—— NetBeans 依赖性检查器决定库中不需要这些函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.