Skip to content

Commit 30d5b3c

Browse files
authored
Merge branch 'main' into dev/rolf/avfoundation
2 parents bfe8634 + b27c03d commit 30d5b3c

File tree

27 files changed

+346
-156
lines changed

27 files changed

+346
-156
lines changed

docs/building-apps/build-properties.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,30 @@ only scan libraries with the `[LinkWith]` attribute for Objective-C classes:
779779
</PropertyGroup>
780780
```
781781

782+
## SkipStaticLibraryValidation
783+
784+
Hot Restart doesn't support linking with static libraries, so by default we'll
785+
show an error if the project tries to link with any static libraries when
786+
using Hot Restart.
787+
788+
However, in some cases it might be useful to ignore such errors (for instance if testing a code path in the app that doesn't require the static library in question), so it's possible to ignore them.
789+
790+
The valid values are:
791+
792+
* "true", "disable": Completely disable the validation.
793+
* "false", "error", empty string: Enable the validation (this is the default)
794+
* "warn": Validate, but show warnings instead of errors.
795+
796+
Example:
797+
798+
```xml
799+
<PropertyGroup>
800+
<SkipStaticLibraryValidation>warn</SkipStaticLibraryValidation>
801+
</PropertyGroup>
802+
```
803+
804+
This will show warnings instead of errors if the project tries to link with a static library.
805+
782806
## StripPath
783807

784808
The full path to the `strip` command-line tool.

msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,4 +1662,27 @@
16621662
<data name="E7136" xml:space="preserve">
16631663
<value>Unknown resource type: {1}.</value>
16641664
</data>
1665+
1666+
<data name="E7141" xml:space="preserve">
1667+
<value>The library {0} is a static library, and static libraries are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.</value>
1668+
<comment>
1669+
The following are literal names and should not be translated: SkipStaticLibraryValidation, true
1670+
{0}: the path to a file
1671+
</comment>
1672+
</data>
1673+
1674+
<data name="E7142" xml:space="preserve">
1675+
<value>Unknown value for 'SkipStaticLibraryValidation': {0}. Valid values are: 'true', 'false', 'warn'.</value>
1676+
<comment>
1677+
The following are literal names and should not be translated: SkipStaticLibraryValidation
1678+
</comment>
1679+
</data>
1680+
1681+
<data name="E7143" xml:space="preserve">
1682+
<value>The file {0} is an object file, and object files are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.</value>
1683+
<comment>
1684+
The following are literal names and should not be translated: SkipStaticLibraryValidation, true
1685+
{0}: the path to a file
1686+
</comment>
1687+
</data>
16651688
</root>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
8+
using Microsoft.Build.Framework;
9+
using Microsoft.Build.Utilities;
10+
11+
using Xamarin.Localization.MSBuild;
12+
using Xamarin.Messaging.Build.Client;
13+
using Xamarin.Utils;
14+
15+
namespace Xamarin.MacDev.Tasks {
16+
public class ValidateNoStaticLibraries : Task {
17+
public string SkipStaticLibraryValidation { get; set; } = string.Empty;
18+
public ITaskItem [] ValidateItems { get; set; } = Array.Empty<ITaskItem> ();
19+
20+
public override bool Execute ()
21+
{
22+
bool onlyWarn = false;
23+
switch (SkipStaticLibraryValidation.ToLowerInvariant ()) {
24+
case "true":
25+
case "disable":
26+
return true;
27+
case "":
28+
case "error":
29+
case "false":
30+
onlyWarn = false;
31+
break;
32+
case "warn":
33+
onlyWarn = true;
34+
break;
35+
default:
36+
Log.LogError (7142, null, MSBStrings.E7142, SkipStaticLibraryValidation); // Unknown value for 'SkipStaticLibraryValidation': {0}. Valid values are: 'true', 'false', 'warn'.
37+
return false;
38+
}
39+
40+
foreach (var item in ValidateItems) {
41+
var path = item.ItemSpec;
42+
if (Directory.Exists (path))
43+
continue; // directories are neither static libraries nor object files.
44+
45+
if (!File.Exists (path)) {
46+
if (onlyWarn) {
47+
Log.LogWarning (158, path, MSBStrings.E0158 /* The file '{0}' does not exist. */, path);
48+
} else {
49+
Log.LogError (158, path, MSBStrings.E0158 /* The file '{0}' does not exist. */, path);
50+
}
51+
continue;
52+
}
53+
54+
if (!MachO.IsStaticLibraryOrObjectFile (path, throw_if_error: false, out var objectFile))
55+
continue;
56+
57+
if (objectFile) {
58+
if (onlyWarn) {
59+
Log.LogWarning (7143, item.ItemSpec, MSBStrings.E7143, path); // The file {0} is an object file, and an object files are not supported with Hot Restart.
60+
} else {
61+
Log.LogError (7143, item.ItemSpec, MSBStrings.E7143, path); // The file {0} is an object file, and an object files are not supported with Hot Restart.
62+
}
63+
} else {
64+
if (onlyWarn) {
65+
Log.LogWarning (7141, item.ItemSpec, MSBStrings.E7141, path); // The library {0} is a static library, and static libraries are not supported with Hot Restart.
66+
} else {
67+
Log.LogError (7141, item.ItemSpec, MSBStrings.E7141, path); // The library {0} is a static library, and static libraries are not supported with Hot Restart.
68+
}
69+
}
70+
}
71+
72+
return !Log.HasLoggedErrors;
73+
}
74+
}
75+
}

msbuild/Xamarin.Shared/Xamarin.Shared.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
104104
<UsingTask TaskName="Xamarin.MacDev.Tasks.UnpackLibraryResources" AssemblyFile="$(_TaskAssemblyName)" />
105105
<UsingTask TaskName="Xamarin.MacDev.Tasks.Unzip" AssemblyFile="$(_TaskAssemblyName)" />
106106
<UsingTask TaskName="Xamarin.MacDev.Tasks.ValidateAppBundleTask" AssemblyFile="$(_TaskAssemblyName)" />
107+
<UsingTask TaskName="Xamarin.MacDev.Tasks.ValidateNoStaticLibraries" AssemblyFile="$(_TaskAssemblyName)" />
107108
<UsingTask TaskName="Xamarin.MacDev.Tasks.WriteAppManifest" AssemblyFile="$(_TaskAssemblyName)" />
108109
<UsingTask TaskName="Xamarin.MacDev.Tasks.WriteAssetPackManifest" AssemblyFile="$(_TaskAssemblyName)" />
109110
<UsingTask TaskName="Xamarin.MacDev.Tasks.WriteItemsToFile" AssemblyFile="$(_TaskAssemblyName)" />

msbuild/Xamarin.iOS.Tasks.Windows/Xamarin.iOS.HotRestart.targets

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@
5252

5353
</Target>
5454

55-
<Target Name="_CollectHotRestartBundleContent" DependsOnTargets="_GenerateBundleName;_ParseBundlerArguments;_ComputeTargetArchitectures;_ComputeVariables;_CollectDecompressedPlugIns;_CollectDecompressedXpcServices">
55+
<Target Name="_ValidateNoStaticLibraries">
56+
<ValidateNoStaticLibraries
57+
SkipStaticLibraryValidation="$(SkipStaticLibraryValidation)"
58+
ValidateItems="@(ResolvedFileToPublish);@(_FileNativeReference);@(_FrameworkNativeReference);@(_DecompressedPlugIns);@(_PlugIns);@(_DecompressedXpcServices);@(_XpcServices)"
59+
/>
60+
</Target>
61+
62+
<Target Name="_CollectHotRestartBundleContent" DependsOnTargets="_GenerateBundleName;_ParseBundlerArguments;_ComputeTargetArchitectures;_ComputeVariables;_CollectDecompressedPlugIns;_CollectDecompressedXpcServices;_ValidateNoStaticLibraries">
5663
<!-- Collect everything to put in the app bundle, except static frameworks -->
5764
<FilterStaticFrameworks
5865
OnlyFilterFrameworks="true"

tests/dotnet/BundleStructure/shared.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
<RootTestsDirectory Condition="'$(RootTestsDirectory)' == ''">$(MSBuildThisFileDirectory)/../..</RootTestsDirectory>
1313
<!-- disable IL stripping, because some of our assemblies aren't actually assemblies, they're just placeholder files -->
1414
<EnableAssemblyILStripping>false</EnableAssemblyILStripping>
15+
16+
<!-- Skip static library validation for Hot Restart, we have some static libraries here we don't care about at runtime -->
17+
<SkipStaticLibraryValidation>warn</SkipStaticLibraryValidation>
1518
</PropertyGroup>
1619

1720
<Import Project="../../common/shared-dotnet.csproj" />

tests/dotnet/UnitTests/WindowsTest.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,26 @@ public void RemoteTest (ApplePlatform platform, string runtimeIdentifiers)
361361
Assert.AreEqual ("3.14", infoPlist.GetString ("CFBundleVersion").Value, "CFBundleVersion");
362362
Assert.AreEqual ("3.14", infoPlist.GetString ("CFBundleShortVersionString").Value, "CFBundleShortVersionString");
363363
}
364+
365+
[Test]
366+
[Category ("Windows")]
367+
[TestCase ("NativeFileReferencesApp", ApplePlatform.iOS, "ios-arm64")]
368+
public void StaticLibrariesWithHotRestart (string project, ApplePlatform platform, string runtimeIdentifier)
369+
{
370+
Configuration.IgnoreIfIgnoredPlatform (platform);
371+
Configuration.AssertRuntimeIdentifiersAvailable (platform, runtimeIdentifier);
372+
Configuration.IgnoreIfNotOnWindows ();
373+
374+
var project_path = GetProjectPath (project, runtimeIdentifiers: runtimeIdentifier, platform: platform, out var _);
375+
Clean (project_path);
376+
var properties = GetDefaultProperties (runtimeIdentifier, GetHotRestartProperties ());
377+
var rv = DotNet.AssertBuildFailure (project_path, properties);
378+
var errors = BinLog.GetBuildLogErrors (rv.BinLogPath).ToList ();
379+
AssertErrorMessages (errors,
380+
$@"The library ..\..\..\test-libraries\.libs\iossimulator\libtest.a is a static library, and static libraries are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.",
381+
$@"The library ..\..\..\test-libraries\.libs\iossimulator\libtest2.a is a static library, and static libraries are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error."
382+
);
383+
}
364384
}
365385

366386
public class AppBundleInfo {

tests/monotouch-test/System.Net.Http/MessageHandlers.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ public void AcceptSslCertificatesServicePointManager (Type handlerType)
592592
}
593593

594594
#if NET
595+
[Ignore ("https://github.com/xamarin/xamarin-macios/issues/21912")]
595596
[TestCase ("https://self-signed.badssl.com/")]
596597
[TestCase ("https://wrong.host.badssl.com/")]
597598
public void AcceptSslCertificatesWithCustomValidationCallbackNSUrlSessionHandler (string url)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.IO;
5+
using System.Linq;
6+
using Microsoft.Build.Utilities;
7+
using NUnit.Framework;
8+
9+
using Xamarin.Tests;
10+
using Xamarin.Utils;
11+
12+
namespace Xamarin.MacDev.Tasks {
13+
[TestFixture]
14+
public class ValidateNoStaticLibrariesTests : TestBase {
15+
ValidateNoStaticLibraries CreateTask (string skipStaticLibraryValidation, params string [] paths)
16+
{
17+
var task = CreateTask<ValidateNoStaticLibraries> ();
18+
task.SkipStaticLibraryValidation = skipStaticLibraryValidation;
19+
task.ValidateItems = paths.Select (v => new TaskItem (v)).ToArray ();
20+
return task;
21+
}
22+
23+
[Test]
24+
[TestCase ("error")]
25+
[TestCase ("false")]
26+
[TestCase ("")]
27+
public void StaticLibraries_Error (string skipStaticLibraryValidation)
28+
{
29+
var paths = new [] {
30+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libtest.a"),
31+
Path.Combine (Configuration.RootPath, "README.md"),
32+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libframework.dylib"),
33+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework", "SwiftTest"),
34+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework", "Info.plist"),
35+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "XStaticArTest.framework", "XStaticArTest"),
36+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "XStaticObjectTest.framework", "XStaticObjectTest"),
37+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "XTest.framework", "XTest"),
38+
};
39+
var task = CreateTask (skipStaticLibraryValidation, paths);
40+
ExecuteTask (task, expectedErrorCount: 3);
41+
Assert.AreEqual (0, Engine.Logger.WarningsEvents.Count, "Warning Count");
42+
Assert.AreEqual ($"The library {paths [0]} is a static library, and static libraries are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.", Engine.Logger.ErrorEvents [0].Message, "Error message 1");
43+
Assert.AreEqual ($"The library {paths [5]} is a static library, and static libraries are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.", Engine.Logger.ErrorEvents [1].Message, "Error message 2");
44+
Assert.AreEqual ($"The file {paths [6]} is an object file, and object files are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.", Engine.Logger.ErrorEvents [2].Message, "Error message 3");
45+
}
46+
47+
[Test]
48+
[TestCase ("warn")]
49+
public void StaticLibraries_Warn (string skipStaticLibraryValidation)
50+
{
51+
var paths = new [] {
52+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libtest.a"),
53+
Path.Combine (Configuration.RootPath, "README.md"),
54+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libframework.dylib"),
55+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework/SwiftTest"),
56+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework/Info.plist"),
57+
};
58+
var task = CreateTask (skipStaticLibraryValidation, paths);
59+
ExecuteTask (task, expectedErrorCount: 0);
60+
Assert.AreEqual (1, Engine.Logger.WarningsEvents.Count, "Warning Count");
61+
Assert.AreEqual ($"The library {paths [0]} is a static library, and static libraries are not supported with Hot Restart. Set 'SkipStaticLibraryValidation=true' in the project file to ignore this error.", Engine.Logger.WarningsEvents [0].Message, "Error message");
62+
}
63+
64+
[Test]
65+
[TestCase ("disable")]
66+
public void StaticLibraries_Disabled (string skipStaticLibraryValidation)
67+
{
68+
var paths = new [] {
69+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libtest.a"),
70+
Path.Combine (Configuration.RootPath, "README.md"),
71+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libframework.dylib"),
72+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework/SwiftTest"),
73+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework/Info.plist"),
74+
"/does/not/exist",
75+
};
76+
var task = CreateTask (skipStaticLibraryValidation, paths);
77+
ExecuteTask (task, expectedErrorCount: 0);
78+
Assert.AreEqual (0, Engine.Logger.WarningsEvents.Count, "Warning Count");
79+
}
80+
81+
[Test]
82+
[TestCase ("invalid")]
83+
public void StaticLibraries_Invalid (string skipStaticLibraryValidation)
84+
{
85+
var paths = new [] {
86+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libtest.a"),
87+
Path.Combine (Configuration.RootPath, "README.md"),
88+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "libframework.dylib"),
89+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework/SwiftTest"),
90+
Path.Combine (Configuration.RootPath, "tests", "test-libraries", ".libs", "iossimulator", "SwiftTest.framework/Info.plist"),
91+
"/does/not/exist",
92+
};
93+
var task = CreateTask (skipStaticLibraryValidation, paths);
94+
ExecuteTask (task, expectedErrorCount: 1);
95+
Assert.AreEqual (0, Engine.Logger.WarningsEvents.Count, "Warning Count");
96+
Assert.AreEqual ($"Unknown value for 'SkipStaticLibraryValidation': {skipStaticLibraryValidation}. Valid values are: 'true', 'false', 'warn'.", Engine.Logger.ErrorEvents [0].Message, "Error Message");
97+
}
98+
99+
[Test]
100+
[TestCase ("")]
101+
[TestCase ("error")]
102+
public void StaticLibraries_Error_Inexistent (string skipStaticLibraryValidation)
103+
{
104+
var task = CreateTask (skipStaticLibraryValidation, "/does/not/exist");
105+
ExecuteTask (task, expectedErrorCount: 1);
106+
Assert.AreEqual (0, Engine.Logger.WarningsEvents.Count, "Warning Count");
107+
Assert.AreEqual ($"The file '/does/not/exist' does not exist.", Engine.Logger.ErrorEvents [0].Message.TrimEnd (), "Error Message");
108+
}
109+
110+
[Test]
111+
[TestCase ("warn")]
112+
public void StaticLibraries_Warn_Inexistent (string skipStaticLibraryValidation)
113+
{
114+
var task = CreateTask (skipStaticLibraryValidation, "/does/not/exist");
115+
ExecuteTask (task, expectedErrorCount: 0);
116+
Assert.AreEqual (1, Engine.Logger.WarningsEvents.Count, "Warning Count");
117+
Assert.AreEqual ($"The file '/does/not/exist' does not exist.", Engine.Logger.WarningsEvents [0].Message.TrimEnd (), "Error Message");
118+
}
119+
}
120+
}

tests/rgen/Microsoft.Macios.Generator.Tests/DataModel/PropertyTests.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public void BackingFieldTests (string propertyName)
2626
type: "string",
2727
isBlittable: false,
2828
isSmartEnum: false,
29+
isReferenceType: false,
2930
symbolAvailability: new (),
3031
attributes: [],
3132
modifiers: [],
@@ -281,7 +282,7 @@ public void CompareDiffAccessors ()
281282
[Fact]
282283
public void CompareDiffAccessorsExportData ()
283284
{
284-
var x = new Property ("First", "string", false, false, new (), [
285+
var x = new Property ("First", "string", false, false, false, new (), [
285286
new ("Attr1"),
286287
new ("Attr2"),
287288
], [
@@ -295,7 +296,7 @@ public void CompareDiffAccessorsExportData ()
295296
modifiers: []
296297
),
297298
]);
298-
var y = new Property ("First", "int", false, false, new (), [
299+
var y = new Property ("First", "int", false, false, false, new (), [
299300
new ("Attr1"),
300301
new ("Attr2"),
301302
], [
@@ -392,22 +393,29 @@ public class TestClass {
392393
isSmartEnum: false,
393394
isReferenceType: true,
394395
symbolAvailability: new (),
395-
attributes: [],
396+
attributes: [
397+
new ("ObjCBindings.ExportAttribute<ObjCBindings.Property>", ["name"]),
398+
],
396399
modifiers: [
397400
SyntaxFactory.Token (SyntaxKind.PublicKeyword),
398401
],
399402
accessors: [
400-
new (AccessorKind.Getter, new (), [], [])
401-
])
403+
new (AccessorKind.Getter, new (), null, [], [])
404+
]
405+
) {
406+
ExportPropertyData = new ("name"),
407+
}
402408
];
403409

404410
const string valueTypeProperty = @"
405411
using System;
412+
using ObjCBindings;
406413
407414
namespace Test;
408415
409416
public class TestClass {
410417
418+
[Export<Property>(""name"")]
411419
public int Name { get; }
412420
}
413421
";
@@ -461,6 +469,7 @@ public string Name {
461469
type: "string",
462470
isBlittable: false,
463471
isSmartEnum: false,
472+
isReferenceType: true,
464473
symbolAvailability: new (),
465474
attributes: [
466475
new ("ObjCBindings.ExportAttribute<ObjCBindings.Property>", ["name"]),
@@ -556,6 +565,7 @@ internal string Name {
556565
type: "string",
557566
isBlittable: false,
558567
isSmartEnum: false,
568+
isReferenceType: true,
559569
symbolAvailability: new (),
560570
attributes: [
561571
new ("ObjCBindings.ExportAttribute<ObjCBindings.Property>", ["name"]),

0 commit comments

Comments
 (0)