Ste*_*mer 5 c++ makefile gnu-make
我有一个非递归的makefile,它定义了可用于构建库等的辅助函数
define make-library
# build lib from *.cpp in current dir...
endef
Run Code Online (Sandbox Code Playgroud)
每个库/二进制文件都在一个单独的makefile段中定义,该段称为module.mk调用这些辅助函数
$(eval $(call make-library, my_lib))
Run Code Online (Sandbox Code Playgroud)
makefile在源树中搜索makefile段,并包含它们
modules := $(shell find . -name module.mk | xargs echo)
include $(modules)
Run Code Online (Sandbox Code Playgroud)
我CPPFLAGS在makefile的顶部定义了一个默认值:
CPPFLAGS += -m64 -std=c++11 -Wall -Wextra -Werror -Wno-system-headers
Run Code Online (Sandbox Code Playgroud)
它们根据构建变体等有选择地更新:
ifeq "$(BUILD)" "debug"
CPPFLAGS += $(DEBUG_FLAGS)
endif
Run Code Online (Sandbox Code Playgroud)
它们在需要时用于每个目标:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
@$(CXX) $(CPPFLAGS) -I$(BASE_DIR) -I. -o $@ -c $(filter %.cpp,$^)
Run Code Online (Sandbox Code Playgroud)
我CPPFLAGS遇到的问题是有时我想在模块中覆盖:
CPPFLAGS += -Wno-unused-but-set-variable
$(eval $(call make-library, my_lib))
Run Code Online (Sandbox Code Playgroud)
但是,这会更新全局 CPPFLAGS,因此每个模块都会获得更新的标志.
我的想法是迭代$(modules),并在包括每个之前,重置CPPFLAGS为默认集.当前模块的任何更改都将重置为下一个.
有点像:
$(foreach module,$(modules),$(eval \
CPPFLAGS := DEFAULT_CPPFLAGS \
include $module))
Run Code Online (Sandbox Code Playgroud)
上面的语法不正确,但应该有希望说明我想要实现的目标 - 关于如何最好地完成我所描述的内容的任何想法?
或者,也许每个人都module.mk可以定义一个LOCAL_FLAGS可以传递给make-library调用的变量?
LOCAL_FLAGS := -Wno-unused-but-set-variable
$(eval $(call make-library, my_lib, $(LOCAL_FLAGS)))
Run Code Online (Sandbox Code Playgroud)
如果在配方时使用它们,则不能拥有每个 makefile 变量。食谱在所有分配/等之后执行。已经完成了。
如果您使用文件局部变量或在解析时强制全局变量扩展,您可以这样做。
您可以保存、设置、使用和重置每个文件中的值module.mk。
$ cat foo/module.mk
oCPPFLAGS:=$(CPPFLAGS)
CPPFLAGS+=something local
target: CPPFLAGS:=$(CPPFLAGS)
target:
some_cmd $(CPPFLAGS)
FOO:=$(oFOO)
Run Code Online (Sandbox Code Playgroud)
或者,更像您最初的尝试,您可以在循环期间强制将它们评估回某个默认值。
$ cat Makefile
$(foreach module,$(modules),$(eval CPPFLAGS := DEFAULT_CPPFLAGS)$(eval include $(module)))
$(eval CPPFLAGS := DEFAULT_CPPFLAGS)
$ cat foo/module.mk
target: CPPFLAGS:=$(CPPFLAGS)
target:
some_cmd $(CPPFLAGS)
Run Code Online (Sandbox Code Playgroud)
但这里重要的是变量在解析时扩展/使用。它们不能在配方时使用,除非它们保存在其他变量中(如上面示例中特定于目标的变量)。