1

我有一个简单的 makefile,可以在 Linux 上将文件编译为p.c可执行文件。gccp.c文件依赖于一个a.h文件。我的生成文件如下所示:

//makefile
CC = gcc

build: p.c a.h
    $(CC) -o out p.c
clean:
    rm -f *.exe
rebuild: clean build
4

6 回答 6

6

您的 makefile 不会生成它承诺生成的文件,即build,cleanrebuild. 由于这些目标不是文件,因此应将它们标记为虚假目标

.PHONY: build clean rebuild

build目标应该是:

build : out

out : p.c a.h
    $(CC) -o $@ p.c
于 2012-09-24T10:50:49.407 回答
2

这部分

build: p.c a.h
    $(CC) -o out p.c

说“我正在使用 $(CC) -o out pc 进行编译,结果将是一个名为 'build' 的文件”。由于您撒谎make(这会创建out文件),它将尝试再次构建“构建”。

这里给 Makefile 编写者一个教训:总是使用$@变量(表示目标)来避免这个错误:

out: p.c a.h
    $(CC) -o $@ p.c

如需更多建议,请参阅Paul 的 Makefile 规则

于 2012-09-24T11:16:11.770 回答
1

学习者,这里有一个使用变量来存储可执行文件名称的例子。这样您只需要在 Makefile 开头的一个地方指定它:

EXECUTABLE = out

.PHONY: build clean rebuild

build: $(EXECUTABLE)

$(EXECUTABLE): p.c a.h
    $(CC) -o $@ p.c

clean:
    rm -f $(EXECUTABLE)

rebuild: clean build

通常你也会在变量中列出你的.c.h文件,这样你就可以轻松地从你的构建中添加/删除文件,而不必在你的 Makefile 中搜索它们使用的所有位置。

于 2012-09-24T13:11:33.047 回答
0

Makefile 具有一般语法:

target : dependencies
    commands to make target from dependencies

build因此,您的 Makefile 期望使用目标创建一个名为的文件build : p.c a.h。由于命令实际上并没有在每次调用 make 时都生成此文件,因此必须重做命令。

(PS:Linux 二进制文件没有 .exe 扩展名)

于 2012-09-24T10:51:41.233 回答
0

如果你想避免总是重新编译源,那么你的目标应该依赖于目标文件,而不是源文件:

目标.exe:宝
        $(CC) -o $@ $?;

po:电脑啊
        $(CC) -c $@ $?;

典型的 makefile 通常没有每个目标文件的显式规则,也通常不会列出实现和头文件之间的显式依赖关系;你通常会看到一个隐含的规则,比如

%.o : %.c
        $(CC) -c $(CFLAGS) $?;

(其中$?表示该目标的先决条件列表),或者,如果您的项目非常简单(一个源文件),您甚至不需要它;你通常可以逃脱

全部:目标目标:target.o

假设您有一个名为 的文件target.c,上面将target使用默认编译器和 CFLAGS 选项构建。

同样,典型的 makefile(至少在我的经验中)没有明确列出头文件依赖项。相反,它依赖于编译器选项来自动生成这些依赖项列表(对于 gcc,该选项是-M)。有关示例,请参见此处。

于 2012-09-24T16:17:35.967 回答
0

我知道“目标”和“输出文件”名称必须完全匹配才能使制作能够识别是否不需要重新编译。所以在 Windows 环境的情况下(已经尝试过mingw32-make.exe)它应该是这样的:

build.exe: p.c a.h
    gcc -o build.exe p.c

或者

build.exe: p.c a.h
    gcc -o build p.c    # .exe is added automatically to generated file

调用make时,此代码将始终导致重新编译:

build: p.c a.h
    gcc -o build p.c    # target is "build" and it is not the same as "build.exe" which is the output of compilation
于 2019-03-14T12:44:07.323 回答