According to make's Setting Variables, I can conditionally assign to a undefined variable with:
FOO ?= bar
Is the operator portable? Can it be used on non-GNU systems?
That syntax is not defined in the POSIX standard for make, so it won't be available in versions of make other than GNU make. Of course, GNU make is itself portable, so it can and very often is used on non-GNU systems, so in that sense it is portable to non-GNU systems :-).
Related
I want to temporarily use a different shell than default /bin/sh with recursive GNU Make setup. Because of recursivity, I can't use the SHELL hack, or I would have to (is that right?) edit all the many makefiles (on each command line I would have to do
$(MAKE) SHELL=$(SHELL)
), which I don't want to do.
Since this is just temporary, I thought I would become root, back up /bin/sh and edit it to something what I want:
#!/bin/dash
echo dash shell
/bin/dash $#
It follows from the GNU Make manual that it runs the recipe lines with
execve("/bin/sh", "-c <recipe line>")
then based on the documentation of execve this should work. But it does not. When I run GNU Make, it completely ignores the above changed /bin/sh and works as if it was not changed.
Why and how to get this to work?
I don't know, this is just a hypothesis, supported by some evidence other than above. When the internal SHELL make variable is default, that is /bin/sh, the login shell, then GNU Make does not run recipes with
execve("/bin/sh", "-c recipe")
but instead, just uses
execve("recipe")
This would clearly contradict the following line from the GNU Make manual
"the program /bin/sh is used as the shell. The argument(s) passed to the shell are taken from the variable .SHELLFLAGS. The default value of .SHELLFLAGS is -c normally"
I would like to execute a command in a Makefile, store the result to a variable and reuse the result later.
In BSD Makefile, I can use the != operator:
PASSWORD != openssl rand -base64 48
In GNU Makefile, I can use the shell function:
PASSWORD := $(shell openssl rand -base64 48)
Is there a way to write this in such a way this is compatible with the two make?
Expected output
In both case, result of the command is assigned to PASSWORD, so I can reuse the same PASSWORD value in the Makefile:
quux:
#echo $(PASSWORD)
#echo $(PASSWORD)
If I run make quux, this will output twice the same password.
For example:
$ gmake quux
Y0ZrQQqLF9JK98x9UiIwWwcCN2Cq1wNqzph3ShG1RK0NeqbxWn6p4XB5zgHvfnbY
Y0ZrQQqLF9JK98x9UiIwWwcCN2Cq1wNqzph3ShG1RK0NeqbxWn6p4XB5zgHvfnbY
This is different than to use the backtick operator. In such cases, compatible with the two make, it will run the command each time.
In GNU make 4.0, the BSD operator != has been added for compatibility. For versions of GNU make prior to that, you're out of luck. You'll have to use the "poor man's" method, which is a recursive make invocation.
Be very careful because the BSD operator and the GNU make $(shell ...) function have slightly different semantics. In your specific situation you'll not notice any difference because the output from the shell command doesn't contain any variable references (no $).
I created a tcsh script, which I want to call through a Makefile environment. Therefore
I want to reference variables inside this tcsh script, which I have defined in the Makefile environment.
I tried to reference environment variables as $?VARIABLE, but this does not work on variables from the Makefile environment.
How can I do this?
Any dollar sign needs to be represented as a $$ in a make rule if it is to be used in commands. Note that it is extremely unwise to program in tcsh. In addition, make uses /bin/sh to execute commands, so you cannot use tcsh syntax in make rules.
All you could do, if you must, is something along
MAKEVAR = foo
target:
tcsh -c 'echo $$HOME $(MAKEVAR)'
What everybody else does is
MAKEVAR = foo
ANOTHERVAR = bar
target:
MAKEVAR=$(MAKEVAR) ANOTHERVAR=$(ANOTHERVAR) script.sh
This works for all make versions, not just GNU make.
If you're using GNU make, you need to export the variables.
There is option in makefile as make -C /pathname (so it build the targeted path).
Is there anything similar in clearmake?
Yes, if you are using clearmake -C gnu.
See "makefile_gnu".
Supported GNU make command options
clearmake –C gnu supports most of the single-character and long-form spellings of GNU make command options, as follows:
-directory=dir
Change to the specified directory before reading the makefiles.
(And that is fairly similar to the gnu make option -C:
‘-C dir’
‘--directory=dir’
Change to directory dir before reading the makefiles.
If multiple ‘-C’ options are specified, each is interpreted relative to the previous one: ‘-C / -C etc’ is equivalent to ‘-C /etc’.
This is typically used with recursive invocations of make (see Recursive Use of make).
)
I'm trying to read a makefile and it uses the variable $(MAKE). I can't see where this is getting defined. Is it a special variable of some sort? We're using GNU make.
It is an automatically defined variable. It is usually used to call make into subdirectories. More info in GNU make manual.