如何使用 C 中的 makefile 构建具有多个文件的程序以及文件间函数调用

问题描述 投票:0回答:2

我正在努力构建一个包含多个文件的程序,该程序使用 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();
}
c file gcc makefile build
2个回答
2
投票

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

我会把寻找更多通用规则作为练习留给读者。


0
投票
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,如果你做错了什么,你可以删除你的东西。做好备份。

© www.soinside.com 2019 - 2024. All rights reserved.