如何在C中链接目标文件?失败“为架构x86_64定义未定义的符号”

时间:2013-03-15 20:51:20

标签: c gcc compilation

所以我正在尝试使用我文件(file2.c)中另一个C(file1.c)文件中定义的函数。我要包含file1(file1.h)的标题才能执行此操作。

但是,每当我尝试使用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

我被告知我需要“将目标文件链接在一起”才能使用file2中file1的功能,但我不知道这意味着什么:(

4 个答案:

答案 0 :(得分:76)

我假设您正在使用gcc,只需链接目标文件:

$ gcc -o output file1.o file2.o

使用

简单地编译目标文件
$ gcc -c file1.c

这会产生file1.o等等。

如果要将文件链接到可执行文件,请执行

$ gcc -o output file1.c file2.c

答案 1 :(得分:20)

现有的答案已经涵盖了“如何”,但我只是想详细说明其他可能想知道的“什么”和“为什么”。

编译器(gcc)的作用:术语“编译”是一个过载的术语,因为它在高级用于表示“将源代码转换为程序”,但在技术上更意味着“转换”源代码到目标代码“。像gcc这样的编译器实际上执行两个相关但可以说是不同的函数来将源代码转换为程序:编译(如后一个将源代码转换为目标代码的定义)和链接(将必要的目标代码文件组合到一起的过程)一个完整的可执行文件)。

您看到的原始错误在技术上是一个“链接错误”,并由链接器“ld”抛出。与(严格)编译时错误不同,没有对源代码行的引用,因为链接器已经在对象空间中。

默认情况下,当gcc被赋予源代码作为输入时,它会尝试编译每个源代码,然后将它们全部链接在一起。如其他响应中所述,可以使用标志来指示gcc首先进行编译,然后稍后使用目标文件在单独的步骤中进行链接。这个两步过程似乎是不必要的(也可能是非常小的程序),但在管理一个非常大的程序时非常重要,每次进行小的更改时编译整个项目都会浪费相当多的时间。

答案 2 :(得分:8)

您可以在一个命令中编译和链接:

gcc file1.c file2.c -o myprogram

运行:

./myprogram

但要回答问题,只需将目标文件传递给gcc

gcc file1.o file2.o -o myprogram

答案 3 :(得分:5)

在一个文件夹中添加foo1.c,foo2.c,foo3.c和makefile bash中的类型make

如果您不想使用makefile,可以运行命令

gcc -c foo1.c foo2.c foo3.c

然后

gcc -o output foo1.o foo2.o foo3.o

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

#include <stdio.h>
void funk2(){
    printf("\nfunk2\n");
}
void funk3(){
    printf("\nfunk3\n");
}

foo3.c

#include <stdio.h>

void funk4(){
    printf("\nfunk4\n");
}
void funk5(){
    printf("\nfunk5\n");
}

生成文件

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