makefile缺少分隔符

makefile缺少分隔符,makefile,syntax-error,gnu-make,Makefile,Syntax Error,Gnu Make,好吧,我被困在这个问题上,我不知道我做错了什么。在一个更复杂的makefile上工作,一切都进行得很顺利,但是突然我出现了“缺少分隔符”错误。我能够将其分解为一个非常简单的场景: test.mk 简单的 以及输出: C:\project>make -f Simple process includeme.mk includeme.mk Simple:4: *** missing separator. Stop. includeme.mk实际上并不存在。我不知道这里出了什么问题,我试过很多

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

test.mk 简单的 以及输出:

C:\project>make -f Simple process
includeme.mk
includeme.mk
Simple:4: *** missing separator.  Stop.
includeme.mk
实际上并不存在。我不知道这里出了什么问题,我试过很多方法。如果我围绕呼叫将_submake包含在如下信息中:

$(info $(call include_submake,${INITIAL_SUBMAKE}))
丢失的分隔符错误消失。另外,如果在
include_submake
define中,我只调用其中一个函数,它就可以正常工作。此外,如果我直接调用函数而不是调用它们
include\u 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
vs普通旧变量赋值 回答第一条评论中的问题。就我个人而言,我更喜欢在几种情况下使用
define
指令

eval
功能一起使用 正如GNU Make手册所建议的那样,
define
指令与。手册中的示例(重点是我的):

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

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

您可以在自己的项目中随意使用任何部分

我遇到了同样的问题。我插入了“tab”,删除了“tab”,重新插入以确保。相同的错误消息

但是,所有这些都是在XCodem内部完成的,令我惊讶的是,XCodem中插入了空格,而不是“\t”。一旦我使用不同的编辑器,这些“幻影”错误就消失了


也不确定复制粘贴发生了什么,但对于过程:target我确实在@echo命令前面有一个选项卡,这肯定会使错误消失。在使用$(call)时,有没有一个好的方法来解释何时应该使用define vs=语义?按照你说的,我可以用$(strip)来包装$(call)一切都很好。如果有任何你可以解释的话,我将不胜感激。不幸的是,我只有1票可以投。哇!谢谢你,伙计。很好的解释,当然更重要的是。我将对你的一些其他东西投赞成票。我还将看看你的embox构建系统。我在你的个人资料上看到了这个网站,但我没有看到“我还没有机会梳理它。@欢迎您,而且,哦,感谢您的支持!实际上,Embox是一个操作系统内核,Mybuild是Embox中使用的一个构建自动化和配置工具。
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...
push_dir = \
    $(info $1)

pop_dir = \
    $(info $1)

include_submake = \
    $(call push_dir,$1) \
    $(call pop_dir,$1)
PROGRAMS = server client server_OBJS = server.o server_priv.o server_access.o server_LIBS = priv protocol client_OBJS = client.o client_api.o client_mem.o client_LIBS = protocol # Everything after this is generic .PHONY: all all: $(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) # 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 baz HEADERS := foo.h $(HEADERS) : %.h : @printf "%s" $(call sh_quote,$(call header_template,$(*F)))> $@ # 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)