Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/website/mmp-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ Mixed-mode assemblies can not be processed by the linker.

See https://msdn.microsoft.com/en-us/library/x0w2664k.aspx for more information on mixed-mode assemblies.

<!-- 2015 used by mtouch -->

### <a name="MM2106"/>MM2106: Could not optimize the call to BlockLiteral.SetupBlock[Unsafe] in * at offset * because *.

The linker reports this warning when it can't optimize a call to BlockLiteral.SetupBlock or Block.SetupBlockUnsafe.
Expand All @@ -258,6 +260,15 @@ To remove the warning either remove the optimization argument to mmp, or pass
By default this option will be automatically enabled whenever it's possible
and safe to do so.

### <a name="MM2108"/>MM2108: '{0}' was stripped of architectures except '{1}' to comply with App Store restrictions. This could break exisiting codesigning signatures. Consider stripping the library with lipo or disabling with --optimize=-trim-architectures");

The App Store now rejects applications which contain libraries and frameworks which contain 32-bit variants. The library was stripped of unused archtectures when copied into the final application bundle.

This is in general safe, and will reduce application bundle size as an added benefit. However, any bundled framework that is code signed will have its signature invalidated (and resigned later if the application is signed).

Consider using `lipo` to remove the unnecessary archtectures permanently from the source library. If the application is not being published to the App Store, this removal can be disabled by passing --optimize=-trim-architectures as Additional MMP Arguments.


# MM3xxx: AOT

## MM30xx: AOT (general) errors
Expand Down Expand Up @@ -363,6 +374,8 @@ See the [equivalent mtouch warning](mtouch-errors.md#MT5218).

### <a name="MM5310">MM5310: install_name_tool failed with an error code '{0}'. Check build log for details.

### <a name="MM5311">MM5311: lipo failed with an error code '{0}'. Check build log for details.

<!-- MM6xxx: mmp internal tools -->
<!-- MM7xxx: reserved -->

Expand Down
3 changes: 3 additions & 0 deletions docs/website/mtouch-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,8 @@ To remove the warning either remove the optimization argument to mtouch, or pass
By default this option will be automatically enabled whenever it's possible
and safe to do so.

<!-- 2018 used by mmp -->

# MT3xxx: AOT error messages

<!--
Expand Down Expand Up @@ -1979,6 +1981,7 @@ An error occurred when signing the application. Please review the build log to s
<!-- 5308 is used by mmp -->
<!-- 5309 is used by mmp -->
<!-- 5310 is used by mmp -->
<!-- 5311 is used by mmp -->

# MT6xxx: mtouch internal tools error messages

Expand Down
77 changes: 77 additions & 0 deletions tests/common/MachO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.IO;

namespace Xamarin.Tests
{
public static class MachO
{
public static List<string> GetArchitectures (string file)
{
var result = new List<string> ();

using (var fs = File.OpenRead (file)) {
using (var reader = new BinaryReader (fs)) {
int magic = reader.ReadInt32 ();
switch ((uint) magic) {
case 0xCAFEBABE: // little-endian fat binary
throw new NotImplementedException ("little endian fat binary");
case 0xBEBAFECA:
int architectures = System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ());
for (int i = 0; i < architectures; i++) {
result.Add (GetArch (System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ()), System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ())));
// skip to next entry
reader.ReadInt32 (); // offset
reader.ReadInt32 (); // size
reader.ReadInt32 (); // align
}
break;
case 0xFEEDFACE: // little-endian mach-o header
case 0xFEEDFACF: // little-endian 64-big mach-o header
result.Add (GetArch (reader.ReadInt32 (), reader.ReadInt32 ()));
break;
case 0xCFFAEDFE:
case 0xCEFAEDFE:
result.Add (GetArch (System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ()), System.Net.IPAddress.NetworkToHostOrder (reader.ReadInt32 ())));
break;
default:
throw new Exception (string.Format ("File '{0}' is neither a Universal binary nor a Mach-O binary (magic: 0x{1})", file, magic.ToString ("x")));
}
}
}

return result;
}

static string GetArch (int cputype, int cpusubtype)
{
const int ABI64 = 0x01000000;
const int X86 = 7;
const int ARM = 12;

switch (cputype) {
case ARM : // arm
switch (cpusubtype) {
case 6: return "armv6";
case 9: return "armv7";
case 11: return "armv7s";
default:
return "unknown arm variation: " + cpusubtype.ToString ();
}
case ARM | ABI64:
switch (cpusubtype) {
case 0:
return "arm64";
default:
return "unknown arm/64 variation: " + cpusubtype.ToString ();
}
case X86: // x86
return "i386";
case X86 | ABI64: // x64
return "x86_64";
}

return string.Format ("unknown: {0}/{1}", cputype, cpusubtype);
}
}
}
127 changes: 115 additions & 12 deletions tests/common/mac/ProjectTestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,94 @@ internal class MessageTool : Tool
}
}

static class FrameworkBuilder
{
const string PListText = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">
<plist version=""1.0"">
<dict>
<key>BuildMachineOSBuild</key>
<string>16B2657</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Foo</string>
<key>CFBundleIdentifier</key>
<string>com.test.Foo</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Foo</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>6.9</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1561.40.100</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>9Q85j</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>17E138</string>
<key>DTSDKName</key>
<string>macosx10.13internal</string>
<key>DTXcode</key>
<string>0930</string>
<key>DTXcodeBuild</key>
<string>9Q85j</string>
</dict>
</plist>";

public static string CreateFatFramework (string tmpDir)
{
Func<string, string> f = x => Path.Combine (tmpDir, x);
File.WriteAllText (f ("foo.c"), "int Answer () { return 42; }");
File.WriteAllText (f ("Info.plist"), PListText);

TI.RunAndAssert ($"clang -m32 -c -o {f ("foo_32.o")} {f ("foo.c")}");
TI.RunAndAssert ($"clang -m64 -c -o {f ("foo_64.o")} {f ("foo.c")}");
TI.RunAndAssert ($"clang -m32 -dynamiclib -o {f ("foo_32.dylib")} {f ("foo_32.o")}");
TI.RunAndAssert ($"clang -m64 -dynamiclib -o {f ("foo_64.dylib")} {f ("foo_64.o")}");
TI.RunAndAssert ($"lipo -create {f ("foo_32.dylib")} {f ("foo_64.dylib")} -output {f ("Foo")}");
TI.RunAndAssert ($"install_name_tool -id @rpath/Foo.framework/Foo {f ("Foo")}");
TI.RunAndAssert ($"mkdir -p {f ("Foo.framework/Versions/A/Resources")}");
TI.RunAndAssert ($"cp {f ("Foo")} {f ("Foo.framework/Versions/A/Foo")}");
TI.RunAndAssert ($"cp {f ("Info.plist")} {f ("Foo.framework/Versions/A/Resources/")}");
TI.RunAndAssert ($"ln -s Versions/A/Foo {f ("Foo.framework/Foo")}");
TI.RunAndAssert ($"ln -s Versions/A/Resources {f ("Foo.framework/Resources")}");
TI.RunAndAssert ($"ln -s Versions/A {f ("Foo.framework/Current")}");
return f ("Foo.framework");
}

public static string CreateThinFramework (string tmpDir, bool sixtyFourBits = true)
{
Func<string, string> f = x => Path.Combine (tmpDir, x);
File.WriteAllText (f ("foo.c"), "int Answer () { return 42; }");
File.WriteAllText (f ("Info.plist"), PListText);

string bitnessArg = sixtyFourBits ? "-m64" : "-m32";
TI.RunAndAssert ($"clang {bitnessArg} -c -o {f ("foo.o")} {f ("foo.c")}");
TI.RunAndAssert ($"clang {bitnessArg} -dynamiclib -o {f ("Foo")} {f ("foo.o")}");
TI.RunAndAssert ($"install_name_tool -id @rpath/Foo.framework/Foo {f ("Foo")}");
TI.RunAndAssert ($"mkdir -p {f ("Foo.framework/Versions/A/Resources")}");
TI.RunAndAssert ($"cp {f ("Foo")} {f ("Foo.framework/Versions/A/Foo")}");
TI.RunAndAssert ($"cp {f ("Info.plist")} {f ("Foo.framework/Versions/A/Resources/")}");
TI.RunAndAssert ($"ln -s Versions/A/Foo {f ("Foo.framework/Foo")}");
TI.RunAndAssert ($"ln -s Versions/A/Resources {f ("Foo.framework/Resources")}");
TI.RunAndAssert ($"ln -s Versions/A {f ("Foo.framework/Current")}");
return f ("Foo.framework");
}
}

// Hide the hacks and provide a nice interface for writting tests that build / run XM projects
static class TI
{
Expand All @@ -54,6 +142,8 @@ public class UnifiedTestConfig
public bool FSharp { get; set; }
public bool XM45 { get; set; }
public bool DiagnosticMSBuild { get; set; }
public bool Release { get; set; } = false;

public string ProjectName { get; set; } = "";
public string TestCode { get; set; } = "";
public string TestDecl { get; set; } = "";
Expand Down Expand Up @@ -98,6 +188,15 @@ public static Version FindMonoVersion ()
return new Version (versionRegex.Match (output).Value.Split (' ')[2]);
}

public static string RunAndAssert (string exe)
{
var parts = exe.Split (new char [] { ' ' }, 2);
if (parts.Length == 1)
return RunAndAssert (exe, "", "Command: " + exe);
else
return RunAndAssert (parts[0], parts[1], "Command: " + exe);
}

public static string RunAndAssert (string exe, string args, string stepName, bool shouldFail = false, Func<string> getAdditionalFailInfo = null, string[] environment = null)
{
StringBuilder output = new StringBuilder ();
Expand Down Expand Up @@ -128,7 +227,7 @@ public static void CleanUnifiedProject (string csprojTarget, bool useMSBuild = f
RunAndAssert ("/Library/Frameworks/Mono.framework/Commands/" + (useMSBuild ? "msbuild" : "xbuild"), new StringBuilder (csprojTarget + " /t:clean"), "Clean");
}

public static string BuildProject (string csprojTarget, bool isUnified, bool diagnosticMSBuild = false, bool shouldFail = false, bool useMSBuild = false, string configuration = null, string[] environment = null)
public static string BuildProject (string csprojTarget, bool isUnified, bool diagnosticMSBuild = false, bool shouldFail = false, bool useMSBuild = false, bool release = false, string[] environment = null)
{
string rootDirectory = FindRootDirectory ();

Expand All @@ -146,10 +245,14 @@ public static string BuildProject (string csprojTarget, bool isUnified, bool dia
buildArgs.Append (diagnosticMSBuild ? " /verbosity:diagnostic " : " /verbosity:normal ");
buildArgs.Append (" /property:XamarinMacFrameworkRoot=" + rootDirectory + "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current ");

if (!string.IsNullOrEmpty (configuration))
buildArgs.Append ($" /property:Configuration={configuration} ");
} else
if (release)
buildArgs.Append ("/property:Configuration=Release ");
else
buildArgs.Append ("/property:Configuration=Debug ");

} else {
buildArgs.Append (" build ");
}

buildArgs.Append (StringUtils.Quote (csprojTarget));

Expand Down Expand Up @@ -269,20 +372,20 @@ public static string GenerateUnifiedExecutableProject (UnifiedTestConfig config)
return GenerateEXEProject (config);
}

public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null, string[] environment = null)
public static string GenerateAndBuildUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string[] environment = null)
{
string csprojTarget = GenerateUnifiedExecutableProject (config);
return BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, useMSBuild: useMSBuild, configuration: configuration, environment: environment);
return BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, useMSBuild: useMSBuild, release: config.Release, environment: environment);
}

public static string RunGeneratedUnifiedExecutable (UnifiedTestConfig config)
{
string bundleName = config.AssemblyName != "" ? config.AssemblyName : config.ProjectName.Split ('.')[0];
string exePath = Path.Combine (config.TmpDir, "bin/Debug/" + bundleName + ".app/Contents/MacOS/" + bundleName);
string exePath = Path.Combine (config.TmpDir, "bin/" + (config.Release ? "Release/" : "Debug/") + bundleName + ".app/Contents/MacOS/" + bundleName);
return RunEXEAndVerifyGUID (config.TmpDir, config.guid, exePath);
}

public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string configuration = null, string[] environment = null)
public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool shouldFail = false, bool useMSBuild = false, string[] environment = null)
{
// If we've already generated guid bits for this config, don't tack on a second copy
if (config.guid == Guid.Empty)
Expand All @@ -291,7 +394,7 @@ public static OutputText TestUnifiedExecutable (UnifiedTestConfig config, bool s
config.TestCode += GenerateOutputCommand (config.TmpDir, config.guid);
}

string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, useMSBuild, configuration, environment);
string buildOutput = GenerateAndBuildUnifiedExecutable (config, shouldFail, useMSBuild, environment);
if (shouldFail)
return new OutputText (buildOutput, "");

Expand All @@ -313,19 +416,19 @@ public static OutputText TestClassicExecutable (string tmpDir, string testCode =
return new OutputText (buildOutput, runOutput);
}

public static OutputText TestSystemMonoExecutable (UnifiedTestConfig config, bool shouldFail = false, string configuration = null)
public static OutputText TestSystemMonoExecutable (UnifiedTestConfig config, bool shouldFail = false)
{
config.guid = Guid.NewGuid ();
var projectName = "SystemMonoExample";
config.TestCode += GenerateOutputCommand (config.TmpDir, config.guid);
config.ProjectName = $"{projectName}.csproj";
string csprojTarget = GenerateSystemMonoEXEProject (config);

string buildOutput = BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, configuration: configuration);
string buildOutput = BuildProject (csprojTarget, isUnified: true, diagnosticMSBuild: config.DiagnosticMSBuild, shouldFail: shouldFail, release: config.Release);
if (shouldFail)
return new OutputText (buildOutput, "");

string exePath = Path.Combine (config.TmpDir, "bin", configuration ?? "Debug", projectName + ".app", "Contents", "MacOS", projectName);
string exePath = Path.Combine (config.TmpDir, "bin", config.Release ? "Release" : "Debug", projectName + ".app", "Contents", "MacOS", projectName);
string runOutput = RunEXEAndVerifyGUID (config.TmpDir, config.guid, exePath);
return new OutputText (buildOutput, runOutput);
}
Expand Down
15 changes: 12 additions & 3 deletions tests/common/mac/SystemMonoExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>false</IncludeMonoRuntime>
<UseSGen>false</UseSGen>
<UseRefCounting>false</UseRefCounting>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<DebugSymbols>true</DebugSymbols>
<Profiling>false</Profiling>
%CODE%
<Profiling>false</Profiling><XamMacArch>x86_64</XamMacArch><CodeSigningKey>Mac Developer</CodeSigningKey><PackageSigningKey>Developer ID Installer</PackageSigningKey></PropertyGroup>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<EnableCodeSigning>false</EnableCodeSigning>
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>false</IncludeMonoRuntime>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<DebugSymbols>true</DebugSymbols>
%CODE%
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
20 changes: 18 additions & 2 deletions tests/common/mac/UnifiedExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,31 @@
<TargetFrameworkIdentifier>Xamarin.Mac</TargetFrameworkIdentifier>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug</OutputPath>
<EnableCodeSigning>false</EnableCodeSigning>
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>false</IncludeMonoRuntime>
<UseSGen>false</UseSGen>
<UseRefCounting>false</UseRefCounting>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
%CODE%
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>false</EnableCodeSigning>
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>true</IncludeMonoRuntime>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<LinkMode>SdkOnly</LinkMode>
%CODE%
</PropertyGroup>
<ItemGroup>
Expand Down
Loading