makefile缺少分隔符
好吧,我被困在这个问题上,我不知道我做错了什么。在一个更复杂的makefile上工作,一切都进行得很顺利,但是突然我出现了“缺少分隔符”错误。我能够将其分解为一个非常简单的场景: test.mk 简单的 以及输出: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实际上并不存在。我不知道这里出了什么问题,我试过很多
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)