链接静态库时获取未定义的引用
我用GCC做了一个静态库。图书馆的建设还可以。
当我使用它时,链接器会在某些函数上抛出未定义的引用错误。但是 nm 表示函数是在静态库中定义和导出的(用 T 标记)。我知道我需要将库放在需要它们的模块之后的链接顺序,因此这不会成为问题。
静态库由 3 个 C 文件构建。 Ac Bc 和 Dc D 模块依赖于 A 和 B(包括它们的标头)。
当我使用 A 和 B 中的函数时没问题,但当我尝试使用 DI 中的任何函数时,会出现未定义的引用错误。
如果我将这些函数移到 A 或 B 中,它就会起作用。但如果它们位于 D 模块中则不然。
我完全不知道发生了什么或者我被忽视了。
我正在使用 Code::Blocks 并使用纯 C 文件。
I made a static library with GCC. Building of the library was OK.
When I use it the linker throws undefined reference errors on some functions. But nm
says the functions are defined and exported in the static library (marked with T). I know about the linking order that I need to put the libraries after that module that needs them so this can not be a problem.
The static library was built from 3 C files. A.c B.c and D.c The D module depend on A and B (includes their headers).
No problem when I use functions from A and B but when I try to use any function from D I get undefined reference errors on them.
If I move these functions in A or B it works. But not if they are in the D module.
I'm completely run out of ideas what's going on or what is I'm overlooked.
I'm using Code::Blocks and working with plain C files.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一个多次有效的老技巧:在链接阶段列出每个静态库两次。
即,在您的 makefile(或您正在使用的任何文件)中,输入:
无论如何,我希望您明白这一点。
An old trick that many times works: List each static library twice in the linking phase.
i.e., in your makefile (or whatever you're using), put:
Anyway, I hope you get the idea.
我发现我添加了一个 .cpp 文件到我的项目中,我只是将其重命名为 .c。我在创建项目时选择了C语言而不是C++。我认为这不会导致问题,
我认为文件扩展名决定 IDE 在 gcc 和 g++ 之间进行选择。但不是。在 Code::Blocks 中,如果添加扩展名为 .cpp 的文件,它将使用 g++。如果添加扩展名为 .c 的文件,它将使用 gcc。但如果您重命名该文件,它将使用相同的编译器。您必须在项目选项中明确更改它。
该 D 模块是使用 g++ 而不是 gcc 构建的。
当我将 IDE 设置为在构建时显示整个命令行而不仅仅是“编译 foo.c”时,我意识到了这一点。
I found out that I added A .cpp file to my project and I just renamed it to .c. I chose C language instead of C++ when I created the project. I did't think this could cause problems
I thought the file extension decides when the IDE chooses between gcc and g++. But not. In Code::Blocks if you add a file with a .cpp extension it will use g++. If you add a file with a .c extension it will use gcc. But if you rename the file it will use the same compiler. You have to change it explicitly in the project options.
That D module was built using g++ instead of gcc.
I realized this when I set the IDE to show me the entire command line when building not just "Compiling foo.c".
在我编写的用于简化应用程序/库构建的主 make 文件中,我使用的解决方案是运行链接步骤两次。使用 -u 链接器选项在第二个链接上指定未定义的符号。
在我的 make 文件中,我有一个这样的目标:
它调用这个宏...第一次尝试链接...
由于我的 sed/regexp 技能不好(我匆忙写了这些东西)我最终得到undefined.txt 包含:
即带有尾随 '
然后我使用此 make 语法来剥离 ' 并删除重复项
'follow' 过滤器是因为如果多次引用未定义符号,则会出现一条消息“更多引用 XXX 跟随”出现在输出中,这会导致 undefined.txt 文件中出现虚假的“follow”,例如
最后我第二次链接(注意对 undefined.txt 的依赖),
顺便说一句,我完全推荐了下面的书,因为我是能够在几天内从头开始编写一个简单的构建系统。
使用 GNU Make 管理项目,第三版
作者:罗伯特·梅克伦堡
In the master make file I wrote to simplify my application/library builds, the solution I used was to run the link step twice. Using the -u linker option to specify undefined symbols on the second link.
In my make file I have a target like this:
which calls this macro... the first attempt at linking...
As my sed/regexp skills aren't good (and I wrote this stuff in a rush) I end up with undefined.txt containing:
i.e. with a trailing '
I then use this make syntax to strip the 's, and remove duplicates
The 'follow' filter is because if an undefined symbol is referenced many times, a message "more references to XXX follow" appears in the output, which leads to a spurious 'follow' in the undefined.txt file e.g.
Finally I link the second time (note the dependency on undefined.txt)
I'd totally recommed the following book by the way, as I was able to write from scratch a simple build system in a couple of days.
Managing Projects with GNU Make, Third Edition
By: Robert Mecklenburg
也许您应该使用
ranlib
或适当的ar
选项来提供 .a 文件的索引。Perhaps you should use
ranlib
or the approriatear
option to provide an index to your .a file.