Skip to content

Commit

Permalink
Move MSBuild projects out of the native build scripts (dotnet#31701)
Browse files Browse the repository at this point in the history
* Move coreclr managed tools that don't need to be published and System.Private.CoreLib into their own subsets in Subsets.props and drive their builds via Arcade instead of the coreclr scripts.

* Remove building System.Private.CoreLib from build scripts. Eventing sources TBD.

* Build packages via an Arcade subset instead of within build.cmd/build.sh

* Remove packages and test build from build.cmd. Clean up options on build.cmd and build.sh

* Generate eventing sources for System.Private.CoreLib within MSBuild instead of in the build.cmd/sh scripts. Clean up the build.sh usage documentation (lots of copy-paste errors).

* Remove check-definitions.py script and supporting goo.

* Fix eventing generation.

* Wire up  TargetArchitecture and OSGroup to coreclr's BuildArch and BuildOS to enable building System.Private.CoreLib for the correct output given the script parameters.

* Stop passing down now non-existent skiptests parameter.

* Fix coreclr .nuget rid parsing to account for linux-musl correctly.

* Update build scripts to use Arcade to build packages.

* Convert from Properties to AdditionalProperties.

* Build crossgen as part of Arcade (self-contained publish TBD).

* Pull down .NET runtime CLI for helix runs with crossgen2.

* Output crossgen2 to the BinDir/crossgen when built from the project file. Enable the test shell scripts to either resolve the dotnet CLI from the path or from relative to Core_Root if the __DotNet variable is undefined.

* Generate distro rid during windows build.

* Various fixes to get files binplaced correctly and builds to work on Linux.

* Fix search for dotnet in repo on bash.

* Remove __BuildTest variable and fix up the script.

* Fix steps in build-job to build S.P.CL before the runtime and build managed tools after the runtime.

* Fix casing typo.

* Refactor detecting system OS and Architecture.

* Fix wasm rid calculation.

* Run crossgen2 on corerun so we run it on the runtime we're going to ship it with.

* Assemble a live self-contained publish in the crossgen2 package.

* Fix init-os-and-arch resolution.

* Ensure that the runtime files we package in crossgen2 are the crossgened ones.

* Remove extraneous /bl

* Build R2RDump to a subfolder instead of the product dir.

* Seperate out the crosssgening corelib step into a separate script.

* Fix permissions on crossgen-corelib.sh

* Rename build.cmd/sh to build-runtime.cmd/sh

* Fix parameters in crossgen2determinism test.

* Run crossgen on System.Private.CoreLib in CI.

* Restore original build.cmd/sh scripts with a deprecation warning and update instructions.

* Initialize developer prompt in crossgen-corelib.cmd script so we can find DIA on CI machines.

* Make sure vs tools are enabled so we can resolve DiaSymReader.

* Call build-native instead of build.

* Fix build-native -> build-runtime.

* Fix permissions.

* Remove dead MSBuild code.

* Factor out python locating targets to make them available to the whole repo.

* PR Feedback/simplification.

* Create a self-contained deps.json for crossgen2 and add it to the package.

* Pass runtimeconfiguration as configuration for crossgen2 deps file generation.

* Try specifying rids directly in crossgen2 project to get the restore correct for the live-build pipeline.

* Run crossgen2 via corerun in R2R.SuperILC.

* Add binlogs to build-runtime.cmd

* Combine non build-runtime steps into a single step so we get one binlog that doesn't get overwritten.

* Add reference to issue describing new workflow.

* Quote python path

* Set arch default.

* PR Feedback and clean up crossgen-corelib's argument list.

* Fix subset name matching to work when one subset name is a substring of another.

* Pass the official build id as an msbuild arg at all times.
Additional cleanup for crossgen-corelib step.

* PR Feedback.

* Fix default subset list construction.

* Add deprecation warnings at beginning and end of build.cmd and build.sh.

* Setup dirs in crossgen-corelib.sh

* Move enforcepgo argument to before the official build arg so that it gets consumed correctly.

* Add cross-os DAC builds as subsets.
Clean up build-runtime parameters and passing the official build ID from runtime.proj.

* Update script usage docs.

* Skip the cross-os dac on x86.

* Build windows->linux cross dac on PR and CI.

* Don't build the cross-OS linux dac on Windows x86.
  • Loading branch information
jkoritzinsky committed Mar 4, 2020
1 parent e66e9fa commit 389835b
Show file tree
Hide file tree
Showing 43 changed files with 1,840 additions and 644 deletions.
3 changes: 2 additions & 1 deletion Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
<ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
</PropertyGroup>

<Import Project="$(RepositoryEngineeringDir)/liveBuilds.targets" />
<Import Project="$(RepositoryEngineeringDir)liveBuilds.targets" />
<Import Project="$(RepositoryEngineeringDir)python.targets" />
<Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" Condition="'$(SkipImportArcadeSdkFromRoot)' != 'true'" />

<PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions docs/workflow/building/coreclr/linux-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ To ensure that your system can allocate enough file-handles for the libraries bu
Build the Runtime and System.Private.CoreLib
=============================================

To build the runtime on Linux, run build.sh from the root of the runtime repository:
To build the runtime on Linux, run build.sh to build the CoreCLR subset category of the runtime:

```
./src/coreclr/build.sh
./build.sh -subsetCategory coreclr
```

After the build is completed, there should some files placed in `runtime/artifacts/bin/coreclr/Linux.x64.Debug`. The ones we are most interested in are:
Expand Down
10 changes: 5 additions & 5 deletions docs/workflow/building/coreclr/osx-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ brew install icu4c
brew link --force icu4c
```

Build the Runtime and Microsoft Core Library
Build the Runtime and System.Private.CoreLib
============================================

To Build CoreCLR, run build.sh from the root of the coreclr repo.
To Build CoreCLR, run build.sh to build the CoreCLR subset category of the runtime:

```sh
./src/coreclr/build.sh
```
./build.sh -subsetCategory coreclr
```

After the build has completed, there should some files placed in `artifacts/bin/coreclr/OSX.x64.Debug`. The ones we are interested in are:
Expand Down Expand Up @@ -75,4 +75,4 @@ an environment variable to the Core_Root folder.
```sh
export CORE_ROOT=/path/to/runtime/artifacts/tests/coreclr/OSX.x64.Debug/Tests/Core_Root
$CORE_ROOT/corerun hello_world.dll
```
```
87 changes: 70 additions & 17 deletions eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,19 @@
<DefaultInstallerSubsets>corehost-managed-depproj-pkgproj-bundle-installers-test</DefaultInstallerSubsets>
<!-- TODO: Split into multiple sets. -->
<DefaultLibrariesSubsets>all</DefaultLibrariesSubsets>
<DefaultCoreClrSubsets>all</DefaultCoreClrSubsets>
<DefaultCoreClrSubsets>runtime-linuxdac-corelib-nativecorelib-tools-packages</DefaultCoreClrSubsets>
<DefaultMonoSubsets>all</DefaultMonoSubsets>

<_subsetCategory Condition="'$(SubsetCategory)' != ''">$(SubsetCategory.ToLowerInvariant())</_subsetCategory>
<_subsetCategory Condition="'$(SubsetCategory)' == ''">$(DefaultSubsetCategories)</_subsetCategory>
<_subset Condition="'$(Subset)' != ''">$(Subset.ToLowerInvariant())</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('installer'))">$(DefaultInstallerSubsets)</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('libraries'))">$(_subset)$(DefaultLibrariesSubsets)</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('coreclr'))">$(_subset)$(DefaultCoreClrSubsets)</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('mono'))">$(_subset)$(DefaultMonoSubsets)</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('libraries'))">$(_subset)-$(DefaultLibrariesSubsets)</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('coreclr'))">$(_subset)-$(DefaultCoreClrSubsets)</_subset>
<_subset Condition="'$(Subset)' == '' and $(_subsetCategory.Contains('mono'))">$(_subset)-$(DefaultMonoSubsets)</_subset>

<!-- Surround _subset in dashes to simplify checks below -->
<_subset>-$(_subset)-</_subset>
</PropertyGroup>

<ItemGroup>
Expand All @@ -81,7 +84,13 @@
<SubsetName Include="All" Category="Libraries" Description="The .NET libraries comprising the shared framework." />

<!-- CoreClr -->
<SubsetName Include="All" Category="CoreClr" Description="The .NET runtime." />
<SubsetName Include="Runtime" Category="CoreClr" Description="The CoreCLR .NET runtime." />
<SubsetName Condition="$([MSBuild]::IsOsPlatform(Windows))" Include="LinuxDac" Category="CoreClr" Description="The cross-OS Windows->libc-based Linux DAC. Skipped on x86." />
<SubsetName Condition="$([MSBuild]::IsOsPlatform(Windows))" Include="AlpineDac" Category="CoreClr" OnDemand="true" Description="The cross-OS Windows->musl-libc-based Linux DAC. Skipped on x86." />
<SubsetName Include="CoreLib" Category="CoreClr" Description="The managed System.Private.CoreLib library for CoreCLR." />
<SubsetName Include="NativeCoreLib" Category="CoreClr" Description="Run crossgen on System.Private.CoreLib library for CoreCLR." />
<SubsetName Include="Tools" Category="CoreClr" Description="Managed tools that support CoreCLR development and testing." />
<SubsetName Include="Packages" Category="CoreClr" Description="The projects that produce NuGet packages for the CoreCLR runtime, crossgen, and IL tools." />

<!-- Mono -->
<SubsetName Include="All" Category="Mono" Description="The Mono .NET runtime." />
Expand All @@ -98,14 +107,26 @@
</ItemGroup>

<!-- Global sets -->
<ItemGroup Condition="$(_subset.Contains('regeneratereadmetable'))">
<ItemGroup Condition="$(_subset.Contains('-regeneratereadmetable-'))">
<ProjectToBuild Include="$(RepoToolsLocalDir)regenerate-readme-table.proj" />
</ItemGroup>

<ItemDefinitionGroup Condition="'$(CoreCLRConfiguration)' != ''">
<CoreClrProjectToBuild>
<AdditionalProperties>Configuration=$(CoreCLRConfiguration)</AdditionalProperties>
</CoreClrProjectToBuild>
<CoreClrCoreLibProjectToBuild>
<AdditionalProperties>Configuration=$(CoreCLRConfiguration)</AdditionalProperties>
</CoreClrCoreLibProjectToBuild>
<CoreClrNativeCoreLibProjectToBuild>
<AdditionalProperties>Configuration=$(CoreCLRConfiguration)</AdditionalProperties>
</CoreClrNativeCoreLibProjectToBuild>
<CoreClrManagedToolsProjectToBuild>
<AdditionalProperties>Configuration=$(CoreCLRConfiguration)</AdditionalProperties>
</CoreClrManagedToolsProjectToBuild>
<CoreClrPackagesProjectToBuild>
<AdditionalProperties>Configuration=$(CoreCLRConfiguration)</AdditionalProperties>
</CoreClrPackagesProjectToBuild>
</ItemDefinitionGroup>

<ItemDefinitionGroup Condition="'$(MonoConfiguration)' != ''">
Expand All @@ -121,58 +142,90 @@
</ItemDefinitionGroup>

<!-- CoreClr sets -->
<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('all'))">
<CoreClrProjectToBuild Include="$(CoreClrProjectRoot)coreclr.proj" BuildInParallel="false" />
<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-corelib-'))">
<CoreClrCoreLibProjectToBuild Include="$(CoreClrProjectRoot)src\System.Private.CoreLib\System.Private.CoreLib.csproj" BuildInParallel="false" />
<ProjectToBuild Include="@(CoreClrCoreLibProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-runtime-'))">
<CoreClrProjectToBuild Include="$(CoreClrProjectRoot)runtime.proj" BuildInParallel="false" />
<ProjectToBuild Include="@(CoreClrProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-linuxdac-')) and $([MSBuild]::IsOsPlatform(Windows)) and '$(TargetArchitecture)' != 'x86'">
<CoreClrLinuxDacProjectToBuild Include="$(CoreClrProjectRoot)runtime.proj" BuildInParallel="false" AdditionalProperties="%(AdditionalProperties);CrossDac=linux" />
<ProjectToBuild Include="@(CoreClrLinuxDacProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-alpinedac-')) and $([MSBuild]::IsOsPlatform(Windows)) and '$(TargetArchitecture)' != 'x86'">
<CoreClrAlpineLinuxDacProjectToBuild Include="$(CoreClrProjectRoot)runtime.proj" BuildInParallel="false" AdditionalProperties="%(AdditionalProperties);CrossDac=alpine" />
<ProjectToBuild Include="@(CoreClrAlpineLinuxDacProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-nativecorelib-'))">
<CoreClrNativeCoreLibProjectToBuild Include="$(CoreClrProjectRoot)crossgen-corelib.proj" BuildInParallel="false" />
<ProjectToBuild Include="@(CoreClrNativeCoreLibProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-tools-'))">
<CoreClrManagedToolsProjectToBuild Include="$(CoreClrProjectRoot)src\tools\runincontext\runincontext.csproj" />
<CoreClrManagedToolsProjectToBuild Include="$(CoreClrProjectRoot)src\tools\r2rdump\R2RDump.csproj" />
<CoreClrManagedToolsProjectToBuild Include="$(CoreClrProjectRoot)src\tools\ReadyToRun.SuperIlc\ReadyToRun.SuperIlc.csproj" />
<CoreClrManagedToolsProjectToBuild Include="$(CoreClrProjectRoot)src\tools\crossgen2\crossgen2\crossgen2.csproj" BuildInParallel="false" />
<ProjectToBuild Include="@(CoreClrManagedToolsProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('coreclr')) and $(_subset.Contains('-packages-'))">
<CoreClrPackagesProjectToBuild Include="$(CoreClrProjectRoot)src\.nuget\packages.builds" BuildInParallel="false" />
<ProjectToBuild Include="@(CoreClrPackagesProjectToBuild)" />
</ItemGroup>
<!-- Mono sets -->
<ItemGroup Condition="$(_subsetCategory.Contains('mono')) and $(_subset.Contains('all'))">
<ItemGroup Condition="$(_subsetCategory.Contains('mono')) and $(_subset.Contains('-all-'))">
<MonoProjectToBuild Include="$(MonoProjectRoot)mono.proj" BuildInParallel="false" />
<MonoProjectToBuild Include="$(MonoProjectRoot)netcore\System.Private.CoreLib\System.Private.CoreLib.csproj" BuildInParallel="false" />
<ProjectToBuild Include="@(MonoProjectToBuild)" />
</ItemGroup>

<!-- Libraries sets -->
<ItemGroup Condition="$(_subsetCategory.Contains('libraries')) and $(_subset.Contains('all'))">
<ItemGroup Condition="$(_subsetCategory.Contains('libraries')) and $(_subset.Contains('-all-'))">
<LibrariesProjectToBuild Include="$(LibrariesProjectRoot)build.proj" BuildInParallel="false" />
<ProjectToBuild Include="@(LibrariesProjectToBuild)" />
</ItemGroup>

<!-- Installer sets -->
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('corehost'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-corehost-'))">
<CorehostProjectToBuild Include="$(InstallerProjectRoot)corehost\build.proj" SignPhase="Binaries" />
<ProjectToBuild Include="@(CorehostProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('managed'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-managed-'))">
<ManagedProjectToBuild Include="$(InstallerProjectRoot)managed\**\*.csproj" SignPhase="Binaries" />
<ManagedProjectToBuild Include="$(InstallerProjectRoot)pkg\packaging\pack-managed.proj" />
<ProjectToBuild Include="@(ManagedProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('depproj'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-depproj-'))">
<DepprojProjectToBuild Include="$(InstallerProjectRoot)pkg\projects\**\*.depproj" SignPhase="R2RBinaries" BuildInParallel="false" />
<ProjectToBuild Include="@(DepprojProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('pkgproj'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-pkgproj-'))">
<PkgprojProjectToBuild Include="$(InstallerProjectRoot)pkg\projects\**\*.pkgproj" SignPhase="MsiFiles" BuildInParallel="false" />
<ProjectToBuild Include="@(PkgprojProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('bundle'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-bundle-'))">
<BundleProjectToBuild Include="$(InstallerProjectRoot)pkg\projects\**\*.bundleproj" SignPhase="BundleInstallerFiles" BuildInParallel="false" />
<ProjectToBuild Include="@(BundleProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('installers'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-installers-'))">
<InstallerProjectToBuild Include="$(InstallerProjectRoot)pkg\packaging\installers.proj" BuildInParallel="false" />
<InstallerProjectToBuild Include="$(InstallerProjectRoot)pkg\packaging\vs-insertion-packages.proj" BuildInParallel="false" />
<ProjectToBuild Include="@(InstallerProjectToBuild)" />
</ItemGroup>

<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('test'))">
<ItemGroup Condition="$(_subsetCategory.Contains('installer')) and $(_subset.Contains('-test-'))">
<TestProjectToBuild Include="$(InstallerProjectRoot)test\Microsoft.NET.HostModel.Tests\AppHost.Bundle.Tests\AppHost.Bundle.Tests.csproj" />
<TestProjectToBuild Include="$(InstallerProjectRoot)test\Microsoft.NET.HostModel.Tests\Microsoft.NET.HostModel.AppHost.Tests\Microsoft.NET.HostModel.AppHost.Tests.csproj" />
<TestProjectToBuild Include="$(InstallerProjectRoot)test\Microsoft.NET.HostModel.Tests\Microsoft.NET.HostModel.Bundle.Tests\Microsoft.NET.HostModel.Bundle.Tests.csproj" />
Expand Down
6 changes: 4 additions & 2 deletions eng/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Param(
[switch]$allconfigurations,
[switch]$coverage,
[string]$testscope,
[string]$arch,
[string]$arch = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant(),
[string]$subsetCategory,
[string]$subset,
[ValidateSet("Debug","Release","Checked")][string]$runtimeConfiguration,
Expand Down Expand Up @@ -146,11 +146,13 @@ foreach ($argument in $PSBoundParameters.Keys)
"framework" { $arguments += " /p:BuildTargetFramework=$($PSBoundParameters[$argument].ToLowerInvariant())" }
"os" { $arguments += " /p:OSGroup=$($PSBoundParameters[$argument])" }
"allconfigurations" { $arguments += " /p:BuildAllConfigurations=true" }
"arch" { $arguments += " /p:ArchGroup=$($PSBoundParameters[$argument]) /p:TargetArchitecture=$($PSBoundParameters[$argument])" }
"arch" { $arch = $PSBoundParameters[$argument]; $arguments += " /p:ArchGroup=$arch /p:TargetArchitecture=$arch" }
"properties" { $arguments += " " + $properties }
default { $arguments += " /p:$argument=$($PSBoundParameters[$argument])" }
}
}

$env:__DistroRid="win-$arch"

Invoke-Expression "& `"$PSScriptRoot/common/build.ps1`" $arguments"
exit $lastExitCode
27 changes: 27 additions & 0 deletions eng/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,35 @@ usage()
echo "Arguments can also be passed in with a single hyphen."
}

initDistroRid()
{
source $scriptroot/native/init-distro-rid.sh

local passedRootfsDir=""
local buildOs="$1"
local buildArch="$2"
local isCrossBuild="$3"
# For RID calculation purposes, say we are always a portable build
# All of our packages that use the distro rid (CoreCLR packages) are portable.
local isPortableBuild=1

# Only pass ROOTFS_DIR if __DoCrossArchBuild is specified.
if (( isCrossBuild == 1 )); then
passedRootfsDir=${ROOTFS_DIR}
fi
initDistroRidGlobal ${buildOs} ${buildArch} ${isPortableBuild} ${passedRootfsDir}
}

arguments=''
cmakeargs=''
extraargs=''
build=false
buildtests=false
subsetCategory=''
checkedPossibleDirectoryToBuild=false
crossBuild=0

source $scriptroot/native/init-os-and-arch.sh

# Check if an action is passed in
declare -a actions=("r" "restore" "b" "build" "buildtests" "rebuild" "t" "test" "pack" "sign" "publish" "clean")
Expand All @@ -89,6 +111,7 @@ while [[ $# > 0 ]]; do
shift 2
;;
-arch)
arch=$2
arguments="$arguments /p:ArchGroup=$2 /p:TargetArchitecture=$2"
shift 2
;;
Expand All @@ -103,6 +126,7 @@ while [[ $# > 0 ]]; do
shift 2
;;
-os)
os=$2
arguments="$arguments /p:OSGroup=$2"
shift 2
;;
Expand Down Expand Up @@ -141,6 +165,7 @@ while [[ $# > 0 ]]; do
shift 2
;;
-cross)
crossBuild=1
arguments="$arguments /p:CrossBuild=True"
shift 1
;;
Expand Down Expand Up @@ -187,6 +212,8 @@ if [ ${#actInt[@]} -eq 0 ]; then
arguments="-restore -build $arguments"
fi

initDistroRid $os $arch $crossBuild

# URL-encode space (%20) to avoid quoting issues until the msbuild call in /eng/common/tools.sh.
# In *proj files (XML docs), URL-encoded string are rendered in their decoded form.
cmakeargs="${cmakeargs// /%20}"
Expand Down
Loading

0 comments on commit 389835b

Please sign in to comment.