Makefile 有这样的规则:
DIR_DEPENDS = F:\depends
!IF !EXIST ("$(DIR_DEPENDS)")
! IF [$(MKD) "$(DIR_DEPENDS)"]
! ENDIF
!ENDIF
DIR_DWNLOAD = $(DIR_DEPENDS)\download
!IF !EXIST ("$(DIR_DWNLOAD)")
! IF [$(MKD) "$(DIR_DWNLOAD)"]
! ENDIF
!ENDIF
URL_GETTEXT32 = <url>
DIR_GETTEXT32 = $(DIR_DEPENDS)\gettext32
URL_GETTEXT64 = <url>
DIR_GETTEXT64 = $(DIR_DEPENDS)\gettext64
## gettext libs
gettextlibs : cfg-depends.mak
if not exist "$(DIR_GETTEXT32)" ($(MKD) "$(DIR_GETTEXT32)")
if not exist "$(DIR_GETTEXT64)" ($(MKD) "$(DIR_GETTEXT64)")
$(MAKE) /nologo /f cfg-depends.mak "URL=$(URL_GETTEXT32)" "LOCALDIR=$(DIR_DWNLOAD)\gettext32.zip" downloadfile
$(MAKE) /nologo /f cfg-depends.mak "URL=$(URL_GETTEXT64)" "LOCALDIR=$(DIR_DWNLOAD)\gettext64.zip" downloadfile
!IF EXIST ("$(7Z)")
"$(7Z)" e "$(DIR_DWNLOAD)\gettext32.zip" -y -o"$(DIR_GETTEXT32)\" *.dll
"$(7Z)" e "$(DIR_DWNLOAD)\gettext64.zip" -y -o"$(DIR_GETTEXT64)\" *.dll
!ELSEIF EXIST ("$(WINRAR)")
"$(WINRAR)" e -ibck -y -op"$(DIR_GETTEXT32)" "$(DIR_DWNLOAD)\gettext32.zip" *.dll
"$(WINRAR)" e -ibck -y -op"$(DIR_GETTEXT64)" "$(DIR_DWNLOAD)\gettext64.zip" *.dll
!ELSE
powershell -nologo -noprofile -command \
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; \
$$zfl=[System.IO.Compression.ZipFile]::OpenRead(\"$(DIR_DWNLOAD)\gettext32.zip\"); \
$$zfl.Entries ^| Where {$$_.Name -like '*.dll'} ^| \
foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($$_, \"$(DIR_GETTEXT32)\$$($$_.Name)\", $$true)}; \
$$zfl.Dispose()
powershell -nologo -noprofile -command \
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; \
$$zfl=[System.IO.Compression.ZipFile]::OpenRead(\"$(DIR_DWNLOAD)\gettext64.zip\"); \
$$zfl.Entries ^| Where{$$_.Name -like '*.dll'} ^| \
foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($$_, \"$(DIR_GETTEXT64)\$$($$_.Name)\", $$true)}; \
$$zfl.Dispose()
!ENDIF
处理时抛出错误:
powershell -nologo -noprofile -command Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; $zfl=[System.IO.Compression.ZipFile]::OpenRead(\"F:\depends\download\gettext32.zip\"); $zfl.Entries ^| Where {$_.Name -like '*.dll'} ^| foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, \"F:\depends\gettext32\$($_.Name)\", $true)}; $zfl.Dispose()
powershell -nologo -noprofile -command Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; $zfl=[System.IO.Compression.ZipFile]::OpenRead(\"\gettext64.zip\"); $zfl.Entries ^| Where{$_.Name -like '*.dll'} ^| foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, \"F:\depends\download\$($_.Name)\", $true)}; $zfl.Dispose()
Exception calling "OpenRead" with "1" argument(s): "Could not find a part of the path 'F:\gettext64.zip'."
At line:1 char:60
+ Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; $zfl=[System.IO.Compr ...
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DirectoryNotFoundException
You cannot call a method on a null-valued expression.
At line:1 char:285
+ ... me)", $true)}; $zfl.Dispose()
+ ~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
NMAKE : fatal error U1077: 'powershell' : return code '0x1'
Stop.
也就是说,正如您所看到的,第二个“powershell”调用命令中 $(DIR_DWNLOAD) 宏的值没有展开。 这种情况仅发生在第二个 powershell 命令中。 具有此宏的所有其他辅助命令都可以正常工作。 我尝试了分离这些预处理器条件的不同变体,但结果在各处都是相同的。
为什么会发生这种情况?我需要做什么才能使该规则正常发挥作用?
看来这种行为的原因已经被发现了。
powershell -nologo -noprofile -command \
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; \
$$zfl=[System.IO.Compression.ZipFile]::OpenRead(\"$(DIR_DWNLOAD)\two-filearchive.zip\"); \
$$zfl.Entries ^| ?{$$_.FullName -match 'dir1/file1.dll'} ^| \
%%{[System.IO.Compression.ZipFileExtensions]::ExtractToFile($$_, """$(DIR_UNZIP)\$$($$_.Name)""", $$true)}; \
$$zfl.Dispose()
copy /y /b "$(DIR_UNZIP)\ShellExecAsUser.dll" "$(DIR_DIST)\directory"
就是这个构造$($_.Name),在文档中描述如下:
只有基本变量引用可以直接嵌入到 可扩展字符串。使用数组索引或成员的变量引用 访问必须包含在子表达式中。
显然,这让 NMAKE 感到困惑,它试图将其扩展为宏(变量)。
我已经这样做了,以在 powershell 命令中排除此构造。
powershell -nologo -noprofile -command \
Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; \
$$zfl=[System.IO.Compression.ZipFile]::OpenRead(\"$(DIR_DWNLOAD)\two-filearchive.zip\"); \
$$zfl.Entries ^| ?{$$_.FullName -match 'dir1/file1.dll'} ^| \
%%{$$n=$$_.Name; [System.IO.Compression.ZipFileExtensions]::ExtractToFile($$_, """$(DIR_UNZIP)\$$n""", $$true)}; \
$$zfl.Dispose()
但这些都是我的假设,我想听听专业人士的意见。也许 powershell 专家会提出一个更优雅的解决方案。