参数化的makefile函数

时间:2015-09-08 09:04:12

标签: makefile

我使用makefile运行docker,我首先收集一些模块进行下载,以便可以缓存它们然后运行docker。我想参考这个,但我不认为我是以最好的方式做到这一点。要使这一点更简洁的指针将非常感激。

franz:
    $(eval REPO_VERSION := $(shell grep franz requirements/github.txt | cut -d'@' -f3 | cut -d'#' -f1))
    if [ -d docker/franz ]; then \
        echo "Updating franz to [$(REPO_VERSION)]"; \
        cd docker/franz && git fetch && git checkout $(REPO_VERSION); \
    else \
        echo "Cloning franz to [$(REPO_VERSION)]"; \
        git clone --branch $(REPO_VERSION) git@github.com:dubizzle/franz.git docker/franz 2> /dev/null; \
    fi \

lilith:
    $(eval REPO_VERSION := $(shell grep lilith requirements/github.txt | cut -d'@' -f3 | cut -d'#' -f1))
    if [ -d docker/lilith ]; then \
        echo "Updating lilith to [$(REPO_VERSION)]"; \
        cd docker/lilith && git fetch && git checkout $(REPO_VERSION); \
    else \
        echo "Cloning lilith to [$(REPO_VERSION)]"; \
        git clone --branch $(REPO_VERSION) git@github.com:dubizzle/lilith.git docker/lilith 2> /dev/null; \
    fi \

dependencies: franz lilith
    git archive --format tar.gz --output docker/archive.tar.gz $(GIT_REF)

基本上,这首先更新github上的需求,下载它们,检查所需的版本,然后更新到该版本。如果这可以成为一个函数,参数化版本将是:

$(eval REPO_VERSION := $(shell grep <repo-name> requirements/github.txt | cut -d'@' -f3 | cut -d'#' -f1))
if [ -d docker/<repo-name> ]; then \
    echo "Updating <repo-name> to [$(REPO_VERSION)]"; \
    cd docker/<repo-name> && git fetch && git checkout $(REPO_VERSION); \
else \
    echo "Cloning <repo-name> to [$(REPO_VERSION)]"; \
    git clone --branch $(REPO_VERSION) git@github.com:dubizzle/<repo-name>.git docker/<repo-name> 2> /dev/null; \
fi \

我已经看过使用definecalleval的一些示例,但是,我无法找到合适的组合来使其发挥作用。 对此有任何帮助将非常感激。

1 个答案:

答案 0 :(得分:0)

从上面提到的教程中,将信息提取到SO。

这是GNU make,请注意。

定义模板:

define RULES_template
$(1)/obj/%.o: $(1)/src/%.c
    $$(CC) $$(CFLAGS) $$(CFLAGS_global) $$(CFLAGS_$(1)) -c $$< -o $$@
endef

这使用一个参数($(1)),它将被适当替换。未声明参数数量,只需将$(1)$(2)等添加到模板即可。请注意其他地方$$的重复。

$(foreach module,$(MODULES),$(eval $(call RULES_template,$(module))))

这会为$(MODULES)中的每个令牌调用上述模板。

call RULES_template,foo使用一个参数foo实例化模板。 eval然后将输出解析为Makefile语法(例如,将其放入某个变量中)。

这已经 years 之前,我从未在高效的环境中使用过该代码,所以我对细节有点模糊。无论如何,我希望它有所帮助。

CMake不仅是跨平台的,而且还有更好的原语来处理复杂的构建机制。我可以推荐它。