これが1つのMakefileだけで可能かどうかはわかりませんが、ファイル内にターゲットを構築しようとすると、現在のシステム上のプロセッサの数が自動的に検出され、ターゲットが並行して構築されるような方法でMakefileを作成したいと考えていました。プロセッサの数。
以下の「擬似コード」の例のようなものですが、はるかにクリーンですか?
all:
@make -j$(NUM_PROCESSORS) all
または:
all: .inparallel
... build all here ...
.inparallel:
@make -j$(NUM_PROCESSORS) $(ORIGINAL_TARGET)
どちらの場合も、入力する必要があるのは次のとおりです。
% make all
うまくいけば、それは理にかなっています。
更新:上記のMakefileの例をまだ期待しています。プロセスの数を見つけることにはあまり興味がありませんが、-jコマンドラインオプションを使用せずに並行してビルドするmakefileを作成する方法には興味があります。
LDD3の第2章を少し調べて、dmckeeの回答を読んだ後、2つのmakefileを使用するというそれほど優れた回答を思いつきませんでした(1つだけをお勧めします)。
_$ 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"
_
このソリューションについてどう思いますか?
私が見る利点は、人々がまだmake
と入力してビルドすることです。したがって、makeと入力する代わりに、人々が知っておく必要のあるNPROCS
およびmake -j$(NPROCS)
の作業を実行する「ドライバー」スクリプトはありません。
欠点は、シリアルビルドを実行するために明示的に_make -f Makefile.goals
_を使用する必要があることです。そして、私はこの問題を解決する方法がわかりません...
更新:上記のコードセグメントに$ Jを追加しました。うまくいくようです。 1つではなく2つのmakefileですが、それでも非常にシームレスで便利です。
検出部分はOSに依存します。 LinuxおよびMacOSXで動作するフラグメントは次のとおりです。
NPROCS:=1
OS:=$(Shell uname -s)
ifeq($(OS),Linux)
NPROCS:=$(Shell grep -c ^processor /proc/cpuinfo)
endif
ifeq($(OS),Darwin) # Assume Mac OS X
NPROCS:=$(Shell system_profiler | awk '/Number Of CPUs/{print $4}{next;}')
endif
それを機能させるには、おそらくmakeを再度呼び出す必要があります。次に、問題は無限再帰の防止です。 2つのmakefile(最初は-j
値をリセットするだけ)を使用することでそれを管理できますが、おそらくそれを微調整することは可能です。
これをMakefileの先頭に追加しました。これにより、makeは任意の数のジョブを作成できますが、負荷平均をCPUコアの数より低く維持しようとします。
MAKEFLAGS+="-j -l $(Shell grep -c ^processor /proc/cpuinfo) "
これはLinux固有であることに注意してください。
これが私が行ったものです:
ifeq ($(OS),Linux)
NUMPROC := $(Shell grep -c ^processor /proc/cpuinfo)
else ifeq ($(OS),Darwin)
NUMPROC := $(Shell sysctl hw.ncpu | awk '{print $$2}')
endif
# Only take half as many processors as available
NUMPROC := $(Shell echo "$(NUMPROC)/2"|bc)
ifeq ($(NUMPROC),0)
NUMPROC = 1
endif
$(NPROCS)
の検出についてはスキップしますが、これを1つのMakefile
で実行する方法は次のとおりです(これはおそらくGNU具体的にしますが、実行しているバリアントのように見えます):
ifeq ($(NPROCS),)
# Code to set NPROCS...
%:
$(MAKE) -j$(NPROCS) NPROCS=$(NPROCS)
else
# All of your targets...
endif
GNU Make Manual の Defining Last-Resort Default Rules および Overriding Part of Another Makefile を参照してください。
自動化する場合は、通常のmakeコマンドをオーバーライドして、ホームディレクトリの.bashrc
内のそれ自体のエイリアスにすることができます。
例:
alias make="make -j"
または、次のようなことを行うことができます。
alias jmake="make -j"
それをオーバーライドしたくないが、makeを並行して実行するための迅速で簡単な(そして記憶に残る)方法が必要な場合。
質問を正しく読んだ場合、目標はビルドプロセスを可能な限り並列化することです。 make
のマニュアルページには、次のように記載されています。
-jオプションを引数なしで指定した場合、makeは同時に実行できるジョブの数を制限しません。
これは基本的にあなたが望む解決策ではありませんか? Makefileに十分な並列ターゲットがある場合は、すべてのCPUを使用し、ターゲットが並列でない場合は、その-j
オプションは何の助けにもなりません。