gpt4 book ai didi

makefile 缺少分隔符

转载 作者:行者123 更新时间:2023-12-02 20:50:16 25 4
gpt4 key购买 nike

好吧,我被困在这个问题上,我不知道我做错了什么。在一个更复杂的 makefile 上一切都很顺利,但突然我得到了“缺少分隔符”错误。我能够将其分解为一个非常简单的场景:

测试.mk

define push_dir
$(info ${1})
endef

define pop_dir
$(info ${1})
endef

define include_submake
$(call push_dir,${1})
$(call pop_dir,${1})
endef

简单

include test.mk

INITIAL_SUBMAKE:= includeme.mk
$(call include_submake,${INITIAL_SUBMAKE})

process:
@echo Processed...

输出:

C:\project>make -f Simple process
includeme.mk
includeme.mk
Simple:4: *** missing separator. Stop.

includeme.mk 实际上并不存在。我不知道这里出了什么问题,我已经尝试了很多方法。如果我将调用包含在信息中,如下所示:

$(info $(call include_submake,${INITIAL_SUBMAKE}))

缺少分隔符的错误消失了。另外,如果在 include_submake 定义中我只调用其中一个函数,它就可以正常工作。此外,如果我直接调用函数而不是调用它们 include_submake 它也可以工作:

include test.mk

INITIAL_SUBMAKE:= includeme.mk
$(call push_dir,${INITIAL_SUBMAKE})
$(call pop_dir,${INITIAL_SUBMAKE})

process:
@echo Processed...


C:\project>make -f Simple process
includeme.mk
includeme.mk
Processed...

我觉得我在这里忽略了一些基本的东西。感谢您的帮助。

最佳答案

发生缺少分隔符错误是因为include_submake的非空返回值,在您的情况下它是单个换行符。 Make 只允许空白字符(即空格或制表符)出现在不被假定为某些规则或另一个指令的一部分的表达式中。

使用普通的 Make 变量赋值重写您的函数,错误就会消失:

push_dir = \
$(info $1)

pop_dir = \
$(info $1)

include_submake = \
$(call push_dir,$1) \
$(call pop_dir,$1)

UPD.:define 与普通旧变量赋值

回答第一条评论中的问题。就我个人而言,我更喜欢在某些情况下使用 define 指令。

eval函数一起使用

正如 GNU Make 手册所建议的,define 指令与 eval function 结合使用非常有用。 。手册中的示例(重点是我的):

PROGRAMS    = server clientserver_OBJS = server.o server_priv.o server_access.oserver_LIBS = priv protocolclient_OBJS = client.o client_api.o client_mem.oclient_LIBS = protocol# Everything after this is generic.PHONY: allall: $(PROGRAMS)define PROGRAM_template  $(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)  ALL_OBJS   += $$($(1)_OBJS)endef$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))$(PROGRAMS):    $(LINK.o) $^ $(LDLIBS) -o $@clean:    rm -f $(ALL_OBJS) $(PROGRAMS)

生成器模板

逐字变量非常适合您想要从 GNU Make 生成文件的情况。例如,考虑根据 Makefile 中的一些信息生成头文件。

# Args:#   1. Header identifier.define header_template/* This file is generated by GNU Make $(MAKE_VERSION). */#ifndef $(inclusion_guard)#define $(inclusion_guard)$(foreach inc,$($1.includes),#include <$(inc).h>)/* Something else... */#endif /* $(inclusion_guard) */endef# 1. Unique header identifier.inclusion_guard = \    __GEN_$1_H# Shell escape.sh_quote = \    '$(subst ','"'"',$1)'foo.includes := bar bazHEADERS := foo.h$(HEADERS) : %.h :    @printf "%s" $(call sh_quote,$(call header_template,$(*F)))> $@

扩展 Make 语法

在我们的项目中,我们使用自己的构建系统,名为 Mybuild ,并且它完全是在 GNU Make 之上实现的。作为我们用来改善 Make 内置语言的糟糕语法的低级 hack 之一,我们开发了一个 special script它允许使用扩展语法来定义函数。脚本本身也是用 Make 编写的,因此它是一种 Make 中的元编程。

特别是,可以使用以下功能:

  • 定义多行函数而不需要使用反斜杠
  • 在函数内部使用注释(在普通的 Make 注释中只能出现在变量赋值指令之外)
  • 定义自定义宏,例如 $(assert ...)$(lambda ...)
  • 内联简单函数,如 $(eq s1,s2)(字符串相等性检查)

这是如何使用扩展语法编写函数的示例。请注意,它成为有效的 Make 函数,并且可以在调用 $(def_all) 后照常调用。

# Reverses the specified list.#   1. The list# Return:#   The list with its elements in reverse order.define reverse    # Start from the empty list.    $(fold ,$1,        # Prepend each new element ($2) to        # the result of previous computations.        $(lambda $2 $1))endef$(def_all)

使用这些新功能,我们能够实现一些非常酷的东西(嗯,至少对于 Make 来说:-)),包括:

  • 面向对象层,具有动态对象分配、类继承、方法调用等
  • GOLD Parser Builder 生成的解析器的 LALR 解析器运行时引擎
  • 为使用 EMF 生成的模型提供运行时支持的建模库

请随意使用 the code 的任何部分在您自己的项目中!

关于makefile 缺少分隔符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10883666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com