Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 非递归make:在循环中包含makefile段_C++_Makefile_Gnu Make - Fatal编程技术网

C++ 非递归make:在循环中包含makefile段

C++ 非递归make:在循环中包含makefile段,c++,makefile,gnu-make,C++,Makefile,Gnu Make,我有一个非递归的makefile,它定义了可用于构建库等的助手函数 define make-library # build lib from *.cpp in current dir... endef 每个库/二进制文件都定义在一个单独的makefile段中,该段称为module.mk,它调用这些辅助函数 $(eval $(call make-library, my_lib)) makefile在源树中搜索makefile段,并将其包括在内 modules := $(shell fi

我有一个非递归的makefile,它定义了可用于构建库等的助手函数

define make-library
    # build lib from *.cpp in current dir...
endef
每个库/二进制文件都定义在一个单独的makefile段中,该段称为
module.mk
,它调用这些辅助函数

$(eval $(call make-library, my_lib))
makefile在源树中搜索makefile段,并将其包括在内

modules := $(shell find . -name module.mk | xargs echo)
include $(modules)
问题: 我在makefile的顶部定义了一组默认的
CPPFLAGS

CPPFLAGS += -m64 -std=c++11 -Wall -Wextra -Werror -Wno-system-headers
它们根据构建变量等进行选择性更新:

ifeq "$(BUILD)" "debug"
    CPPFLAGS += $(DEBUG_FLAGS)
endif
在需要时,在每个目标中使用它们:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    @$(CXX) $(CPPFLAGS) -I$(BASE_DIR) -I. -o $@ -c $(filter %.cpp,$^)
我遇到的问题是,有时我想覆盖模块中的
CPPFLAGS

CPPFLAGS += -Wno-unused-but-set-variable
$(eval $(call make-library, my_lib))
但是,这会更新全局
CPPFLAGS
,因此每个模块都会获得更新的标志

解决方案: 我的想法是迭代
$(模块)
,在包含每个模块之前,将
CPPFLAGS
重置为默认设置。当前模块中的任何更改都将在下一个模块中重置

大致如下:

$(foreach module,$(modules),$(eval \
    CPPFLAGS := DEFAULT_CPPFLAGS \
    include $module))
问题: 上面的语法是不正确的,但应该有希望说明我试图实现的目标——关于如何最好地完成我所描述的任务,有什么想法吗

备选方案: 或者,每个
module.mk
可以定义一个
LOCAL\u FLAGS
变量,该变量可以传递给
make library
调用

LOCAL_FLAGS := -Wno-unused-but-set-variable
$(eval $(call make-library, my_lib, $(LOCAL_FLAGS)))

如果每个makefile变量在配方时使用,则不能使用它们。完成所有作业/等后执行配方

如果在解析时使用文件局部变量或强制全局变量展开,则可以这样做

您可以保存、设置、使用和重置每个
module.mk
文件中的值

$ cat foo/module.mk
oCPPFLAGS:=$(CPPFLAGS)
CPPFLAGS+=something local

target: CPPFLAGS:=$(CPPFLAGS)
target:
        some_cmd $(CPPFLAGS)

FOO:=$(oFOO)
或者,更像您最初的尝试,您可以在循环过程中强制将它们返回到某个默认值

$ 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)
但这里重要的是变量在解析时被扩展/使用。它们不能在配方时使用,除非它们保存在其他变量中(如上面示例中的特定于目标的变量)。

在我的构建系统中,我将参数从
此变量传递给编译器,而不是全局
CFLAGS
,尽管
CFLAGS
也传递给编译器。 然后,在定义构建规则后,我可以清除所有
this.*
变量,如下所示:

$(foreach var,$(filter this_%,$(.VARIABLES)),$(eval $(var) := ))
我为这个做了一个定义

prorab-clear-this-vars = $(foreach var,$(filter this_%,$(.VARIABLES)),$(eval $(var) := ))
它可以这样使用

$(eval $(prorab-clear-this-vars))

尝试使用if…else…?手动传递额外参数?没有理由将
find
的输出通过管道传输到
xargs echo
。我不认为这会起作用:原因是CPPFLAGS仍将由foreach的最后一次迭代定义,而不是真正的“中间”每个模块。可能使用特定于目标的变量?如何在各种
module.mk
文件中使用
CPPFLAGS
?您希望它们在目标配方运行时或仅在makefile解析时具有正确的值吗?(也就是说,它们是在配方行中使用还是在解析阶段添加到其他简单扩展(:=)变量?@EtanReisner我已经用有关
CPPFLAGS
使用的其他信息更新了这个问题,感谢您的回答!我怀疑通用的
$(OBJ_DIR)/%.o:$(SRC_DIR)/%.cpp
规则不起作用,因为这不是特定于目标的。是否可以为每个目标设置
.o:.cpp
规则?似乎不对?规则/配方不是,但目标特定变量适用于其所有先决条件。目标特定变量还有一个特殊功能:定义目标特定变量时,该变量值对该目标的所有先决条件及其所有先决条件都有效(除非这些先决条件使用其自身的目标特定变量值覆盖该变量)看起来这就是我需要的!谢谢特定于目标的变量工作得非常好-谢谢!嗯,您的第一个示例缺少配方的
目标: