xamarin-macios/tools/common/DerivedLinkContext.cs

81 строка
2.1 KiB
C#
Исходник Обычный вид История

using System.Collections.Generic;
using Mono.Cecil;
using Mono.Linker;
[mtouch] Make sure native symbols from third-party libraries are preserved in dylibs. Fixes #51548. The native linker treats object files (.o) and static libraries (.a files, which are archives of .o files) differently. The native linker will always include object files into the executable: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ld foo.o -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib 0000000000000fe0 T _xxx However, if the object file is inside a static library: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ar cru foo.a foo.o $ ld foo.a -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib <no output> This means that our testing library (libtest.a) which is a fat library of _object files_, do not show the problems reported in bug #51548. So: a) I've fixed the creation of libtest.a to be a fat library of _static libraries_. This causes the `FastDev_LinkWithTest` test to fail exactly like in bug #51548. b) I've made mtouch pass `-u <native symbol>` to the native linker, for every native symbol referenced in a managed assembly, when creating a dylib. Amazingly this seems to work fine even with symbols to Objective-C classes (`_OBJC_CLASS_$_<class name>`). c) This also required adding support for collecting the Objective-C names of all managed types registered with Objective-C to the linker. The information is already available in the static registrar, but that would require us to make sure the static registrar is executed before compiling dylibs, which means those two tasks won't be able to run in parallel (also there's no guarantee we'll even run the static registrar). https://bugzilla.xamarin.com/show_bug.cgi?id=51548
2017-01-18 12:25:58 +03:00
using XamCore.Registrar;
namespace Xamarin.Tuner
{
public class DerivedLinkContext : LinkContext
{
[mtouch] Make sure native symbols from third-party libraries are preserved in dylibs. Fixes #51548. The native linker treats object files (.o) and static libraries (.a files, which are archives of .o files) differently. The native linker will always include object files into the executable: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ld foo.o -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib 0000000000000fe0 T _xxx However, if the object file is inside a static library: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ar cru foo.a foo.o $ ld foo.a -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib <no output> This means that our testing library (libtest.a) which is a fat library of _object files_, do not show the problems reported in bug #51548. So: a) I've fixed the creation of libtest.a to be a fat library of _static libraries_. This causes the `FastDev_LinkWithTest` test to fail exactly like in bug #51548. b) I've made mtouch pass `-u <native symbol>` to the native linker, for every native symbol referenced in a managed assembly, when creating a dylib. Amazingly this seems to work fine even with symbols to Objective-C classes (`_OBJC_CLASS_$_<class name>`). c) This also required adding support for collecting the Objective-C names of all managed types registered with Objective-C to the linker. The information is already available in the static registrar, but that would require us to make sure the static registrar is executed before compiling dylibs, which means those two tasks won't be able to run in parallel (also there's no guarantee we'll even run the static registrar). https://bugzilla.xamarin.com/show_bug.cgi?id=51548
2017-01-18 12:25:58 +03:00
internal StaticRegistrar StaticRegistrar;
Dictionary<string, List<MemberReference>> required_symbols;
[mtouch] Make sure native symbols from third-party libraries are preserved in dylibs. Fixes #51548. The native linker treats object files (.o) and static libraries (.a files, which are archives of .o files) differently. The native linker will always include object files into the executable: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ld foo.o -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib 0000000000000fe0 T _xxx However, if the object file is inside a static library: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ar cru foo.a foo.o $ ld foo.a -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib <no output> This means that our testing library (libtest.a) which is a fat library of _object files_, do not show the problems reported in bug #51548. So: a) I've fixed the creation of libtest.a to be a fat library of _static libraries_. This causes the `FastDev_LinkWithTest` test to fail exactly like in bug #51548. b) I've made mtouch pass `-u <native symbol>` to the native linker, for every native symbol referenced in a managed assembly, when creating a dylib. Amazingly this seems to work fine even with symbols to Objective-C classes (`_OBJC_CLASS_$_<class name>`). c) This also required adding support for collecting the Objective-C names of all managed types registered with Objective-C to the linker. The information is already available in the static registrar, but that would require us to make sure the static registrar is executed before compiling dylibs, which means those two tasks won't be able to run in parallel (also there's no guarantee we'll even run the static registrar). https://bugzilla.xamarin.com/show_bug.cgi?id=51548
2017-01-18 12:25:58 +03:00
Dictionary<string, TypeDefinition> objectivec_classes;
// SDK candidates - they will be preserved only if the application (not the SDK) uses it
List<ICustomAttributeProvider> srs_data_contract = new List<ICustomAttributeProvider> ();
List<ICustomAttributeProvider> xml_serialization = new List<ICustomAttributeProvider> ();
HashSet<TypeDefinition> cached_isnsobject;
HashSet<TypeDefinition> needs_isdirectbinding_check;
HashSet<MethodDefinition> generated_code;
public HashSet<TypeDefinition> CachedIsNSObject {
get { return cached_isnsobject; }
set { cached_isnsobject = value; }
}
public HashSet<TypeDefinition> NeedsIsDirectBindingCheck {
get { return needs_isdirectbinding_check; }
set { needs_isdirectbinding_check = value; }
}
public HashSet<MethodDefinition> GeneratedCode {
get { return generated_code; }
set { generated_code = value; }
}
public IList<ICustomAttributeProvider> DataContract {
get {
return srs_data_contract;
}
}
public IList<ICustomAttributeProvider> XmlSerialization {
get {
return xml_serialization;
}
}
public List<MemberReference> GetRequiredSymbolList (string symbol)
{
List<MemberReference> rv;
if (!RequiredSymbols.TryGetValue (symbol, out rv))
required_symbols [symbol] = rv = new List<MemberReference> ();
return rv;
}
public Dictionary<string, List<MemberReference>> RequiredSymbols {
get {
if (required_symbols == null)
required_symbols = new Dictionary<string, List<MemberReference>> ();
return required_symbols;
}
}
[mtouch] Make sure native symbols from third-party libraries are preserved in dylibs. Fixes #51548. The native linker treats object files (.o) and static libraries (.a files, which are archives of .o files) differently. The native linker will always include object files into the executable: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ld foo.o -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib 0000000000000fe0 T _xxx However, if the object file is inside a static library: $ echo "void xxx () {}" > foo.m $ clang -c foo.m -o foo.o -arch x86_64 $ ar cru foo.a foo.o $ ld foo.a -dylib -o foo.dylib -macosx_version_min 10.12 -arch x86_64 $ nm foo.dylib <no output> This means that our testing library (libtest.a) which is a fat library of _object files_, do not show the problems reported in bug #51548. So: a) I've fixed the creation of libtest.a to be a fat library of _static libraries_. This causes the `FastDev_LinkWithTest` test to fail exactly like in bug #51548. b) I've made mtouch pass `-u <native symbol>` to the native linker, for every native symbol referenced in a managed assembly, when creating a dylib. Amazingly this seems to work fine even with symbols to Objective-C classes (`_OBJC_CLASS_$_<class name>`). c) This also required adding support for collecting the Objective-C names of all managed types registered with Objective-C to the linker. The information is already available in the static registrar, but that would require us to make sure the static registrar is executed before compiling dylibs, which means those two tasks won't be able to run in parallel (also there's no guarantee we'll even run the static registrar). https://bugzilla.xamarin.com/show_bug.cgi?id=51548
2017-01-18 12:25:58 +03:00
public Dictionary<string, TypeDefinition> ObjectiveCClasses {
get {
if (objectivec_classes == null)
objectivec_classes = new Dictionary<string, TypeDefinition> ();
return objectivec_classes;
}
}
public DerivedLinkContext (Pipeline pipeline, AssemblyResolver resolver)
: base (pipeline, resolver)
{
}
}
}