C语言 如何在 C 中链接目标文件?因“架构 x86_64 的未定义符号”而失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15441877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"
提问by adi
So I'm trying trying to use a function defined in another C (file1.c) file in my file (file2.c). I'm including the header of file1 (file1.h) in order to do this.
所以我试图在我的文件 (file2.c) 中使用另一个 C (file1.c) 文件中定义的函数。为了做到这一点,我包含了 file1 (file1.h) 的头文件。
However, I keep getting the following error whenever I try to compile my file using gcc:
但是,每当我尝试使用 gcc 编译我的文件时,我都会收到以下错误:
Undefined symbols for architecture x86_64:
"_init_filenames", referenced from:
_run_worker in cc8hoqCM.o
"_read_list", referenced from:
_run_worker in cc8hoqCM.o
ld: symbol(s) not found for architecture x86_64
I've been told I need to "link the object files together" in order to use the functions from file1 in file2, but I have no clue what that means :(
有人告诉我,我需要“将目标文件链接在一起”才能使用 file2 中的 file1 中的函数,但我不知道这意味着什么:(
回答by bash.d
I assume you are using gcc, to simply link object files do:
我假设您正在使用gcc, 来简单地链接目标文件:
$ gcc -o output file1.o file2.o
To get the object-files simply compile using
要获得目标文件,只需使用
$ gcc -c file1.c
this yields file1.o and so on.
这会产生 file1.o 等等。
If you want to link your files to an executable do
如果要将文件链接到可执行文件,请执行以下操作
$ gcc -o output file1.c file2.c
回答by SeKa
The existing answers already cover the "how", but I just wanted to elaborate on the "what" and "why" for others who might be wondering.
现有的答案已经涵盖了“如何”,但我只是想为可能想知道的其他人详细说明“什么”和“为什么”。
What a compiler (gcc) does: The term "compile" is a bit of an overloaded term because it is used at a high-level to mean "convert source code to a program", but more technically means to "convert source code to object code". A compiler like gcc actually performs two related, but arguably distinct functions to turn your source code into a program: compiling (as in the latter definition of turning source to object code) and linking (the process of combining the necessary object code files together into one complete executable).
编译器 (gcc) 的作用:术语“编译”是一个重载的术语,因为它在高级别的意思是“将源代码转换为程序”,但在技术上更指“将源代码转换为程序”目标代码”。像 gcc 这样的编译器实际上执行两个相关但可以说是不同的功能来将您的源代码转换为程序:编译(如将源代码转换为目标代码的后一个定义)和链接(将必要的目标代码文件组合在一起的过程)一个完整的可执行文件)。
The original error that you saw is technically a "linking error", and is thrown by "ld", the linker. Unlike (strict) compile-time errors, there is no reference to source code lines, as the linker is already in object space.
您看到的原始错误在技术上是“链接错误”,由链接器“ld”抛出。与(严格的)编译时错误不同,没有对源代码行的引用,因为链接器已经在对象空间中。
By default, when gcc is given source code as input, it attempts to compile each and then link them all together. As noted in the other responses, it's possible to use flags to instruct gcc to just compile first, then use the object files later to link in a separate step. This two-step process may seem unnecessary (and probably is for very small programs) but it is very important when managing a very large program, where compiling the entire project each time you make a small change would waste a considerable amount of time.
默认情况下,当 gcc 以源代码作为输入时,它会尝试编译每一个,然后将它们链接在一起。正如其他回复中所述,可以使用标志来指示 gcc 首先编译,然后在单独的步骤中使用目标文件进行链接。这个两步过程可能看起来没有必要(并且可能对于非常小的程序而言),但是在管理非常大的程序时非常重要,每次进行小的更改时编译整个项目都会浪费大量时间。
回答by Johnsyweb
You could compile and link in one command:
您可以在一个命令中编译和链接:
gcc file1.c file2.c -o myprogram
And run with:
并运行:
./myprogram
But to answer the question as asked, simply pass the object files to gcc:
但是要回答所问的问题,只需将目标文件传递给gcc:
gcc file1.o file2.o -o myprogram
回答by Ar maj
Add foo1.c , foo2.c , foo3.c and makefile in one folder the type make in bash
将 foo1.c , foo2.c , foo3.c 和 makefile 添加到一个文件夹中 bash 中的 make 类型
if you do not want to use the makefile, you can run the command
如果不想使用makefile,可以运行命令
gcc -c foo1.c foo2.c foo3.c
then
然后
gcc -o output foo1.o foo2.o foo3.o
foo1.c
foo1.c
#include <stdio.h>
#include <string.h>
void funk1();
void funk1() {
printf ("\nfunk1\n");
}
int main(void) {
char *arg2;
size_t nbytes = 100;
while ( 1 ) {
printf ("\nargv2 = %s\n" , arg2);
printf ("\n:> ");
getline (&arg2 , &nbytes , stdin);
if( strcmp (arg2 , "1\n") == 0 ) {
funk1 ();
} else if( strcmp (arg2 , "2\n") == 0 ) {
funk2 ();
} else if( strcmp (arg2 , "3\n") == 0 ) {
funk3 ();
} else if( strcmp (arg2 , "4\n") == 0 ) {
funk4 ();
} else {
funk5 ();
}
}
}
foo2.c
foo2.c
#include <stdio.h>
void funk2(){
printf("\nfunk2\n");
}
void funk3(){
printf("\nfunk3\n");
}
foo3.c
foo3.c
#include <stdio.h>
void funk4(){
printf("\nfunk4\n");
}
void funk5(){
printf("\nfunk5\n");
}
makefile
生成文件
outputTest: foo1.o foo2.o foo3.o
gcc -o output foo1.o foo2.o foo3.o
make removeO
outputTest.o: foo1.c foo2.c foo3.c
gcc -c foo1.c foo2.c foo3.c
clean:
rm -f *.o output
removeO:
rm -f *.o
回答by ashmew2
Since there's no mention of how to compile a .c file together with a bunch of .o files, and this comment asks for it:
由于没有提到如何将 .c 文件与一堆 .o 文件一起编译,因此此评论要求:
where's the main.c in this answer? :/ if file1.c is the main, how do you link it with other already compiled .o files? – Tom Brito Oct 12 '14 at 19:45
这个答案中的 main.c 在哪里?:/ 如果 file1.c 是主要文件,你如何将它与其他已经编译的 .o 文件链接起来?– 汤姆布里托 2014 年 10 月 12 日,19:45
$ gcc main.c lib_obj1.o lib_obj2.o lib_objN.o -o x0rbin
$ gcc main.c lib_obj1.o lib_obj2.o lib_objN.o -o x0rbin
Here, main.c is the C file with the main() function and the object files (*.o) are precompiled. GCC knows how to handle these together, and invokes the linker accordingly and results in a final executable, which in our case is x0rbin.
这里,main.c 是带有 main() 函数的 C 文件,目标文件 (*.o) 是预编译的。GCC 知道如何一起处理这些,并相应地调用链接器并产生最终的可执行文件,在我们的例子中是 x0rbin。
You will be able to use functions not defined in the main.c but using an extern reference to functions defined in the object files (*.o).
您将能够使用未在 main.c 中定义的函数,但可以使用对目标文件 (*.o) 中定义的函数的外部引用。
You can also link with .obj or other extensions if the object files have the correct format (such as COFF).
如果目标文件具有正确的格式(例如 COFF),您还可以使用 .obj 或其他扩展名进行链接。

