-
Notifications
You must be signed in to change notification settings - Fork 555
[mmp] Add stripping of 32-bit dylibs to work with new App Store restrictions #3387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
chamons
commented
Feb 2, 2018
- [macOS]Mac App failed to publish with error:"Unsupported Architectures. Your executable contained the following disallowed architectures: '[i386 Payload/MacCoolApp.app/Contents/MonoBundle/libMonoPosixHelper.dylib)]" #3367
- Required some test work that might be more obvious by themselves. We can squash when landing.
- Turns out that /p:configuration:debug is not sufficient to tell mmp to do the right thing - That, in most projects, sets the DebugSymbols property, which really is what is checked. - However, two of our projects did not have that, so we always did release mmp work. - Removed configuration property for tests and addded real "Release" configuration option
- dotnet#3367 - App Store will now fail builds if you add in a 32-bit dylib - If you are a 32-bit app you don't need the 64-bit part of your fat dylib anyway - Add --native-strip to allow customization of behavior, as not everyone uses app store
|
Build failure |
spouliot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ the tests
tools/mmp/driver.cs
Outdated
| string archToRemove = arch == "i386" ? "x86_64" : "i386"; | ||
| int ret = XcodeRun ("lipo", $"{dest} -remove {archToRemove} -output {dest}"); | ||
| if (ret != 0) | ||
| throw new MonoMacException (5310, true, "lipo failed with an error code '{0}'. Check build log for details.", ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a new error? if so it should be documented
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I forgot.
tools/mmp/driver.cs
Outdated
| if (ret != 0) | ||
| throw new MonoMacException (5310, true, "lipo failed with an error code '{0}'. Check build log for details.", ret); | ||
| if (name != "MonoPosixHelper") | ||
| ErrorHelper.Warning (1501, $"{name} was stripped of architecture {archToRemove} to comply with App Store restrictions. This could break exisiting codesigning signatures. Consider stripping the library with lipo or disabling with --native-strip=skip"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
|
|
||
| bool isStaticLib = real_src.EndsWith (".a", StringComparison.Ordinal); | ||
| bool isDynamicLib = real_src.EndsWith (".dylib", StringComparison.Ordinal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens for frameworks ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing, but something very likely should. Let me get someone in to test this case in submission to Apple.
|
|
||
| test.Release = true; | ||
| buildOutput = TI.TestUnifiedExecutable (test).BuildOutput; | ||
| Assert.AreEqual (releaseStrips, didStrip (buildOutput), "Release lipo usage did not match expectations"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also test that the binary only has the desired architectures? We already have code to get the architectures of a binary file: https://github.com/xamarin/xamarin-macios/blob/bec116c273ab119c648522a28c3f650881ed4d9e/tests/mtouch/MTouch.cs#L3996
| if (!string.IsNullOrEmpty (configuration)) | ||
| buildArgs.Append ($" /property:Configuration={configuration} "); | ||
| } else | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: else goes on the same line as the closing brace.
tools/mmp/driver.cs
Outdated
| CopyFileAndRemoveReadOnly (real_src, dest); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whitespace noise.
|
Build failure |
|
I believe I've handled the current code review issues and added framework stripping. I did not build after merging master, as a mono bump took too long before end of day. I'll check back tomorrow. Please consider re-reviewing as a lot has changed. |
|
Build failure |
1 similar comment
|
Build failure |
spouliot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to discuss optimizations/docs
But otherwise it seems good :)
tools/mmp/driver.cs
Outdated
| default: | ||
| ErrorHelper.Error (26, $"Could not parse the command line argument '-native-strip:{v}'"); | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if that should be added in the new optimizations ? c.c. @rolfbjarne
It behaves just like them, i.e. a sane default (computed based on the project settings) and overrides for enabling and disabling it.
In any case it needs to be documented outside the errors code it introduce.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have two interpretations of strip: mtouch takes the arguments nostrip (to not strip IL from managed assemblies) and nosymbolstrip (to not strip native symbols from the executable). Both of these makes sense (their command-line tools are named mono-cil-strip and strip, respectively), but for this case, the work "strip" doesn't even show up in the man page for lipo.
My suggestion: --trim-architectures.
I think this could make sense to include as an optimization (it even makes sense for XI as well, since we do the same thing there, the only difference would be the default: enabled for device builds (faster deploy), and disabled for sim builds (faster build). It's never been optional for XI though).
| { | ||
| static class StringExtensions | ||
| { | ||
| internal static string [] SplitLines (this string s) => s.Split (new [] { Environment.NewLine }, StringSplitOptions.None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe tools/common/StringUtils.cs is a better place for this?
tools/mmp/driver.cs
Outdated
| if (ret != 0) | ||
| throw new MonoMacException (5311, true, "lipo failed with an error code '{0}'. Check build log for details.", ret); | ||
| if (name != "MonoPosixHelper") | ||
| ErrorHelper.Warning (2108, $"{name} was stripped of architecture {archToRemove} to comply with App Store restrictions. This could break exisiting codesigning signatures. Consider stripping the library with lipo or disabling with --native-strip=skip"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this warning show up for all libraries, independent of their original architecture(s)? You don't seem to have any logic to detect which architecture(s) the libraries had before running lipo.
That said, mtouch also does the same thing, and has code to do this without running lipo: https://github.com/xamarin/xamarin-macios/blob/96085adb66129c42e9ae8e28f44d06112f9e1896/tools/common/MachO.cs#L194-L200
the only problem is that I don't think that code can handle slices of non-standard architectures like PPC (see bug #42464).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "obvious" thing to do here is to first write a test that says "if I'm 64-bit and i have a 64-bit library there should be no warning".
And yes, it looks like that test would fail right now. :(
tools/mmp/driver.cs
Outdated
| default: | ||
| ErrorHelper.Error (26, $"Could not parse the command line argument '-native-strip:{v}'"); | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have two interpretations of strip: mtouch takes the arguments nostrip (to not strip IL from managed assemblies) and nosymbolstrip (to not strip native symbols from the executable). Both of these makes sense (their command-line tools are named mono-cil-strip and strip, respectively), but for this case, the work "strip" doesn't even show up in the man page for lipo.
My suggestion: --trim-architectures.
I think this could make sense to include as an optimization (it even makes sense for XI as well, since we do the same thing there, the only difference would be the default: enabled for device builds (faster deploy), and disabled for sim builds (faster build). It's never been optional for XI though).
|
I've moved to --optimize=-trim-architectures instead of a new option and fixed the location of common string utils. I'm going to work on fixing the likely every present warning w\ native libraries. @rolfbjarne please review my optimization changes, first time I've added one. |
|
build |
|
Build failure |
|
Build failure |
|
I can reproduce them when run from the command line but not from the IDE, which is strange. In any case, looking. |
…ly from mdb/pdb files copied - I am uncertain why this started failing, but a number of test changes might have triggered it. - In any case, the code was flat wrong before.
…libMonoPosixHelper.dylib will strip in Release
|
Build failure |
|
This PR has started to turn into a monster, just like every other time I touch mmp... A few more tests are failing locally after the last set of pushes. Looking now. |
… to release/debug changes and output more failure info
|
Looks clean enough locally now. 🤞 |
|
Build failure |
1 similar comment
|
Build failure |
|
Looks like some tests are comparing strings that changed when I added a message. Fixing. |
|
Build failure |
|
Build failure |
|
Some known test failures: https://github.com/xamarin/maccore/issues/640 Looking into protocol failures, feel unrelated. |
|
https://github.com/xamarin/maccore/issues/655 for the protocol failures. |
…ictions (dotnet#3387) - dotnet#3367 - App Store will now fail builds if you add in a 32-bit dylib - If you are a 32-bit app you don't need the 64-bit part of your fat dylib anyway - Add --optimize=-trim-architectures to allow customization of behavior, as not everyone uses app store In addition, while writing tests for this is was noticed that mmp tests did not "really" run Release configuration correctly in most cases. Fixing this turned out to be a bit of a pain, but necessary to correctly test this (and other things). - Turns out that /p:configuration:debug is not sufficient to tell mmp to do the right thing - That, in most projects, sets the DebugSymbols property, which really is what is checked. - However, two of our projects did not have that, so we always did release mmp work. - Removed configuration property for tests and added real "Release" configuration option
…ictions (#3387) (#3633) - #3367 - App Store will now fail builds if you add in a 32-bit dylib - If you are a 32-bit app you don't need the 64-bit part of your fat dylib anyway - Add --optimize=-trim-architectures to allow customization of behavior, as not everyone uses app store In addition, while writing tests for this is was noticed that mmp tests did not "really" run Release configuration correctly in most cases. Fixing this turned out to be a bit of a pain, but necessary to correctly test this (and other things). - Turns out that /p:configuration:debug is not sufficient to tell mmp to do the right thing - That, in most projects, sets the DebugSymbols property, which really is what is checked. - However, two of our projects did not have that, so we always did release mmp work. - Removed configuration property for tests and added real "Release" configuration option