将 Powershell 核心设置为 Windows/Linux 上的默认 GNU Make shell

gek*_*gek 3 powershell makefile gnu-make

在 Windows 上的 makefile 中。

使用以下 make 版本:

PS C:\projects> make --version
GNU Make 4.1
Built for i686-w64-mingw32
Copyright (C) 1988-2014 Free Software Foundation, Inc.
Run Code Online (Sandbox Code Playgroud)

我试图在没有明确指定 shell 的情况下设置SHELL := pwsh/COMSPEC := pwsh和运行命令:

# COMSPEC := pwsh -c
SHELL := pwsh -c

VAR=asdf/asdf

.PHONY: get_var

get_var:
    @Write-Output $(VAR)
Run Code Online (Sandbox Code Playgroud)

没有成功。我有一个错误:

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
Run Code Online (Sandbox Code Playgroud)

如果在命令中明确指定了 shell,则它可以工作:

# COMSPEC := pwsh -c
# SHELL := pwsh -c

VAR=asdf/asdf

.PHONY: get_var

get_var:
    @pwsh -c Write-Output $(VAR)
Run Code Online (Sandbox Code Playgroud)

跑:

PS C:\projects\makefile_factory> make -f .\fi.makefile get_var
asdf/asdf
Run Code Online (Sandbox Code Playgroud)

另外,我查看了make 文档

然而,在 MS-DOS和 MS-Windows 环境中使用 SHELL 的值,因为在这些系统上大多数用户没有设置这个变量,因此它很可能被专门设置为由 make 使用。在 MS-DOS 上,如果 SHELL 的设置不适合 make,可以将变量 MAKESHELL 设置为 make 应该使用的 shell;如果设置,它将被用作外壳而不是 SHELL 的值。

所以我尝试设置环境变量 SHELL/MAKESHELL 没有结果:

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
Run Code Online (Sandbox Code Playgroud)

那么,没有办法将 pwsh 指定为默认 shell 吗?

Aar*_*ock 5

什么@raspy说的是真的,但是,我发现了一个辉煌的解决方法!

如果您查看这里的if 语句,您会注意到如果shellflags设置为其他内容,-c或者-ce它将始终使用慢速选项(这意味着它将始终通过SHELL二进制文件直接执行!)。幸运的是,我们可以.SHELLFLAGS直接设置,看看这些文档

无论如何,这意味着我们需要做的就是将 设置为或.SHELLFLAGS之外的其他内容,例如我们可以使用 powershell将它们捆绑在一起:-c-ce-Command

SHELL := pwsh
.SHELLFLAGS := -Command

VAR=asdf/asdf

.PHONY: get_var
get_var:
    @Write-Output $(VAR)
Run Code Online (Sandbox Code Playgroud)

或者,在我想要 Windows 上的 PowerShell.exe 和 Linux 上的默认 shell 的示例中:

ifeq ($(OS),Windows_NT)
SHELL := powershell.exe
.SHELLFLAGS := -NoProfile -Command
endif

test.txt:
    echo "hello, world" > test.txt

test:
    rm test.txt
Run Code Online (Sandbox Code Playgroud)

干杯!