Skip to content

Commit de75159

Browse files
[release/6.0] Create a parent CMake project for building app bundles on CI (#59154)
Backport of #58965 to release/6.0 This allows us to not run the CMake configure step separately for each libraries test suite which speeds up the build. Helps with #58549
1 parent 8da5835 commit de75159

File tree

7 files changed

+340
-84
lines changed

7 files changed

+340
-84
lines changed

eng/pipelines/runtime-staging.yml

+44-2
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,10 @@ jobs:
6565
buildConfig: Release
6666
runtimeFlavor: mono
6767
platforms:
68-
- MacCatalyst_x64
6968
- iOSSimulator_x64
7069
- tvOSSimulator_x64
7170
# don't run tests on arm64 PRs until we can get significantly more devices
7271
- ${{ if eq(variables['isFullMatrix'], true) }}:
73-
- MacCatalyst_arm64
7472
- iOSSimulator_arm64
7573
variables:
7674
# map dependencies variables to local variables
@@ -101,6 +99,50 @@ jobs:
10199
eq(variables['monoContainsChange'], true),
102100
eq(variables['isFullMatrix'], true))
103101
102+
#
103+
# MacCatalyst interp - requires AOT Compilation and Interp flags
104+
# Build the whole product using Mono and run libraries tests
105+
#
106+
- template: /eng/pipelines/common/platform-matrix.yml
107+
parameters:
108+
jobTemplate: /eng/pipelines/common/global-build-job.yml
109+
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
110+
buildConfig: Release
111+
runtimeFlavor: mono
112+
platforms:
113+
- MacCatalyst_x64
114+
# don't run tests on arm64 PRs until we can get significantly more devices
115+
- ${{ if eq(variables['isFullMatrix'], true) }}:
116+
- MacCatalyst_arm64
117+
variables:
118+
# map dependencies variables to local variables
119+
- name: librariesContainsChange
120+
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
121+
- name: monoContainsChange
122+
value: $[ dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'] ]
123+
jobParameters:
124+
testGroup: innerloop
125+
nameSuffix: AllSubsets_Mono
126+
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=adhoc /p:RunAOTCompilation=true /p:MonoForceInterpreter=true /p:BuildDarwinFrameworks=true
127+
timeoutInMinutes: 180
128+
condition: >-
129+
or(
130+
eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
131+
eq(dependencies.evaluate_paths.outputs['SetPathVars_mono.containsChange'], true),
132+
eq(dependencies.evaluate_paths.outputs['SetPathVars_installer.containsChange'], true),
133+
eq(variables['isFullMatrix'], true))
134+
# extra steps, run tests
135+
extraStepsTemplate: /eng/pipelines/libraries/helix.yml
136+
extraStepsParameters:
137+
creator: dotnet-bot
138+
interpreter: true
139+
testRunNamePrefixSuffix: Mono_$(_BuildConfig)
140+
condition: >-
141+
or(
142+
eq(variables['librariesContainsChange'], true),
143+
eq(variables['monoContainsChange'], true),
144+
eq(variables['isFullMatrix'], true))
145+
104146
#
105147
# Build the whole product using Mono and run libraries tests
106148
#

eng/testing/AppleRunnerTemplate.sh

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ if [[ "$TARGET" == "ios-device" ]]; then SCHEME_SDK=Release-iphoneos; fi
3535
if [[ "$TARGET" == "tvos-device" ]]; then SCHEME_SDK=Release-appletvos; fi
3636
if [[ "$TARGET" == "maccatalyst" ]]; then SCHEME_SDK=Release-maccatalyst; fi
3737

38+
if [[ "$TARGET" == "ios-device" || "$TARGET" == "tvos-device" ]]; then SIGNAL_APP_END="--signal-app-end"; fi
39+
3840
cd $EXECUTION_DIR
3941

4042
# it doesn't support parallel execution yet, so, here is a hand-made semaphore:
@@ -62,6 +64,7 @@ $HARNESS_RUNNER apple $XHARNESS_CMD \
6264
--targets="$TARGET" \
6365
--xcode="$XCODE_PATH" \
6466
--output-directory="$XHARNESS_OUT" \
67+
$SIGNAL_APP_END \
6568
$ADDITIONAL_ARGS
6669

6770
_exitCode=$?

eng/testing/tests.mobile.targets

+16-13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
<PropertyGroup>
33
<!-- OutDir is not set early enough to set this property in .props file. -->
44
<BundleDir>$([MSBuild]::NormalizeDirectory('$(OutDir)', 'AppBundle'))</BundleDir>
5+
<PublishDir Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(IsFunctionalTest)' != 'true'">$(AppBundleRoot)tests\$(AssemblyName)</PublishDir>
6+
<PublishDir Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(IsFunctionalTest)' == 'true'">$(AppBundleRoot)runonly\$(AssemblyName)</PublishDir>
7+
<BundleDir Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true'">$([MSBuild]::NormalizeDirectory('$(PublishDir)', 'AppBundle'))</BundleDir>
58
<RunScriptOutputPath>$([MSBuild]::NormalizePath('$(BundleDir)', '$(RunScriptOutputName)'))</RunScriptOutputPath>
69
<RunAOTCompilation Condition="'$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'tvOS'">true</RunAOTCompilation>
710

@@ -157,6 +160,10 @@
157160
<Optimized>true</Optimized>
158161
<MainLibraryFileName Condition="'$(MainLibraryFileName)' == ''">AppleTestRunner.dll</MainLibraryFileName>
159162
<_MobileIntermediateOutputPath Condition="'$(RunAOTCompilation)' == 'true'">$(IntermediateOutputPath)mobile</_MobileIntermediateOutputPath>
163+
<GenerateXcodeProject>true</GenerateXcodeProject>
164+
<GenerateCMakeProject>false</GenerateCMakeProject>
165+
<GenerateXcodeProject Condition="'$(UseAppBundleRootForBuildingTests)' == 'true'">false</GenerateXcodeProject>
166+
<GenerateCMakeProject Condition="'$(UseAppBundleRootForBuildingTests)' == 'true' and '$(IgnoreForCI)' != 'true'">true</GenerateCMakeProject>
160167
</PropertyGroup>
161168
<PropertyGroup>
162169
<AOTMode Condition="'$(TargetOS)' != 'MacCatalyst'">Full</AOTMode>
@@ -214,34 +221,30 @@
214221
ForceInterpreter="$(MonoForceInterpreter)"
215222
InvariantGlobalization="$(InvariantGlobalization)"
216223
UseConsoleUITemplate="True"
217-
GenerateXcodeProject="True"
218-
BuildAppBundle="True"
224+
GenerateXcodeProject="$(GenerateXcodeProject)"
225+
GenerateCMakeProject="$(GenerateCMakeProject)"
226+
BuildAppBundle="$(GenerateXcodeProject)"
219227
Optimized="$(Optimized)"
220228
DevTeamProvisioning="$(DevTeamProvisioning)"
221229
OutputDirectory="$(BundleDir)"
222230
AppDir="$(PublishDir)">
223231
<Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" />
224232
<Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" />
225233
</AppleAppBuilderTask>
226-
<Message Importance="High" Text="Xcode: $(XcodeProjectPath)"/>
227-
<Message Importance="High" Text="App: $(AppBundlePath)"/>
234+
<Message Importance="High" Text="Xcode: $(XcodeProjectPath)" Condition="'$(GenerateXcodeProject)' == 'true'" />
235+
<Message Importance="High" Text="App: $(AppBundlePath)" Condition="'$(GenerateXcodeProject)' == 'true'"/>
228236

229-
<ItemGroup>
237+
<ItemGroup Condition="'$(GenerateXcodeProject)' == 'true'">
230238
<_appFiles Include="$(AppBundlePath)/../**/*" />
231239
</ItemGroup>
232240

233241
<Copy SourceFiles="@(_appFiles)"
234242
DestinationFolder="$(TestArchiveTestsDir)/%(RecursiveDir)"
235243
SkipUnchangedFiles="true"
236-
Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'" />
237-
238-
<RemoveDir Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'" Directories="$(AppBundlePath)" />
239-
<ItemGroup>
240-
<_removeFiles Include="$(OutDir)*.*" />
241-
</ItemGroup>
244+
Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(GenerateXcodeProject)' == 'true'" />
242245

243-
<Delete Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true' and '$(OutDir)' != ''" Files="@(_removeFiles)" />
244-
<RemoveDir Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'" Directories="$(PublishDir)" />
246+
<RemoveDir Condition="'$(ArchiveTests)' == 'true' and '$(IgnoreForCI)' != 'true'"
247+
Directories="$(OutDir)" />
245248
</Target>
246249

247250
<!-- This .targets file is also imported by the runtime Trimming tests, and we want to be able to manually configure trimming in them so this

src/libraries/Directory.Build.props

+3
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@
116116
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>
117117
<TestArchiveRuntimeRoot>$(TestArchiveRoot)runtime/</TestArchiveRuntimeRoot>
118118

119+
<UseAppBundleRootForBuildingTests Condition="'$(ArchiveTests)' == 'true' and ('$(TargetOS)' == 'MacCatalyst' or '$(TargetOS)' == 'iOS' or '$(TargetOS)' == 'iOSSimulator' or '$(TargetOS)' == 'tvOS' or '$(TargetOS)' == 'tvOSSimulator')">true</UseAppBundleRootForBuildingTests>
120+
<AppBundleRoot Condition="'$(UseAppBundleRootForBuildingTests)' == 'true'">$(ArtifactsDir)bundles\</AppBundleRoot>
121+
119122
<NetCoreAppCurrentRefPath>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'ref', '$(NetCoreAppCurrent)'))</NetCoreAppCurrentRefPath>
120123
<NetCoreAppCurrentRuntimePath>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'runtime', '$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)'))</NetCoreAppCurrentRuntimePath>
121124

src/libraries/tests.proj

+79
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,85 @@
326326
Condition="'$(TestAssemblies)' == 'true' and
327327
'$(Coverage)' == 'true'" />
328328

329+
<!-- Build Apple app bundles using AppBundleRoot -->
330+
<UsingTask Condition="'$(UseAppBundleRootForBuildingTests)' == 'true'"
331+
TaskName="XcodeCreateProject"
332+
AssemblyFile="$(AppleAppBuilderTasksAssemblyPath)" />
333+
334+
<UsingTask Condition="'$(UseAppBundleRootForBuildingTests)' == 'true'"
335+
TaskName="XcodeBuildApp"
336+
AssemblyFile="$(AppleAppBuilderTasksAssemblyPath)" />
337+
338+
<Target Condition="'$(UseAppBundleRootForBuildingTests)' == 'true'"
339+
Name="BuildAppleAppBundles"
340+
AfterTargets="Build">
341+
342+
<PropertyGroup>
343+
<!-- TODO: Unify this with TestArchiveTestsRoot in src/libraries/Directory.Build.props somehow,
344+
we can't use IsFunctionalTest==true here because it is only set in the context of the .csproj -->
345+
<TestArchiveNormalTestsRoot>$(TestArchiveRoot)tests/</TestArchiveNormalTestsRoot>
346+
<TestArchiveFunctionalTestsRoot>$(TestArchiveRoot)runonly/</TestArchiveFunctionalTestsRoot>
347+
348+
<TestArchiveNormalTestsDir>$(TestArchiveNormalTestsRoot)$(OSPlatformConfig)/</TestArchiveNormalTestsDir>
349+
<TestArchiveFunctionalTestsDir>$(TestArchiveFunctionalTestsRoot)$(OSPlatformConfig)/</TestArchiveFunctionalTestsDir>
350+
351+
<NormalTestsAppBundleRoot>$(AppBundleRoot)/tests/</NormalTestsAppBundleRoot>
352+
<FunctionalTestsAppBundleRoot>$(AppBundleRoot)/runonly/</FunctionalTestsAppBundleRoot>
353+
354+
<NormalTestsAllAppBundlesRoot>$(AppBundleRoot)/tests.all/</NormalTestsAllAppBundlesRoot>
355+
<FunctionalTestsAllAppBundlesRoot>$(AppBundleRoot)/runonly.all/</FunctionalTestsAllAppBundlesRoot>
356+
</PropertyGroup>
357+
358+
<ItemGroup>
359+
<NormalTestAppBundles Include="$(NormalTestsAppBundleRoot)*/AppBundle/CMakeLists.txt" />
360+
<NormalTestCMakeEntries Include="cmake_minimum_required(VERSION 3.16)" />
361+
<NormalTestCMakeEntries Include="project(NormalTestAppBundles)" />
362+
<NormalTestCMakeEntries Include="add_subdirectory(%(NormalTestAppBundles.RootDir)%(NormalTestAppBundles.Directory) %(NormalTestAppBundles.RecursiveDir) EXCLUDE_FROM_ALL)" />
363+
364+
<FunctionalTestAppBundles Include="$(FunctionalTestsAppBundleRoot)*/AppBundle/CMakeLists.txt" />
365+
<FunctionalTestCMakeEntries Include="cmake_minimum_required(VERSION 3.16)" />
366+
<FunctionalTestCMakeEntries Include="project(FunctionalTestAppBundles)" />
367+
<FunctionalTestCMakeEntries Include="add_subdirectory(%(FunctionalTestAppBundles.RootDir)%(FunctionalTestAppBundles.Directory) %(FunctionalTestAppBundles.RecursiveDir) EXCLUDE_FROM_ALL)" />
368+
</ItemGroup>
369+
370+
<WriteLinesToFile File="$(NormalTestsAllAppBundlesRoot)CMakeLists.txt" Lines="@(NormalTestCMakeEntries)" Overwrite="true" WriteOnlyWhenDifferent="true" />
371+
<WriteLinesToFile File="$(FunctionalTestsAllAppBundlesRoot)CMakeLists.txt" Lines="@(FunctionalTestCMakeEntries)" Overwrite="true" WriteOnlyWhenDifferent="true" />
372+
373+
<XcodeCreateProject
374+
TargetOS="$(TargetOS)"
375+
Arch="$(TargetArchitecture)"
376+
ProjectName="NormalTestAppBundles"
377+
CMakeListsDirectory="$(NormalTestsAllAppBundlesRoot)"
378+
Condition="'@(NormalTestAppBundles)' != ''" />
379+
380+
<XcodeCreateProject
381+
TargetOS="$(TargetOS)"
382+
Arch="$(TargetArchitecture)"
383+
ProjectName="FunctionalTestAppBundles"
384+
CMakeListsDirectory="$(FunctionalTestsAllAppBundlesRoot)"
385+
Condition="'@(FunctionalTestAppBundles)' != ''" />
386+
387+
<MakeDir Directories="$(TestArchiveNormalTestsDir)" />
388+
<MakeDir Directories="$(TestArchiveFunctionalTestsDir)" />
389+
390+
<ItemGroup>
391+
<!-- xcodeproj are directories, not files -->
392+
<XcodeProjects Condition="'@(NormalTestAppBundles)' != ''" Include="$([System.IO.Directory]::GetDirectories('$(NormalTestsAllAppBundlesRoot)NormalTestAppBundles/%(NormalTestAppBundles.RecursiveDir)', '*.xcodeproj'))" DestinationFolder="$(TestArchiveNormalTestsDir)" />
393+
<XcodeProjects Condition="'@(FunctionalTestAppBundles)' != ''" Include="$([System.IO.Directory]::GetDirectories('$(FunctionalTestsAllAppBundlesRoot)FunctionalTestAppBundles/%(FunctionalTestAppBundles.RecursiveDir)', '*.xcodeproj'))" DestinationFolder="$(TestArchiveFunctionalTestsDir)" />
394+
</ItemGroup>
395+
396+
<XcodeBuildApp
397+
TargetOS="$(TargetOS)"
398+
Arch="$(TargetArchitecture)"
399+
XcodeProjectPath="%(XcodeProjects.Identity)"
400+
DevTeamProvisioning="$(DevTeamProvisioning)"
401+
Optimized="True"
402+
DestinationFolder="%(XcodeProjects.DestinationFolder)" />
403+
404+
<RemoveDir Condition="'$(ArchiveTests)' == 'true'"
405+
Directories="$(AppBundleRoot)" />
406+
</Target>
407+
329408
<!-- Restoring all trimming test projects upfront in one single call to RestoreTrimmingProjects
330409
so as to avoid possible race conditions that could happen if we restore each individually. -->
331410
<Target Name="RestoreTrimmingProjects"

src/tasks/AppleAppBuilder/AppleAppBuilder.cs

+16-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class AppleAppBuilderTask : Task
1515
private string targetOS = TargetNames.iOS;
1616

1717
/// <summary>
18-
/// The Apple OS we are targeting (iOS or tvOS)
18+
/// The Apple OS we are targeting (ios, tvos, iossimulator, tvossimulator)
1919
/// </summary>
2020
[Required]
2121
public string TargetOS
@@ -64,7 +64,7 @@ public string TargetOS
6464
public ITaskItem[] Assemblies { get; set; } = Array.Empty<ITaskItem>();
6565

6666
/// <summary>
67-
/// Target arch, can be "arm64" (device) or "x64" (simulator) at the moment
67+
/// Target arch, can be "arm64", "arm" or "x64" at the moment
6868
/// </summary>
6969
[Required]
7070
public string Arch { get; set; } = ""!;
@@ -106,6 +106,11 @@ public string TargetOS
106106
/// </summary>
107107
public bool GenerateXcodeProject { get; set; }
108108

109+
/// <summary>
110+
/// Generate CMake project
111+
/// </summary>
112+
public bool GenerateCMakeProject { get; set; }
113+
109114
/// <summary>
110115
/// Files to be ignored in AppDir
111116
/// </summary>
@@ -224,14 +229,12 @@ public override bool Execute()
224229
throw new ArgumentException("Using DiagnosticPorts require diagnostics_tracing runtime component.");
225230
}
226231

232+
var generator = new Xcode(Log, TargetOS, Arch);
233+
227234
if (GenerateXcodeProject)
228235
{
229-
Xcode generator = new Xcode(Log, TargetOS, Arch);
230-
generator.EnableRuntimeLogging = EnableRuntimeLogging;
231-
generator.DiagnosticPorts = DiagnosticPorts;
232-
233236
XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles, assemblerFilesToLink,
234-
AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, RuntimeComponents, NativeMainSource);
237+
AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, EnableRuntimeLogging, DiagnosticPorts, RuntimeComponents, NativeMainSource);
235238

236239
if (BuildAppBundle)
237240
{
@@ -242,10 +245,15 @@ public override bool Execute()
242245
}
243246
else
244247
{
245-
AppBundlePath = generator.BuildAppBundle(XcodeProjectPath, Arch, Optimized, DevTeamProvisioning);
248+
AppBundlePath = generator.BuildAppBundle(XcodeProjectPath, Optimized, DevTeamProvisioning);
246249
}
247250
}
248251
}
252+
else if (GenerateCMakeProject)
253+
{
254+
generator.GenerateCMake(ProjectName, MainLibraryFileName, assemblerFiles, assemblerFilesToLink,
255+
AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, ForceAOT, ForceInterpreter, InvariantGlobalization, Optimized, EnableRuntimeLogging, DiagnosticPorts, RuntimeComponents, NativeMainSource);
256+
}
249257

250258
return true;
251259
}

0 commit comments

Comments
 (0)