예제 #1
0
        bool IsRequiredSymbol(Symbol symbol, Assembly single_assembly = null, Abi?target_abis = null)
        {
            if (symbol.Ignore)
            {
                return(false);
            }

            // If this symbol is only defined for certain abis, verify if there is an abi match
            if (target_abis.HasValue && symbol.ValidAbis.HasValue && (target_abis.Value & symbol.ValidAbis.Value) == 0)
            {
                return(false);
            }

            // Check if this symbol is used in the assembly we're filtering to
            if (single_assembly != null && !symbol.Members.Any((v) => v.Module.Assembly == single_assembly.AssemblyDefinition))
            {
                return(false);                // nope, this symbol is not used in the assembly we're using as filter.
            }
            // If we're code-sharing, the managed linker might have found symbols
            // that are not in any of the assemblies in the current app.
            // This occurs because the managed linker processes all the
            // assemblies for all the apps together, but when linking natively
            // we're only linking with the assemblies that actually go into the app.
            if (App.Platform != ApplePlatform.MacOSX && App.IsCodeShared && symbol.Assemblies.Count > 0)
            {
                // So if this is a symbol related to any assembly, make sure
                // at least one of those assemblies are in the current app.
                if (!symbol.Assemblies.Any((v) => Assemblies.Contains(v)))
                {
                    return(false);
                }
            }

            switch (symbol.Type)
            {
            case SymbolType.Field:
                return(true);

            case SymbolType.Function:
#if MTOUCH
                // functions are not required if they're used in an assembly which isn't using dlsym, and we're AOT-compiling.
                if (App.IsSimulatorBuild)
                {
                    return(true);
                }
                if (App.Platform == ApplePlatform.MacCatalyst)
                {
                    return(true);
                }
                if (single_assembly != null)
                {
                    return(App.UseDlsym(single_assembly.FileName));
                }

                if (symbol.Members?.Any() == true)
                {
                    foreach (var member in symbol.Members)
                    {
                        if (App.UseDlsym(member.Module.FileName))
                        {
                            // If any assembly uses dlsym to reference this symbol, it's a required symbol that must be preserved,
                            // because otherwise stripping the binary will cause the symbol (but not the function itself) to be removed,
                            // preventing any assembly using dlsym to find it.
                            return(true);
                        }
                    }
                    // None of the members use dlsym (and we have at least one member), then we don't need to preserve the symbol.
                    return(false);
                }
#endif
                return(true);

            case SymbolType.ObjectiveCClass:
                // Objective-C classes are not required when we're using the static registrar and we're not compiling to shared libraries,
                // (because the registrar code is linked into the main app, but not each shared library,
                // so the registrar code won't keep symbols in the shared libraries).
                if (single_assembly != null)
                {
                    return(true);
                }
                return(App.Registrar != RegistrarMode.Static);

            default:
                throw ErrorHelper.CreateError(99, Errors.MX0099, $"invalid symbol type {symbol.Type} for symbol {symbol.Name}");
            }
        }
예제 #2
0
        bool IsRequiredSymbol(Symbol symbol, Assembly single_assembly = null)
        {
            if (symbol.Ignore)
            {
                return(false);
            }

            // Check if this symbol is used in the assembly we're filtering to
            if (single_assembly != null && !symbol.Members.Any((v) => v.Module.Assembly == single_assembly.AssemblyDefinition))
            {
                return(false);                // nope, this symbol is not used in the assembly we're using as filter.
            }
#if MTOUCH
            // If we're code-sharing, the managed linker might have found symbols
            // that are not in any of the assemblies in the current app.
            // This occurs because the managed linker processes all the
            // assemblies for all the apps together, but when linking natively
            // we're only linking with the assemblies that actually go into the app.
            if (App.IsCodeShared && symbol.Assemblies.Count > 0)
            {
                // So if this is a symbol related to any assembly, make sure
                // at least one of those assemblies are in the current app.
                if (!symbol.Assemblies.Any((v) => Assemblies.Contains(v)))
                {
                    return(false);
                }
            }
#endif

            switch (symbol.Type)
            {
            case SymbolType.Field:
                return(true);

            case SymbolType.Function:
#if MTOUCH
                // functions are not required if they're used in an assembly which isn't using dlsym, and we're AOT-compiling.
                if (App.IsSimulatorBuild)
                {
                    return(true);
                }
                if (single_assembly != null)
                {
                    return(App.UseDlsym(single_assembly.FileName));
                }

                if (symbol.Members != null)
                {
                    foreach (var member in symbol.Members)
                    {
                        if (!App.UseDlsym(member.Module.FileName))
                        {
                            return(false);
                        }
                    }
                }
#endif
                return(true);

            case SymbolType.ObjectiveCClass:
                // Objective-C classes are not required when we're using the static registrar and we're not compiling to shared libraries,
                // (because the registrar code is linked into the main app, but not each shared library,
                // so the registrar code won't keep symbols in the shared libraries).
                if (single_assembly != null)
                {
                    return(true);
                }
                return(App.Registrar != RegistrarMode.Static);

            default:
                throw ErrorHelper.CreateError(99, $"Internal error: invalid symbol type {symbol.Type} for symbol {symbol.Name}. Please file a bug report with a test case (https://bugzilla.xamarin.com).");
            }
        }