Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I break a variable definition across multiple lines in a Makefile without spaces?

Tags:

makefile

Consider the following 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)

The output of running make is

.:/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

Observe that there are spaces after each :.

Is there a way to define the variable CP with the line breaks, but without the extraneous space substituting every newline?

like image 826
merlin2011 Avatar asked Jan 19 '14 23:01

merlin2011


2 Answers

It’s impossible to prevent backslash-newline from becoming a space, and it’s clumsy and error-prone to try to remove the spaces afterwards (what if there are supposed to be spaces?), but you can remove each as it’s produced. This has the significant advantage of working anywhere, even inside function calls. The trick is to embed the space produced in an expression that expands to nothing.

$(call foo) with empty/undefined foo would work, but we can do better: variable names can contain spaces in (GNU) Make. It’s hard to assign to them, but we don’t want to anyway. So then we can shorten it to $(a b) or even $(a ); a backslash-newline will be turned into a space before the lookup. But even a single space works:

foo=bar$(\
)baz

Finally, the parentheses may be omitted for a single-character variable name:

foo=bar$\
baz

…which finally looks like we are (fully) escaping the newline rather than using it somehow. So long as no one assigns to “ ” (which is even crazier than using it!), anyway.

like image 57
Davis Herring Avatar answered Sep 25 '22 23:09

Davis Herring


Not really; the backslash-newline combination is defined to produce a space. However, if you are using GNU Make, you could simply $(subst : ,:,$(CP)).

like image 32
tripleee Avatar answered Sep 23 '22 23:09

tripleee