Question:
In the makefile on Windows.
With the following make version:
1 2 3 4 5 |
PS C:\projects> make --version GNU Make 4.1 Built for i686-w64-mingw32 Copyright (C) 1988-2014 Free Software Foundation, Inc. |
I have tried to set SHELL := pwsh
/ COMSPEC := pwsh
and run command without explicit shell specifying:
1 2 3 4 5 6 7 8 9 10 |
# COMSPEC := pwsh -c SHELL := pwsh -c VAR=asdf/asdf .PHONY: get_var get_var: @Write-Output $(VAR) |
without success. I’ve got an error:
1 2 3 4 5 6 |
PS C:\projects\makefile_factory> make -f .\fi.makefile get_var process_begin: CreateProcess(NULL, Write-Output asdf/asdf, ...) failed. make (e=2): ═х єфрхЄё эрщЄш єърчрээ√щ Їрщы. .\fi.makefile:10: recipe for target 'get_var' failed make: *** [get_var] Error 2 |
If shell specified explicitly in the command, it works:
1 2 3 4 5 6 7 8 9 10 |
# COMSPEC := pwsh -c # SHELL := pwsh -c VAR=asdf/asdf .PHONY: get_var get_var: @pwsh -c Write-Output $(VAR) |
run:
1 2 3 |
PS C:\projects\makefile_factory> make -f .\fi.makefile get_var asdf/asdf |
Also, i’ve looked into make documentation:
However, on MS-DOS and MS-Windows the value of SHELL in the
environment is used, since on those systems most users do not set this
variable, and therefore it is most likely set specifically to be used
by make. On MS-DOS, if the setting of SHELL is not suitable for make,
you can set the variable MAKESHELL to the shell that make should use;
if set it will be used as the shell instead of the value of SHELL.
So i tried to set environment variable SHELL/MAKESHELL with no result:
1 2 3 4 5 6 7 8 9 10 11 |
PS C:\projects\makefile_factory> $env:SHELL C:\Program Files\PowerShell\7\pwsh.exe PS C:\projects\makefile_factory> $env:MAKESHELL C:\Program Files\PowerShell\7\pwsh.exe PS C:\projects\makefile_factory> make -f .\fi.makefile get_var Write-Output asdf/asdf process_begin: CreateProcess(NULL, Write-Output asdf/asdf, ...) failed. make (e=2): ═х єфрхЄё эрщЄш єърчрээ√щ Їрщы. .\fi.makefile:9: recipe for target 'get_var' failed make: *** [get_var] Error 2 |
So, isn’t there a way to specify pwsh as a default shell?
Answer:
What @raspy says is true, but, I found a glorious workaround!
If you take a look at this if statement right here you’ll notice that if the shellflags
is set to something besides -c
or -ce
it will always use the slow option (Which means it will always execute through the SHELL
rather the binary directly! 🎉🎉). Luckily for us, we can set the .SHELLFLAGS
directly, take a look at these docs
In any event, all that means we need to do is set the .SHELLFLAGS
to something besides -c
or -ce
, for example with powershell we can use -Command
, tying it all together:
1 2 3 4 5 6 7 8 9 |
SHELL := pwsh .SHELLFLAGS := -Command VAR=asdf/asdf .PHONY: get_var get_var: @Write-Output $(VAR) |
Or, in my example where I want PowerShell.exe on Windows & the default shell on Linux:
1 2 3 4 5 6 7 8 9 10 11 |
ifeq ($(OS),Windows_NT) SHELL := powershell.exe .SHELLFLAGS := -NoProfile -Command endif test.txt: echo "hello, world" > test.txt test: rm test.txt |
Cheers!