name: Verify runtime library linkage description: Verify runtime library linkage (static or shared) inputs: path: description: Installation directory required: true runs: using: composite steps: - run: | New-Variable path -Value '${{ inputs.path }}' -Option Constant function Parse-DllLine { param( [Parameter(Mandatory=$true)] [string] $Line ) if ($Line -match '^\s*DLL Name:\s*(?\S+)\s*$') { $Matches.dll } else { throw "Line doesn't match the pattern: $Line" } } function Parse-PeHeaders { param( [Parameter(ValueFromPipeline)] [string[]] $Output ) process { $Output | Select-String 'DLL Name:' -SimpleMatch -CaseSensitive | %{ Parse-DllLine $_ } } } function Parse-NeededLine { param( [Parameter(Mandatory=$true)] [string] $Line ) if ($Line -match '^\s*NEEDED\s*(?\S+)\s*$') { $Matches.dll } else { throw "Line doesn't match the pattern: $Line" } } function Parse-ElfHeaders { param( [Parameter(ValueFromPipeline)] [string[]] $Output ) process { $Output | Select-String 'NEEDED' -SimpleMatch -CaseSensitive | %{ Parse-NeededLine $_ } } } function Get-LinkedLibraries { param( [Parameter(Mandatory=$true)] [string] $ExePath ) $objdump = 'objdump' if ($env:CI_HOST_WINDOWS) { $objdump = 'C:\ProgramData\chocolatey\bin\objdump.exe' } if ($env:CI_TARGET_PE) { & $objdump -x $ExePath | Parse-PeHeaders | echo } if ($env:CI_TARGET_ELF) { & $objdump -x $ExePath | Parse-ElfHeaders | echo } } function Do-ValidateLinkedLibraries { param( [Parameter(Mandatory=$true)] [ValidateNotNull()] [string[]] $Actual, [ValidateNotNull()] [string[]] $Forbidden ) echo 'Linked libraries:' echo $Actual $unexpected = $Actual | ?{$_ -in $Forbidden} if ($unexpected.Count -gt 0) { throw "Links to the following unexpected libraries: $($unexpected -join ', ')" } } function Validate-LinkedLibraries { param( [Parameter(Mandatory=$true)] [ValidateNotNull()] [string[]] $Actual ) $windows_forbidden = @('msvcrt.dll') if ($env:CI_MINGW) { if (!$env:CI_HOST_WINDOWS) { $windows_forbidden = @() } } # Linking libstdc++ statically on Cygwin is broken, see the # cygwin_static_libstdc++.yml workflow. $cygwin_forbidden = @('msvcrt.dll') $linux_forbidden = @() if ($env:CI_TARGET_CYGWIN) { Do-ValidateLinkedLibraries ` -Actual $Actual ` -Forbidden $cygwin_forbidden } elseif ($env:CI_TARGET_WINDOWS) { Do-ValidateLinkedLibraries ` -Actual $Actual ` -Forbidden $windows_forbidden } elseif ($env:CI_TARGET_LINUX) { Do-ValidateLinkedLibraries ` -Actual $Actual ` -Forbidden $linux_forbidden } else { throw 'Where am I?' } } $exe_path = (Join-Path $path 'bin' 'foo') + $env:CI_EXE_EXT $libraries = Get-LinkedLibraries $exe_path Validate-LinkedLibraries $libraries shell: pwsh