GCC 编译 (ld) 问题的最后一步

Final step in GCC compiling (ld) issue

我正在尝试编写一个逐步编译的makefile,问题在第四步,链接。

程序由多个文件组成,开头为main.c:

#include "file1.h"
#include "file2.h"

int main() {
  printout1("Print one");
  printout2(5);
  return 0;
}

file1.h

#include <stdio.h>

void printout1(char *str);

file1.c

#include "file1.h"

void printout1(char *str) {
  printf("%s\n", str);
}

file2.h

#include <stdio.h>
#include "file1.h"

void printout2(int);

file2.c

#include "file2.h"

void printout2(int val) {
  printf("%d\n", val);
  printout1("Print two");
}

我正在尝试使用以下 makefile 编译该程序:

all:
    cpp main.c main.i 
    gcc -S main.i
    as -o main.o main.s
    ld -o main.o

出现以下错误:

ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
main.o: in function 'main':
main.c:(.text+0xa): undefined reference to 'printout1'
main.c:(.text+0x14): undefined reference to 'printout2'
makefile:2 recipe for target 'all' failed
make:***[all] Error 1

我对这类事情还很陌生,我知道问题出在头文件上,只是不知道如何将它们包含在其中。

两个主要问题:

  1. gcc 是所有必需步骤的前端——不要尝试直接调用工具链的其他工具,始终使用 gcc。这将确保它始终为这些其他工具添加所需的选项。

  2. 你在不同的编译单元(file1和file2)中有函数,但是从来没有编译过link这些。


使用您的结构的 GNU make 的合理 Makefile 如下所示:

CC ?= gcc

all: main

main: main.o file1.o file2.o
    $(CC) -o$@ $^

%.o: %.c
    $(CC) -c -o$@ $<

.PHONY: all

这会将所有 .c 文件直接编译为目标文件,最后 link 将它们(使用 $(CC),因此,例如 gcc)编译为最终的可执行文件。规则 all 被标记为 .PHONY 因为它不会创建名为 all 的文件——您应该让 make 知道这一点。

您当然可以明确地添加额外的步骤,但这没有多大意义。