考虑以下Makefile
CP = .:${HADOOP_HOME}/share/hadoop/common/lib/hadoop-auth-2.2.0.jar:\
${HADOOP_HOME}/share/hadoop/hdfs/hadoop-hdfs-2.2.0.jar:\
${HADOOP_HOME}/share/hadoop/common/hadoop-common-2.2.0.jar:\
${HADOOP_HOME}/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.2.0.jar:\
${HADOOP_HOME}/share/hadoop/mapreduce/lib/hadoop-annotations-2.2.0.jar\
all:
echo $(CP)
正在运行make
的输出是
.:/home/hduser/Hadoop/hadoop-2.2.0/share/hadoop/common/lib/hadoop-auth-2.2.0.jar: /home/hduser/Hadoop/hadoop-2.2.0/share/hadoop/hdfs/hadoop-hdfs-2.2.0.jar: /home/hduser/Hadoop/hadoop-2.2.0/share/hadoop/common/hadoop-common-2.2.0.jar: /home/hduser/Hadoop/hadoop-2.2.0/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.2.0.jar: /home/hduser/Hadoop/hadoop-2.2.0/share/hadoop/mapreduce/lib/hadoop-annotations-2.2.0.jar
观察每个:
后面有空格。
有没有办法用换行符定义变量CP
,但没有多余的空格替换每一个换行符?
答案 0 :(得分:4)
不是真的;反斜杠 - 换行符组合定义为生成空格。但是,如果您使用的是GNU Make,则只需$(subst : ,:,$(CP))
。
答案 1 :(得分:2)
很抱歉这一点,但我 想 这会给你你想要的东西:
CP = .:${HADOOP_HOME}/share/hadoop/common/lib/hadoop-auth-2.2.0.jar:
CP:=$(CP)${HADOOP_HOME}/share/hadoop/hdfs/hadoop-hdfs-2.2.0.jar:
CP:=$(CP)${HADOOP_HOME}/share/hadoop/common/hadoop-common-2.2.0.jar:
CP:=$(CP)${HADOOP_HOME}/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.2.0.jar:
CP:=$(CP)${HADOOP_HOME}/share/hadoop/mapreduce/lib/hadoop-annotations-2.2.0.jar
这应该将下一行附加到CP的值上,与“+ =”略有不同,这会增加一个空格。
答案 2 :(得分:2)
阻止反斜杠 - 换行符不可能成为一个空格,并且之后尝试删除空格是笨拙且容易出错的(如果应该有空格怎么办?),但是你可以删除每个产生的。这具有在任何地方工作的显着优势,甚至内部函数调用。诀窍是将表达式中生成的空间嵌入到无任何内容中。
具有空/未定义$(call foo)
的 foo
可以工作,但我们可以做得更好:变量名称可以在(GNU)Make中包含空格。分配给他们很难,但我们不想反正。那么我们可以将其缩短为$(a b)
甚至$(a )
;在查找之前,反斜杠换行符将变为空格。但即使是一个空间也可以工作:
foo=bar$(\
)baz
最后,对于单字符变量名称,可省略括号:
foo=bar$\
baz
...最终看起来我们(完全)逃避换行而不是以某种方式使用它。只要没有人将分配给“”(这甚至比使用更疯狂!),无论如何。
答案 3 :(得分:2)
最简单的解决方案是使用$\<newline>
分割线。使用
为了简洁起见,遵循假路径:
CP = one$\
two$\
three$\
four
all:
echo $(CP)
输出将是&#34; onetwothreefour&#34;没有空格。这是因为GNU Make
将用一个空格替换反斜杠 - 换行符 - 空格,制作
分配给CP
等同于:
CP = one$ two$ three$ four
从
https://www.gnu.org/software/make/manual/html_node/Reference.html#Reference:&#34; A
美元符号后跟一个美元符号以外的字符,开括号
或者open-brace将该单个字符视为变量名称。&#34;
所以$<space>
对是名称为单个变量的扩展
空间特征。由于默认情况下未定义此变量,因此它将展开
到空字符串。
请注意,变量CP
仍会包含$<space>
对
扩大了。大多数情况下,这并不重要,但如果你的makefile
取决于使用$(value CP)
来处理基础(未扩展)值,
上述技术可能会提供令人惊讶的结果。
另一种技术是清除CP
的值。这需要GNU Make
3.80或以上,因为它依赖于$(value)
和$(eval)
。它使
使用一些变量和函数进行洗涤过程。
首先,将变量empty
定义为空字符串和变量
space
和newline
分别包含文字空格和换行符:
empty :=
space := $(empty) $(empty)
define newline
endef
接下来,使用$(eval)
以编程方式创建递归扩展变量
具有给定值:
# Define recursively expanded variable $1 with value $2.
defineVar = $(eval define $1$(newline)$2$(newline)endef)
并定义函数resubst
以重复替换一个字符串
另一:
# Replace $1 with $2 in $3 until no more changes are made.
resubst = $\
$(if $(findstring $1,$3),$\
$(call resubst,$\
$1,$\
$2,$\
$(subst $1,$2,$3)),$\
$3)
这些足以用任意方式二维定义函数 换行和缩进。一般方法包括三个步骤:
函数def
删除换行符/空白行
来自递归扩展的$(value)
的延续
通过define
/ endef
:
# $1 - name of function to redefine as a normalized single-line function.
def = $\
$(call defineVar,$\
$1,$\
$(subst $(newline),$\
$(empty),$\
$(call resubst,$\
$(newline)$(space),$\
$(newline),$\
$(newline)$(value $1))))
现在def
可用于后处理递归扩展变量。对于
例如:
define CP
one
two
three
four
endef
$(call def,CP)
现在,$(value CP)
将返回所需的onetwothreefour
。
以上是我的文章&#34; GNU Make line continuation&#34;的精华: http://drmikehenry.com/gnu-make-line-continuations/
答案 4 :(得分:0)
我使它类似于@ goodguy5
CP:=${HADOOP_HOME}/share/hadoop/common/lib/hadoop-auth-2.2.0.jar
CP+=$(CP)${HADOOP_HOME}/share/hadoop/hdfs/hadoop-hdfs-2.2.0.jar
CP+=$(CP)${HADOOP_HOME}/share/hadoop/common/hadoop-common-2.2.0.jar
CP+=$(CP)${HADOOP_HOME}/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.2.0.jar
CP+=$(CP)${HADOOP_HOME}/share/hadoop/mapreduce/lib/hadoop-annotations-2.2.0.jar