链接静态库时获取未定义的引用

发布于 2024-09-08 18:22:35 字数 371 浏览 3 评论 0原文

我用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓬勃野心 2024-09-15 18:22:35

一个多次有效的老技巧:在链接阶段列出每个静态库两次。

即,在您的 makefile(或您正在使用的任何文件)中,输入:

gcc -o <outfile> <liba> <libb> <libc> <liba> <libb> <libc>

无论如何,我希望您明白这一点。

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:

gcc -o <outfile> <liba> <libb> <libc> <liba> <libb> <libc>

Anyway, I hope you get the idea.

清眉祭 2024-09-15 18:22:35

我发现我添加了一个 .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".

总以为 2024-09-15 18:22:35

在我编写的用于简化应用程序/库构建的主 make 文件中,我使用的解决方案是运行链接步骤两次。使用 -u 链接器选项在第二个链接上指定未定义的符号。

在我的 make 文件中,我有一个这样的目标:

undefined.txt:
    @$(generate-undefined-syms)

它调用这个宏...第一次尝试链接...

define generate-undefined-syms
    $(PRINTF) "$(this_makefile): Generating undefined symbols ... \n"
    $(CC) -o rubbish $(LDFLAGS) $(objects) $(LDLIBS) 2>&1 | $(GREP) 'undefined reference' > tmp.txt; \
    $(SED) 's/^.*`/-Wl,-u/g' < tmp.txt > undefined.txt; \
    rm -f tmp.txt rubbish
endef

由于我的 sed/regexp 技能不好(我匆忙写了这些东西)我最终得到undefined.txt 包含:

-uSomeSym'
-uSomeOtherSym'

即带有尾随 '

然后我使用此 make 语法来剥离 ' 并删除重复项

undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))

'follow' 过滤器是因为如果多次引用未定义符号,则会出现一条消息“更多引用 XXX 跟随”出现在输出中,这会导致 undefined.txt 文件中出现虚假的“follow”,例如

-Wl, uXXXX' follow

最后我第二次链接(注意对 undefined.txt 的依赖),

$(application): $(library_dependencies) $(objects) undefined.txt
    $(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)

顺便说一句,我完全推荐了下面的书,因为我是能够在几天内从头开始编写一个简单的构建系统。

使用 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:

undefined.txt:
    @$(generate-undefined-syms)

which calls this macro... the first attempt at linking...

define generate-undefined-syms
    $(PRINTF) "$(this_makefile): Generating undefined symbols ... \n"
    $(CC) -o rubbish $(LDFLAGS) $(objects) $(LDLIBS) 2>&1 | $(GREP) 'undefined reference' > tmp.txt; \
    $(SED) 's/^.*`/-Wl,-u/g' < tmp.txt > undefined.txt; \
    rm -f tmp.txt rubbish
endef

As my sed/regexp skills aren't good (and I wrote this stuff in a rush) I end up with undefined.txt containing:

-uSomeSym'
-uSomeOtherSym'

i.e. with a trailing '

I then use this make syntax to strip the 's, and remove duplicates

undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))

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.

-Wl, uXXXX' follow

Finally I link the second time (note the dependency on undefined.txt)

$(application): $(library_dependencies) $(objects) undefined.txt
    $(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)

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

神仙妹妹 2024-09-15 18:22:35

也许您应该使用 ranlib 或适当的 ar 选项来提供 .a 文件的索引。

Perhaps you should use ranlib or the approriate ar option to provide an index to your .a file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文