我有一个简单的makefile:
run: myprogram
./myprog.out
myprogram: main.o otherfile.o
gcc -o myprog.out main.o otherfile.o
%.o : %.c
gcc -c $<
现在这把所有的.o文件放在我的c和h文件旁边,这很烦人。我想有一个名为“myObj”的子文件夹,例如所有的.o文件都被转储到其中,但仍然希望它将myprog构建到根文件夹中。这个问题的在线示例都过于复杂,我不确定其中的哪些行对我实现这一点至关重要,但它们似乎都有基本的$(OBJDIR)/%.o : %.c
。所以我试着:
OBJDIR=myObj
run: myprogram
./myprog.out
myprogram: main.o otherfile.o
gcc -o myprog.out main.o otherfile.o
$(OBJDIR)/%.o : %.c
gcc -c $<
然而,这做了完全相同的事情,并转储根文件夹中的所有.o文件。我怎么能把它们放到子文件夹里呢?
2条答案
按热度按时间nnsrf1az1#
正如注解中提到的,您需要在链接二进制文件的规则中指定
.o
文件在目录中,并且编译.c
文件的规则需要指定输出文件(在目录中)。你还有些其他奇怪的东西。
run
依赖于一个名为myprogram
的文件,该文件永远不会存在,并运行一个名为myprogram.out
的命令。同样,您有一个规则,声称要构建一个名为
myprogram
的文件,但实际上构建了一个名为myprogram.out
的文件。这些可能会导致你的代码被不必要地重新编译(或重新链接)。每个规则都应该构建它声称要构建的文件。所以你可能想要这样的东西:
dsekswqp2#
我已经修复了这些错误,并将你的makefile扩展为一个最小的变体:
我所做的改变:
.PHONY
,如run
)。这可确保在不必要时不会重新生成最新文件。-MMD -MP
到GCC标志,以生成.d
文件和.o
文件。-include
以包含这些文件。myObj
目录,则会自动创建该目录。$@
(输出文件名),$<
(第一个先决条件),$^
(所有先决条件),而不是硬编码的文件名。MAKEFLAGS
被修改为禁用内置规则,并在并行编译期间产生正常的输出。gcc -c
被替换为$(COMPILE.c)
,并且对于链接,gcc
被替换为$(LINK.c)
。这允许您使用一些预定义的环境或Make变量(CC
用于编译器,CFLAGS
用于标志等)更改编译器及其标志。(感谢@TobySpeight):=
而不是=
(微优化,每次使用时都不重新计算)。.c
),以避免将来添加.cpp
文件时.c
和.cpp
文件之间的名称冲突。