gpt4 book ai didi

makefile - 如何使用 makefile 将 .o 和 .exe 文件放在/build/目录中

转载 作者:行者123 更新时间:2023-12-01 11:20:16 25 4
gpt4 key购买 nike

我正在努力寻找有关真正初学者级别的 makefile 的任何信息。连问题here ,如所问,使用大量我不理解的符号呈现,例如 $(CC) $(INC) $< $(CFLAGS) -o $(BIN)$@ $(LIBS) .那让我失望。

我的生成文件如下所示:

cpptest: main.o
g++ -o cpptest main.o

main.o: main.cpp
g++ -c main.cpp

clean:
rm cpptest main.o

这是我知道如何处理 makefile 的全部限制。它可以工作,但将 main.o 和 cpptest.exe 文件放入项目根目录。

我想将 main.o 文件和 cpptest.exe 文件放入/build/目录中。但是,如果我输入 ./build/在每个 main.o 和每个 cpptest 之前,目标文件出现在项目根目录中,而 exe 文件根本不出现。

我正在 Windows 上使用 Sublime Text 3 构建这个东西,这是值得的。

最佳答案

一个稍微好一点的解决方案如下:注意,我正在做一些时髦的事情,但我会一路解释

all: build/cpptest

.PHONY: all

build:
@echo "building directory $@"
mkdir -p $@

build/cpptest: build/main.o | build
@echo building $@
g++ -o $@ $^

build/main.o: main.cpp | build
@echo building $@
g++ -o $@ -c $^

clean:
@echo cleaning...
rm -f build/*

好的,让我们看看第一个和第二个目标:
all: build/cpptest

.PHONY: all

我创建了一个名为 all 的默认目标.这是一个虚拟目标(它实际上并没有构建一个名为 all 的文件),所以我标记了 all通过使其依赖于 .PHONY 而变得虚假. (这基本上告诉 make 不要忽略 all 规则,如果名为 all 的新文件已经存在)。 all没有配方,因此除了导致创建其依赖项之外,它什么都不做。这可能看起来有点复杂,但它是 makefile 中的标准做法,因为它使您可以自由地按照您认为有用的任何顺序组织下面的规则。

第三个目标:
build:
@echo "building directory $@"
mkdir -p $@

对于第一个目标 build,这是您正在创建的目录的名称。 build是目标,它没有依赖关系,并且有两个配方行。第一个配方行以 @ 开头.这只是意味着在运行之前不要打印配方。如果你没有这个,你的输出看起来像:
 echo "building directory build"
building directory build

这是丑陋的。 @只有在行的开头才会这样做。您会注意到,稍后您会看到 $@ .这是不同的。它是一个扩展为目标名称的变量(在本例中为 build)。在适当的时候开始使用这个变量是一个好习惯,因为它会在以后简化更复杂的 makefile。 build的第二个秘方目标创建目录。

第四个目标:
build/cpptest: build/main.o | build
@echo building $@
g++ -o $@ $^

这说 build/cpptest依赖于 build/main.obuild (即,在其他两个完成之前不要开始构建这些)。一大空洞:注意 |前符号 build .这使其成为仅订单依赖项。这意味着如果 build目录已存在,且其时间戳比 build/cpptest 新,那就不考虑 build/cpptest过时(不要重建它)。另一方面,另一个依赖项, build/main.o位于 | 的左侧象征。这告诉 make 如果 build/main.o不存在,或者如果它比 build/cpptest 新,然后 make 应该重建 build/cpptest .

我们需要 |的原因(仅订单依赖)为 build是每次添加新文件时都会更新目录的日期。因此, build将始终具有比 build/cpptest 更新的时间戳.这种属于高级 makefile 的东西,但这是正确的方法,所以我想我会在这里展示它。

正如@Felix 所指出的,并非所有版本的 make 都提供 order-only(尽管 GNU make 确实支持它)。

对于食谱,我使用了 $@变量和 $^多变的。 $^表示所有非订单依赖项(即 main.cpp 在这种情况下)。这些在规则运行之前展开。

您可以更进一步,使其真正正确(例如定义 $(objs) 变量等),这使得将来更容易维护 makefile,但希望这会给您一个良好的开端。

关于makefile - 如何使用 makefile 将 .o 和 .exe 文件放在/build/目录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44706649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com