Jak mogę napisać plik makefile, aby automatycznie wykryć i zrównać kompilację z GNU Make?
Nie jestem pewien, czy jest to możliwe tylko w jednym pliku Makefile, ale miałem nadzieję napisać plik Makefile w taki sposób, że próba zbudowania dowolnego celu w pliku automatycznie magicznie wykrywa liczbę procesorów w bieżącym systemie i buduje cel równolegle dla liczby procesorów.
Coś w stylu poniższych przykładów "pseudokodów", ale dużo czystsze?
all:
@make -j$(NUM_PROCESSORS) all
Lub:
all: .inparallel
... build all here ...
.inparallel:
@make -j$(NUM_PROCESSORS) $(ORIGINAL_TARGET)
W obu przypadkach wystarczy wpisać:
% make all
Miejmy nadzieję, że to sprawia, że sens.
UPDATE: wciąż mam nadzieję na przykładowy plik Makefile dla powyższego. Nie interesuje mnie znalezienie liczby procesów, ale interesuje mnie jak napisać plik makefile do zbudowania równolegle bez opcji linii poleceń-J.
7 answers
Część detekcji będzie zależna od systemu operacyjnego. Oto fragment, który będzie działał na Linuksie i Mac OS X:
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
Aby go uruchomić, prawdopodobnie będziesz musiał ponownie wywołać make. Więc Twoim problemem jest zapobieganie nieskończonej rekurencji. Możesz zarządzać tym, mając dwa pliki Makefile(pierwszy tylko resetuje wartość -j
), ale prawdopodobnie jest to możliwe do finezji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-29 11:30:23
Po grzebaniu w rozdziale 2 ldd3 i przeczytaniu odpowiedzi dmckee ' ego, wymyśliłem niezbyt dobrą odpowiedź na użycie dwóch plików Makefile (wolałbym tylko jeden).
$ 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"
Co sądzisz o tym rozwiązaniu?
Korzyści widzę, że ludzie nadal typować make
budować. Więc nie ma jakiegoś skryptu "sterownika", który wykonuje NPROCS
i make -j$(NPROCS)
pracę, o której ludzie będą musieli wiedzieć zamiast pisać make.
Minusem jest to, że będziesz musiał wyraźnie użyć make -f Makefile.goals
, Aby zrób seryjną kompilację. I nie jestem pewien, jak rozwiązać ten problem...
Aktualizacja: Dodano $J do powyższego segmentu kodu. Wygląda na to, że praca działa całkiem dobrze. Mimo że jego dwa pliki Makefile zamiast jednego, nadal jest całkiem bezproblemowy i przydatny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-29 15:41:10
Oto co zrobiłem:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-12 19:36:30
Właśnie dodałem to do mojego pliku Makefile. Pozwala tworzyć dowolną liczbę zadań, ale stara się utrzymać średnie obciążenie poniżej liczby rdzeni procesora.
MAKEFLAGS+="-j -l $(shell grep -c ^processor /proc/cpuinfo) "
Uwaga Jest to specyficzne dla Linuksa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-09 07:21:23
Pominę detekcję $(NPROCS)
, ale oto jak możesz to zrobić w jednym Makefile
(to jest prawdopodobnie GNU Make specific, ale wygląda na wariant, który używasz):
ifeq ($(NPROCS),)
# Code to set NPROCS...
%:
$(MAKE) -j$(NPROCS) NPROCS=$(NPROCS)
else
# All of your targets...
endif
Zobacz Definiowanie domyślnych regułi nadpisywanie części innego pliku Makefilew GNU Make Manual.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-03 23:31:17
Jeśli chcesz, aby była automatyczna, możesz nadpisać typowe polecenie make jako alias do siebie w .bashrc
w katalogu domowym.
Przykład:
alias make="make -j"
Albo możesz zrobić coś takiego:
alias jmake="make -j"
W przypadku, gdy nie chcesz go nadpisać, ale chcesz szybkiego i łatwego (i niezapomnianego) sposobu na równoległe uruchamianie make.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-25 06:40:16
Jeśli dobrze przeczytam pytanie, celem jest jak największe zrównoleglenie procesu budowania. Strona podręcznika make
zawiera następujące dane
Jeśli opcja-j jest podana bez argumentu, make nie ograniczy liczby zadań, które mogą być uruchomione jednocześnie.
Czy nie jest to w zasadzie rozwiązanie, które chcesz? Jeśli Twój plik Makefile ma wystarczającą ilość równoległych celów, użyjesz wszystkich swoich procesorów, a jeśli cele nie są równoległe, ta opcja -j
nie pomoże anywas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-18 18:19:06