在Raspbian中创建一个Makefile

我正在尝试在Raspbian(Raspberry Pi)中为我的C程序创建一个Makefile。 我的程序包含一堆.c和.h文件。 我看过无数的Makefiles,但我不会解释它如何与多个文件一起工作。 Makefile中总有.o文件,但据我所知,目标文件是编译的结果,所以我没有任何o。 文件,因为我正在尝试编译我的.c文件。

请向我解释这是如何工作的。

编辑:

谢谢。 所以我尝试了这个,它开始编译,但有错误’多重定义’。 例:

这些是我的文件:

main.c main.h calibration.c calibration.h file.c file.h frame.c frame.h gamepad.c gamepad.h gpio.c gpio.h uart.c uart.h types.h 

这是我的makefile:

 all: main main: main.o calibration.o file.o frame.o gamepad.o gpio.o uart.o %.o: %.c gcc -c -std=c99 -Wall $< -o $@ -lncurses 

我在哪里可以放’types.h’? 对于每个文件,我都会收到错误“多个定义”

一个非常简单但典型的makefile可能看起来像这样

 SOURCES = source1.c source2.c source3.c OBJECTS = $(SOURCES:%.c=%.o) TARGET = myExecutable $(TARGET): $(OBJECTS) gcc $^ -o $@ %.o: %.c gcc -c $< -o $@ 

复杂的部分:

  • SOURCES = source1.c source2.c source3.c这是一个变量定义,它将字符串"source1.c source2.c source3.c给变量SOURCES

  • $(SOURCES:%.c=%.o)这是patsubst 文本函数的简写。 它接受来自$(SOUCES)变量的所有文本,并用%.o替换模式%.c ,即它需要例如字符串source1.c并将其替换为source1.o

  • $(TARGET): $(OBJECTS)这使myExecutable依赖于所有目标文件,这意味着如果修改了一个目标文件,则将执行规则中的命令。

  • gcc $^ -o $@这会调用gcc命令,将所有依赖项( $^ )作为参数(即所有目标文件)传递,并告诉gcc输出一个具有目标名称( $@ )的文件。

  • %.o: %.c这是使目标文件依赖于其源文件的规则。 因此,如果您有source1.c那么source1.o将依赖于该源文件。

  • gcc -c $< -o $@这是将源文件(第一个依赖项, $< )编译为目标文件(使用-c选项)并将其命名为规则目标( $@ )的命令。

另请注意,如果make没有特定目标的情况下调用make ,则将选择第一个规则。 对于上面的makefile,它将是$(TARGET): $(OBJECTS)规则,它将确保所有目标文件都是从源文件构建的,然后将目标文件链接到生成的可执行文件中。

make规则的基本语法是:

 target … : prerequisites … recipe … … 

分号的左边是目标。 目标是您的目标文件( .o )。 分号右侧是创建此文件所需的文件。 这些文件是源文件( .c )。

让我们举一个这样的规则可能是什么样子的基本例子。

 %.o: %.c gcc -c $< -o $@ 

%符号是通配符。 %.o表示以.o结尾的所有内容。 因此,如果你想创建一个目标文件,你可以说make file.omake会尝试找到一个可以用来制作这个目标的规则。 这恰好是我刚才展示的规则,因为file.o匹配%.o

然后是recipe 。 这是将要执行的。 通常是关于调用编译器( gcc ),并将其提供给源文件以生成目标文件。 这就是我们用gcc -c $< -o $@做的事情。 $<$@分别表示targetprerequisites

那么,当你'想要'构建你的程序时会发生什么? 您通常会输入make ,它将构建。 键入make时使用的默认规则是all 。 因此,如果您制定了关于all规则的规则,那么您可以指定要创建的文件来构建程序。 这样一条规则的例子:

 all: main 

然后,当调用make时,它会找到该规则并发现它需要main 。 要创建main您需要另一条规则:

 main: file.o 

这个规则说要构建main ,你需要file.o 因此,当您将所有示例规则放在一起时,您会得到:

 all: main main: file.o %.o: %.c gcc -c $< -o $@ 

请注意,您可以指定多个文件,因此可以使用file.o main.o other_file.o等来代替file.o main.o other_file.o如果他们可以找到一个规则来创建它,那么将指定您指定的每个先决条件。