How can I write a makefile to auto-detect and parallelize the build with GNU Make?

前端 未结 7 1553
悲&欢浪女
悲&欢浪女 2021-02-01 03:37

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 num

7条回答
  •  一整个雨季
    2021-02-01 04:11

    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?

    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.

    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...

    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.

提交回复
热议问题