简体   繁体   English

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

[英]Getting undefined references when linking against a static library

I made a static library with GCC. 我用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). 但是nm说这些函数是在静态库(标记为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. 静态库是从3 C文件构建的。 Ac Bc and Dc The D module depend on A and B (includes their headers). Ac Bc和Dc D模块依赖于A和B(包括其标题)。

No problem when I use functions from A and B but when I try to use any function from DI get undefined reference errors on them. 当我使用A和B中的函数时没问题,但是当我尝试使用DI中的任何函数时,它们上会出现未定义的引用错误。

If I move these functions in A or B it works. 如果我将这些功能移到A或B中,它将起作用。 But not if they are in the D module. 但是如果它们在D模块中,则不会。

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. 我正在使用Code :: Blocks并使用纯C文件。

An old trick that many times works: List each static library twice in the linking phase. 很多老方法都起作用:在链接阶段两次列出每个静态库。

ie, in your makefile (or whatever you're using), put: 即,在您的makefile(或您使用的任何文件)中,放入:

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

Anyway, I hope you get the idea. 无论如何,我希望你能明白。

In the master make file I wrote to simplify my application/library builds, the solution I used was to run the link step twice. 在为简化应用程序/库构建而编写的主make文件中,我使用的解决方案是运行链接步骤两次。 Using the -u linker option to specify undefined symbols on the second link. 使用-u链接器选项在第二个链接上指定未定义的符号。

In my make file I have a target like this: 在我的make文件中,我有一个这样的目标:

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: 由于我的sed / regexp技能不好(我匆忙编写了这些东西),所以最终得到undefined.txt,其中包含:

-uSomeSym'
-uSomeOtherSym'

ie with a trailing ' 即尾随'

I then use this make syntax to strip the 's, and remove duplicates 然后,我使用此make语法剥离,并删除重复项

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 eg “跟随”过滤器是因为,如果多次引用未定义的符号,则输出中会出现一条消息“遵循XXX的更多引用”,这会导致undefined.txt文件中出现虚假的“跟随”,例如

-Wl, uXXXX' follow

Finally I link the second time (note the dependency on undefined.txt) 最后,我第二次链接(注意对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 用GNU Make管理项目,第三版作者:Robert Mecklenburg

I found out that I added A .cpp file to my project and I just renamed it to .c. 我发现我在项目中添加了一个.cpp文件,然后将其重命名为.c。 I chose C language instead of C++ when I created the project. 创建项目时,我选择了C语言而不是C ++。 I did't think this could cause problems 我认为这不会引起问题

I thought the file extension decides when the IDE chooses between gcc and g++. 我以为文件扩展名决定了IDE在gcc和g ++之间进行选择的时间。 But not. 但不是。 In Code::Blocks if you add a file with a .cpp extension it will use g++. 在Code :: Blocks中,如果添加扩展名为.cpp的文件,它将使用g ++。 If you add a file with a .c extension it will use gcc. 如果添加扩展名为.c的文件,它将使用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. 该D模块是使用g ++而不是gcc构建的。

I realized this when I set the IDE to show me the entire command line when building not just "Compiling foo.c". 当我将IDE设置为在构建时不仅仅显示“ Compiling foo.c”时向我显示整个命令行时,我意识到了这一点。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 链接到静态库 - Linking against a static library gcc静态链接未定义的引用 - gcc static linking undefined references 链接静态库时,目标代码如何复制到可执行文件中? - How is object code copied into executable when linking against static library? 将共享库与静态库链接 - Linking shared library against static library 如何在使用gnu-make链接静态库时遵循链接顺序? - How to follow linking order when linking against static library with gnu-make? 与GCC构建的静态库链接时,MSVC项目缺少“ __popcountdi2” - MSVC project missing “__popcountdi2” when linking against GCC-built static library 将共享库与静态库链接:静态库的编译方式必须与应用程序链接它的方式不同吗? - Linking a shared library against a static library: must the static library be compiled differently than if an application were linking it? “警告:将共享库与静态库链接起来不可移植”是什么意思? - What is the meaning of “Warning: Linking the shared library against static library is not portable”? 与使用名称空间的外部库链接时,如何解决C中的未定义引用? - How to solve undefined references in C when linking with an external library that uses name space? 即使与libole32链接,外部库中的未定义OLE引用也是如此 - Undefined OLE references in external library even when linking with libole32
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM