非递归make:在循环中包含makefile段 [英] Non-recursive make: include makefile segment in a loop

查看:81
本文介绍了非递归make:在循环中包含makefile段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a non recursive makefile which defines helper functions which can be used to build libraries etc

define make-library
    # build lib from *.cpp in current dir...
endef

每个库/二进制文件都在名为module.mk的单独的makefile段中定义,该段调用这些辅助函数

Each library/binary is defined in a separate makefile segment called module.mk which calls these helper functions

$(eval $(call make-library, my_lib))

makefile在源代码树中搜索makefile段,并将其包括在内

The makefile searches the source tree for makefile segments, and includes them

modules := $(shell find . -name module.mk | xargs echo)
include $(modules)

问题:

我在makefile的顶部定义了一组默认的CPPFLAGS:

CPPFLAGS += -m64 -std=c++11 -Wall -Wextra -Werror -Wno-system-headers

根据构建变体等有选择地更新它们:

They are selectively updated depending on build variant etc:

ifeq "$(BUILD)" "debug"
    CPPFLAGS += $(DEBUG_FLAGS)
endif

在需要的每个目标中使用它们:

they are used in each target where required:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    @$(CXX) $(CPPFLAGS) -I$(BASE_DIR) -I. -o $@ -c $(filter %.cpp,$^)

我的问题是有时我想覆盖模块中的CPPFLAGS:

The problem I have is that sometimes I want to override CPPFLAGS in a module:

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

但是,这会更新全局 CPPFLAGS,因此每个模块都会获取更新的标志.

However, this updates the global CPPFLAGS, so every module gets the updated flags.

我的想法是遍历$(modules),并且在包含每个c4之前,将CPPFLAGS重置为默认设置.当前模块中的所有更改都将在下一个重置.

My idea is to iterate over $(modules), and before including each one, reset CPPFLAGS to a default set. Any changes in the current module will be reset for the next.

类似的东西:

$(foreach module,$(modules),$(eval \
    CPPFLAGS := DEFAULT_CPPFLAGS \
    include $module))

问题:

以上语法是错误的,但是希望可以说明我正在尝试实现的目标-有关如何最好地完成我所描述的工作的任何想法?

Question:

The above syntax is incorrect, but should hopefully illustrate what I'm trying to achieve - any ideas on how best to do what I've described?

或者,也许每个module.mk都可以定义一个LOCAL_FLAGS变量,该变量可以传递给make-library调用?

Alternately, perhaps each module.mk could define a LOCAL_FLAGS variable which could be passed to the make-library call?

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

推荐答案

如果在配方时使用每个makefile文件变量,则不能使用它们.在所有分配/等之后执行配方.已经完成了.

You can't have per-makefile variables if they are used at recipe time. Recipes execute after all assignments/etc. have been done.

如果您使用文件局部变量或在解析时强制扩展全局变量,则可以执行此操作.

If you use file-local variables or force the global variables expansion at parse time you can do this though.

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

You can save, set, use and reset the values in each module.mk file.

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

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

FOO:=$(oFOO)

或者,更像您的原始尝试,您可以在循环过程中将它们强制评估为默认值.

Or, more like your original attempt, you can force eval them back to some default value during the loop.

$ 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)

但是这里重要的是变量在解析时被扩展/使用.除非将它们保存在其他变量中(例如上面示例中的目标特定变量),否则它们不能在配方时使用.

But the important thing here is the variables are expanded/used at parse time. They cannot be used at recipe time unless they are saved in some other variable (like the target-specific ones in the examples above).

这篇关于非递归make:在循环中包含makefile段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆