From cc7ba62a130b6d25c967f09d8b39a3195e854675 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Mon, 9 May 2022 21:06:14 +0700 Subject: [PATCH 1/2] (#29, #55) CI: assert Windows dependencies of everything --- .github/workflows/main.yml | 4 +++ README.md | 6 +++++ windows/libraries.gold.txt | 52 ++++++++++++++++++++++++++++++++++++++ windows/test.ps1 | 41 ++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 windows/libraries.gold.txt create mode 100644 windows/test.ps1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 929631f..4a23b8f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -229,6 +229,10 @@ jobs: name: tdlib.windows path: ./artifacts + - name: Windows-specific testing + shell: pwsh + run: ./windows/test.ps1 + - name: Prepare package for testing shell: pwsh run: ./windows/prepare-package.ps1 diff --git a/README.md b/README.md index ca51f1a..7b8ea85 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,11 @@ If using .NET, then you'll probably need to also install [tdsharp][], and then u For other technologies or if you don't want to use tdsharp in .NET, you can just download the binaries and then use them in a manner your technology allows to use dynamically loaded libraries. Consult the [TDLib][tdlib] documentation for further directions. +Library Dependencies +-------------------- + +On Windows, [Microsoft Visual C++ Redistributable][cpp.redist] of version 2019 or higher is required by TDLib. + Documentation ------------- @@ -26,6 +31,7 @@ Documentation - [License][docs.license] - [Maintainership][docs.maintainership] +[cpp.redist]: https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-160 [docs.changelog]: ./CHANGELOG.md [docs.license]: ./LICENSE_1_0.txt [docs.maintainership]: ./MAINTAINERSHIP.md diff --git a/windows/libraries.gold.txt b/windows/libraries.gold.txt new file mode 100644 index 0000000..a3ec3fe --- /dev/null +++ b/windows/libraries.gold.txt @@ -0,0 +1,52 @@ +libcrypto-1_1-x64.dll + ADVAPI32.dll + api-ms-win-crt-convert-l1-1-0.dll + api-ms-win-crt-environment-l1-1-0.dll + api-ms-win-crt-filesystem-l1-1-0.dll + api-ms-win-crt-heap-l1-1-0.dll + api-ms-win-crt-runtime-l1-1-0.dll + api-ms-win-crt-stdio-l1-1-0.dll + api-ms-win-crt-string-l1-1-0.dll + api-ms-win-crt-time-l1-1-0.dll + api-ms-win-crt-utility-l1-1-0.dll + bcrypt.dll + CRYPT32.dll + KERNEL32.dll + USER32.dll + VCRUNTIME140.dll + WS2_32.dll +libssl-1_1-x64.dll + api-ms-win-crt-convert-l1-1-0.dll + api-ms-win-crt-runtime-l1-1-0.dll + api-ms-win-crt-stdio-l1-1-0.dll + api-ms-win-crt-string-l1-1-0.dll + api-ms-win-crt-time-l1-1-0.dll + api-ms-win-crt-utility-l1-1-0.dll + KERNEL32.dll + libcrypto-1_1-x64.dll + VCRUNTIME140.dll +tdjson.dll + api-ms-win-crt-convert-l1-1-0.dll + api-ms-win-crt-heap-l1-1-0.dll + api-ms-win-crt-math-l1-1-0.dll + api-ms-win-crt-runtime-l1-1-0.dll + api-ms-win-crt-stdio-l1-1-0.dll + api-ms-win-crt-string-l1-1-0.dll + api-ms-win-crt-time-l1-1-0.dll + CRYPT32.dll + KERNEL32.dll + libcrypto-1_1-x64.dll + libssl-1_1-x64.dll + MSVCP140.dll + Normaliz.dll + VCRUNTIME140_1.dll + VCRUNTIME140.dll + WS2_32.dll + zlib1.dll +zlib1.dll + api-ms-win-crt-convert-l1-1-0.dll + api-ms-win-crt-heap-l1-1-0.dll + api-ms-win-crt-runtime-l1-1-0.dll + api-ms-win-crt-stdio-l1-1-0.dll + KERNEL32.dll + VCRUNTIME140.dll diff --git a/windows/test.ps1 b/windows/test.ps1 new file mode 100644 index 0000000..61e3f51 --- /dev/null +++ b/windows/test.ps1 @@ -0,0 +1,41 @@ +param ( + [string] $Artifacts = "$PSScriptRoot/../artifacts", + [string] $GoldFile = "$PSScriptRoot/../windows/libraries.gold.txt", + [string] $ResultFile = "$PSScriptRoot/../windows/libraries.temp.txt", + [switch] $GenerateGold +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +Write-Output "Saving library check results to $ResultFile…" + +if (Test-Path $ResultFile) { + Remove-Item $ResultFile +} + +Get-ChildItem "$Artifacts/*.dll" | Sort-Object -Property Name | ForEach-Object { + $libraryPath = $_.FullName + + Write-Output "Checking file $libraryPath…" + $output = dumpbin /DEPENDENTS $libraryPath + if (!$?) { + throw "dumpbin /DEPENDENTS $libraryPath returned an exit code $LASTEXITCODE; output: $output" + } + + $libraryNames = $output | Where-Object { $_ -match '^ [^ ]' } | ForEach-Object { $_.TrimStart() } | Sort-Object + $_.Name >> $ResultFile + $libraryNames | ForEach-Object { " $_" >> $ResultFile } +} + +if ($GenerateGold) { + Move-Item -Force $ResultFile $GoldFile +} else { + $goldContent = Get-Content -Raw $GoldFile + $tempContent = Get-Content -Raw $ResultFile + if ($goldContent -ne $tempContent) { + Write-Output "Current contents are following:`n" + Write-Output $tempContent + throw "File contents are not equal: $GoldFile and $ResultFile" + } +} From 1738f1d11d0d15948ea72638d25bf89fe217ba62 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Tue, 10 May 2022 16:03:18 +0700 Subject: [PATCH 2/2] (#29) CI: use Dependencies instead of dumpbin --- .github/workflows/main.yml | 10 ++++++++ .gitignore | 2 ++ windows/install.ps1 | 49 ++++++++++++++++++++++++++++++++++++++ windows/libraries.gold.txt | 12 +++++----- windows/test.ps1 | 10 ++++---- 5 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 windows/install.ps1 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4a23b8f..4677bd0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -229,6 +229,16 @@ jobs: name: tdlib.windows path: ./artifacts + - name: Cache downloads for Windows + uses: actions/cache@v2 + with: + path: build/downloads + key: ${{ hashFiles('windows/install.ps1') }} + + - name: Install dependencies + shell: pwsh + run: ./windows/install.ps1 + - name: Windows-specific testing shell: pwsh run: ./windows/test.ps1 diff --git a/.gitignore b/.gitignore index c086591..2bfe820 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /.idea/ /build/ + +*.temp.txt diff --git a/windows/install.ps1 b/windows/install.ps1 new file mode 100644 index 0000000..5ae17c6 --- /dev/null +++ b/windows/install.ps1 @@ -0,0 +1,49 @@ +# NOTE: Only used in tests right now. +param ( + $DependenciesLink = 'https://github.com/lucasg/Dependencies/releases/download/v1.11.1/Dependencies_x64_Release_.without.peview.exe.zip', + $DependenciesHash = '7D22DC00F1C09FD4415D48AD74D1CF801893E83B9A39944B0FCE6DEA7CEAEA99', + $DownloadStorage = "$PSScriptRoot/../build/downloads", + $DependenciesInstallPath = "$PSScriptRoot/../build/tools/dependencies" +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version Latest + +if (!(Test-Path $DownloadStorage)) { + New-Item -Type Directory $DownloadStorage | Out-Null +} + +$dependenciesFileName = [Uri]::new($DependenciesLink).Segments | Select-Object -Last 1 +$dependenciesDownloadPath = "$DownloadStorage/$dependenciesFileName" +if (Test-Path $dependenciesDownloadPath) { + Write-Output "File `"$dependenciesDownloadPath`" already exists; checking its hash…" + $actualHash = Get-FileHash -Algorithm SHA256 $dependenciesDownloadPath + if ($actualHash.Hash -eq $DependenciesHash) { + Write-Output 'Hash check succeeded; reusing the downloaded item.' + } else { + Write-Output "Actual hash: $($actualHash.Hash)." + Write-Output "Expected hash: $DependenciesHash." + Write-Output "Deleting file for re-download…" + Remove-Item $dependenciesDownloadPath + } +} + +if (!(Test-Path $dependenciesDownloadPath)) { + Write-Output "Downloading `"$DependenciesLink`"…" + Invoke-WebRequest $DependenciesLink -OutFile $dependenciesDownloadPath +} + +$actualHash = Get-FileHash -Algorithm SHA256 $dependenciesDownloadPath +if ($actualHash.Hash -ne $DependenciesHash) { + Write-Output "Actual hash: $($actualHash.Hash)." + Write-Output "Expected hash: $DependenciesHash." + Write-Output "Hashes don't match." + throw 'Cannot download Dependencies tool.' +} + +if (Test-Path $DependenciesInstallPath) { + Remove-Item -Recurse $DependenciesInstallPath +} + +Expand-Archive $dependenciesDownloadPath $DependenciesInstallPath +Write-Output "Dependencies tool installed to directory `"$DependenciesInstallPath`"." diff --git a/windows/libraries.gold.txt b/windows/libraries.gold.txt index a3ec3fe..6db0764 100644 --- a/windows/libraries.gold.txt +++ b/windows/libraries.gold.txt @@ -1,4 +1,4 @@ -libcrypto-1_1-x64.dll +libcrypto-3-x64.dll ADVAPI32.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-environment-l1-1-0.dll @@ -15,7 +15,7 @@ libcrypto-1_1-x64.dll USER32.dll VCRUNTIME140.dll WS2_32.dll -libssl-1_1-x64.dll +libssl-3-x64.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll api-ms-win-crt-stdio-l1-1-0.dll @@ -23,7 +23,7 @@ libssl-1_1-x64.dll api-ms-win-crt-time-l1-1-0.dll api-ms-win-crt-utility-l1-1-0.dll KERNEL32.dll - libcrypto-1_1-x64.dll + libcrypto-3-x64.dll VCRUNTIME140.dll tdjson.dll api-ms-win-crt-convert-l1-1-0.dll @@ -35,12 +35,12 @@ tdjson.dll api-ms-win-crt-time-l1-1-0.dll CRYPT32.dll KERNEL32.dll - libcrypto-1_1-x64.dll - libssl-1_1-x64.dll + libcrypto-3-x64.dll + libssl-3-x64.dll MSVCP140.dll Normaliz.dll - VCRUNTIME140_1.dll VCRUNTIME140.dll + VCRUNTIME140_1.dll WS2_32.dll zlib1.dll zlib1.dll diff --git a/windows/test.ps1 b/windows/test.ps1 index 61e3f51..b22efe7 100644 --- a/windows/test.ps1 +++ b/windows/test.ps1 @@ -1,4 +1,6 @@ param ( + [string] $Dependencies = "$PSScriptRoot/../build/tools/dependencies/Dependencies.exe", + [string] $Artifacts = "$PSScriptRoot/../artifacts", [string] $GoldFile = "$PSScriptRoot/../windows/libraries.gold.txt", [string] $ResultFile = "$PSScriptRoot/../windows/libraries.temp.txt", @@ -17,13 +19,13 @@ if (Test-Path $ResultFile) { Get-ChildItem "$Artifacts/*.dll" | Sort-Object -Property Name | ForEach-Object { $libraryPath = $_.FullName - Write-Output "Checking file $libraryPath…" - $output = dumpbin /DEPENDENTS $libraryPath + Write-Output "Checking file `"$libraryPath`"…" + $output = & $Dependencies -json -imports $libraryPath | ConvertFrom-Json if (!$?) { - throw "dumpbin /DEPENDENTS $libraryPath returned an exit code $LASTEXITCODE; output: $output" + throw "Dependencies.exe returned an exit code $LASTEXITCODE." } - $libraryNames = $output | Where-Object { $_ -match '^ [^ ]' } | ForEach-Object { $_.TrimStart() } | Sort-Object + $libraryNames = $output.Imports | Select-Object -ExpandProperty Name | Sort-Object $_.Name >> $ResultFile $libraryNames | ForEach-Object { " $_" >> $ResultFile } }