如何编写Makefile以使用GNU Make自动检测并并行化构建? [英] How can I write a makefile to auto-detect and parallelize the build with GNU Make?

查看:120
本文介绍了如何编写Makefile以使用GNU Make自动检测并并行化构建?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不确定仅在一个Makefile中是否可以实现,但是我希望以一种方式编写Makefile,以便尝试在文件中构建任何目标都可以自动检测当前系统上的处理器数量并构建针对处理器数量并行定位.

Not sure if this is possible in one Makefile alone, but I was hoping to write a Makefile in a way such that trying to build any target in the file auto-magically detects the number of processors on the current system and builds the target in parallel for the number of processors.

类似于下面的伪代码"示例,但是更干净吗?

Something like the below "pseudo-code" examples, but much cleaner?

all:
    @make -j$(NUM_PROCESSORS) all

或者:

all: .inparallel
    ... build all here ...

.inparallel:
    @make -j$(NUM_PROCESSORS) $(ORIGINAL_TARGET)

在两种情况下,您只需要输入:

In both cases, all you would have to type is:

% make all

希望这是有道理的.

更新:仍然希望上面提供示例Makefile.对查找进程数并不是很感兴趣,但对如何编写一个不带-j命令行选项的并行生成的makefile感兴趣.

UPDATE: Still hoping for an example Makefile for the above. Not really interested in finding the number of processes, but interested in how to write a makefile to build in parallel without the -j command line option.

推荐答案

仔细研究LDD3第2章并阅读dmckee的答案后,我想到了使用两个makefile的好方法(我只希望使用一个makefile) ).

After poking around the LDD3 chapter 2 a bit and reading dmckee's answer, I came up with this not so great answer of using two makefiles (I would prefer just one).

$ cat Makefile
MAKEFLAGS += -rR --no-print-directory

NPROCS := 1
OS := $(shell uname)
export NPROCS

ifeq ($J,)

ifeq ($(OS),Linux)
  NPROCS := $(shell grep -c ^processor /proc/cpuinfo)
else ifeq ($(OS),Darwin)
  NPROCS := $(shell system_profiler | awk '/Number of CPUs/ {print $$4}{next;}')
endif # $(OS)

else
  NPROCS := $J
endif # $J

all:
    @echo "running $(NPROCS) jobs..."
    @$(MAKE) -j$(NPROCS) -f Makefile.goals $@

%:
    @echo "building in $(NPROCS) jobs..."
    @$(MAKE) -j$(NPROCS) -f Makefile.goals $@
$ cat Makefile.goals
MAKEFLAGS += -rR --no-print-directory
NPROCS ?= 1

all: subgoal
    @echo "$(MAKELEVEL) nprocs = $(NPROCS)"

subgoal:
    @echo "$(MAKELEVEL) subgoal"

您如何看待该解决方案?

What do you think about this solution?

我看到的好处是,人们仍然键入make进行构建.因此,没有某些驱动程序"脚本可以执行NPROCSmake -j$(NPROCS)的工作,而人们无需输入make就能知道.

Benefits I see is that people still type make to build. So there isn't some "driver" script that does the NPROCS and make -j$(NPROCS) work which people will have to know instead of typing make.

缺点是您必须显式使用make -f Makefile.goals才能进行串行构建.而且我不确定如何解决这个问题...

Downside is that you'll have to explicitly use make -f Makefile.goals in order to do a serial build. And I'm not sure how to solve this problem...

已更新:在上述代码段中添加了$ J.似乎工作正常.即使它的两个makefile而不是一个,它仍然是无缝的和有用的.

UPDATED: added $J to above code segment. Seems work work quite well. Even though its two makefiles instead of one, its still quite seamless and useful.

这篇关于如何编写Makefile以使用GNU Make自动检测并并行化构建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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