如何使用Makefile在C语言中构建具有多个文件和文件间函数调用的程序。

huangapple go评论65阅读模式
英文:

How to build a program with multiple files whith inter files function calls with makefile in C

问题

我在构建一个使用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();
}
英文:

I am struggling with building a program with multiple files whith inter files function calls with makefile in C. Let's say that I have a main file which call a function call_print_hello() declared in a header file fdeclar_macros.h and written in the file script1.c. The function call_print_hello() itself calls another function print_hello() also declared in fdeclar_macros.h and written in script2.c. I have also a makefile but when I run it I get the following error message:

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:
  &quot;_call_print_hello&quot;, 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

Here are the content of the files:

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 &quot;fdeclar_macros.h&quot;

int main(){
  call_print_hello();
  return 0;
}

fdeclar_macros.h:


#define NUMBER 3

void print_hello();
void call_print_hello();

script1.c:

#include &lt;stdio.h&gt;
#include &quot;fdeclar_macros.h&quot;

void print_hello(){
  printf(&quot;hello %d\n&quot;, NUMBER);
}

script2.c:

#include &quot;fdeclar_macros.h&quot;

void call_print_hello(){
  print_hello();
}

答案1

得分: 2

make目标“main”可执行文件不包含对“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

我将把寻找更通用规则的任务留给读者。

英文:

The make target for the main executable does not contain a dependency on script2.o and the rule to build main does not link script2.o into the main executable either.

So the linker tries to build an executable with the content of script2.o missing, but as that content is required, linking fails.

One easy fix would be to change the original rule

main: main.o script1.o
    $(CC) -o main main.o script1.o

by adding script2.o:

main: main.o script1.o script2.o
    $(CC) -o main main.o script1.o script2.o

I will leave finding more general rules as an exercise to the reader.

答案2

得分: 1

以下是代码部分的中文翻译:

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

请注意,这些内容是计算机程序的一部分,用于构建和运行程序。如果您有任何与代码相关的问题或需要进一步的解释,请随时提出。

英文:
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

huangapple
  • 本文由 发表于 2023年2月19日 20:07:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定