Skip to content

Commit

Permalink
Remove unneeded built DLLs, add MinGW DLLs automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
mlocati committed Sep 22, 2024
1 parent 6995586 commit 33fd145
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 48 deletions.
45 changes: 6 additions & 39 deletions .github/workflows/build-exe-create-output
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ copyFile () {
mkdir -p "$(dirname "$destinationPath")"
case "$fileType" in
binary)
strip --strip-unneeded "$sourcePath" -o "$destinationPath"
"$MINGW_HOST-strip" --strip-unneeded "$sourcePath" -o "$destinationPath"
;;
text)
perl -pe 's/\r\n|\n|\r/\r\n/g' <"$sourcePath" >"$destinationPath"
Expand Down Expand Up @@ -61,32 +61,11 @@ if [ ! -d "$DESTINATION" ]; then
printf 'Destination directory (%s) not found\n' "$DESTINATION"
exit 1
fi
LINK="${3:-}"
case "$LINK" in
shared | static)
;;
'')
echo 'Missing 3rd argument (link)'
exit 1
;;
*)
printf 'Missing/wrong link (%s)\n' "$LINK"
exit 1
;;
esac
BITS="${4:-}"
case "$BITS" in
32 | 64)
;;
'')
echo 'Missing 4rd argument (bits)'
exit 1
;;
*)
printf 'Missing/wrong bits (%s)\n' "$BITS"
exit 1
;;
esac
MINGW_HOST="${3:-}"
if [ -z "$MINGW_HOST" ]; then
echo 'Missing 3nd argument (MinGW host)'
exit 1
fi

mkdir -p "$DESTINATION/share/gettext"

Expand All @@ -108,15 +87,3 @@ cp -r "$SOURCE/share/gettext/styles" "$DESTINATION/share/gettext/"
cp -r $SOURCE/share/gettext-*/its "$DESTINATION/share/gettext"
copyFile "$SOURCE/share/gettext/msgunfmt.tcl"
copyFile "$SOURCE/cldr-plurals.xml" '' lib/gettext/common/supplemental/plurals.xml
case "$LINK$BITS" in
shared32)
copyFile /usr/i686-w64-mingw32/sys-root/mingw/bin/libgcc_s_sjlj-1.dll '' bin/libgcc_s_sjlj-1.dll
copyFile /usr/i686-w64-mingw32/sys-root/mingw/bin/libstdc++-6.dll '' bin/libstdc++-6.dll
copyFile /usr/i686-w64-mingw32/sys-root/mingw/bin/libwinpthread-1.dll '' bin/libwinpthread-1.dll
;;
shared64)
copyFile /usr/x86_64-w64-mingw32/sys-root/mingw/bin/libwinpthread-1.dll '' bin/libwinpthread-1.dll
copyFile /usr/x86_64-w64-mingw32/sys-root/mingw/bin/libstdc++-6.dll '' bin/libstdc++-6.dll
copyFile /usr/x86_64-w64-mingw32/sys-root/mingw/bin/libgcc_s_seh-1.dll '' bin/libgcc_s_seh-1.dll
;;
esac
188 changes: 188 additions & 0 deletions .github/workflows/build-exe-dependencies.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<#
$Env:PATH += ";C:\Program Files (x86)\Microsoft Visual Studio\Installer"
#>

param (
[Parameter(Mandatory = $true)]
[ValidateSet(32, 64)]
[int] $bits,
[Parameter(Mandatory = $true)]
[ValidateSet('shared', 'static')]
[string] $link,
[Parameter(Mandatory = $true)]
[ValidateLength(1, [int]::MaxValue)]
[ValidateScript({Test-Path -LiteralPath $_ -PathType Container})]
[string] $outputPath,
[Parameter(Mandatory = $true)]
[ValidateLength(1, [int]::MaxValue)]
[ValidateScript({Test-Path -LiteralPath $_ -PathType Container})]
[string] $mingwPath
)

function Find-Dumpbin
{
[OutputType([string])]
$vsPath = & vswhere.exe -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
if (-not($?)) {
throw "vswhere failed"
}
$vcToolsVersion = Get-Content -LiteralPath "$vsPath\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt" -TotalCount 1
switch ($bits) {
32 {
$result = "$vsPath\VC\Tools\MSVC\$vcToolsVersion\bin\Hostx86\x86\dumpbin.exe"
}
64 {
$result = "$vsPath\VC\Tools\MSVC\$vcToolsVersion\bin\HostX64\x64\dumpbin.exe"
}
}
if (-not(Test-Path -LiteralPath $result -PathType Leaf)) {
throw "$result`ndoes not exist"
}
$result
}

function Get-Dependencies()
{
[OutputType([string[]])]
param(
[Parameter(Mandatory = $true)]
[ValidateLength(1, [int]::MaxValue)]
[ValidateScript({Test-Path -LiteralPath $_ -PathType Leaf})]
[string] $path
)

$dumpbinResult = & "$dumpbin" /NOLOGO /DEPENDENTS "$path"
if (-not($?)) {
throw "dumpbin failed to analyze the file $($path)"
}
[string[]]$dependencies = @()
$started = $false
foreach ($line in $dumpbinResult) {
$line = $line.Trim()
if (-not($line)) {
continue;
}
if ($started) {
if ($line -eq 'Summary') {
break
}
$dependencies += $line.ToLowerInvariant()
} elseif ($line -eq 'Image has the following dependencies:') {
$started = $true
}
}
$dependencies
}

class Binary
{
[System.IO.FileInfo] $File
[string[]] $Dependencies
Binary([System.IO.FileInfo]$file)
{
$this.File = $file
$this.Dependencies = Get-Dependencies $this.File.FullName
}
}

class Binaries
{
[bool] $MinGWFilesAdded = $false

[Binary[]] $Items

Binaries()
{
$this.Items = @()
}

[void] Add([Binary]$binary)
{
if ($this.GetBinaryByName($binary.File.Name)) {
throw "Duplicated binary name $($binary.File.Name)"
}
$this.Items += $binary
}

[Binary] GetBinaryByName([string] $name)
{
foreach ($item in $this.Items) {
if ($item.File.Name -eq $name) {
return $item
}
}
return $null
}

[void] RemoveUnusedDlls()
{
do {
$repeat = $false
foreach ($binary in $this.Items) {
if ($binary.File.Extension -ne '.dll') {
continue
}
$name = $binary.File.Name.ToLowerInvariant()
$unused = $true
foreach ($other in $this.Items) {
if ($other -ne $binary -and $other.Dependencies -contains $name) {
$unused = $false
break
}
}
if ($unused) {
Write-Host "$($binary.File.Name) is never used: deleting it"
$binary.File.Delete()
$this.Items = $this.Items | Where-Object { $_ -ne $binary }
$repeat = $true
break
}
}
} while ($repeat)
}

[void] AddMingwDlls([string] $mingwBinPath)
{
$checkedDeps = @()
for ($index = 0; $index -lt $this.Items.Count; $index++) {
$binary = $this.Items[$index]
foreach ($dependency in $binary.Dependencies) {
if ($checkedDeps -contains $dependency) {
continue
}
$checkedDeps += $dependency
if ($this.GetBinaryByName($dependency)) {
continue
}
$mingwDllPath = Join-Path -Path $mingwBinPath -ChildPath $dependency
if (-not(Test-Path -LiteralPath $mingwDllPath -PathType Leaf)) {
continue
}
Write-Host -Object "Adding MinGW DLL $dependency"
Copy-Item -LiteralPath $mingwDllPath -Destination $binary.File.Directory
$newFilePath = Join-Path -Path $binary.File.Directory -ChildPath $dependency
$newFile = Get-ChildItem -LiteralPath $newFilePath -File
$newBinary = [Binary]::new($newFile)
$this.Add($newBinary)
$this.MinGWFilesAdded = $true
}
}
}
}

$dumpbin = Find-Dumpbin
$mingwBinPath = Join-Path -Path $mingwPath -ChildPath 'sys-root\mingw\bin'
$outputBinPath = Join-Path -Path $outputPath -ChildPath 'bin'
$binaries = [Binaries]::new()
foreach ($file in Get-ChildItem -LiteralPath $outputBinPath -Recurse -File) {
if ($file.Extension -eq '.exe' -or $file.Extension -eq '.dll') {
$binary = [Binary]::new($file)
$binaries.Add($binary)
}
}

$binaries.RemoveUnusedDlls()
$binaries.AddMingwDlls($mingwBinPath)
if ($binaries.MinGWFilesAdded) {
# todo
}
5 changes: 1 addition & 4 deletions .github/workflows/build-exe-setup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ $gettextIgnoreTestsC = 'gettext-tools/gnulib-tests/test-asyncsafe-spin2.c gettex
switch ($bits) {
32 {
$cygwinPackages = "$cygwinPackages,mingw64-i686-gcc-core,mingw64-i686-gcc-g++,mingw64-i686-headers,mingw64-i686-runtime"
$mingwPath = '/usr/i686-w64-mingw32'
$mingwHost = 'i686-w64-mingw32'
}
64 {
$cygwinPackages = "$cygwinPackages,mingw64-x86_64-gcc-core,mingw64-x86_64-gcc-g++,mingw64-x86_64-headers,mingw64-x86_64-runtime"
$mingwPath = '/usr/x86_64-w64-mingw32'
$mingwHost = 'x86_64-w64-mingw32'
}
}
Expand All @@ -36,8 +34,7 @@ switch ($link) {
}
}
"cygwin-packages=$cygwinPackages" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"cygwin-path=/installed/bin:$mingwPath/bin:$mingwPath/sys-root/mingw/bin:/usr/sbin:/usr/bin:/sbin:/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"mingw-path=$mingwPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"cygwin-path=/installed/bin:/usr/$mingwHost/bin:/usr/$mingwHost/sys-root/mingw/bin:/usr/sbin:/usr/bin:/sbin:/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"mingw-host=$mingwHost" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"configure-options=$configureOptions" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
"gettext-cppflags=$gettextCppFlags" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
Expand Down
14 changes: 9 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ jobs:
CC='${{ steps.setup.outputs.mingw-host }}-gcc'
CXX='${{ steps.setup.outputs.mingw-host }}-g++'
LD='${{ steps.setup.outputs.mingw-host }}-ld'
CPPFLAGS='-I${{ steps.setup.outputs.mingw-path }}/sys-root/mingw/include -D__USE_MINGW_ANSI_STDIO=0 -g0 -O2'
LDFLAGS='-L${{ steps.setup.outputs.mingw-path }}/sys-root/mingw/lib'
CPPFLAGS='-I/usr/${{ steps.setup.outputs.mingw-host }}/sys-root/mingw/include -D__USE_MINGW_ANSI_STDIO=0 -g0 -O2'
LDFLAGS='-L/usr/${{ steps.setup.outputs.mingw-host }}/sys-root/mingw/lib'
ac_cv_func__set_invalid_parameter_handler=no
gl_cv_header_working_stdint_h=no
--host=${{ steps.setup.outputs.mingw-host }}
Expand Down Expand Up @@ -180,8 +180,8 @@ jobs:
CC='${{ steps.setup.outputs.mingw-host }}-gcc'
CXX='${{ steps.setup.outputs.mingw-host }}-g++'
LD='${{ steps.setup.outputs.mingw-host }}-ld'
CPPFLAGS='-I/installed/include -I${{ steps.setup.outputs.mingw-path }}/sys-root/mingw/include -D__USE_MINGW_ANSI_STDIO=0 -g0 -O2 ${{ steps.setup.outputs.gettext-cppflags }}'
LDFLAGS='-L/installed/lib -L${{ steps.setup.outputs.mingw-path }}/sys-root/mingw/lib'
CPPFLAGS='-I/installed/include -I/usr/${{ steps.setup.outputs.mingw-host }}/sys-root/mingw/include -D__USE_MINGW_ANSI_STDIO=0 -g0 -O2 ${{ steps.setup.outputs.gettext-cppflags }}'
LDFLAGS='-L/installed/lib -L/usr/${{ steps.setup.outputs.mingw-host }}/sys-root/mingw/lib'
ac_cv_func__set_invalid_parameter_handler=no
gl_cv_header_working_stdint_h=no
--host=${{ steps.setup.outputs.mingw-host }}
Expand Down Expand Up @@ -222,7 +222,11 @@ jobs:
run: make install && cp ../COPYING /installed/gettext-license.txt
-
name: Copy built assets
run: ./.github/workflows/build-exe-create-output /installed /output ${{ matrix.link }} ${{ matrix.bits}}
run: ./.github/workflows/build-exe-create-output /installed /output '${{ steps.setup.outputs.mingw-host }}'
-
name: Check dependencies
shell: pwsh
run: ./.github/workflows/build-exe-dependencies.ps1 ${{ matrix.bits }} ${{ matrix.link }} C:\cygwin\output C:\cygwin\usr\${{ steps.setup.outputs.mingw-host }}
-
name: Upload artifact
uses: actions/upload-artifact@v4
Expand Down

0 comments on commit 33fd145

Please sign in to comment.