【问题标题】:Symbols missing from Linux static library using NetBeans使用 NetBeans 的 Linux 静态库中缺少符号
【发布时间】:2017-12-27 04:51:05
【问题描述】:

我正在开发一个最终将开源的 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 构建后在 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 是不必要的。

【问题讨论】:

  • 它可能会有点麻烦,但您可以考虑使用-E 选项进行编译。这将在预处理器运行后显示源代码,因此您应该能够看到-DMEMCHECK 是否在做您认为应该做的事情。您的代码将在#includes 之后接近尾声。您可以将输出重定向到一个文件,gcc -E code.c > ppCode.cstackoverflow.com/questions/3742822/preprocessor-output
  • 还建议使用-Wextra 标志进行编译以打开更多警告。
  • @yano:在我看来,如果条件有问题,Windows 构建也会很不稳定。
  • 这当然是最有意义的,但显然有些事情正在发生。 IDE 可以在幕后#define 东西,谁知道呢?不会打赌我的下一张薪水是问题所在,但值得一看 IMO。只是链中要消除的另一个变量。

标签: c gcc netbeans-8


【解决方案1】:

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

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

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

所以我回到 Google 并找到了这个站点: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 依赖项检查器确定库中不需要这些函数。

【讨论】:

    猜你喜欢
    • 2019-02-11
    • 2020-04-09
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 2010-12-25
    • 2011-08-06
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多