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

C 在链接静态库时获取未定义的引用,c,gcc,static-libraries,linker-errors,undefined-reference,C,Gcc,Static Libraries,Linker Errors,Undefined Reference,我用GCC创建了一个静态库。图书馆的建筑还可以 当我使用它时,链接器会在某些函数上抛出未定义的引用错误。但是nm表示这些函数是在静态库中定义和导出的(用T标记)。我知道链接顺序,我需要将库放在需要它们的模块之后,这样就不会有问题了 静态库是由3个C文件构建的。A.c B.c和D.c D模块依赖于A和B(包括它们的标题) 当我使用来自A和B的函数时没有问题,但是当我尝试使用来自D的任何函数时,我会在它们上得到未定义的引用错误 如果我在A或B中移动这些函数,它就会工作。但如果它们在D模块中,则不会

我用GCC创建了一个静态库。图书馆的建筑还可以

当我使用它时,链接器会在某些函数上抛出未定义的引用错误。但是
nm
表示这些函数是在静态库中定义和导出的(用T标记)。我知道链接顺序,我需要将库放在需要它们的模块之后,这样就不会有问题了

静态库是由3个C文件构建的。A.c B.c和D.c D模块依赖于A和B(包括它们的标题)

当我使用来自A和B的函数时没有问题,但是当我尝试使用来自D的任何函数时,我会在它们上得到未定义的引用错误

如果我在A或B中移动这些函数,它就会工作。但如果它们在D模块中,则不会

我完全不知道发生了什么或是什么我被忽视了


我正在使用Code::Blocks并处理普通C文件。

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

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

i、 例如,在makefile(或您正在使用的任何文件)中,放置:

gcc-o

无论如何,我希望你能理解。

我发现我在我的项目中添加了一个.cpp文件,我刚刚将它重命名为.c。当我创建项目时,我选择了C语言而不是C++。我不认为这会引起问题

我认为文件扩展名决定IDE何时在gcc和g++之间进行选择。但不是。在Code::Blocks中,如果添加扩展名为.cpp的文件,它将使用g++。如果添加扩展名为.c的文件,它将使用gcc。但是,如果重命名该文件,它将使用相同的编译器。您必须在项目选项中明确更改它

该D模块是使用g++而不是gcc构建的


当我将IDE设置为在构建时显示整个命令行而不仅仅是“编译foo.c”时,我意识到了这一点。在我为简化应用程序/库构建而编写的master 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
i、 e.带有尾随'

然后,我使用这个make语法来剥离,并删除重复项

undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))
“follow”过滤器是因为如果多次引用未定义的符号,则输出中会出现一条消息“more references to XXX follow”,这会导致undefined.txt文件中出现虚假的“follow”,例如

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

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

使用GNU Make管理项目,第三版
By:Robert Mecklenburg

请提供更多信息,说明哪些函数在哪个C文件中,哪些函数得到未定义的引用(以及您是从该库中的另一个对象文件还是从另一个对象调用它们)。
undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))
-Wl, uXXXX' follow
$(application): $(library_dependencies) $(objects) undefined.txt
    $(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)