diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index af6e47f6..32567749 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -41,6 +41,11 @@ jobs: shell: pwsh run: swift build --verbose --build-tests + - name: Build mscorlib.winmd + working-directory: Generator + shell: pwsh + run: .\SPMPostBuild.ps1 -Config debug + - name: Test code generator working-directory: Generator shell: pwsh @@ -49,8 +54,7 @@ jobs: - name: Build WinRTComponent working-directory: InteropTests shell: pwsh - run: | - & .\SPMPrebuild.ps1 -SwiftWinRT "$Env:GITHUB_WORKSPACE\Generator\.build\debug\SwiftWinRT.exe" + run: .\SPMPrebuild.ps1 -SwiftWinRT "$Env:GITHUB_WORKSPACE\Generator\.build\debug\SwiftWinRT.exe" - name: Build InteropTests working-directory: InteropTests diff --git a/Generator/Dependencies/swift-dotnetmetadata/CMakeLists.txt b/Generator/Dependencies/swift-dotnetmetadata/CMakeLists.txt index 1d0e7fb8..236affed 100644 --- a/Generator/Dependencies/swift-dotnetmetadata/CMakeLists.txt +++ b/Generator/Dependencies/swift-dotnetmetadata/CMakeLists.txt @@ -1,7 +1,7 @@ FetchContent_Declare( swift-dotnetmetadata GIT_REPOSITORY https://github.com/tristanlabelle/swift-dotnetmetadata.git - GIT_TAG 20790178c573dcc2238fa2af8680c0e6f23f7c5e + GIT_TAG b4870688be31d889ed51da9beac466ede9f366dd SOURCE_SUBDIR "don't use cmakelists") FetchContent_MakeAvailable(swift-dotnetmetadata) diff --git a/Generator/Package.resolved b/Generator/Package.resolved index 847c6354..95852fb3 100644 --- a/Generator/Package.resolved +++ b/Generator/Package.resolved @@ -24,7 +24,7 @@ "location" : "https://github.com/tristanlabelle/swift-dotnetmetadata", "state" : { "branch" : "main", - "revision" : "20790178c573dcc2238fa2af8680c0e6f23f7c5e" + "revision" : "b4870688be31d889ed51da9beac466ede9f366dd" } } ], diff --git a/Generator/SPMPostBuild.ps1 b/Generator/SPMPostBuild.ps1 new file mode 100644 index 00000000..ee2f68fe --- /dev/null +++ b/Generator/SPMPostBuild.ps1 @@ -0,0 +1,26 @@ +<# +.SYNOPSIS +Builds mscorlib.winmd and locates it next to SwiftWinRT.exe. + +.PARAMETER Config +The build configuration that was used to build SwiftWinRT.exe. +#> +[CmdletBinding(PositionalBinding = $false)] +param( + [Parameter(Mandatory = $true)] + [string] $Config +) + +$TargetTripleArch = switch ($Env:PROCESSOR_ARCHITECTURE) { + "amd64" { "x86_64" } + "arm64" { "aarch64" } + "x86" { "i686" } + default { throw "Unsupported architecture: $Env:PROCESSOR_ARCHITECTURE" } +} + +$BinaryDir = "$PSScriptRoot\.build\$TargetTripleArch-unknown-windows-msvc\$Config" +if (-not (Test-Path $BinaryDir)) { + throw "The binary directory does not exist: $BinaryDir" +} + +& "$PSScriptRoot\.build\checkouts\swift-dotnetmetadata\WindowsMetadataCoreLibrary\Assemble.ps1" -OutputPath "$BinaryDir\mscorlib.winmd" \ No newline at end of file diff --git a/Generator/Sources/SwiftWinRT/CommandLineArguments.swift b/Generator/Sources/SwiftWinRT/CommandLineArguments.swift index ba69def2..80214034 100644 --- a/Generator/Sources/SwiftWinRT/CommandLineArguments.swift +++ b/Generator/Sources/SwiftWinRT/CommandLineArguments.swift @@ -7,6 +7,9 @@ struct CommandLineArguments: ParsableCommand { abstract: "A WinRT projections generator for Swift.") } + @Option(name: .customLong("mscorlib"), help: .init("A path to the mscorlib.winmd/dll to use. Defaults to looking for mscorlib.winmd next to the exe.", valueName: "path")) + var mscorlibPath: String? = nil + @Option(name: .customLong("reference"), help: .init("A path to a .winmd file with the APIs to project.", valueName: "file")) var references: [String] = [] diff --git a/Generator/Sources/SwiftWinRT/main.swift b/Generator/Sources/SwiftWinRT/main.swift index 62a63c8b..c920be87 100644 --- a/Generator/Sources/SwiftWinRT/main.swift +++ b/Generator/Sources/SwiftWinRT/main.swift @@ -22,12 +22,8 @@ do { let spmOptions = SPMOptions(commandLineArguments: commandLineArguments, projectionConfig: projectionConfig) let cmakeOptions = CMakeOptions(commandLineArguments: commandLineArguments, projectionConfig: projectionConfig) - // Resolve the mscorlib dependency from the .NET Framework 4 machine installation let context = WinMDLoadContext() - guard let mscorlibPath = SystemAssemblies.DotNetFramework4.mscorlibPath else { - throw AssemblyLoadError.notFound(message: "mscorlib was not found on the machine.") - } - _ = try context.load(path: mscorlibPath) + _ = try context.load(path: commandLineArguments.mscorlibPath ?? getDefaultMscorlibPath()) let projection = try createProjection( commandLineArguments: commandLineArguments, @@ -52,4 +48,12 @@ catch let error { print(error) fflush(stdout) throw error +} + +func getDefaultMscorlibPath() -> String { + Bundle.main.executableURL! + .deletingLastPathComponent() + .appendingPathComponent("mscorlib.winmd", isDirectory: false) + .path + .replacingOccurrences(of: "/", with: "\\") } \ No newline at end of file diff --git a/InteropTests/SPMPrebuild.ps1 b/InteropTests/SPMPrebuild.ps1 index ce42dd22..e20fdecf 100644 --- a/InteropTests/SPMPrebuild.ps1 +++ b/InteropTests/SPMPrebuild.ps1 @@ -18,23 +18,26 @@ $ErrorActionPreference = "Stop" if (-not $SwiftWinRT) { Write-Host -ForegroundColor Cyan "Building SwiftWinRT.exe with SPM..." - $SwiftConfiguration = "debug" + $BuildConfig = "debug" $RepoRoot = (& git.exe -C "$PSScriptRoot" rev-parse --path-format=absolute --show-toplevel).Trim() $GeneratorProjectDir = "$RepoRoot\Generator" & swift.exe build ` --package-path $GeneratorProjectDir ` - --configuration $SwiftConfiguration ` + --configuration $BuildConfig ` --build-path "$GeneratorProjectDir\.build" if ($LASTEXITCODE -ne 0) { throw "Failed to build SwiftWinRT.exe" } + & "$GeneratorProjectDir\SPMPostBuild.ps1" -Config $BuildConfig + $TargetTripleArch = switch ($Env:PROCESSOR_ARCHITECTURE) { "amd64" { "x86_64" } "arm64" { "aarch64" } "x86" { "i686" } default { throw "Unsupported architecture: $Env:PROCESSOR_ARCHITECTURE" } } - $SwiftWinRT = "$GeneratorProjectDir\.build\$TargetTripleArch-unknown-windows-msvc\$SwiftConfiguration\SwiftWinRT.exe" + + $SwiftWinRT = "$GeneratorProjectDir\.build\$TargetTripleArch-unknown-windows-msvc\$BuildConfig\SwiftWinRT.exe" } else { $SwiftWinRT = [IO.Path]::GetFullPath($SwiftWinRT)