How can I write the contents of a makefile variable to file, without invoking a shell command? The problem is that the contents of the variable is possible longer than the shell allows for a command (i.e. longer than MAX_ARG_STRLEN (131072) characters).
In particular, in a makefile I have a variable containing a long list of filenames to process (including their absolute pathes for out-of-source builds). Now I need to write those filenames to a (temporary) file, which I can then pass to another command.
So far, we had a rule like ($COLLATED_FILES
is the variable containing the paths):
$(outdir)/collated-files.tely: $(COLLATED_FILES)
$(LYS_TO_TELY) --name=$(outdir)/collated-files.tely --title="$(TITLE)" \
--author="$(AUTHOR)" $^
This breaks if COLLATED_FILES
is longer than about 130000 characters, we get the error message:
make[2]: execvp: /bin/sh: Argument list too long
As a solution, we are now trying to write the contents of the variable to a file and use that file in the $(LYS_TO_TELY)
command. Unfortunately, I have not yet found a way to do this without invoking the shell.
My attempts include:
$(outdir)/collated-files.list: $(COLLATED_FILES)
echo "" > $@
$(foreach f,$^,echo $f >> $@;)
But this also invokes all echo
commands at once in a shell, so the shell command is just as long.
Is there any way to write the contents of $(COLLATED_FILES)
to a file on disk without passing them on the command line to a shell command?
I also searched whether I could pipe the contents of the variable to the shell, but I couldn't find anything in that direction, either...
Commands and executionIf you want a string to have a dollar sign, you can use $$ . This is how to use a shell variable in bash or sh . Note the differences between Makefile variables and Shell variables in this next example.
If you've not exported the environment variable, it is not accessible until you do export it, or unless you pass it explicitly on the command line: make DEMOPATH="${demoPath}" … If you are using a C shell derivative, substitute setenv demoPath /usr/local/demo for the export command.
$MAKE is the default variable which gets replaced with "make". And in your scenario, $MAKE is used in commands part (recipe) of makefile. It means whenever there is a change in dependency, make executes the command make --no-print-directory post-build in whichever directory you are on.
Assuming you are using GNU Make, there is the file
function!
https://www.gnu.org/software/make/manual/html_node/File-Function.html
$(file op filename,text)
where op
is either >
or >>
.
This requires GNU Make 4.0+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With