设置Powershell core为windowslinux的默认GNU Make shell。

问题描述 投票:1回答:1

在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.

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

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

VAR=asdf/asdf

.PHONY: get_var

get_var:
    @Write-Output $(VAR)

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

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

如果在命令中明确地指定了shell,就可以了。

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

VAR=asdf/asdf

.PHONY: get_var

get_var:
    @pwsh -c Write-Output $(VAR)

run:

PS C:\projects\makefile_factory> make -f .\fi.makefile get_var
asdf/asdf

另外,我还研究了 编制文件:

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

所以我试着设置环境变量SHELLMAKESHELL,没有结果。

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

那么,有没有一种方法可以指定pwsh为默认shell?

powershell makefile gnu-make
1个回答
1
投票

这并不像人们想象的那样容易。一般来说,GNU make在决定要调用shell之前,并不会真正调用shell,而是采取快捷方式,试图直接调用命令(execCreateProcess 视平台而定)。)

而如何 make 决定是否需要外壳?嗯,它有一个 预定义 特定shell要知道的关键字列表。对于Windows,有一个单独的 列表 特定关键词的数量 cmd 和一个Unixy-shell.现在,什么是Unixy(也就是伯恩兼容的)shell?

现在,什么是Unixy(也就是伯恩兼容的)shell?嗯,它是另一个 预定义 列表。sh, bash, ksh, rksh, zsh, ash, dash. 注无 pwsh 这里。

所以为了得到 make 命令必须包含一个已知的关键字或字符,才能实际执行shell,否则 make 将尝试直接运行命令,而不调用shell。

还有一件事要记住:当设置 SHELL它必须是文件的全路径或全名,以通过搜索解决 PATH 环境变量。请注意,PowerShell的可执行文件为 pwsh.exepwsh 和虽然后者在命令行上工作,但它是命令行解释器尝试不同的扩展。make 只是简单地检查该文件是否 存在.

将以上所有内容加起来,我就可以运行PowerShell了,具体如下。

> Get-Content .\Makefile
SHELL := pwsh.exe

VAR=asdf/asdf

.PHONY: get_var

get_var:
        @&Write-Output $(VAR)
        @$$PSVersionTable

用刚编译好的Win32 GNU make进行测试。

> ..\make-4.1\WinRel\gnumake.exe -dr
GNU Make 4.1
Built for Windows32
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Reading makefile 'Makefile'...
find_and_set_shell() path search set default_shell = C:/Program Files/PowerShell/7/pwsh.exe
Updating makefiles....
 Considering target file 'Makefile'.
  Looking for an implicit rule for 'Makefile'.
  No implicit rule found for 'Makefile'.
  Finished prerequisites of target file 'Makefile'.
 No need to remake target 'Makefile'.
Updating goal targets....
Considering target file 'get_var'.
 File 'get_var' does not exist.
 Finished prerequisites of target file 'get_var'.
Must remake target 'get_var'.
CreateProcess(NULL,C:/Program Files/PowerShell/7/pwsh.exe -c "&Write-Output asdf/asdf",...)
Putting child 00B86400 (get_var) PID 12170424 on the chain.
Live child 00B86400 (get_var) PID 12170424
Main thread handle = 0000016C
asdf/asdf
Reaping winning child 00B86400 PID 12170424
CreateProcess(NULL,C:/Program Files/PowerShell/7/pwsh.exe -c $PSVersionTable,...)
Live child 00B86400 (get_var) PID 12193536

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Reaping winning child 00B86400 PID 12193536
Removing child 00B86400 PID 12193536 from chain.
Successfully remade target file 'get_var'.
© www.soinside.com 2019 - 2024. All rights reserved.