我刚刚完成了一项学校作业,我在测试代码时遇到了问题,因为我在运行make packetize
后继续得到以下输出(这是教授给我们的makefile)
cc packetize.c -o packetize
/tmp/ccJJyqF6.o: In function `block_to_packet':
packetize.c:(.text+0xb1): undefined reference to `crc_message'
collect2: ld returned 1 exit status
make: *** [packetize] Error 1
block_to_packet
在名为packetize.c
的文件中定义,crc_message
在crc16.c
中定义(两者都包含#include "data.h"
行)。 data.h
中还包含crc_message
的函数标题所有这些文件都在同一目录中。在过去的一个半小时里,我一直在努力编译它们,并无休止地搜索谷歌无济于事。它与我读过的链接有关,我的导师没有教过这个,所以我不知道如何编译这些文件来测试他们的输出。任何人都可以让我知道什么是错的?
答案 0 :(得分:4)
你的头文件绝对没问题。您所拥有的是链接器错误:packetize.c
的编译运行没有问题,但是您尝试链接可执行文件文件{{1} (因为你没有给出packetize
选项,说明“编译到对象文件”)。可执行文件也需要-c
的编译代码。
您必须在编译器行上提供所有源:
crc16.c
或者你必须编译成单个目标文件,最终链接在一起:
cc packetize.c crc16.c -o myApp
前者是你在一次性命令行中所做的,后者是Makefile通常所做的。 (因为如果您所做的只是修改cc -c packetize.c -o packetize.o
cc -c crc16.c -o crc16.o
cc packetize.o crc16.o -o myApp
,则无需重新编译crc16.c
。在大型项目中,重新编译可能需要花费大量时间。)
修改强>
教程时间。请注意给定命令行中是否存在packetize.c
选项。
考虑:
-c
源文件定义函数// foo.c
int foo()
{
return 42;
}
。
foo()
头文件声明函数// foo.h
int foo();
。
foo()
源文件引用 // main.c
#include "foo.h"
int main()
{
return foo();
}
。
在文件foo()
中,include使编译器意识到最终在某处,main.c
中声明了函数foo()
的定义。此时所有编译器都需要知道函数将存在,它不带参数,并返回foo.h
。这足以编译源到目标代码:
int
但是,实际编译可执行文件 <:>
。cc -c main.c -o main.o
编译器承诺(通过声明)将存在cc main.c -o testproc # fail of compile-source-to-exe
ld main.o -o testproc # fail of link-object-to-exe
的定义,这对于编译器而言足够。
链接器但是(在第一个示例中由foo()
隐式运行)需要该定义。可执行文件需要执行函数cc
,但在foo()
中找不到它。无法解析对main.c
的引用。 “未解决的参考错误”。
您需要一次性编译两个源文件......
foo()
...或者编译cc foo.c main.c -o testproc # compile-source-to-exe
并为链接器提供两个目标文件,以便它可以解析所有引用:
foo.c
Post Scriptum :如上图所示,直接调用cc -c foo.c -o foo.o
ld foo.o main.o -o testproc # link-objects-to-exe
很可能无法正常工作。链接需要一些额外的参数,ld
隐式添加 - C运行时支持,标准C库,类似的东西。我没有在上面的例子中给出这些参数,因为它们会使问题混淆,超出了问题的范围。
答案 1 :(得分:0)
您还必须编译crc16.c并链接这两个目标文件以构建二进制文件。否则,调用crc_message()的packetize.c不知道它。
尝试使用
cc packetize.c crc16.c -o packetize
来自packetize.c的来电crc_message()就可以了。
答案 2 :(得分:0)
正如Totland所写,crc_message是在crc16.c中定义的;这意味着packetize.c无法看到定义,无论他们拥有多少共享头。您没有编译错误,但链接器出错。
如果首先将c文件编译为目标文件,然后将所有内容链接到可执行文件,它将起作用。