使用make构建多个二进制文件 [英] Using make to build several binaries

查看:314
本文介绍了使用make构建多个二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个Makefile(在父目录中)以调用其他几个Makefile(在子目录中),这样我可以通过仅调用一个父Makefile来构建多个二进制文件(每个项目子目录一个).

我的研究因在递归Makefile上查找大量负载而受阻,但是我认为这是您试图将几个目录Makefile生成为 single 二进制文件的地方?

也许我想做的事最好由Shell脚本处理,也许依次调用每个子目录中的make,但是我认为Makefile可能是一个更优雅的解决方案?

非常感谢收到的所有指针

使用linux和GNU工具链的PS

解决方案

上面第一个答案中给出的for循环解决方案实际上不应原样使用.在这种方法中,如果您的一个子make失败,则构建不会失败(应该如此),而是继续其他目录.不仅如此,构建的最终结果将取决于最后一个子目录的退出代码,因此,即使成功,即使其他子目录失败,构建也会成功.不好!<​​/p>

您可以通过执行以下操作来解决此问题:

all: 
        @for dir in $(SUBDIRS); \
        do \
            $(MAKE) -C $${dir} $@ || exit $$?; \
        done

但是,现在您遇到了相反的问题:如果您运行"make -k"(即使有错误,也要继续执行),那么在这种情况下就不会遵守.仍然会在失败时退出.

上述两种方法的另一个问题是,它们会序列化所有子目录的构建,因此,如果启用并行构建(使用make的-j选项),则将仅在单个子目录中而不是在所有子目录中进行并行构建.

Eregrith和sinsedrix的解决方案更接近于您想要的解决方案,尽管仅供参考,但您永远不要在调用递归make调用时使用"make".就像在johfel的示例中一样,您应该始终使用$(MAKE).

您想要的是这样的东西

SUBDIRS = subdir1 subdir1 subdir3 ...

all: $(addprefix all.,$(SUBDIRS))
all.%:
        @ $(MAKE) -C '$*' '$(basename $@)'
.PHONY: $(addprefix all.,$(SUBDIRS))

当然,您可以为诸如安装"之类的其他目标添加更多这样的节.还有更多花哨的方法可以处理具有任何通用目标的子目录,但这需要更多细节.

如果要支持并行构建,则可能需要在此级别声明依赖项,以避免并行构建相互依赖的目录.例如,在上面的示例中,如果直到subdir1和subdir2都完成后才可以构建subdir3(但可以并行构建subdir1和subdir2),则可以将以下内容添加到您的makefile中:

all.subdir3 : all.subdir1 all.subdir2

I want to create a Makefile (in a parent dir) to call several other Makefiles (in sub dirs) such that I can build several binaries (one per project sub dir) by invoking just the one parent Makefile.

My research has been hampered by finding loads of stuff on recursive Makefiles, but I think this is where you are trying to build several directories Makefiles into a single binary?

Maybe what I want to do is better handled by a shell script perhaps invoking make in each sub directory in turn, but I thought a Makefile might be a more elegant solution?

any pointers gratefully received

PS using linux and the GNU tool chain

解决方案

The for loop solution given in the first answer above actually shouldn't be used, as-is. In that method, if one of your sub-makes fails the build will not fail (as it should) but continue on with the other directories. Not only that, but the final result of the build will be whatever the exit code of the last subdirectory make was, so if that succeeded the build succeeds even if some other subdirectory failed. Not good!!

You could fix it by doing something like this:

all: 
        @for dir in $(SUBDIRS); \
        do \
            $(MAKE) -C $${dir} $@ || exit $$?; \
        done

However now you have the opposite problem: if you run "make -k" (continue even if there are errors) then this won't be obeyed in this situation. It'll still exit on failure.

An additional issue with both of the above methods is that they serialize the building of all subdirectories, so if you enable parallel builds (with make's -j option) that will only happen within a single subdirectory, instead of across all subdirectories.

Eregrith and sinsedrix have solutions that are closer to what you want, although FYI you should never, ever use "make" when you are invoking a recursive make invocation. As in johfel's example you should ALWAYS use $(MAKE).

Something like this is what you want:

SUBDIRS = subdir1 subdir1 subdir3 ...

all: $(addprefix all.,$(SUBDIRS))
all.%:
        @ $(MAKE) -C '$*' '$(basename $@)'
.PHONY: $(addprefix all.,$(SUBDIRS))

And of course you can add more stanzas like this for other targets such as "install" or whatever. There are even more fancy ways to handle building subdirectories with any generic target, but this requires a bit more detail.

If you want to support parallel builds you may need to declare dependencies at this level to avoid parallel builds of directories which depend on each other. For example in the above if you cannot build subdir3 until after both subdir1 and subdir2 are finished (but it's OK for subdir1 and subdir2 to build in parallel) then you can add something like this to your makefile:

all.subdir3 : all.subdir1 all.subdir2

这篇关于使用make构建多个二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆