我刚刚完成了一次学校作业,并且在测试我的代码时遇到了问题,因为我在运行后一直得到以下输出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
所有这些文件都在同一目录中。在过去的一个半小时里,我一直在尝试编译它们,并且无休止地搜索了Google。它与我已阅读的链接有关,我的讲师没有讲授此链接,因此我不知道如何编译这些文件以测试其输出。谁能让我知道怎么了?
您的头文件绝对正确。您所拥有的存在一个链接器错误:编译时packetize.c
没有问题,但是随后您尝试链接一个可执行文件packetize
(因为没有提供-c
指出“编译为目标文件”的选项)。可执行文件也将需要编译后的代码crc16.c
。
您必须在编译器行中提供所有源代码:
cc packetize.c crc16.c -o myApp
或者,您必须编译成单独的目标文件,最终将它们链接在一起:
cc -c packetize.c -o packetize.o
cc -c crc16.c -o crc16.o
cc packetize.o crc16.o -o myApp
前者是您在单次命令行中要做的事情,后者是Makefile通常要做的事情。(因为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()
。
在该文件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
,并为链接器提供两个目标文件,以便它可以解析所有引用:
cc -c foo.c -o foo.o
ld foo.o main.o -o testproc # link-objects-to-exe
Scriptum之后:ld
直接按上述方式进行呼叫很可能无法正常工作。链接需要几个附加参数,这些附加参数cc
会隐式添加-C运行时支持,标准C库等类似的东西。在上面的示例中,我没有提供这些参数,因为它们会使问题变得混乱,并且超出了问题的范围。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句