**未定义的参考**链接两个库的错误
我会在尝试编译两个库的 main 时不确定的参考错误。我有两个文件 lib1/func1.c 和 lib2/func2.c 在单独的文件夹中。这些文件包含两个函数 print1()
和 print2()
,函数 print1()
是调用 print2() 。
我将它们分别编译成两个库 libfunc1.a
和 libfunc2.a
。
但是,当我尝试编译 main 时,它正在调用 print1()
时,我会收到以下错误:
/usr/bin/ld: /home/sv/ztest2/lib1/libfunc1.a(func1.o): in function print1:
/home/sv/ztest2/lib1/func1.c:7: undefined reference to print2
collect2: error: ld returned 1 exit status
make: *** [Makefile:21: DP] Error 1
这是代码和makefiles:
makefile :
TARGET = DP
HOME = /home/slav/FORECAST/ztest2
INCDIRS = -I./ \
-I$(HOME)/lib1 \
-I$(HOME)/lib2
LIBDIRS = -L$(HOME)/lib1 \
-L$(HOME)/lib2
SRCFILES = DP.c
OBJFILES = DP.o
CFLAGS = -g -O3 $(INCDIRS)
all: $(TARGET)
$(TARGET): $(OBJFILES)
cc $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LIBDIRS) -lfunc2 -lfunc1
clean:
-rm *.o $(TARGET)
dp.c :
#include "func1.h"
int main()
{
print1();
return 0;
}
func1.h :
void print1();
func1.c :
#include <stdio.h>
void print1()
{
printf("print1 is called!\n");
print2();
}
func2.h :
extern void print2();
func2。 C :
#include <stdio.h>
void print2()
{
printf("print2 is called!\n");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
必须按顺序列出库,需要其符号。
命令
cc $(cflags)-o $(target)$(objfiles)$(libdirs)-lfunc2 -lfunc1
告诉链接器首先使用func2
库来解决可执行文件中的任何未决引用正在构建,然后使用func1
库。由于链接器流程
func2
首先,并且在此过程中没有待处理的引用print2
,因此链接器不包括print2
print2 /代码>在可执行文件中。
稍后,当链接器正在处理
func1
时,它在可执行文件中包含print1
的模块,因为main
使用它。该模块print1
使用print2
,因此包括该模块将新的引用添加到print2
中。然后,当链接器完成处理func1
时,它具有未解决的参考。链接器不会返回到func2
再次检查它。由于
func1
库取决于func2
,请将链接命令更改为cc $(cflags)-O $(target)$(objfiles)$(libdirs) - lfunc1 -lfunc2
。(如果
func2
库也取决于func1
,那是一个不好的设计,应重新考虑。如果没有更改,请要求链接器多次重新考虑库,与-lfunc1 -lfunc2 -lfunc1
一样,可能会解决直接问题,但可能会出现其他问题。)Libraries must be listed in the order their symbols are needed.
The command
cc $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LIBDIRS) -lfunc2 -lfunc1
tells the linker to first use thefunc2
library to resolve any pending references in the executable it is building and then to use thefunc1
library.Since the linker processes
func2
first and, at the time it does so, there is no pending reference toprint2
, the linker does not include the module withprint2
in the executable.Later, when the linker is processing
func1
, it includes the module withprint1
in the executable becausemain
uses it. That moduleprint1
usesprint2
, so including that module adds a new reference toprint2
. Then, when the linker is done processingfunc1
, it has an unresolved reference. The linker does not go back tofunc2
to check it again.Since the
func1
library depends onfunc2
, change the link command tocc $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LIBDIRS) -lfunc1 -lfunc2
.(If the
func2
library also depends onfunc1
, that is a bad design and should be reconsidered. If it is not changed, asking the linker to reconsider the libraries multiple times, as with-lfunc1 -lfunc2 -lfunc1
, might fix the immediate problem, but others can arise.)