我用GCC创建了一个静态库。图书馆的建设还行。
当我使用它时,链接器会在某些函数上抛出未定义的引用错误。但nm
表示函数是在静态库中定义和导出的(用T标记)。我知道我需要将库放在需要它们的模块之后的链接顺序,所以这不是问题。
静态库是从3个C文件构建的。 A.c B.c和D.c D模块依赖于A和B(包括它们的标题)。
当我使用A和B中的函数时没问题,但是当我尝试使用D中的任何函数时,我会得到未定义的引用错误。
如果我在A或B中移动这些功能,它可以工作。但不是如果他们在D模块中。
我完全没有想法发生了什么或者我被忽视了什么。
我正在使用Code :: Blocks并使用普通的C文件。
答案 0 :(得分:2)
多次使用的旧技巧:在链接阶段列出每个静态库两次。
即,在你的makefile(或你正在使用的任何东西)中,输入:
gcc -o <outfile> <liba> <libb> <libc> <liba> <libb> <libc>
无论如何,我希望你明白这一点。
答案 1 :(得分:1)
我发现我在项目中添加了一个.cpp文件,我只是将其重命名为.c。我在创建项目时选择了C语言而不是C ++。我认为这不会导致问题
我认为文件扩展名决定了IDE在gcc和g ++之间选择的时间。但不是。在Code :: Blocks中,如果添加扩展名为.cpp的文件,它将使用g ++。如果添加扩展名为.c的文件,则使用gcc。但是如果重命名文件,它将使用相同的编译器。您必须在项目选项中明确更改它。
D模块是使用g ++而不是gcc构建的。
当我设置IDE以在构建时不仅仅是“编译foo.c”时向我显示整个命令行,我意识到了这一点。
答案 2 :(得分:1)
在我为简化应用程序/库构建而编写的主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语法来删除's,并删除重复项
undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))
'follow'过滤器是因为如果多次引用未定义的符号,则输出中会出现“更多引用XXX follow”的消息,这会导致undefined.txt文件中出现虚假的“跟随”,例如
-Wl, uXXXX' follow
最后我第二次链接(注意对undefined.txt的依赖)
$(application): $(library_dependencies) $(objects) undefined.txt
$(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)
顺便说一下,我完全推荐了下面的书,因为我能够在几天内从头开始编写一个简单的构建系统。
使用GNU Make管理项目,第三版 作者:罗伯特梅克伦堡
答案 3 :(得分:0)
也许您应该使用ranlib
或相应的ar
选项为.a文件提供索引。