kyk*_*yku 24 makefile gnu-make
我有以下makefile:
CXXFLAGS = -std=c++0x -Wall
SRCS = test1.cpp test2.cpp
OBJDIR = object
OBJS = $(SRCS:%.cpp=$(OBJDIR)/%.o)
all: test1
release: clean test1
test1: $(OBJS)
$(CXX) -o $@ $(OBJS)
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -MD -c -o $@ $<
-include $(SRCS:.cpp=.d)
clean:
rm -rf $(OBJDIR)/*
.PHONY: all clean release
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试调用"make -j4 release",那么干净的目标通常会在构建文件的过程中执行,从而导致编译失败.我的问题是如何在开始发布版本之前确保干净的目标已完成.
Nei*_*eil 31
我的偏好是
release:
$(MAKE) clean
$(MAKE) test1
Run Code Online (Sandbox Code Playgroud)
这迫使两个目标连续制造而不会干扰它们的内部平行度(如果有的话).
Eld*_*mov 11
您可以将执行拆分为非并行(for release)和并行(对于其余目标)阶段.
ifneq ($(filter release,$(MAKECMDGOALS)),)
.NOTPARALLEL:
endif
release: clean
$(MAKE) test1
Run Code Online (Sandbox Code Playgroud)
.NOTPARALLEL如果release在命令行中提到target,则target将禁止并行执行.在release本身将重新目标使清洗后,并建立test1并行.
如果在命令行上给出多个目标,则更聪明的解决方案也会重新调用每个单个目标的Make,以便release目标的存在不会强制其余目标执行非并行.
ifneq ($(words $(MAKECMDGOALS)),1)
.NOTPARALLEL:
$(sort all $(MAKECMDGOALS)):
@$(MAKE) -f $(firstword $(MAKEFILE_LIST)) $@
else
# ...
endif
Run Code Online (Sandbox Code Playgroud)
上面的聪明解决方案不适用于不支持作业服务器的GNU make版本.例如,在版本4.0之前发布的GNU make的MinGW /本机版本不支持作业服务器.(GNU make的Cygwin/MSYS版本.)下面的代码使用make 3.81中引入的.FEATURES变量来检测是否支持作业服务器.在需要时不使用此变通办法的症状是您的"并行"构建将被序列化.
# Check if job server supported:
ifeq ($(filter jobserver, $(.FEATURES)),)
# Job server not supported: sub-makes will only start one job unless
# you specify a higher number here. Here we use a MS Windows environment
# variable specifying number of processors.
JOBSARG := -j $(NUMBER_OF_PROCESSORS)
else
# Job server is supported; let GNU Make work as normal.
JOBSARG :=
endif
# .FEATURES only works in GNU Make 3.81+.
# If GNU make is older, assume job server support.
ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))),3.81)
# If you are using GNU Make < 3.81 that does not support job servers, you
# might want to specify -jN parameter here instead.
JOBSARG :=
endif
ifneq ($(words $(MAKECMDGOALS)),1)
.NOTPARALLEL:
# The "all" target is required in the list,
# in case user invokes make with no targets.
$(sort all $(MAKECMDGOALS)):
@$(MAKE) $(JOBSARG) -f $(firstword $(MAKEFILE_LIST)) $@
else
# Put remainder of your makefile here.
endif
Run Code Online (Sandbox Code Playgroud)