Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb8e9c83

Browse files
authored
[mtouch] Detect when we run into the 32-bit arm size limitation, and report a better error.Fixes#6526. (#6855)
Also limit the output from the native compiler, so that we don't overload theIDEs with output if the native compiler produces tens of thousands of errors.Fixes#6526.
1 parent37e710c commitb8e9c83

File tree

6 files changed

+197
-27
lines changed

6 files changed

+197
-27
lines changed

‎docs/website/mmp-errors.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,9 @@ If this is not the case, please file a [bug report](https://github.com/xamarin/x
631631

632632
<aname="MM5218" />
633633

634+
<!-- 5107 is used by mtouch-->
635+
<!-- 5108 is used by mtouch-->
636+
634637
####MM5218: Can't ignore the dynamic symbol {symbol} (--ignore-dynamic-symbol={symbol}) because it was not detected as a dynamic symbol.
635638

636639
See the[equivalent mtouch warning](~/ios/troubleshooting/mtouch-errors.md#MT5218).

‎docs/website/mtouch-errors.md‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,6 +2587,46 @@ Reference: https://github.com/xamarin/xamarin-macios/issues/6492
25872587

25882588
This usually indicates a bug in Xamarin.iOS; please file a new issue on[github](https://github.com/xamarin/xamarin-macios/issues/new).
25892589

2590+
###MT5107: The assembly {assembly} can't be AOT-compiled for 32-bit architectures because the native code is too big for the 32-bit ARM architecture.
2591+
2592+
The object file format for 32-bit ARM architectures (armv7 and armv7s) has
2593+
certain size restrictions for the native code. This error will be shown when
2594+
the limit is hit.
2595+
2596+
Possible solutions:
2597+
2598+
* Only build for ARM64. This can be changed in the project's iOS Build
2599+
options, and it's by far the easiest solution. Apple is on its way to
2600+
removing the 32-bit ARM architectures, so this will eventually be the
2601+
final solution too.
2602+
* Enable the linker for all assemblies (or review any custom linker
2603+
arguments, such as linker definition files, to avoid skipping the
2604+
linker). The idea is for the linker to remove more unused code, and if
2605+
enough unused code is removed, then the size limit won't be reached.
2606+
* Disable debugging. Debugging support makes the AOT compiler produce more
2607+
code, which can be enough to hit the limit. This can be changed in the
2608+
project's iOS Debug options (but the downside is of course that
2609+
debugging won't work).
2610+
* Enable LLVM. The LLVM compiler can sometimes produce smaller code, which
2611+
can be enough to get below the size limit. The downside is that
2612+
debugging won't work, and the build will be much slower.
2613+
* There's usually a particularly big assembly that's causing problems;
2614+
sometimes it can help to split such assemblies into smaller assemblies.
2615+
This can be a significant amount of work though, and there's no
2616+
guarantee it would eventually work.
2617+
* Remove code from the app that isn't needed/used.
2618+
2619+
Reference:https://github.com/xamarin/xamarin-macios/issues/6787
2620+
2621+
###MT5108: The {linker/compiler} output is too long, it's been limited to 1000 lines.
2622+
2623+
This is a warning indicating that the output from the linker or compiler was
2624+
truncated because it was too long.
2625+
2626+
To get the complete output, you can either manually run the command from the
2627+
command line, or alternatively add`-v -v -v -v -v -v` (six or more -v's) to
2628+
the additional mtouch argument in the project's iOS Build options.
2629+
25902630
###MT52xx: Linking
25912631

25922632
<!--

‎tests/mtouch/MTouch.cs‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,6 +3009,30 @@ static int FilterClauseProperty {
30093009
}
30103010
}
30113011

3012+
[Test]
3013+
publicvoidMT5107()
3014+
{
3015+
AssertDeviceAvailable();
3016+
3017+
using(varmtouch=newMTouchTool()){
3018+
mtouch.TargetVer="10.3";
3019+
mtouch.Profile=Profile.iOS;
3020+
mtouch.Abi="armv7";
3021+
mtouch.Linker=MTouchLinker.DontLink;
3022+
/* Once the xcode11 branch has been merged into master, we should be able to do the following instead, which will make the test faster
3023+
mtouch.Linker = MTouchLinker.LinkSdk;
3024+
mtouch.CustomArguments = new string [] { "--linkskip=System.Core" };
3025+
mtouch.CreateTemporaryApp (extraCode: "[Foundation.Preserve] class PreserveMe { void M () { System.Console.WriteLine (typeof (System.Collections.Generic.HashSet<string>)); } }", extraArg: "-r:System.Core.dll");
3026+
*/
3027+
mtouch.CreateTemporaryApp();
3028+
mtouch.AssertExecuteFailure(MTouchAction.BuildDev);
3029+
mtouch.AssertError(5107,"The assembly 'Xamarin.iOS.dll' can't be AOT-compiled for 32-bit architectures because the native code is too big for the 32-bit ARM architecture.");
3030+
mtouch.AssertWarning(5108,"The compiler output is too long, it's been limited to 1000 lines.");
3031+
mtouch.AssertErrorCount(1);
3032+
mtouch.AssertWarningCount(1);
3033+
}
3034+
}
3035+
30123036
[Test]
30133037
publicvoidMT5211()
30143038
{

‎tools/common/BuildTasks.cs‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
usingSystem.Collections.Generic;
66
usingSystem.Linq;
77
usingSystem.IO;
8+
usingSystem.Text;
89
usingSystem.Threading;
910
usingSystem.Threading.Tasks;
1011

@@ -293,6 +294,40 @@ public override string ToString ()
293294
{
294295
returnGetType().Name;
295296
}
297+
298+
boolreported_5107;
299+
protectedvoidCheckFor5107(stringassembly_name,stringline,List<Exception>exceptions)
300+
{
301+
if(line.Contains("can not encode offset")&&line.Contains("in resulting scattered relocation")){
302+
if(!reported_5107){
303+
// There can be thousands of these, but we only need one.
304+
reported_5107=true;
305+
exceptions.Add(ErrorHelper.CreateError(5107,"The assembly '{0}' can't be AOT-compiled for 32-bit architectures because the native code is too big for the 32-bit ARM architecture.",assembly_name));
306+
}
307+
}
308+
}
309+
310+
// Writes a list of lines to stderr, writing only a limited number of lines if there are too many of them.
311+
protectedvoidWriteLimitedOutput(stringfirst,IEnumerable<string>lines,List<Exception>exceptions)
312+
{
313+
if((first==null||first.Length==0)&&!lines.Any())
314+
return;
315+
316+
if(Driver.Verbosity<6&&lines.Count()>1000){
317+
lines=lines.Take(1000);// Limit the output so that we don't overload VSfM.
318+
exceptions.Add(ErrorHelper.CreateWarning(5108,"The compiler output is too long, it's been limited to 1000 lines."));
319+
}
320+
321+
// Construct the entire message before writing anything, so that there's a better chance the message isn't
322+
// mixed up with output from other threads.
323+
varsb=newStringBuilder();
324+
if(first!=null&&first.Length>0)
325+
sb.AppendLine(first);
326+
foreach(varlineinlines)
327+
sb.AppendLine(line);
328+
sb.Length-=Environment.NewLine.Length;// strip off the last newline, since we're adding it in the next line
329+
Console.Error.WriteLine(sb);
330+
}
296331
}
297332

298333
classSingleThreadedSynchronizationContext:SynchronizationContext

‎tools/common/Driver.cs‎

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,19 @@ static void SetTargetFramework (string fx)
223223
#endif
224224
}
225225

226-
publicstaticint RunCommand(stringpath,stringargs,string[]env=null,StringBuilderoutput=null,boolsuppressPrintOnErrors= false)
226+
publicstaticint RunCommand(stringpath,stringargs)
227+
{
228+
return RunCommand(path,args,null,(Action<string>)null);
229+
}
230+
231+
publicstaticint RunCommand(stringpath,stringargs,string[]env=null,StringBuilderoutput=null,boolsuppressPrintOnErrors= false)
232+
{
233+
if(output!=null)
234+
return RunCommand(path,args,env,(v)=>{if(v!=null)output.AppendLine(v);},suppressPrintOnErrors);
235+
return RunCommand(path,args,env,(Action<string>)null,suppressPrintOnErrors);
236+
}
237+
238+
publicstaticint RunCommand(stringpath,stringargs,string[]env=null,Action<string>output_received=null,boolsuppressPrintOnErrors= false)
227239
{
228240
Exception stdin_exc=null;
229241
var info=new ProcessStartInfo(path,args);
@@ -234,8 +246,15 @@ public static int RunCommand (string path, string args, string[] env = null, Str
234246
System.Threading.ManualResetEvent stdout_completed=newSystem.Threading.ManualResetEvent(false);
235247
System.Threading.ManualResetEvent stderr_completed=newSystem.Threading.ManualResetEvent(false);
236248

237-
if(output==null)
249+
var lockobj=newobject();
250+
StringBuilder output=null;
251+
if(output_received==null){
238252
output=newStringBuilder();
253+
output_received=(line)=>{
254+
if(line!=null)
255+
output.AppendLine(line);
256+
};
257+
}
239258

240259
if(env!=null){
241260
if(env.Length%2!=0)
@@ -252,17 +271,17 @@ public static int RunCommand (string path, string args, string[] env = null, Str
252271

253272
p.OutputDataReceived+=(s,e)=>{
254273
if(e.Data!=null){
255-
lock(output)
256-
output.AppendLine(e.Data);
274+
lock(lockobj)
275+
output_received(e.Data);
257276
}else{
258277
stdout_completed.Set();
259278
}
260279
};
261280

262281
p.ErrorDataReceived+=(s,e)=>{
263282
if(e.Data!=null){
264-
lock(output)
265-
output.AppendLine(e.Data);
283+
lock(lockobj)
284+
output_received(e.Data);
266285
}else{
267286
stderr_completed.Set();
268287
}
@@ -276,13 +295,22 @@ public static int RunCommand (string path, string args, string[] env = null, Str
276295
stderr_completed.WaitOne(TimeSpan.FromSeconds(1));
277296
stdout_completed.WaitOne(TimeSpan.FromSeconds(1));
278297

298+
output_received(null);
299+
279300
if(p.ExitCode!=0){
280301
// note: this repeat the failing command line. However we can't avoid this since we're often
281302
// running commands in parallel (so the last one printed might not be the one failing)
282-
if(!suppressPrintOnErrors)
283-
Console.Error.WriteLine("Process exited with code {0}, command:\n{1} {2}{3}",p.ExitCode,path,args,output.Length>0?"\n"+output.ToString():string.Empty);
303+
if(!suppressPrintOnErrors){
304+
// We re-use the stringbuilder so that we avoid duplicating the amount of required memory,
305+
// while only calling Console.WriteLine once to make it less probable that other threads
306+
// also write to the Console, confusing the output.
307+
if(output==null)
308+
output=new StringBuilder();
309+
output.Insert(0,$"Process exited with code{p.ExitCode}, command:\n{path}\n");
310+
Console.Error.WriteLine(output);
311+
}
284312
returnp.ExitCode;
285-
} elseif(verbose>0&&output.Length>0&&!suppressPrintOnErrors){
313+
}elseif(verbose>0&&output!=null&&output.Length>0&&!suppressPrintOnErrors){
286314
Console.WriteLine(output.ToString());
287315
}
288316

@@ -295,7 +323,14 @@ public static int RunCommand (string path, string args, string[] env = null, Str
295323

296324
publicstaticTask<int>RunCommandAsync(stringpath,stringargs,string[]env=null,StringBuilderoutput=null,boolsuppressPrintOnErrors=false)
297325
{
298-
returnTask.Run(()=>RunCommand(path,args,env,output,suppressPrintOnErrors));
326+
if(output!=null)
327+
return RunCommandAsync(path,args,env,(v)=>{if(v!=null)output.AppendLine(v);},suppressPrintOnErrors);
328+
return RunCommandAsync(path,args,env,(Action<string>)null,suppressPrintOnErrors);
329+
}
330+
331+
publicstaticTask<int>RunCommandAsync(stringpath,stringargs,string[]env=null,Action<string>output_received=null,boolsuppressPrintOnErrors=false)
332+
{
333+
returnTask.Run(()=>RunCommand(path,args,env,output_received,suppressPrintOnErrors));
299334
}
300335

301336
#if!MMP_TEST

‎tools/mtouch/BuildTasks.mtouch.cs‎

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ protected Task<int> StartAsync ()
3737
returnTask.Run(()=>Start());
3838
}
3939

40+
// both stdout and stderr will be sent to this function.
41+
// null will be sent when there's no more output
42+
// calls to this function will be synchronized (no need to lock in here).
43+
protectedvirtualvoidOutputReceived(stringline)
44+
{
45+
if(line!=null)
46+
Output.AppendLine(line);
47+
}
48+
4049
protectedintStart()
4150
{
4251
if(Driver.Verbosity>0)
@@ -45,15 +54,16 @@ protected int Start ()
4554
varinfo=ProcessStartInfo;
4655
varstdout_completed=newManualResetEvent(false);
4756
varstderr_completed=newManualResetEvent(false);
57+
varlockobj=newobject();
4858

4959
Output=newStringBuilder();
5060

5161
using(varp=Process.Start(info)){
5262
p.OutputDataReceived+=(sender,e)=>
5363
{
5464
if(e.Data!=null){
55-
lock(Output)
56-
Output.AppendLine(e.Data);
65+
lock(lockobj)
66+
OutputReceived(e.Data);
5767
}else{
5868
stdout_completed.Set();
5969
}
@@ -62,8 +72,8 @@ protected int Start ()
6272
p.ErrorDataReceived+=(sender,e)=>
6373
{
6474
if(e.Data!=null){
65-
lock(Output)
66-
Output.AppendLine(e.Data);
75+
lock(lockobj)
76+
OutputReceived(e.Data);
6777
}else{
6878
stderr_completed.Set();
6979
}
@@ -77,6 +87,8 @@ protected int Start ()
7787
stderr_completed.WaitOne(TimeSpan.FromSeconds(1));
7888
stdout_completed.WaitOne(TimeSpan.FromSeconds(1));
7989

90+
OutputReceived(null);
91+
8092
GC.Collect();// Workaround for: https://bugzilla.xamarin.com/show_bug.cgi?id=43462#c14
8193

8294
if(Driver.Verbosity>=2&&Output.Length>0)
@@ -181,6 +193,8 @@ public class AOTTask : ProcessTask
181193
publicstringAssemblyPath;// path to the .s file.
182194
List<string>inputs;
183195
publicAotInfoAotInfo;
196+
List<Exception>exceptions=newList<Exception>();
197+
List<string>output_lines=newList<string>();
184198

185199
publicoverrideIEnumerable<string>Outputs{
186200
get{
@@ -226,6 +240,19 @@ public override bool IsUptodate {
226240
}
227241
}
228242

243+
protectedoverridevoidOutputReceived(stringline)
244+
{
245+
if(line==null)
246+
return;
247+
248+
if(line.StartsWith("AOT restriction: Method '",StringComparison.Ordinal)&&line.Contains("must be static since it is decorated with [MonoPInvokeCallback]")){
249+
exceptions.Add(ErrorHelper.CreateError(3002,line));
250+
}else{
251+
CheckFor5107(AssemblyName,line,exceptions);
252+
}
253+
output_lines.Add(line);
254+
}
255+
229256
protectedasyncoverrideTaskExecuteAsync()
230257
{
231258
varexit_code=awaitStartAsync();
@@ -241,19 +268,11 @@ .byte 0
241268
return;
242269
}
243270

244-
Console.Error.WriteLine("AOT Compilation exited with code {0}, command:\n{1}{2}",exit_code,Command,Output.Length>0?("\n"+Output.ToString()):string.Empty);
245-
if(Output.Length>0){
246-
List<Exception>exceptions=newList<Exception>();
247-
foreach(varlineinOutput.ToString().Split('\n')){
248-
if(line.StartsWith("AOT restriction: Method '",StringComparison.Ordinal)&&line.Contains("must be static since it is decorated with [MonoPInvokeCallback]")){
249-
exceptions.Add(newMonoTouchException(3002,true,line));
250-
}
251-
}
252-
if(exceptions.Count>0)
253-
thrownewAggregateException(exceptions.ToArray());
254-
}
271+
WriteLimitedOutput($"AOT Compilation exited with code{exit_code}, command:\n{Command}",output_lines,exceptions);
255272

256-
thrownewMonoTouchException(3001,true,"Could not AOT the assembly '{0}'",AssemblyName);
273+
exceptions.Add(ErrorHelper.CreateError(3001,"Could not AOT the assembly '{0}'",AssemblyName));
274+
275+
thrownewAggregateException(exceptions);
257276
}
258277

259278
publicoverridestringToString()
@@ -545,7 +564,21 @@ protected async Task<int> CompileAsync ()
545564

546565
Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));
547566

548-
varrv=awaitDriver.RunCommandAsync(App.CompilerPath,CompilerFlags.ToString(),null,null);
567+
varexceptions=newList<Exception>();
568+
varoutput=newList<string>();
569+
varassembly_name=Path.GetFileNameWithoutExtension(OutputFile);
570+
varoutput_received=newAction<string>((stringline)=>{
571+
if(line==null)
572+
return;
573+
output.Add(line);
574+
CheckFor5107(assembly_name,line,exceptions);
575+
});
576+
577+
varrv=awaitDriver.RunCommandAsync(App.CompilerPath,CompilerFlags.ToString(),null,output_received,suppressPrintOnErrors:true);
578+
579+
WriteLimitedOutput(rv!=0?$"Compilation failed with code{rv}, command:\n{App.CompilerPath}{CompilerFlags.ToString()}":null,output,exceptions);
580+
581+
ErrorHelper.Show(exceptions);
549582

550583
returnrv;
551584
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp