Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break a string across lines in a makefile without spaces?

In a makefile, escaping a new-line with \ allows to split a single-line long string content across multiple source lines. However, the new-line is replaced with a space. Is there a transparent line break in the source that does not affect the string content?

VAR=w\
o\
r\
d

all:
    echo $(VAR)

The desired output is 'word', but the actual output is 'w o r d'.

like image 980
alexei Avatar asked Jan 20 '14 23:01

alexei


People also ask

How do you break a line in makefile?

As in normal makefile syntax, a single logical recipe line can be split into multiple physical lines in the makefile by placing a backslash before each newline. A sequence of lines like this is considered a single recipe line, and one instance of the shell will be invoked to run it.

What does $< mean in makefile?

The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.

How do you add a line in makefile?

So, you can format your makefiles for readability by adding newlines into the middle of a statement: you do this by escaping the internal newlines with a backslash ( \ ) character.

How do you comment multiple lines in makefile?

' # ' in a line of a makefile starts a comment. It and the rest of the line are ignored, except that a trailing backslash not escaped by another backslash will continue the comment across multiple lines.


2 Answers

The simplest solution is to use $\<newline> to split the line (at least if you are using GNU Make):

VAR = w$\
      o$\
      r$\
      d

all:
    echo $(VAR)

The output will be "word" with no spaces. This is because GNU Make will replace backslash-newline-whitespace with a single space, making the assignment to VAR be equivalent to:

VAR = w$ o$ r$ d

From https://www.gnu.org/software/make/manual/html_node/Reference.html#Reference: "A dollar sign followed by a character other than a dollar sign, open-parenthesis or open-brace treats that single character as the variable name." So the $<space> pairs are expansions of the variable whose name is a single space character. Since this variable is not defined by default, it will expand to the empty string.

Note that the variable VAR will still contain the $<space> pairs until it is expanded. Most of the time, this doesn't matter, but if your makefile depends on using $(value VAR) to process the underlying (unexpanded) value, the above technique may provide surprising results.

Also, the recently released GNU Make 4.3 now explicitly documents this technique for splitting lines (https://www.gnu.org/software/make/manual/make.html#Splitting-Lines):

Splitting Without Adding Whitespace

If you need to split a line but do not want any whitespace added, you can utilize a subtle trick: replace your backslash/newline pairs with the three characters dollar sign/backslash/newline:

var := one$\
       word

After make removes the backslash/newline and condenses the following line into a single space, this is equivalent to:

var := one$ word

Then make will perform variable expansion. The variable reference ‘$ ’ refers to a variable with the one-character name “ ” (space) which does not exist, and so expands to the empty string, giving a final assignment which is the equivalent of:

var := oneword

For other ideas, see my answer to a similar question here: How can I break a variable definition across multiple lines in a Makefile without spaces?

A longer treatment of line continuation options can be found in my article "GNU Make line continuations": http://drmikehenry.com/gnu-make-line-continuations/

like image 55
Michael Henry Avatar answered Sep 17 '22 15:09

Michael Henry


This was just asked yesterday: How can I break a variable definition across multiple lines in a Makefile without spaces?

The short answer is no, there's no way to do that. This behavior is required by the POSIX standard for make.

All you can do is try postprocessing the string to remove the whitespaces using $(subst ...) or similar.

like image 23
MadScientist Avatar answered Sep 20 '22 15:09

MadScientist