Make throws "Command not found" when passing a variable - makefile

I am using
GNU Make 3.82
Built for x86_64-redhat-linux-gnu
In the Makefile I have
download:
aws s3 cp s3://$(PATH) .
and when doing make PATH=<a valid location> download
it throws the error
make[1]: aws: Command not found
When debugging this, I noticed that this only happens when $(PATH) is being used. When the s3 path doesn't use a variable, the make command works.
What is going on and how can I pass a variable to the make command?

PATH is a system variable which your shell uses to find executables. If you redefine it, aws can no longer be found in PATH. Use a different variable name.

Related

Makefile docker command with single quote failling

With this in a Makefile:
single:
docker network inspect -f '{{ .IPAM }}' web-proxy
double:
docker network inspect -f "{{ .IPAM }}" web-proxy
make single fails with make: docker: Permission denied while make double succeeds. Both commands work if I input them directly in my bash.
It happens only since I upgraded to Ubuntu 22.04.1 (from the 22.04). I have docker 20.10.20, bash 5.1.16 and GNU Make 4.3
Any idea were it can come from ? From what I have read the Makefile doesn't care about quotes: https://stackoverflow.com/a/23332194
I don't know why updating your system made a difference, but this is almost certainly related to a bug in gnulib (that GNU make uses).
If you add a semicolon to the end of the docker command line in the single target I'll bet it will work again.
The bug is this: if some directory on your PATH contains a subdirectory with the name of a command you want to invoke, then if make attempts to run that command directly (without using a shell) it will fail because it tries to "run" that directory. So for example if you have /my/dir in PATH and the directory /my/dir/docker/. exists, you will get this error (for simple docker commands).
The "double" target works because (due to the {{) make's trivial parser decides that this command it not "simple enough" to parse directly, and it runs the shell to do it; the shell doesn't get confused by that directory.
You can (1) add the semicolon as above, or (2) figure out why some directory on your PATH contains a docker subdirectory and remove it.
The next release of GNU make (probably released by the end of the month) will fix this issue (includes a newer version of the gnulib module, with the fix).

Makefile Cygwin: mkdir, "The syntax of the command is incorrect."

Running the following Makefile gives an error message
The syntax of the command is incorrect.
This is because the makefile calls mkdir which is a windows command instead of mkdir from Cygwin. Even though I put cygwin path first in the environment variable, it still calls the windows mkdir instead of the Cygwin one. One quick way to fix is to use mkdir.exe. Then the Cygwin one is called. I am looking for a method to call the correct one without changing the Makefile is there any way to tell Makefile which one it should call. Something in the settings?
all:
echo "make started"
mkdir -p test/tmp
echo "make ended"
Output:
C:\Users\me\Desktop\New_folder>make
echo "make started"
"make started"
mkdir -p test/tmp
The syntax of the command is incorrect.
make: *** [all] Error 1
C:\Users\me\Desktop\New_folder>
I am looking for a method to call the correct one without changing the Makefile is there any way to tell Makefile which one it should call. Something in the settings?
It's unclear which setting you're referring to, but the root of the issue is the shell the Makefile is using. It looks like it's getting cmd.exe in your case, so unqualified "mkdir" triggers its builtin. No path search is performed.
You could try to work around that by directing make to use a different shell, something like this:
make SHELL=\path\to\cygwin\bash.exe
or you could launch make from a bash shell in the first place.
Be aware, however, that even if that works, this may not be the last issue you encounter. Makefiles not built with Windows specifically in mind -- which is most of them -- cannot often adapt to the quite different Windows environment. I've had more luck with MinGW in this area, and then with Automake-based makefiles, but it has nevertheless required some special accommodation in makefile sources and in programming-language sources.

Using an environment variable in GNU makefile SHELL variable

In a makefile, I have the following:
SHELL = $(SOME_DIRECTORY)/sh
showme:
echo $(SHELL)
This is on MS Windows. The situation is that make is in the PATH (or is being directly invoked) but an acceptable shell (i.e. sh.exe) is NOT in the PATH. Neither is it an option to globally modify the PATH variable to include a sh.exe (too much potential conflict between Cygwin, msysgit, and more). Therefore, make defaults to using the Windows cmd.exe command processor, which is hardly ideal.
It is an option to set a system-wide environment variable other than PATH however. So I had the bright idea of putting a path to the directory containing sh.exe in SOME_DIRECTORY and then using it in the SHELL variable in the makefile. But it's not working for some frustrating reason:
make
echo sh.exe
sh.exe
If I use any other variable than SHELL and echo it, then it prints the expected result. But of course that doesn't have the desired effect of changing the shell.
What am I missing here? What do I need to do to have an environment variable with a custom user-specified name (i.e. not SHELL, PATH, etc.) affect the shell used by make?
Which make are you using? GNU make (gmake) 3.82 is most common and it should work in the way you expect. As MadScientist notes, gmake behaves differently under windows wrt SHELL.
You should be able to set SHELL to the full path of an existing executable file, and gmake will use it to execute commands.
However: if SHELL is not set OR if it is set to a non-existent file, gmake will use the value of ComSpec (mind the caps) as the shell.
Is there an exe at the test path you're using? So $(SOME_DIRECTORY)/sh is an existing exe? (Note that you can omit the '.exe' and gmake will supply it for you, but the file must exist)

CMake: Running shell script after expanding variables in it

Following is the issue, I am encountering
I have a shell script named my_script.sh.IN. I use configure_file for expanding script and thus creating my_script.sh.
I then need to run my_script.sh. For this purpose, I am using execute_process().
I need all of this at CMake time.
Issue: Problem is that when I run "cmake", system complains that he could not find "my_script.sh". I think that execute_process dependencies seem to be calculated before configure_file() function runs.
When I run "cmake" command second time, everything goes fine. Does anybody knows that how can I able to execute configure_file before execute_process?
You should try something like that:
set_source_files_properties("pat/to/my_script.sh" PROPERTIES GENERATED true)
It tells cmake to not check the existency of the file too early. You will probably have to use the variable containing the path of your generated shell script instead of typing directly its path.
But your issue is more probably related to order of the executed cmake commands. You should ensure configure_file() is run BEFORE execute_process() by CMake parser.

Why does make tell me "Command not found"?

I have the following simple makefile:
all:
fat_imgen.exe
Where fat_imgen.exe is an executable in the same directory as the makefile. When I try and run this however this happens:
>make
fat_imgen.exe
make: fat_imgen.exe: Command not found
make: *** [all] Error 127
If I run fat_imgen from that same command prompt then it starts as expected - why can't make find fat_imgen.exe?
This is all running under Mingw / Windows.
When using a simple commend like the name of an executable, GNU make will start the executable directly. If the directory where the executable is found is not in the PATH/path, make will fail.
If you put the directory in the path, your makefile should work normally.
Also, as suggested in a comment by #AlexFarber, by adding './' GNU make will assume a more complex command (since not all shells are created equal), and hand the command over to the configured shell. That will work, since the shell is created in the directory where the command is then found.

Resources