我正在努力构建一个包含多个文件的程序,该程序使用 C 中的 makefile 进行文件间函数调用。假设我有一个主文件,它调用一个函数
call_print_hello()
在头文件中声明 fdeclar_macros.h
并写入文件 script1.c
。函数 call_print_hello()
本身调用另一个函数 print_hello()
也在 fdeclar_macros.h
中声明并写在 script2.c
中。我也有一个makefile
但是当我运行它时我收到以下错误消息:
gcc -g -Wall -c main.c
gcc -g -Wall -c script1.c
gcc -o main main.o script1.o
Undefined symbols for architecture x86_64:
"_call_print_hello", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
文件内容如下:
makefile
:
CC = gcc
CFLAGS = -g -Wall
main: main.o script1.o
$(CC) -o main main.o script1.o
main.o: main.c fdeclar_macros.h
$(CC) $(CFLAGS) -c main.c
script2.o: script2.c fdeclar_macros.h
$(CC) $(CFLAGS) -c script2.c
script1.o: script1.c fdeclar_macros.h
$(CC) $(CFLAGS) -c script1.c
run: main
./main
clean:
$(RM) -rf justify *.dSYM *.o
main.c
:
#include "fdeclar_macros.h"
int main(){
call_print_hello();
return 0;
}
fdeclar_macros.h
:
#define NUMBER 3
void print_hello();
void call_print_hello();
script1.c
:
#include <stdio.h>
#include "fdeclar_macros.h"
void print_hello(){
printf("hello %d\n", NUMBER);
}
script2.c
:
#include "fdeclar_macros.h"
void call_print_hello(){
print_hello();
}
main
可执行文件的 make 目标不包含对 script2.o
的依赖,构建 main
的规则也没有将 script2.o
链接到 main
可执行文件中。
因此链接器尝试构建一个缺少
script2.o
内容的可执行文件,但由于需要该内容,因此链接失败。
一个简单的解决方法是改变原来的规则
main: main.o script1.o
$(CC) -o main main.o script1.o
通过添加
script2.o
:
main: main.o script1.o script2.o
$(CC) -o main main.o script1.o script2.o
我会把寻找更多通用规则作为练习留给读者。
NAME = my_programm
CC = gcc
CFLAGS = -Wall -Werror -Wextra
MY_SOURCES = main.c script1.c script2.c
MY_OBJECTS = $(MY_SOURCES:.c=.o)
$(NAME): $(MY_OBJECTS)
@cc $(CFLAGS) $(MY_OBJECTS) -o $(NAME)
clean:
@rm -f $(MY_OBJECTS)
@rm -f $(NAME)
run:
./my_programm
你写了./main.当您没有像我一样更改名称时,您应该执行 ./a.out(在 Linux 上)。当你用 -o 编译时,你可以重命名它。小心 makefile,如果你做错了什么,你可以删除你的东西。做好备份。