使用 GNU Make 输出平面对象文件目录结构
我有一个使用 GNU Make 的 C++ 小项目。我希望能够将以下源文件: 转换
src/
a.cpp
b/
b.cpp
c/
c.cpp
为以下输出结构(此时我不关心重复项):
build/
a.o
b.o
c.o
到目前为止,我有以下内容,不幸的是,这将 .o 和 .d 放在了旁边对于每个 .cpp:
OBJS := $(foreach file,$(SRCS),$(file).o)
DEPS := $(patsubst %.o,%.d,$(OBJS))
sinclude $(DEPS)
$(OBJS) : %.o : %.cpp
@echo Compiling $<
$(CC) $(CC_FLAGS) $(INCS) -MMD -o $@ $<
我知道 $(notdir ...) 函数,但此时我使用它来过滤对象的努力失败了。有人能解释一下吗?这似乎是相当合理的事情。
I have a C++ small project using GNU Make. I'd like to be able to turn the following source files:
src/
a.cpp
b/
b.cpp
c/
c.cpp
into the following output structure (I'm not concerned about duplicates at this point):
build/
a.o
b.o
c.o
So far I have the following, which unfortunately puts the .o and .d right next to each .cpp:
OBJS := $(foreach file,$(SRCS),$(file).o)
DEPS := $(patsubst %.o,%.d,$(OBJS))
sinclude $(DEPS)
$(OBJS) : %.o : %.cpp
@echo Compiling lt;
$(CC) $(CC_FLAGS) $(INCS) -MMD -o $@ lt;
I'm aware of the $(notdir ...) function, but at this point my efforts to use it to filter the objects has failed. Can anyone shed some light on this? It seems like fairly reasonable thing to do.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可能不太喜欢这种方法,但是:
在 Makefile.am 中效果很好。只是说你不需要手写所有内容。
You might not particulary like this approach, but:
does the trick quite well in a Makefile.am. Just sayin' that you don't need to write everything by hand.
至少有两种方法可以做到这一点。首先(也是我建议的)是您可以将构建目录添加到目标名称(即使使用模式规则时)。例如:
其次,您可以使用 VPATH 变量告诉 make 在不同的目录中搜索先决条件。这可能是更常用(过度)使用的方法。它至少有一个严重的缺点,那就是如果你照着做,后来遇到“重复”的问题,就没有办法解决问题。使用前一种方法,您始终可以镜像构建目录下的源目录结构,以避免重复冲突。
编辑:我之前的回答在细节上有点简短,所以我将对其进行扩展以表明这实际上像广告中那样有效。这是一个完整的工作示例 Makefile,它使用上述第一种技术来解决问题。只需将其粘贴到 Makefile 中并运行 make ——它将完成其余的工作并表明这确实有效。
编辑:我不知道如何让SO在我的答案文本中允许使用制表符(它用空格替换它们)。复制并粘贴此示例后,您需要将命令脚本中的前导空格转换为制表符。
特别要注意的是,存在具有重复名称的源文件(ac 和 a/ac、bc 和 b/bc 等),这不会导致任何问题。另请注意,没有使用 VPATH,由于其固有的限制,我建议避免使用 VPATH。
There are at least two ways you can do this. First (and what I'd recommend) is you can add the build directory to the target names (even when using a pattern rule). For example:
Second, you can use the VPATH variable to tell make to search a different directory for prerequisites. This is probably the more commonly (over) used approach. It has at least one serious drawback, and that is if you go with it, and later run into problems with "duplicates", there's no way to solve the problem. With the former approach, you can always mirror the source directory structure underneath the build directory to avoid duplicates clashing.
Edit: My previous answer was a little short on detail, so I will expand upon it to show that this actually works as advertised. Here is a complete working example Makefile that uses the first technique described above to solve the problem. Simply paste this into a Makefile and run make -- it will do the rest and show that this does in fact work.
Edit: I can't figure out how to get SO to allow tab characters in my answer text (it replaced them with spaces). After copying and pasting this example, you'll need to convert the leading spaces in the command scripts into tabs.
In particular, note that there are source files with duplicate names (a.c and a/a.c, b.c and b/b.c, etc) and that this doesn't cause any problems. Also note there is no use of VPATH, which I recommend to avoid using due to its inherent limitations.
然后引用源文件而不使用其目录名; Make 将搜索 vpath。
Then refer to source files without their directory name; Make will search the vpath.
按照最初的要求创建平面目录结构。
确实使用
vpath
来追踪源文件,但所有的簿记都是从SRC
列表中自动完成的。抱歉,
回声
很丑,但我只有我的胜利盒来测试它。Creating the flat directory structure as initially requested.
Does use
vpath
to track down the source files, but all the bookeeping is done automagically from theSRC
list.Sorry about the ugly
echo
's but I only had my win box to test it on.这是针对 Win32 mingw32-make 的。这是有效的。
最重要的部分是
-mkdir $(patsubst %/,%,$(dir $@))
win32 的 。我们需要去掉 win32 后面的 / 。
This is for Win32 mingw32-make. it's works.
The most important part is
-mkdir $(patsubst %/,%,$(dir $@))
for win32. We need to strip the trailling / for win32.