diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bc771ca7e..0fe903e0e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,14 +29,6 @@ jobs: uses: actions/setup-dotnet@v5 with: dotnet-version: '10.0.x' - - name: Setup .NET 9.0 - uses: actions/setup-dotnet@v5 - with: - dotnet-version: '9.0.x' - - name: Setup .NET 8.0 - uses: actions/setup-dotnet@v5 - with: - dotnet-version: '8.0.x' # CI debug information - name: Version Information @@ -88,11 +80,8 @@ jobs: uses: actions/setup-dotnet@v5 with: dotnet-version: '10.0.x' - - name: Setup .NET 9.0 - uses: actions/setup-dotnet@v5 - with: - dotnet-version: '9.0.x' - name: Setup .NET 8.0 + if: matrix.framework == 'net8.0' uses: actions/setup-dotnet@v5 with: dotnet-version: '8.0.x' @@ -100,6 +89,14 @@ jobs: # Build & Test - name: Build run: pwsh make.ps1 + - name: NGen + if: matrix.os == 'windows-latest' && matrix.framework == 'net462' + run: ./make.ps1 ngen + shell: pwsh + - name: ReadyToRun + if: matrix.framework != 'net462' + run: ./make.ps1 -frameworks ${{ matrix.framework }} readytorun + shell: pwsh - name: Version Information (${{ matrix.framework }}) run: | $ipy = "bin/Release/${{ matrix.framework }}/ipy" diff --git a/.vsts-ci.yml b/.vsts-ci.yml index efe759131..9a1a753bb 100644 --- a/.vsts-ci.yml +++ b/.vsts-ci.yml @@ -137,20 +137,22 @@ jobs: inputs: packageType: 'sdk' version: '10.0.x' - - task: UseDotNet@2 - displayName: Install .NET 9.0 runtime for testing - inputs: - packageType: 'runtime' - version: '9.0.x' - task: UseDotNet@2 displayName: Install .NET 8.0 runtime for testing inputs: packageType: 'runtime' version: '8.0.x' + condition: eq(variables.framework, 'net8.0') # Build & Test - powershell: ./make.ps1 displayName: Build + - powershell: ./make.ps1 ngen + displayName: NGen + condition: and(succeeded(), eq(variables.osName, 'Windows'), eq(variables.framework, 'net462')) + - powershell: ./make.ps1 -frameworks $(framework) readytorun + displayName: ReadyToRun + condition: and(succeeded(), ne(variables.framework, 'net462')) - powershell: ./make.ps1 -frameworks $(framework) test-all displayName: Test ($(framework)) diff --git a/make.ps1 b/make.ps1 index 2075ca48d..19342e25d 100755 --- a/make.ps1 +++ b/make.ps1 @@ -213,6 +213,69 @@ function Test([String] $target, [String] $configuration, [String[]] $frameworks, } } +function Ngen([String] $configuration) { + if ($global:isUnix) { + Write-Warning "ngen is only available on Windows" + return + } + + $binDir = [System.IO.Path]::Combine($_BASEDIR, "bin", $configuration, "net462") + $frameworkDir = [System.IO.Path]::Combine($env:SystemRoot, "Microsoft.NET") + + # ipy.exe is AnyCPU so ngen needs to match the bitness of the process it will run as + $targets = @( + @{ exe = "ipy.exe"; framework = $(if ([System.Environment]::Is64BitOperatingSystem) { "Framework64" } else { "Framework" }) }, + @{ exe = "ipy32.exe"; framework = "Framework" } + ) + + foreach ($target in $targets) { + $exePath = [System.IO.Path]::Combine($binDir, $target.exe) + if (!(Test-Path $exePath)) { + Write-Error "Could not find $exePath, build the $configuration configuration first" + $global:Result = -1 + return + } + + $ngen = [System.IO.Path]::Combine($frameworkDir, $target.framework, "v4.0.30319", "ngen.exe") + + # installing the exe also compiles its static dependencies (IronPython, Microsoft.Scripting, etc.), + & $ngen install $exePath /nologo + if ($LastExitCode -ne 0) { $global:Result = $LastExitCode } + + # but modules loaded at runtime have to be listed explicitly and bound using the exe's configuration + $assemblies = @([System.IO.Path]::Combine($binDir, "IronPython.Modules.dll")) + @(Get-ChildItem -Path ([System.IO.Path]::Combine($binDir, "DLLs")) -Filter "IronPython.*.dll" | ForEach-Object { $_.FullName }) + foreach ($assembly in $assemblies) { + & $ngen install $assembly /ExeConfig:$exePath /nologo + if ($LastExitCode -ne 0) { $global:Result = $LastExitCode } + } + } +} + +function ReadyToRun([String] $configuration, [String[]] $frameworks) { + foreach ($framework in $frameworks) { + if ($framework -eq "net462") { + Write-Warning "ReadyToRun is not available for $framework, use the ngen target instead" + continue + } + + $binDir = [System.IO.Path]::Combine($_BASEDIR, "bin", $configuration, $framework) + $workDir = [System.IO.Path]::Combine($_BASEDIR, "obj", "ReadyToRun", $configuration, $framework) + $publishDir = [System.IO.Path]::Combine($workDir, "publish") + + # publishing for a specific runtime also produces runtime specific deps.json/runtimeconfig.json files + # so build and publish to a separate folder and only copy the precompiled assemblies over the portable build + dotnet publish ([System.IO.Path]::Combine($_BASEDIR, "src", "executables", "IronPython.Console", "IronPython.Console.csproj")) -c $configuration -f $framework --use-current-runtime --self-contained false -p:PublishReadyToRun=true "-p:OutputPath=$([System.IO.Path]::Combine($workDir, "build"))/" -o $publishDir -nologo -v minimal + if ($LastExitCode -ne 0) { + $global:Result = $LastExitCode + continue + } + + foreach ($assembly in @("ipy.dll", "IronPython.dll", "IronPython.Modules.dll", "Microsoft.Dynamic.dll", "Microsoft.Scripting.dll", "Microsoft.Scripting.Metadata.dll")) { + Copy-Item -Path ([System.IO.Path]::Combine($publishDir, $assembly)) -Destination $binDir -Force + } + } +} + function Purge() { Main "Clean" "Release" Main "Clean" "Debug" @@ -254,12 +317,8 @@ switch -wildcard ($target) { "test" { Test "all" $configuration $frameworks $platform; break } # utility targets - "ngen" { - if(!$global:isUnix) { - $imagePath = [System.IO.Path]::Combine($_BASEDIR, "bin\$configuration\net462\ipy.exe") - & "${env:SystemRoot}\Microsoft.NET\Framework\v4.0.30319\ngen.exe" install $imagePath - } - } + "ngen" { Ngen $configuration } + "readytorun" { ReadyToRun $configuration $frameworks } "purge" { Purge } default { Write-Error "No target '$target'" ; Exit -1 } diff --git a/src/executables/IronPython.Console/IronPython.Console.csproj b/src/executables/IronPython.Console/IronPython.Console.csproj index 285ff1272..efe9d2c88 100644 --- a/src/executables/IronPython.Console/IronPython.Console.csproj +++ b/src/executables/IronPython.Console/IronPython.Console.csproj @@ -13,11 +13,8 @@ - - false - Content - PreserveNewest - + + diff --git a/tests/IronPython.Tests/Cases/IronPythonCasesManifest.ini b/tests/IronPython.Tests/Cases/IronPythonCasesManifest.ini index 56bb858b6..302605c7a 100644 --- a/tests/IronPython.Tests/Cases/IronPythonCasesManifest.ini +++ b/tests/IronPython.Tests/Cases/IronPythonCasesManifest.ini @@ -60,7 +60,7 @@ Reason=Memory allocation on Mono may not match MS.NET Timeout=300000 # 5 minute timeout - slow on macOS [IronPython.test_numtypes] -Timeout=300000 # 5 minute timeout - slow in general, but should finish within 3 min +Timeout=600000 # 10 minute timeout - slow on macOS [IronPython.test_peverify] Ignore=true