I have a Makefile variable as follows
L_PATH_INCLUDE = c:\dir1\include C:\dir2\include C:\dir3\include
I need to handover this to other tool which need this as
tool.exe add-include-dir "c:\dir1\include" "C:\dir2\include" "C:\dir3\include"
I tried following way but tool reporting error that there should not be variable with single character and I have used $(space)
$(subst $(space)," ",$(strip $(L_PATH_INCLUDE)))
Could it be possible in any other way without using $(space) or single character variable
There is no problem with placing quotes, it is not an interpreted symbol. But you need to place quotes around all the paths in L_PATH_INCLUDE and to achieve this I'd do that :
L_PATH_INCLUDE = c:\dir1\include C:\dir2\include C:\dir3\include
all:
echo $(addprefix ",$(addsuffix ",$(L_PATH_INCLUDE)))
Which outputs this with make all :
echo "c:\dir1\include" "C:\dir2\include" "C:\dir3\include"
c:\dir1\include C:\dir2\include C:\dir3\include
You can just replace echo with your command and it'll do it.
Basically the idea is to use addprefix and addsuffix to add quotes at the beginning and at the end of each word in L_PATH_INCLUDE.
If you copy/paste my answer in your Makefile, please be aware of replacing the four spaces by a proper tabulation.
L_PATH_INCLUDE = c:\dir1\include C:\dir2\include C:\dir3\include
L_PATH_INCLUDE_QUOTED := $(patsubst %,"%",$(L_PATH_INCLUDE))
$(info L_PATH_INCLUDE_QUOTED=$(L_PATH_INCLUDE_QUOTED))
Related
I am trying to automate the processing of files that sometimes contain an "equal sign" with GNU Make. For example, say the filename is called hello=world.txt and the Makefile is the following:
default: hello=world.txt.gz
hello=world.txt.gz : hello=world.txt
gzip hello=world.txt
echo done
You get the following error:
test.make:5: *** commands commence before first target. Stop.
How can you escape the equal signs? I have tried backslashes, double quotes and single quotes. Any ideas?
This is one solution:
equal := =
default: hello$(equal)world.txt.gz
hello$(equal)world.txt.gz : hello$(equal)world.txt
gzip hello$(equal)world.txt
echo done
Use %=
in makefiles special character must be escaped by %
I read this question: Makefile: $subst in dependency list, but I still can't make my shell script work correctly.
I have a makefile with a line with the contents:
##public_detailed#|test_create|Syntax: commoncmdsyntax test_create test_name=<test-name>
A target runs a multiline bash script, where the commoncmdsyntax must be replaced by a string containing words and spaces.
In the script, I use cut to assign to a variable desc the following string:
Syntax: commoncmdsyntax test_create test_name=<test-name>
The problem is that commoncmdsyntax is not replaced by new text here:
$(subst commoncmdsyntax,new text,$$desc)
I also tried to replace it by a single word, like XX, but it also does not work.
The subst function (as in $(subst commoncmdsyntax,new text,$$desc)) is a Make function, so Make will perform the substitution before running any rule and therefore before your script assigns a value to desc. So even if secondary expansion worked the way you seem to think it will, this approach would still fail.
If you want to perform a substitution within something made by a shell script (in a recipe), the sensible way is to do so within the recipe:
echo $dest | sed 's/commoncmdsyntax/new text/'
We can give you a more detailed solution if you give us a minimal complete example of the problem.
How and when do I quote a string in a make file? What is best practice?
Is the following the way to quote?
$(warning $(shell ls -ld "$(CURDIR)" ) )
I'm familiar with Bash where you usually quote variables to allow for embedded spaces. Do you do such in a makefile?
How should I do assignment statements with a string?
vara := "$(CURDIR)"
varb := $(CURDIR)
varc := /home/me/source
vard := "/home/me/source"
What about the space after the equal?
You should never quote anything because of make. Make doesn't understand or parse single- or double-quote characters in any way. Every quoting character you write in a makefile will be kept as a literal quote and passed along as-is to the commands that make invokes.
So, if the shell expects and can interpret a quoted string, then you should use quotes. Where the shell doesn't expect or won't correctly interpret a quoted string, you should not use quotes.
In your examples, whether the quotes are acceptable or not depends on how those variables are used. As above, make won't do anything special with quotes, which means that vard (for example) contains the literal string "/home/me/source" (including the quotes).
If you use that value in a way where the shell will handle the quotes for you, then it's fine:
all: ; echo $(vard)
will print /home/me/source (no quotes) because the shell interprets them. But if you use the variable in a make context, for example as a target or a prerequisite:
all: $(vard)
$(vard): ; echo $#
then this is not right, because the target and prerequisite are the literal strings "/home/me/source" (including the quotes).
In general it's best to not use quotes around filenames in variables, and instead add the quotes in the recipe around the make variable. Of course if the variable contains an entire shell script, not just a filename, then you should add appropriate quoting to the script.
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'.
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/
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.
I have an issue in batch programming. I fetch the strings generated by consoles, then the string contains double quotes and I will save that to a variable, like,
"/path/compile" -o source.cpp
And now my problem is, how can I remove this 2 double quotes? I'm not sure how to remove that quotes in the middle of the string.
Please advise
set a="hello" world
set b=%a:"=%
correct syntax:
set "tempvar="/path/compile" -o source.cpp"
echo %tempvar%
set "tempvar=%tempvar:"=%"
echo %tempvar%