The values of macros (variables) in the NMAKE preprocessor directive are not expanded

81 Views Asked by At

Makefile has a rule like this:

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

An error is thrown when it is processed:

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.

That is, as you can see the value of the $(DIR_DWNLOAD) macro in the second "powershell" call command is not expanded. And this happens only for the second powershell command. All other secondary commands that have this macro work fine. I have tried different variants of separating these preprocessor conditions, but the result is the same everywhere.

Why is this happening? What do I need to do to make this rule work properly?

1

There are 1 best solutions below

0
Restorer On

It seems that the cause of this behavior has been discovered.

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"

It is this construct $($_.Name), which is described in the documentation as follows:

Only basic variable references can be directly embedded in an expandable string. Variables references using array indexing or member access must be enclosed in a subexpression.

Apparently, this confuses NMAKE and it tries to expand it as a macro (variable).
I have done it this way to exclude this construct in the powershell command.

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()

But these are my assumptions and I would like to hear the opinion of professionals. And perhaps powershell experts will suggest a more elegant solution.