在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.o
, make
会尝试找到一个可以用来制作这个目标的规则。 这恰好是我刚才展示的规则,因为file.o
匹配%.o
。
然后是recipe
。 这是将要执行的。 通常是关于调用编译器( gcc
),并将其提供给源文件以生成目标文件。 这就是我们用gcc -c $< -o $@
做的事情。 $<
和$@
分别表示target
和prerequisites
。
那么,当你'想要'构建你的程序时会发生什么? 您通常会输入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
如果他们可以找到一个规则来创建它,那么将指定您指定的每个先决条件。