2019-07-24 19:01:14 +03:00
2016-04-21 15:57:02 +03:00
/ *
* Copyright 2011 - 2014 Xamarin Inc . All rights reserved .
* Copyright 2010 Novell Inc .
*
* Authors :
* Sebastien Pouliot < sebastien @xamarin . com >
* Aaron Bockover < abock @xamarin . com >
* Rolf Bjarne Kvinge < rolf @xamarin . com >
* Geoff Norton < gnorton @novell . com >
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
* /
using System ;
using System.Collections ;
using System.Globalization ;
using System.IO ;
using System.Linq ;
using System.Text ;
using System.Text.RegularExpressions ;
using System.Diagnostics ;
using System.ComponentModel ;
using System.Collections.Generic ;
using System.Runtime.InteropServices ;
using System.Xml ;
2017-01-11 23:10:39 +03:00
using System.Threading.Tasks ;
2016-04-21 15:57:02 +03:00
using Mono.Cecil ;
using Mono.Linker ;
using Mono.Options ;
using Mono.Tuner ;
using MonoMac.Tuner ;
using Xamarin.Utils ;
using Xamarin.Linker ;
2018-02-05 18:26:29 +03:00
using Registrar ;
using ObjCRuntime ;
2016-04-21 15:57:02 +03:00
namespace Xamarin.Bundler {
2016-12-01 19:18:30 +03:00
enum Action {
None ,
Help ,
Version ,
RunRegistrar ,
}
2016-04-21 15:57:02 +03:00
public static partial class Driver {
[mtouch/mmp] Fix tracking of whether the static registrar should run again or not. Fixes #641. (#3534)
* [tests] Improve debug spew for the RebuildTest_WithExtensions test.
* [mtouch/mmp] Store/load if the dynamic registrar is removed or not into the cached link results.
Store/load if the dynamic registrar is removed or not into the cached link
results, so that we generate the correct main.m even if cached linker results
are used.
* [mtouch/mmp] The static registrar must not execute if we're loading cached results from the linker.
The static registrar must not execute if we're loading cached results from the
linker, because the static registrar needs information from the linker that's
not restored from the cache.
* [mtouch/mmp] Share Touch code.
* [mtouch/mmp] Make it possible to touch inexistent files (to create them).
* [mtouch/mmp] Fix tracking of whether the static registrar should run again or not.
The recent changes to support optimizing away the dynamic registrar caused the
Xamarin.MTouch.RebuildTest_WithExtensions test to regress.
The problem
-----------
* The linker now collects and stores information the static registrar needs.
* This information is not restored from disk when the linker realizes that it
can reload previously linked assemblies instead of executing again.
* The static registrar runs again (for another reason).
* The information the static registrar needs isn't available, and incorrect
output follows.
So fix 1: show an error if the static registrar runs when the linker loaded
cached results.
The exact scenario the test ran into is this:
* 1st build: everything is new and everything is built.
* 2nd build: contents of .exe changes, the linker runs again, the static
registrar runs again, but sees that the generated output didn't change, so
it doesn't write the new content to disk (this is an optimization to avoid
compiling the registrar.m file again unless needed).
* 3rd build: only the .exe timestamp changes, the linker sees nothing changes
in the contents of the .exe and loads the previously linked assemblies from
disk, the static registrar sees that the .exe's timestamp is newer than
registrar.m's timestamp and run again, but doesn't produce the right result
because it doesn't have the information it needs.
Considered solutions
--------------------
1. Only track timestamps, not file contents. This is not ideal, since it will
result in more work done: in particular for the case above, it would add a
registrar.m compilation in build #2, and linker rerun + static registrar
rerun + registrar.m compilation + final native link in build #3.
2. Always write the output of the static registrar, even if it hasn't changed.
This is not ideal either, since it will also result in more work done: for
the case above, it would add a registrar.m compilation + final native link
in build #3.
3. Always write the output of the static registrar, but track if it changed or
not, and if it didn't, just touch registrar.o instead of recompiling it.
This only means the final native link in build #3 is added (see #5 for why
this is worse than it sounds).
4. Always write the output of the static registrar, but track it it changed or
not, and if it didn't, just touch registrar.o instead of recompiling it,
and track that too, so that the final native link in build #3 isn't needed
anymore. Unfortunately this may result in incorrect behavior, because now
the msbuild tasks will detect that the executable has changed, and may run
dsymutil + strip again. The executable didn't actually change, which means
it would be the previously stripped executable, and thus we'd end up with
an empty .dSYM because we ran dsymtil on an already stripped executable.
5. Idea #4, but write the output of the final link into a temporary directory
instead of the .app, so that we could track whether we should update the
executable in the .app or not. This is not optimal either, because
executables can be *big* (I've seen multi-GB tvOS bitcode executables), and
extra copies of such files should not be taken lightly.
6. Idea #4, but tell the MSBuild tasks that dsymutil/strip doesn't need to be
rerun even if the timestamp of the executable changed. This might actually
work, but now the solution's become quite complex.
Implemented solution
--------------------
Use stamp files to detect whether a file is up-to-date or not.
In particular:
* When we don't write to a file because the new contents are identical to the
old contents, we now touch a .stamp file. This stamp file means "the
accompanying file was determined to be up-to-date when the stamp was
touched."
* When checking whether a file is up-to-date, also check for the presence of a
.stamp file, and if it exists, use the highest timestamp between the stamp
file and the actual file.
Now the test scenario becomes:
* 1st build: everything is new and everything is built.
* 2nd build: contents of .exe changes, the linker runs again, the static
registrar runs again, but sees that the generated output didn't change, so
it doesn't write the new content to disk, but it creates a registrar.m.stamp
file to indicate the point in time when registrar.m was considered up-to-
date.
* 3rd build: only the .exe timestamp changes, the linker sees nothing changes
in the contents of the .exe and loads the previously linked assemblies from
disk, the static registrar sees that the .exe's timestamp is *older* than
registrar.m.stamp's timestamp and doesn't run again.
We only use the stamp file for source code (registrar.[m|h], main.[m|h],
pinvokes.[m|h]), since using it every time has too much potential for running
into other problems (for instance we should never create .stamp files inside
the .app).
Fixes these test failures:
1) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single","",False,System.String[])
single
Expected: <empty>
But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory371/testApp.app/testApp is modified, timestamp: 2/15/2018 3:04:11 PM > 2/15/2018 3:04:09 PM" >
2) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("dual","armv7,arm64",False,System.String[])
dual
Expected: <empty>
But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory375/testApp.app/testApp is modified, timestamp: 2/15/2018 3:06:03 PM > 2/15/2018 3:06:00 PM" >
3) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("llvm","armv7+llvm",False,System.String[])
llvm
Expected: <empty>
But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory379/testApp.app/testApp is modified, timestamp: 2/15/2018 3:07:14 PM > 2/15/2018 3:07:12 PM" >
4) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("debug","",True,System.String[])
debug
Expected: <empty>
But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory383/testApp.app/testApp is modified, timestamp: 2/15/2018 3:08:16 PM > 2/15/2018 3:08:13 PM" >
5) Failed : Xamarin.MTouch.RebuildTest_WithExtensions("single-framework","",False,System.String[])
single-framework
Expected: <empty>
But was: < "/Users/builder/data/lanes/5746/4123bf7e/source/xamarin-macios/tests/mtouch/bin/Debug/tmp-test-dir/Xamarin.Tests.BundlerTool.CreateTemporaryDirectory387/testApp.app/testApp is modified, timestamp: 2/15/2018 3:09:18 PM > 2/15/2018 3:09:16 PM" >
Fixes https://github.com/xamarin/maccore/issues/641
2018-02-19 22:28:04 +03:00
internal const string NAME = "mmp" ;
2018-11-05 10:16:29 +03:00
const string PRODUCT = "Xamarin.Mac" ;
2020-02-19 17:23:52 +03:00
const string LOCAL_BUILD_DIR = "_mac-build" ;
const string FRAMEWORK_LOCATION_VARIABLE = "XAMMAC_FRAMEWORK_PATH" ;
2017-01-31 12:18:45 +03:00
internal static Application App = new Application ( Environment . GetCommandLineArgs ( ) ) ;
2019-04-25 19:08:10 +03:00
static Target BuildTarget ;
2016-04-21 15:57:02 +03:00
static List < string > resources = new List < string > ( ) ;
static List < string > resolved_assemblies = new List < string > ( ) ;
static List < string > ignored_assemblies = new List < string > ( ) ;
2018-12-12 17:55:57 +03:00
public static List < string > native_references = new List < string > ( ) ;
2016-04-21 15:57:02 +03:00
static List < string > native_libraries_copied_in = new List < string > ( ) ;
2016-12-01 19:18:30 +03:00
static Action action ;
2016-04-21 15:57:02 +03:00
static string output_dir ;
static string app_name ;
static bool generate_plist ;
2018-02-13 16:32:00 +03:00
public static RegistrarMode Registrar { get { return App . Registrar ; } private set { App . Registrar = value ; } }
2016-04-21 15:57:02 +03:00
static bool no_executable ;
static bool embed_mono = true ;
2019-10-14 17:18:46 +03:00
static List < string > link_flags ;
2016-11-29 21:44:05 +03:00
static bool? disable_lldb_attach = null ;
2020-02-26 17:49:55 +03:00
static bool? disable_omit_fp = null ;
2016-10-13 18:42:05 +03:00
static string machine_config_path = null ;
2017-08-09 17:39:04 +03:00
static bool bypass_linking_checks = false ;
2016-04-21 15:57:02 +03:00
static string contents_dir ;
static string frameworks_dir ;
static string macos_dir ;
static string resources_dir ;
static string mmp_dir ;
static string custom_bundle_name ;
static string tls_provider ;
static string http_message_provider ;
static string BundleName { get { return custom_bundle_name ! = null ? custom_bundle_name : "MonoBundle" ; } }
2016-07-28 15:49:21 +03:00
static string AppPath { get { return Path . Combine ( macos_dir , app_name ) ; } }
2016-04-21 15:57:02 +03:00
static string icon ;
static string certificate_name ;
public static bool Force ;
Add bindings for NSXpcConnection and related types (#7001)
* Add bindings for NSXpcConnection and related types
* Re-add accidentally deleted file
* Typo fix
* Add NSXpcInterface.CreateForType()
* Add MethodInfo-taking overloads to NSXpcInterface
* Add null check
* Mark methods with wrappers as internal
Also fixed a formatting bug that I didn't catch earlier.
* Change NSXPCProxyCreating methods to be strongly typed
I got rid of the NSXpcProxyCreating interface in this change,
because its only user was NSXpcConnection, and I needed to
inline the protocol methods into the class definition so I
could mark them as [Internal].
* Add missing casts
* Add NSXpcConnectionOptions enum
* Convert NSXpcConnection constructor to use new enum
* Remove now-unneeded manual constructor
* Fix bgen warning
* Typo fix
* Fix selector
* Remove incorrect use of BindAsAttribute
Per the docs, this only works for enums backed
by NSNumber and NSValue, not for enums
passed directly as integers.
* Fix duplicated selector errors
* Throw ArgumentException instead of InvalidOperationException
* Extend AppExtension targets to produce XPC services
Rather than create an entirely new set of targets
(that would require VS and VSMac updates to properly
consume), I have decided to use the existing AppExtension
build targets to produce XPC services as well. All the
user must do is set the $(IsXPCService) property to true in
their project file, and the targets will do The Right Thing™.
Note that this support is Mac-only for now; I may need a bit
of help adjusting them to work on for iOS/watchOS/tvOS, as I
am not as familiar with those platforms.
* Copy XPC service bundles into the correct location
* Move IsXPCService property definition to props file
* Don't pass /extension to mmp for XPC service targets
This would cause the XPC service binary to
be linked incorrectly.
* Add NSXpcConnection/NSXpcInterface.cs files to the build
* Fix build
* Fix build
* Add required type parameter requirements
* Fix type parameter requirements
* Fix return type
* Fix return type of NSXpcInterface.CreateForProtocol ()
* Take ownership of the returned object types
* Adjust XPC service mmp invocation
I need to link the XPC service bundle as if it is an app extension, but
I must not use xamarin_mac_extension_main. I added a new flag to make
this possible.
* Change mmp to correctly construct XPC service bundle
* Set the MonoBundleExecutable Info.plist key for XPC services
* Use the runtime to get the protocol
* Make NSXpcInterface.CreateForProtocol() public
The static registrar must be used for Cocoa to accept the protocol
as a valid XPC interface, but that then seems to break resolving
the protocol from the type. I must therefore hard-code the protocol
name in my code, and that requires I make this constructor public.
* Add XpcInterfaceAttribute
See the doc comment in XpcInterfaceAttribute.cs for why
this type is required. The referenced mmp optimizations
will be added in future commits.
* Add XpcInterfaceAttribute to generator build
* Add support for XpcInterfaceAttribute to the generator
* Force static generation of protocols decorated with XpcInterfaceAttribute
* Change how static registrar translates block parameters
Previously, they would always be marshalled as "id".
This would throw off the XPC subsystem, which parses
the block signature to determine the communication
protocol.
* Undo whitespace noise
* Remove unneeded casts
* Add trailing comma
* Use HasAttribute instead of GetCustomAttribute
* Fix style issues
* Bind NSXpcConnection.auditSessionIdentifier
* Address naming feedback
* Make Get/SetAllowedClasses public
IMHO, passing the selector as a string is just as
usable as passing a MethodInfo, and is also less
verbose if you copy/paste the selector string
from the ExportAttribute. There is no reason why
we cannot have both overloads be public.
* Update overload names to match
* Update more overload names to match
* Make mmp --xpc imply --extension
* Reformat if statement
* Fix build
* Conditionalize creation of PlugIns and XPCServices directories
* Add AutoGeneratedName
Co-Authored-By: Rolf Bjarne Kvinge <rolf@xamarin.com>
* Get rid of ProtocolizeAttribute
* Update availability attributes to please xharness
I actually think xharness is wrong here, since the
NSXPCConnection header lists these types as being
available starting in macOS 10.8.
* Update sharpie ignore files to reflect changes
This should fix the xtro-sharpie test failures CI has been reporting.
* Fix MM4105 error generation
* Adjust error message in test to match mmp
I had to change the error text slightly, because the type of the parameter
cannot be determined where the error is thrown anymore. However, the newer
exception message IMO is just as clear.
* Make exception message match test exactly
* Remove outdated copyright header text
* Remove more outdated copyright header text
* Revert changes to MM4105 error generation
I have a more elegant way of fixing this test now.
* Return "id" if Invoke method cannot be found
This fixes the MM4105 error unit test,
without requiring modification to that test.
* Remove redundant availability attributes
* Add DesignatedInitializerAttribute
* Re-add required code to macOS-Foundation.ignore
* Put DesignatedInitializer on the right constructor
* Update xtro-sharpie ignore files
2019-10-22 16:38:01 +03:00
static bool is_extension , is_xpc_service ;
2018-12-06 22:16:10 +03:00
static bool frameworks_copied_to_bundle_dir ; // Have we copied any frameworks to Foo.app/Contents/Frameworks?
static bool dylibs_copied_to_bundle_dir = > native_libraries_copied_in . Count > 0 ;
2016-05-26 00:20:33 +03:00
2018-11-05 10:16:29 +03:00
static Version min_xcode_version = new Version ( 6 , 0 ) ;
2016-04-21 15:57:02 +03:00
static void ShowHelp ( OptionSet os ) {
Console . WriteLine ( "mmp - Xamarin.Mac Packer" ) ;
Console . WriteLine ( "Copyright 2010 Novell Inc." ) ;
Console . WriteLine ( "Copyright 2011-2016 Xamarin Inc." ) ;
Console . WriteLine ( "Usage: mmp [options] application-exe" ) ;
os . WriteOptionDescriptions ( Console . Out ) ;
}
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
public static bool IsUnifiedFullXamMacFramework { get { return TargetFramework = = TargetFramework . Xamarin_Mac_4_5_Full ; } }
public static bool IsUnifiedFullSystemFramework { get { return TargetFramework = = TargetFramework . Xamarin_Mac_4_5_System ; } }
public static bool IsUnifiedMobile { get { return TargetFramework = = TargetFramework . Xamarin_Mac_2_0_Mobile ; } }
2019-05-23 23:59:40 +03:00
public static bool LinkProhibitedFrameworks { get ; private set ; }
2020-04-14 17:32:42 +03:00
public static bool UseLegacyAssemblyResolution { get ; private set ; }
2016-04-21 15:57:02 +03:00
2020-04-14 10:09:55 +03:00
static string mono_prefix ;
static string MonoPrefix {
get {
if ( mono_prefix = = null ) {
mono_prefix = Environment . GetEnvironmentVariable ( "MONO_PREFIX" ) ;
if ( string . IsNullOrEmpty ( mono_prefix ) )
mono_prefix = "/Library/Frameworks/Mono.framework/Versions/Current" ;
}
return mono_prefix ;
}
}
static string PkgConfig {
get {
var pkg_config = Path . Combine ( MonoPrefix , "bin" , "pkg-config" ) ;
if ( ! File . Exists ( pkg_config ) )
throw ErrorHelper . CreateError ( 5313 , Errors . MX5313 , pkg_config ) ;
return pkg_config ;
}
}
2016-12-23 20:50:35 +03:00
public static string GetArch32Directory ( Application app )
{
throw new InvalidOperationException ( "Arch32Directory when not Mobile or Full?" ) ;
2016-12-01 19:18:30 +03:00
}
2016-12-23 20:50:35 +03:00
public static string GetArch64Directory ( Application app )
{
if ( IsUnifiedMobile )
2020-02-19 17:23:52 +03:00
return Path . Combine ( FrameworkLibDirectory , "x86_64" , "mobile" ) ;
2016-12-23 20:50:35 +03:00
else if ( IsUnifiedFullXamMacFramework )
2020-02-19 17:23:52 +03:00
return Path . Combine ( FrameworkLibDirectory , "x86_64" , "full" ) ;
2016-12-23 20:50:35 +03:00
throw new InvalidOperationException ( "Arch64Directory when not Mobile or Full?" ) ;
2016-12-01 19:18:30 +03:00
}
2017-02-08 22:40:48 +03:00
static AOTOptions aotOptions = null ;
2017-01-11 23:10:39 +03:00
2016-04-21 15:57:02 +03:00
public static bool EnableDebug {
get { return App . EnableDebug ; }
}
2020-02-19 00:05:42 +03:00
static int Main2 ( string [ ] args )
2016-04-21 15:57:02 +03:00
{
var os = new OptionSet ( ) {
{ "f|force" , "Forces the recompilation of code, regardless of timestamps" , v = > Force = true } ,
2017-01-03 17:14:47 +03:00
{ "cache=" , "Specify the directory where temporary build files will be cached" , v = > App . Cache . Location = v } ,
2020-05-05 16:35:02 +03:00
{ "a|assembly=" , "Add an assembly to be processed" , v = > App . References . Add ( v ) } ,
2016-04-21 15:57:02 +03:00
{ "r|resource=" , "Add a resource to be included" , v = > resources . Add ( v ) } ,
{ "o|output=" , "Specify the output path" , v = > output_dir = v } ,
{ "n|name=" , "Specify the application name" , v = > app_name = v } ,
{ "d|debug" , "Build a debug bundle" , v = > App . EnableDebug = true } ,
{ "s|sgen:" , "Use the SGen Garbage Collector" ,
v = > {
if ( ! ParseBool ( v , "sgen" ) )
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 43 , Errors . MX0043 ) ;
2016-04-21 15:57:02 +03:00
} ,
true // do not show the option anymore
} ,
{ "boehm:" , "Enable the Boehm garbage collector" ,
v = > {
if ( ParseBool ( v , "boehm" ) )
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 43 , Errors . MX0043 ) ; } ,
2016-04-21 15:57:02 +03:00
true // do not show the option anymore
} ,
{ "new-refcount:" , "Enable new refcounting logic" ,
v = > {
if ( ! ParseBool ( v , "new-refcount" ) )
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 80 , Errors . MX0080 ) ;
2016-04-21 15:57:02 +03:00
} ,
true // do not show this option anymore
} ,
{ "nolink" , "Do not link the assemblies" , v = > App . LinkMode = LinkMode . None } ,
2020-01-31 23:02:52 +03:00
{ "mapinject" , "Inject a fast method map [deprecated]" , v = > { ErrorHelper . Show ( new MonoMacException ( 16 , false , Errors . MX0016 , "--mapinject" ) ) ; } } ,
2016-04-21 15:57:02 +03:00
{ "minos=" , "Minimum supported version of Mac OS X" ,
v = > {
try {
2017-11-23 19:16:30 +03:00
App . DeploymentTarget = StringUtils . ParseVersion ( v ) ;
2016-04-21 15:57:02 +03:00
} catch ( Exception ex ) {
2020-01-31 23:02:52 +03:00
ErrorHelper . Error ( 26 , ex , Errors . MX0026 , $"minos:{v}" , ex . Message ) ;
2016-04-21 15:57:02 +03:00
}
}
} ,
2017-05-17 01:05:26 +03:00
{ "linkplatform" , "Link only the Xamarin.Mac.dll platform assembly" , v = > App . LinkMode = LinkMode . Platform } ,
2016-04-21 15:57:02 +03:00
{ "linksdkonly" , "Link only the SDK assemblies" , v = > App . LinkMode = LinkMode . SDKOnly } ,
{ "linkskip=" , "Skip linking of the specified assembly" , v = > App . LinkSkipped . Add ( v ) } ,
{ "i18n=" , "List of i18n assemblies to copy to the output directory, separated by commas (none,all,cjk,mideast,other,rare,west)" , v = > App . I18n = LinkerOptions . ParseI18nAssemblies ( v ) } ,
{ "c|certificate=" , "The Code Signing certificate for the application" , v = > { certificate_name = v ; } } ,
{ "p" , "Generate a plist for the application" , v = > { generate_plist = true ; } } ,
{ "i|icon=" , "Use the specified file as the bundle icon" , v = > { icon = v ; } } ,
{ "xml=" , "Provide an extra XML definition file to the linker" , v = > App . Definitions . Add ( v ) } ,
2018-05-29 20:08:34 +03:00
{ "time" , v = > WatchLevel + + } ,
2020-05-11 17:27:19 +03:00
{ "arch=" , "Specify the architecture ('x86_64') of the native runtime (default to 'x86_64', which is the only valid value) [DEPRECATED, use --abi instead]" , v = > { App . ParseAbi ( v ) ; } , true } ,
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
{ "profile=" , "(Obsoleted in favor of --target-framework) Specify the .NET profile to use" , v = > SetTargetFramework ( v ) , true } ,
2018-04-30 16:33:48 +03:00
{ "force-thread-check" , "Keep UI thread checks inside (even release) builds [DEPRECATED, use --optimize=-remove-uithread-checks instead]" , v = > { App . Optimizations . RemoveUIThreadChecks = false ; } , true } ,
{ "disable-thread-check" , "Remove UI thread checks inside (even debug) builds [DEPRECATED, use --optimize=remove-uithread-checks instead]" , v = > { App . Optimizations . RemoveUIThreadChecks = true ; } , true } ,
2017-10-20 23:42:14 +03:00
{ "registrar:" , "Specify the registrar to use (dynamic [default], static, partial)" , v = > {
2016-04-21 15:57:02 +03:00
switch ( v ) {
case "static" :
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . Static ;
2016-04-21 15:57:02 +03:00
break ;
case "dynamic" :
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . Dynamic ;
2016-04-21 15:57:02 +03:00
break ;
2016-12-05 23:16:03 +03:00
case "partial" :
case "partial-static" :
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . PartialStatic ;
2016-12-05 23:16:03 +03:00
break ;
2016-04-21 15:57:02 +03:00
case "il" :
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . Dynamic ;
2016-04-21 15:57:02 +03:00
break ;
case "default" :
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . Default ;
2016-04-21 15:57:02 +03:00
break ;
default :
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 20 , true , Errors . MX0020 , "--registrar" , "dynamic, static, partial, or default" ) ;
2016-04-21 15:57:02 +03:00
}
2017-10-20 23:42:14 +03:00
}
2016-04-21 15:57:02 +03:00
} ,
{ "sdk=" , "Specifies the SDK version to compile against (version, for example \"10.9\")" ,
v = > {
try {
2017-11-23 19:16:30 +03:00
App . SdkVersion = StringUtils . ParseVersion ( v ) ;
2016-04-21 15:57:02 +03:00
} catch ( Exception ex ) {
2020-01-31 23:02:52 +03:00
ErrorHelper . Error ( 26 , ex , Errors . MX0026 , $"sdk:{v}" , ex . Message ) ;
2016-04-21 15:57:02 +03:00
}
}
} ,
{ "no-root-assembly" , "Specifies that mmp will not process a root assembly. This is if the app needs to be packaged with a different directory structure than what mmp supports." , v = > no_executable = true } ,
{ "embed-mono:" , "Specifies whether the app will embed the Mono runtime, or if it will use the system Mono found at runtime (default: true)." , v = > {
embed_mono = ParseBool ( v , "embed-mono" ) ;
}
} ,
{ "link_flags=" , "Specifies additional arguments to the native linker." ,
2019-10-14 17:18:46 +03:00
v = > {
if ( ! StringUtils . TryParseArguments ( v , out var lf , out var ex ) )
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 26 , ex , Errors . MX0026 , $"-link_flags={v}" , ex . Message ) ;
2019-10-14 17:18:46 +03:00
if ( link_flags = = null )
link_flags = new List < string > ( ) ;
link_flags . AddRange ( lf ) ;
}
2016-04-21 15:57:02 +03:00
} ,
{ "ignore-native-library=" , "Add a native library to be ignored during assembly scanning and packaging" ,
v = > ignored_assemblies . Add ( v )
} ,
{ "native-reference=" , "Add a native (static, dynamic, or framework) library to be included in the bundle. Can be specified multiple times." ,
v = > {
native_references . Add ( v ) ;
if ( v . EndsWith ( ".framework" , true , CultureInfo . InvariantCulture ) )
App . Frameworks . Add ( v ) ;
}
} ,
{ "custom_bundle_name=" , "Specify a custom name for the MonoBundle folder." , v = > custom_bundle_name = v , true } , // Hidden hack for "universal binaries"
{ "tls-provider=" , "Specify the default TLS provider" , v = > { tls_provider = v ; } } ,
{ "http-message-handler=" , "Specify the default HTTP Message Handler" , v = > { http_message_provider = v ; } } ,
2016-05-26 00:20:33 +03:00
{ "extension" , "Specifies an app extension" , v = > is_extension = true } ,
Add bindings for NSXpcConnection and related types (#7001)
* Add bindings for NSXpcConnection and related types
* Re-add accidentally deleted file
* Typo fix
* Add NSXpcInterface.CreateForType()
* Add MethodInfo-taking overloads to NSXpcInterface
* Add null check
* Mark methods with wrappers as internal
Also fixed a formatting bug that I didn't catch earlier.
* Change NSXPCProxyCreating methods to be strongly typed
I got rid of the NSXpcProxyCreating interface in this change,
because its only user was NSXpcConnection, and I needed to
inline the protocol methods into the class definition so I
could mark them as [Internal].
* Add missing casts
* Add NSXpcConnectionOptions enum
* Convert NSXpcConnection constructor to use new enum
* Remove now-unneeded manual constructor
* Fix bgen warning
* Typo fix
* Fix selector
* Remove incorrect use of BindAsAttribute
Per the docs, this only works for enums backed
by NSNumber and NSValue, not for enums
passed directly as integers.
* Fix duplicated selector errors
* Throw ArgumentException instead of InvalidOperationException
* Extend AppExtension targets to produce XPC services
Rather than create an entirely new set of targets
(that would require VS and VSMac updates to properly
consume), I have decided to use the existing AppExtension
build targets to produce XPC services as well. All the
user must do is set the $(IsXPCService) property to true in
their project file, and the targets will do The Right Thing™.
Note that this support is Mac-only for now; I may need a bit
of help adjusting them to work on for iOS/watchOS/tvOS, as I
am not as familiar with those platforms.
* Copy XPC service bundles into the correct location
* Move IsXPCService property definition to props file
* Don't pass /extension to mmp for XPC service targets
This would cause the XPC service binary to
be linked incorrectly.
* Add NSXpcConnection/NSXpcInterface.cs files to the build
* Fix build
* Fix build
* Add required type parameter requirements
* Fix type parameter requirements
* Fix return type
* Fix return type of NSXpcInterface.CreateForProtocol ()
* Take ownership of the returned object types
* Adjust XPC service mmp invocation
I need to link the XPC service bundle as if it is an app extension, but
I must not use xamarin_mac_extension_main. I added a new flag to make
this possible.
* Change mmp to correctly construct XPC service bundle
* Set the MonoBundleExecutable Info.plist key for XPC services
* Use the runtime to get the protocol
* Make NSXpcInterface.CreateForProtocol() public
The static registrar must be used for Cocoa to accept the protocol
as a valid XPC interface, but that then seems to break resolving
the protocol from the type. I must therefore hard-code the protocol
name in my code, and that requires I make this constructor public.
* Add XpcInterfaceAttribute
See the doc comment in XpcInterfaceAttribute.cs for why
this type is required. The referenced mmp optimizations
will be added in future commits.
* Add XpcInterfaceAttribute to generator build
* Add support for XpcInterfaceAttribute to the generator
* Force static generation of protocols decorated with XpcInterfaceAttribute
* Change how static registrar translates block parameters
Previously, they would always be marshalled as "id".
This would throw off the XPC subsystem, which parses
the block signature to determine the communication
protocol.
* Undo whitespace noise
* Remove unneeded casts
* Add trailing comma
* Use HasAttribute instead of GetCustomAttribute
* Fix style issues
* Bind NSXpcConnection.auditSessionIdentifier
* Address naming feedback
* Make Get/SetAllowedClasses public
IMHO, passing the selector as a string is just as
usable as passing a MethodInfo, and is also less
verbose if you copy/paste the selector string
from the ExportAttribute. There is no reason why
we cannot have both overloads be public.
* Update overload names to match
* Update more overload names to match
* Make mmp --xpc imply --extension
* Reformat if statement
* Fix build
* Conditionalize creation of PlugIns and XPCServices directories
* Add AutoGeneratedName
Co-Authored-By: Rolf Bjarne Kvinge <rolf@xamarin.com>
* Get rid of ProtocolizeAttribute
* Update availability attributes to please xharness
I actually think xharness is wrong here, since the
NSXPCConnection header lists these types as being
available starting in macOS 10.8.
* Update sharpie ignore files to reflect changes
This should fix the xtro-sharpie test failures CI has been reporting.
* Fix MM4105 error generation
* Adjust error message in test to match mmp
I had to change the error text slightly, because the type of the parameter
cannot be determined where the error is thrown anymore. However, the newer
exception message IMO is just as clear.
* Make exception message match test exactly
* Remove outdated copyright header text
* Remove more outdated copyright header text
* Revert changes to MM4105 error generation
I have a more elegant way of fixing this test now.
* Return "id" if Invoke method cannot be found
This fixes the MM4105 error unit test,
without requiring modification to that test.
* Remove redundant availability attributes
* Add DesignatedInitializerAttribute
* Re-add required code to macOS-Foundation.ignore
* Put DesignatedInitializer on the right constructor
* Update xtro-sharpie ignore files
2019-10-22 16:38:01 +03:00
{ "xpc" , "Specifies an XPC service" , v = > { is_extension = true ; is_xpc_service = true ; } } ,
2016-06-08 19:47:09 +03:00
{ "allow-unsafe-gac-resolution" , "Allow MSBuild to resolve from the System GAC" , v = > { } , true } , // Used in Xamarin.Mac.XM45.targets and must be ignored here. Hidden since it is a total hack. If you can use it, you don't need support
2017-08-09 17:39:04 +03:00
{ "force-unsupported-linker" , "Bypass safety checkes preventing unsupported linking options." , v = > bypass_linking_checks = true , true } , // Undocumented option for a reason, You get to keep the pieces when it breaks
2016-10-13 18:42:05 +03:00
{ "disable-lldb-attach=" , "Disable automatic lldb attach on crash" , v = > disable_lldb_attach = ParseBool ( v , "disable-lldb-attach" ) } ,
2020-02-26 17:49:55 +03:00
{ "disable-omit-fp=" , "Disable a JIT optimization where the frame pointer is omitted from the stack. This is optimization is disabled by default for debug builds." , v = > disable_omit_fp = ParseBool ( v , "disable-omit-fp" ) } ,
2016-10-13 18:42:05 +03:00
{ "machine-config=" , "Custom machine.config file to copy into MonoBundle/mono/4.5/machine.config. Pass \"\" to copy in a valid \"empty\" config file." , v = > machine_config_path = v } ,
2016-12-01 19:18:30 +03:00
{ "runregistrar:" , "Runs the registrar on the input assembly and outputs a corresponding native library." ,
v = > {
action = Action . RunRegistrar ;
App . RegistrarOutputLibrary = v ;
} ,
true /* this is an internal option */
} ,
2020-02-19 17:23:52 +03:00
{ "xamarin-framework-directory=" , "The framework directory" , v = > { framework_dir = v ; } , true } ,
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
{ "xamarin-full-framework" , "Used with --target-framework=4.5 to select XM Full Target Framework. Deprecated, use --target-framework=Xamarin.Mac,Version=v4.0,Profile=Full instead." , v = > { TargetFramework = TargetFramework . Xamarin_Mac_4_5_Full ; } , true } ,
{ "xamarin-system-framework" , "Used with --target-framework=4.5 to select XM Full Target Framework. Deprecated, use --target-framework=Xamarin.Mac,Version=v4.0,Profile=System instead." , v = > { TargetFramework = TargetFramework . Xamarin_Mac_4_5_System ; } , true } ,
2017-10-20 23:42:14 +03:00
{ "aot:" , "Specify assemblies that should be AOT compiled\n- none - No AOT (default)\n- all - Every assembly in MonoBundle\n- core - Xamarin.Mac, System, mscorlib\n- sdk - Xamarin.Mac.dll and BCL assemblies\n- |hybrid after option enables hybrid AOT which allows IL stripping but is slower (only valid for 'all')\n - Individual files can be included for AOT via +FileName.dll and excluded via -FileName.dll\n\nExamples:\n --aot:all,-MyAssembly.dll\n --aot:core,+MyOtherAssembly.dll,-mscorlib.dll" ,
2017-01-11 23:10:39 +03:00
v = > {
2017-02-08 22:40:48 +03:00
aotOptions = new AOTOptions ( v ) ;
2017-01-11 23:10:39 +03:00
}
} ,
2019-05-23 23:59:40 +03:00
{ "link-prohibited-frameworks" , "Natively link against prohibited (rejected by AppStore) frameworks" , v = > { LinkProhibitedFrameworks = true ; } } ,
2020-02-21 06:25:23 +03:00
{ "warn-on-type-ref=" , "Warn if any of the comma-separated types is referenced by assemblies - both before and after linking" , v = > {
App . WarnOnTypeRef . AddRange ( v . Split ( new char [ ] { ',' } , StringSplitOptions . RemoveEmptyEntries ) ) ;
}
} ,
2020-04-14 17:32:42 +03:00
{ "legacy-assembly-resolution" , "Use a legacy assembly resolution logic when using the Xamarin.Mac Full framework." , v = > { UseLegacyAssemblyResolution = true ; } , false /* hidden until we know if it's needed */ } ,
2016-04-21 15:57:02 +03:00
} ;
2019-12-20 18:27:36 +03:00
var extra_args = Environment . GetEnvironmentVariable ( "MMP_ENV_OPTIONS" ) ;
if ( ! string . IsNullOrEmpty ( extra_args ) ) {
var l = new List < string > ( args ) ;
l . AddRange ( extra_args . Split ( new char [ ] { ' ' } , StringSplitOptions . RemoveEmptyEntries ) ) ;
args = l . ToArray ( ) ;
}
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
if ( ParseOptions ( App , os , args , ref action ) )
return 0 ;
2017-11-16 18:02:34 +03:00
2017-02-08 22:40:48 +03:00
if ( aotOptions = = null ) {
string forceAotVariable = Environment . GetEnvironmentVariable ( "XM_FORCE_AOT" ) ;
if ( forceAotVariable ! = null )
aotOptions = new AOTOptions ( forceAotVariable ) ;
}
2016-12-23 20:50:35 +03:00
App . RuntimeOptions = RuntimeOptions . Create ( App , http_message_provider , tls_provider ) ;
2016-04-21 15:57:02 +03:00
2019-07-24 19:01:14 +03:00
if ( IsUnifiedFullSystemFramework ) {
2016-04-21 15:57:02 +03:00
// With newer Mono builds, the system assemblies passed to us by msbuild are
// no longer safe to copy into the bundle. They are stripped "fake" BCL
// copies. So we redirect to the "real" ones. Thanks TargetFrameworkDirectories :(
Regex monoAPIRegex = new Regex ( "lib/mono/.*-api/" , RegexOptions . IgnoreCase ) ;
Regex monoAPIFacadesRegex = new Regex ( "lib/mono/.*-api/Facades/" , RegexOptions . IgnoreCase ) ;
FixReferences ( x = > monoAPIRegex . IsMatch ( x ) & & ! monoAPIFacadesRegex . IsMatch ( x ) , x = > x . Replace ( monoAPIRegex . Match ( x ) . Value , "lib/mono/4.5/" ) ) ;
}
2018-10-05 17:43:53 +03:00
if ( Registrar = = RegistrarMode . PartialStatic & & App . LinkMode ! = LinkMode . None )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 2110 , true , Errors . MM2110 ) ;
2018-10-05 17:43:53 +03:00
2016-04-21 15:57:02 +03:00
// sanity check as this should never happen: we start out by not setting any
// Unified/Classic properties, and only IsUnifiedMobile if we are are on the
// XM framework. If we are not, we set IsUnifiedFull to true iff we detect
// an explicit reference to the full unified Xamarin.Mac assembly; that is
// only one of IsUnifiedMobile or IsUnifiedFull should ever be true. IsUnified
// is true if one of IsUnifiedMobile or IsUnifiedFull is true; IsClassic is
// implied if IsUnified is not true;
int IsUnifiedCount = IsUnifiedMobile ? 1 : 0 ;
if ( IsUnifiedFullSystemFramework )
IsUnifiedCount + + ;
if ( IsUnifiedFullXamMacFramework )
IsUnifiedCount + + ;
2019-07-24 19:01:14 +03:00
if ( IsUnifiedCount ! = 1 )
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 99 , Errors . MX0099 , "IsClassic/IsUnified/IsUnifiedMobile/IsUnifiedFullSystemFramework/IsUnifiedFullXamMacFramework logic regression" ) ;
2016-04-21 15:57:02 +03:00
2017-05-30 17:23:28 +03:00
ValidateXamarinMacReference ( ) ;
2017-08-09 17:39:04 +03:00
if ( ! bypass_linking_checks & & ( IsUnifiedFullSystemFramework | | IsUnifiedFullXamMacFramework ) ) {
2017-05-17 01:05:26 +03:00
switch ( App . LinkMode ) {
case LinkMode . None :
case LinkMode . Platform :
break ;
default :
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 2007 , true , Errors . MM2007 ) ;
2017-05-17 01:05:26 +03:00
}
}
2016-04-21 15:57:02 +03:00
2018-11-05 10:16:29 +03:00
ValidateXcode ( false , true ) ;
2016-12-01 19:18:30 +03:00
2017-04-05 22:38:40 +03:00
App . Initialize ( ) ;
2017-09-29 20:45:53 +03:00
// InitializeCommon needs SdkVersion set to something valid
ValidateSDKVersion ( ) ;
2018-03-02 16:30:18 +03:00
// InitializeCommon needs the current profile
2019-07-24 19:01:14 +03:00
if ( IsUnifiedFullXamMacFramework | | IsUnifiedFullSystemFramework )
Profile . Current = new XamarinMacProfile ( ) ;
2018-03-02 16:30:18 +03:00
else
2019-07-24 19:01:14 +03:00
Profile . Current = new MacMobileProfile ( ) ;
2018-03-02 16:30:18 +03:00
2019-04-25 19:08:10 +03:00
BuildTarget = new Target ( App ) ;
2019-05-09 22:36:42 +03:00
App . Targets . Add ( BuildTarget ) ;
2016-05-11 13:24:55 +03:00
App . InitializeCommon ( ) ;
2018-09-14 20:12:59 +03:00
Log ( "Xamarin.Mac {0}.{1}" , Constants . Version , Constants . Revision ) ;
2020-02-18 23:44:19 +03:00
Log ( 1 , "Selected target framework: {0}; API: Unified" , targetFramework ) ;
2018-08-13 21:09:31 +03:00
Log ( 1 , $"Selected Linking: '{App.LinkMode}'" ) ;
2016-12-13 21:12:03 +03:00
2016-12-01 19:18:30 +03:00
if ( action = = Action . RunRegistrar ) {
App . Registrar = RegistrarMode . Static ;
App . RunRegistrar ( ) ;
2020-02-19 00:05:42 +03:00
return 0 ;
2016-12-01 19:18:30 +03:00
}
2016-04-21 15:57:02 +03:00
try {
2017-11-16 18:02:34 +03:00
Pack ( App . RootAssemblies ) ;
2016-04-21 15:57:02 +03:00
} finally {
2017-01-03 17:14:47 +03:00
if ( App . Cache . IsCacheTemporary ) {
2016-04-21 15:57:02 +03:00
// If we used a temporary directory we created ourselves for the cache
// (in which case it's more a temporary location where we store the
// temporary build products than a cache), it will not be used again,
// so just delete it.
try {
2017-01-03 17:14:47 +03:00
Directory . Delete ( App . Cache . Location , true ) ;
2016-04-21 15:57:02 +03:00
} catch {
// Don't care.
}
} else {
// Write the cache data as the last step, so there is no half-done/incomplete (but yet detected as valid) cache.
2017-01-03 17:14:47 +03:00
App . Cache . ValidateCache ( ) ;
2016-04-21 15:57:02 +03:00
}
}
Log ( "bundling complete" ) ;
2020-02-19 00:05:42 +03:00
return 0 ;
2016-04-21 15:57:02 +03:00
}
2017-05-30 17:23:28 +03:00
static void ValidateXamarinMacReference ( )
{
// Many Xamarin.Mac references are technically valid, so whitelisting risks breaking working project
// However, passing in Mobile / Xamarin.Mac folders and resolving full/4.5 or vice versa is
// far from expected. So catch the common cases if we can
2020-05-05 16:35:02 +03:00
string reference = App . References . FirstOrDefault ( x = > x . EndsWith ( "Xamarin.Mac.dll" , StringComparison . Ordinal ) ) ;
2017-05-30 17:23:28 +03:00
if ( reference ! = null ) {
bool valid = true ;
if ( IsUnifiedMobile )
valid = ! reference . Contains ( "full/" ) & & ! reference . Contains ( "4.5/" ) ;
else if ( IsUnifiedFullXamMacFramework | | IsUnifiedFullSystemFramework )
valid = ! reference . Contains ( "mobile/" ) & & ! reference . Contains ( "Xamarin.Mac/" ) ;
if ( ! valid )
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 1407 , Errors . MM1407 , reference , TargetFramework ) ;
2017-05-30 17:23:28 +03:00
}
}
2016-04-21 15:57:02 +03:00
static void FixReferences ( Func < string , bool > match , Func < string , string > fix )
{
2020-05-05 16:35:02 +03:00
for ( var i = 0 ; i < App . References . Count ; i + + ) {
if ( match ( App . References [ i ] ) )
App . References [ i ] = fix ( App . References [ i ] ) ;
}
2016-04-21 15:57:02 +03:00
}
2016-12-13 21:12:03 +03:00
// SDK versions are only passed in as X.Y but some frameworks/APIs require X.Y.Z
// Mutate them if we have a new enough Xcode
static Version MutateSDKVersionToPointRelease ( Version rv )
{
if ( rv . Major = = 10 & & ( rv . Revision = = 0 | | rv . Revision = = - 1 ) ) {
2020-03-06 03:48:28 +03:00
if ( rv . Minor = = 15 & & XcodeVersion > = new Version ( 11 , 4 ) )
return new Version ( rv . Major , rv . Minor , 4 ) ;
2018-02-27 14:53:13 +03:00
if ( rv . Minor = = 13 & & XcodeVersion > = new Version ( 9 , 3 ) )
return new Version ( rv . Major , rv . Minor , 4 ) ;
2017-11-28 23:29:05 +03:00
if ( rv . Minor = = 13 & & XcodeVersion > = new Version ( 9 , 2 ) )
return new Version ( rv . Major , rv . Minor , 2 ) ;
2018-02-27 14:53:13 +03:00
if ( rv . Minor = = 13 & & XcodeVersion > = new Version ( 9 , 1 ) )
return new Version ( rv . Major , rv . Minor , 1 ) ;
2017-02-24 11:17:03 +03:00
if ( rv . Minor = = 12 & & XcodeVersion > = new Version ( 8 , 3 ) )
return new Version ( rv . Major , rv . Minor , 4 ) ;
2016-12-13 21:12:03 +03:00
if ( rv . Minor = = 12 & & XcodeVersion > = new Version ( 8 , 2 ) )
return new Version ( rv . Major , rv . Minor , 2 ) ;
if ( rv . Minor = = 12 & & XcodeVersion > = new Version ( 8 , 1 ) )
return new Version ( rv . Major , rv . Minor , 1 ) ;
if ( rv . Minor = = 11 & & XcodeVersion > = new Version ( 7 , 3 ) )
return new Version ( rv . Major , rv . Minor , 4 ) ;
}
2018-07-02 14:45:34 +03:00
// Since Version has wrong behavior:
// new Version (10, 14) < new Version (10, 14, 0) => true
// Force any unset revision to 0 instead of -1
if ( rv . Revision = = - 1 )
return new Version ( rv . Major , rv . Minor , 0 ) ;
2016-12-13 21:12:03 +03:00
return rv ;
}
// Validates that sdk_version is set to a reasonable value before compile
static void ValidateSDKVersion ( )
2016-04-21 15:57:02 +03:00
{
2016-12-23 20:50:35 +03:00
if ( App . SdkVersion ! = null ) {
2016-12-13 21:12:03 +03:00
// We can't do mutation while parsing command line args as XcodeVersion isn't set yet
2016-12-23 20:50:35 +03:00
App . SdkVersion = MutateSDKVersionToPointRelease ( App . SdkVersion ) ;
2016-04-21 15:57:02 +03:00
return ;
2016-12-13 21:12:03 +03:00
}
2016-04-21 15:57:02 +03:00
if ( string . IsNullOrEmpty ( DeveloperDirectory ) )
return ;
var sdks = new List < Version > ( ) ;
var sdkdir = Path . Combine ( DeveloperDirectory , "Platforms" , "MacOSX.platform" , "Developer" , "SDKs" ) ;
foreach ( var sdkpath in Directory . GetDirectories ( sdkdir ) ) {
var sdk = Path . GetFileName ( sdkpath ) ;
2016-10-20 16:34:26 +03:00
if ( sdk . StartsWith ( "MacOSX" , StringComparison . Ordinal ) & & sdk . EndsWith ( ".sdk" , StringComparison . Ordinal ) ) {
2016-04-21 15:57:02 +03:00
Version sdkVersion ;
if ( Version . TryParse ( sdk . Substring ( 6 , sdk . Length - 10 ) , out sdkVersion ) )
sdks . Add ( sdkVersion ) ;
}
}
if ( sdks . Count > 0 ) {
sdks . Sort ( ) ;
// select the highest.
2016-12-23 20:50:35 +03:00
App . SdkVersion = MutateSDKVersionToPointRelease ( sdks [ sdks . Count - 1 ] ) ;
2016-04-21 15:57:02 +03:00
}
}
static void CheckForUnknownCommandLineArguments ( IList < Exception > exceptions , IList < string > arguments )
{
for ( int i = arguments . Count - 1 ; i > = 0 ; i - - ) {
2016-10-20 16:34:26 +03:00
if ( arguments [ i ] . StartsWith ( "-" , StringComparison . Ordinal ) ) {
2020-01-31 23:02:52 +03:00
exceptions . Add ( ErrorHelper . CreateError ( 18 , Errors . MX0018 , arguments [ i ] ) ) ;
2016-04-21 15:57:02 +03:00
arguments . RemoveAt ( i ) ;
}
}
}
2018-02-12 16:42:19 +03:00
public static void SelectRegistrar ( )
2016-04-21 15:57:02 +03:00
{
2018-02-12 16:42:19 +03:00
if ( Registrar = = RegistrarMode . Default ) {
2016-12-05 23:16:03 +03:00
if ( ! App . EnableDebug )
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . Static ;
2019-07-24 19:01:14 +03:00
else if ( App . LinkMode = = LinkMode . None & & embed_mono & & App . IsDefaultMarshalManagedExceptionMode & & File . Exists ( PartialStaticLibrary ) )
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . PartialStatic ;
2016-12-05 23:16:03 +03:00
else
2017-09-29 20:45:53 +03:00
Registrar = RegistrarMode . Dynamic ;
Log ( 1 , $"Defaulting registrar to '{Registrar}'" ) ;
2016-12-05 23:16:03 +03:00
}
2018-02-12 16:42:19 +03:00
}
static void Pack ( IList < string > unprocessed )
{
string fx_dir = null ;
string root_assembly = null ;
var native_libs = new Dictionary < string , List < MethodDefinition > > ( ) ;
2016-04-21 15:57:02 +03:00
if ( no_executable ) {
if ( unprocessed . Count ! = 0 ) {
var exceptions = new List < Exception > ( ) ;
CheckForUnknownCommandLineArguments ( exceptions , unprocessed ) ;
2020-01-31 23:02:52 +03:00
exceptions . Add ( new MonoMacException ( 50 , true , Errors . MM0050 , unprocessed . Count , string . Join ( "', '" , unprocessed . ToArray ( ) ) ) ) ;
2016-04-21 15:57:02 +03:00
throw new AggregateException ( exceptions ) ;
}
if ( string . IsNullOrEmpty ( output_dir ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 51 , true , Errors . MM0051 ) ;
2016-04-21 15:57:02 +03:00
if ( string . IsNullOrEmpty ( app_name ) )
app_name = Path . GetFileNameWithoutExtension ( output_dir ) ;
} else {
if ( unprocessed . Count ! = 1 ) {
var exceptions = new List < Exception > ( ) ;
CheckForUnknownCommandLineArguments ( exceptions , unprocessed ) ;
if ( unprocessed . Count > 1 ) {
2020-01-31 23:02:52 +03:00
exceptions . Add ( ErrorHelper . CreateError ( 8 , Errors . MM0008 , unprocessed . Count , string . Join ( "', '" , unprocessed . ToArray ( ) ) ) ) ;
2016-04-21 15:57:02 +03:00
} else if ( unprocessed . Count = = 0 ) {
2020-01-31 23:02:52 +03:00
exceptions . Add ( ErrorHelper . CreateError ( 17 , Errors . MX0017 ) ) ;
2016-04-21 15:57:02 +03:00
}
throw new AggregateException ( exceptions ) ;
}
root_assembly = unprocessed [ 0 ] ;
if ( ! File . Exists ( root_assembly ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 7 , true , Errors . MX0007 , root_assembly ) ;
2018-03-02 16:30:18 +03:00
2016-04-21 15:57:02 +03:00
string root_wo_ext = Path . GetFileNameWithoutExtension ( root_assembly ) ;
if ( Profile . IsSdkAssembly ( root_wo_ext ) | | Profile . IsProductAssembly ( root_wo_ext ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 3 , true , Errors . MX0003 , root_wo_ext ) ;
2016-04-21 15:57:02 +03:00
2020-05-05 16:35:02 +03:00
if ( App . References . Exists ( a = > Path . GetFileNameWithoutExtension ( a ) . Equals ( root_wo_ext ) ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 23 , true , Errors . MM0023 , root_wo_ext ) ;
2016-04-21 15:57:02 +03:00
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
string monoFrameworkDirectory ;
if ( TargetFramework = = TargetFramework . Xamarin_Mac_2_0_Mobile ) {
monoFrameworkDirectory = TargetFramework . Identifier ;
} else {
2016-04-21 15:57:02 +03:00
monoFrameworkDirectory = "4.5" ;
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
}
2016-04-21 15:57:02 +03:00
fx_dir = Path . Combine ( MonoDirectory , "lib" , "mono" , monoFrameworkDirectory ) ;
if ( ! Directory . Exists ( fx_dir ) )
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
throw new MonoMacException ( 1403 , true , Errors . MM1403 , "Directory" , fx_dir , TargetFramework ) ;
2016-04-21 15:57:02 +03:00
2020-05-05 16:35:02 +03:00
App . References . Add ( root_assembly ) ;
BuildTarget . Resolver . CommandLineAssemblies = App . References ;
2016-04-21 15:57:02 +03:00
2020-04-14 17:32:42 +03:00
if ( ! UseLegacyAssemblyResolution & & ( IsUnifiedFullSystemFramework | | IsUnifiedFullXamMacFramework ) ) {
// We need to look in the GAC/System mono for both FullSystem and FullXamMac, because that's
// how we've been resolving assemblies in the past (Cecil has a fall-back mode where it looks
// in the GAC, and we never disabled that, meaning that we always looked in the GAC if failing
// to resolve from somewhere else). This makes it explicit that we look in the GAC, and we
// now also warn when using FullXamMac and finding assemblies in the GAC.
BuildTarget . Resolver . GlobalAssemblyCache = Path . Combine ( SystemMonoDirectory , "lib" , "mono" , "gac" ) ;
var framework_dir = Path . GetDirectoryName ( typeof ( object ) . Module . FullyQualifiedName ) ;
BuildTarget . Resolver . SystemFrameworkDirectories = new [ ] {
framework_dir ,
Path . Combine ( framework_dir , "Facades" )
} ;
}
2016-04-21 15:57:02 +03:00
if ( string . IsNullOrEmpty ( app_name ) )
app_name = root_wo_ext ;
if ( string . IsNullOrEmpty ( output_dir ) )
output_dir = Environment . CurrentDirectory ;
}
CreateDirectoriesIfNeeded ( ) ;
2019-02-11 19:29:13 +03:00
2020-05-11 17:27:19 +03:00
App . SetDefaultAbi ( ) ;
App . ValidateAbi ( ) ;
BuildTarget . Abis = App . Abis . ToList ( ) ;
2019-02-11 19:29:13 +03:00
2016-04-21 15:57:02 +03:00
Watch ( "Setup" , 1 ) ;
if ( ! no_executable ) {
BuildTarget . Resolver . FrameworkDirectory = fx_dir ;
BuildTarget . Resolver . RootDirectory = Path . GetDirectoryName ( Path . GetFullPath ( root_assembly ) ) ;
GatherAssemblies ( ) ;
CheckReferences ( ) ;
2017-04-28 19:09:03 +03:00
if ( ! is_extension & & ! resolved_assemblies . Exists ( f = > Path . GetExtension ( f ) . ToLower ( ) = = ".exe" ) & & ! App . Embeddinator )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 79 , true , Errors . MM0079 , "" ) ;
2016-04-21 15:57:02 +03:00
// i18n must be dealed outside linking too (e.g. bug 11448)
if ( App . LinkMode = = LinkMode . None )
CopyI18nAssemblies ( App . I18n ) ;
CopyAssemblies ( ) ;
Watch ( "Copy Assemblies" , 1 ) ;
}
CopyResources ( ) ;
Watch ( "Copy Resources" , 1 ) ;
CopyConfiguration ( ) ;
Watch ( "Copy Configuration" , 1 ) ;
ExtractNativeLinkInfo ( ) ;
2017-11-16 18:18:18 +03:00
BuildTarget . ValidateAssembliesBeforeLink ( ) ;
2016-04-21 15:57:02 +03:00
if ( ! no_executable ) {
foreach ( var nr in native_references ) {
if ( ! native_libs . ContainsKey ( nr ) )
native_libs . Add ( nr , null ) ;
}
var linked_native_libs = Link ( ) ;
foreach ( var kvp in linked_native_libs ) {
List < MethodDefinition > methods ;
2016-11-23 23:00:01 +03:00
if ( native_libs . TryGetValue ( kvp . Key , out methods ) ) {
if ( methods = = null ) {
methods = new List < MethodDefinition > ( ) ;
native_libs [ kvp . Key ] = methods ;
}
2016-04-21 15:57:02 +03:00
methods . AddRange ( kvp . Value ) ;
2016-11-23 23:00:01 +03:00
}
else {
2016-04-21 15:57:02 +03:00
native_libs . Add ( kvp . Key , kvp . Value ) ;
2016-11-23 23:00:01 +03:00
}
2016-04-21 15:57:02 +03:00
}
Watch ( string . Format ( "Linking (mode: '{0}')" , App . LinkMode ) , 1 ) ;
}
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
2017-04-05 22:38:40 +03:00
// These must occur _after_ Linking
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
BuildTarget . CollectAllSymbols ( ) ;
2017-04-05 22:38:40 +03:00
BuildTarget . ComputeLinkerFlags ( ) ;
BuildTarget . GatherFrameworks ( ) ;
2016-04-21 15:57:02 +03:00
2018-10-15 22:39:29 +03:00
CopyMonoNative ( ) ;
2016-04-21 15:57:02 +03:00
CopyDependencies ( native_libs ) ;
Watch ( "Copy Dependencies" , 1 ) ;
// MDK check
2020-03-17 17:49:39 +03:00
Compile ( ) ;
2016-04-21 15:57:02 +03:00
Watch ( "Compile" , 1 ) ;
2020-03-17 17:49:39 +03:00
2016-04-21 15:57:02 +03:00
if ( generate_plist )
GeneratePList ( ) ;
if ( App . LinkMode ! = LinkMode . All & & App . RuntimeOptions ! = null )
2017-05-08 18:58:21 +03:00
App . RuntimeOptions . Write ( resources_dir ) ;
2016-04-21 15:57:02 +03:00
2017-02-08 22:40:48 +03:00
if ( aotOptions ! = null & & aotOptions . IsAOT ) {
AOTCompilerType compilerType ;
2017-01-11 23:10:39 +03:00
if ( IsUnifiedMobile | | IsUnifiedFullXamMacFramework )
2019-07-24 19:01:14 +03:00
compilerType = AOTCompilerType . Bundled64 ;
2017-01-11 23:10:39 +03:00
else if ( IsUnifiedFullSystemFramework )
2019-07-24 19:01:14 +03:00
compilerType = AOTCompilerType . System64 ;
2017-01-11 23:10:39 +03:00
else
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 0099 , Errors . MX0099 , "\"AOT with unexpected profile.\"" ) ;
2017-01-11 23:10:39 +03:00
[Do not merge yet] Update to mono 2017-04 branch (#1960)
* Update to mono 2017-04 branch
* Patch from Zoltan to fix build error with CppSharp.CppParser.dll
* Include new linker files in Makefile, based on mareks commit
* [msbuild] Fix running bgen for Xamarin.Mac.
bgen must be executed with the system mono, not bmac-mobile-mono, and without
the MONO_PATH variable set.
* System.Data tests should act as if they are running on mobile profile
* Add --runtime=mobile to mono flags in Modern
* Move runtime launcher options up
* System.Data tests should use Mobile profile (mac fix)
* Bump 2017-04 to pick up AOT and assembly resolution fixes
* Build fixes for netstandard.dll and System.Drawing.Primitives.dll
The new handling went in with https://github.com/mono/mono/pull/4501.
I also noticed that WatchOS was missing a target for System.Drawing.Primitives.dll, so I added that.
* Add netstandard.dll to 2.1/Facades and System.Drawing.Primitives.dll to WatchOS
* Fix 2.1/Facades/netstandard.dll build
* Fix the netstandard targets
* Bump mono to latest 2017-04 commit
* [xharness] Fix adding defines to csproj by correctly detecting existing defines.
* Bump mono to latest 2017-04 commit
* [mtouch] Update csproj with new files.
* [mtouch] Improve reporting for MarkExceptions from the linker.
* Bump mono to latest 2017-04 commit
* Bump mono to pick up latest 2017-04 branch commit (Fixes #55436)
Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=55436
* Add a missing Makefile dependency
* Chris Hamons patch to apply --runtime=mobile as necessary at AOT time
(It is currently being applied for some configurations at runtime only)
* Bump system mono
* Bump mono for assembly loader changes
* Bump system mono
* Update assemblies list as some where moved to facades
https://github.com/mono/mono/commit/6ca5ec442b494bed8cfb44258c1c73c091ba3122
https://github.com/mono/mono/commit/c38e4d9220b16488e6f8f9e1f05aed4a8af16e62
* Bump mono to latest 2017-04 commit
* Add another new facade
* Bump mono to tip of 2017-04.
* Bump mono to tip of 2017-04.
* [tests][mtouch] Adjust tests to cope with fewer assemblies being included in linked apps. Fixes #56307 and #56308.
System.dll is now completely linked away unless the app actually uses any
System.dll API.
This is the change that caused this to change: https://github.com/mono/mono/commit/4960d5d2a28a08476ee4239e1746f04afce41c13
Previously the following types would always be kept by the linker:
```
$ monodis --typedef System.dll
Typedef Table
1: (null) (flist=1, mlist=1, flags=0x0, extends=0x0)
2: ObjCRuntime.INativeObject (flist=1, mlist=1, flags=0xa0, extends=0x0)
3: Mono.Net.CFObject (flist=1, mlist=2, flags=0x100000, extends=0x5)
4: Mono.Net.CFArray (flist=4, mlist=19, flags=0x100, extends=0xc)
5: Mono.Net.CFNumber (flist=5, mlist=32, flags=0x100100, extends=0xc)
6: Mono.Net.CFRange (flist=5, mlist=41, flags=0x100108, extends=0x25)
7: Mono.Net.CFString (flist=7, mlist=42, flags=0x100100, extends=0xc)
8: Mono.Net.CFData (flist=8, mlist=53, flags=0x100100, extends=0xc)
9: Mono.Net.CFDictionary (flist=8, mlist=63, flags=0x0, extends=0xc)
10: Mono.Net.CFMutableDictionary (flist=10, mlist=75, flags=0x100100, extends=0x24)
11: Mono.Net.CFUrl (flist=10, mlist=80, flags=0x100100, extends=0xc)
12: Mono.Net.CFRunLoop (flist=10, mlist=83, flags=0x100100, extends=0xc)
13: Mono.Net.CFBoolean (flist=10, mlist=94, flags=0x100, extends=0x5)
14: Mono.AppleTls.SecCertificate (flist=13, mlist=106, flags=0x100100, extends=0x5)
15: Mono.AppleTls.SecIdentity (flist=14, mlist=122, flags=0x100, extends=0x5)
16: Mono.AppleTls.SecIdentity/ImportOptions (flist=19, mlist=134, flags=0x100105, extends=0x5)
17: Mono.AppleTls.SecKey (flist=19, mlist=134, flags=0x100100, extends=0x5)
18: Mono.AppleTls.SecStatusCode (flist=21, mlist=141, flags=0x100, extends=0x69)
19: Mono.AppleTls.SecTrustResult (flist=395, mlist=141, flags=0x100, extends=0x69)
20: Mono.AppleTls.SecImportExport (flist=404, mlist=141, flags=0x100100, extends=0x5)
21: Mono.AppleTls.SecImportExport/<>c (flist=404, mlist=144, flags=0x102103, extends=0x5)
22: Mono.AppleTls.SecPolicy (flist=406, mlist=147, flags=0x100100, extends=0x5)
23: Mono.AppleTls.SecTrust (flist=407, mlist=154, flags=0x100100, extends=0x5)
24: System.Security.Cryptography.OidGroup (flist=408, mlist=174, flags=0x101, extends=0x69)
25: System.Security.Cryptography.Oid (flist=420, mlist=174, flags=0x100101, extends=0x5)
26: System.Security.Cryptography.CAPI (flist=423, mlist=176, flags=0x100180, extends=0x5)
27: System.Security.Cryptography.AsnEncodedData (flist=423, mlist=178, flags=0x100101, extends=0x5)
28: System.Security.Cryptography.X509Certificates.X509Utils (flist=424, mlist=179, flags=0x100100, extends=0x5)
29: System.Security.Cryptography.X509Certificates.PublicKey (flist=424, mlist=181, flags=0x100101, extends=0x5)
30: System.Security.Cryptography.X509Certificates.X509Certificate2 (flist=429, mlist=188, flags=0x102101, extends=0x51)
31: System.Security.Cryptography.X509Certificates.X509Certificate2Impl (flist=431, mlist=204, flags=0x100080, extends=0x55)
32: System.Security.Cryptography.X509Certificates.X509CertificateCollection (flist=431, mlist=209, flags=0x102101, extends=0x6d)
33: System.Security.Cryptography.X509Certificates.X509CertificateCollection/X509CertificateEnumerator (flist=431, mlist=212, flags=0x100102, extends=0x5)
34: System.Security.Cryptography.X509Certificates.X509Helper2 (flist=432, mlist=217, flags=0x100180, extends=0x5)
35: <PrivateImplementationDetails> (flist=432, mlist=218, flags=0x100, extends=0x5)
36: <PrivateImplementationDetails>/__StaticArrayInitTypeSize=9 (flist=433, mlist=219, flags=0x113, extends=0x25)
```
Some of the above types from System.dll implemented ObjCRuntime.INativeObject
(from System.dll), which our linker detected as implementing
ObjCRuntime.INativeObject (from Xamarin.iOS.dll), so these types were treated
as custom NSObject subclasses, and the MarkNSObjects linker step would mark
them (which would in turn cause all the other types in the list to be marked).
With that change, these types now implement ObjCRuntimeInternal.INativeObject,
and the linker does not treat them as custom NSObject subclasses anymore.
I think the new behavior is correct: these types do not actually inherit from
the real NSObject/INativeObject, so the linker should not treat them as such.
This may run into different bugs because the linker might now remove more
stuff than before, but that would be a different issue.
This means that the fix is to modify these tests accordingly.
https://bugzilla.xamarin.com/show_bug.cgi?id=56307
https://bugzilla.xamarin.com/show_bug.cgi?id=56308
* Bump mono to latest.
* Fix merge conflict that was missed
* [mtouch] Renumber new error which clashes with an existing error number in master.
2017-05-29 19:39:29 +03:00
AOTCompiler compiler = new AOTCompiler ( aotOptions , compilerType , IsUnifiedMobile , ! EnableDebug ) ;
2017-02-08 22:40:48 +03:00
compiler . Compile ( mmp_dir ) ;
2017-01-11 23:10:39 +03:00
Watch ( "AOT Compile" , 1 ) ;
}
2016-04-21 15:57:02 +03:00
if ( ! string . IsNullOrEmpty ( certificate_name ) ) {
CodeSign ( ) ;
Watch ( "Code Sign" , 1 ) ;
}
}
2018-10-15 22:39:29 +03:00
static void CopyMonoNative ( )
{
string name ;
2020-04-16 15:19:45 +03:00
if ( File . Exists ( Path . Combine ( GetMonoLibraryDirectory ( App ) , "libmono-system-native.dylib" ) ) ) {
2019-03-25 18:01:09 +03:00
// legacy libmono-system-native.a needs to be included if it exists in the mono in question
name = "libmono-system-native" ;
} else {
// use modern libmono-native
2019-05-09 22:36:42 +03:00
switch ( BuildTarget . MonoNativeMode ) {
2019-03-25 18:01:09 +03:00
case MonoNativeMode . Unified :
name = "libmono-native-unified" ;
break ;
case MonoNativeMode . Compat :
name = "libmono-native-compat" ;
break ;
default :
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 99 , Errors . MX0099 , $"Invalid mono native type: '{BuildTarget.MonoNativeMode}'" ) ;
2019-03-25 18:01:09 +03:00
}
2018-10-15 22:39:29 +03:00
}
2020-04-16 15:19:45 +03:00
var src = Path . Combine ( GetMonoLibraryDirectory ( App ) , name + ".dylib" ) ;
2018-10-15 22:39:29 +03:00
var dest = Path . Combine ( mmp_dir , "libmono-native.dylib" ) ;
2019-05-09 22:36:42 +03:00
Watch ( $"Adding mono-native library {name} for {BuildTarget.MonoNativeMode}." , 1 ) ;
2018-10-15 22:39:29 +03:00
2019-02-01 21:40:50 +03:00
if ( App . Optimizations . TrimArchitectures = = true ) {
// copy to temp directory and lipo there to avoid touching the final dest file if it's up to date
var temp_dest = Path . Combine ( App . Cache . Location , "libmono-native.dylib" ) ;
2018-10-15 22:39:29 +03:00
2019-05-24 18:51:17 +03:00
if ( Application . UpdateFile ( src , temp_dest ) )
2019-02-01 21:40:50 +03:00
LipoLibrary ( name , temp_dest ) ;
2019-05-24 18:51:17 +03:00
Application . UpdateFile ( temp_dest , dest ) ;
2019-02-01 21:40:50 +03:00
}
else {
// we can directly update the dest
Application . UpdateFile ( src , dest ) ;
}
2018-10-15 22:39:29 +03:00
}
2016-04-21 15:57:02 +03:00
static void ExtractNativeLinkInfo ( )
{
var exceptions = new List < Exception > ( ) ;
BuildTarget . ExtractNativeLinkInfo ( exceptions ) ;
if ( exceptions . Count > 0 )
throw new AggregateException ( exceptions ) ;
Watch ( "Extracted native link info" , 1 ) ;
}
2020-04-14 10:09:55 +03:00
static string system_mono_directory ;
static string SystemMonoDirectory {
get {
if ( system_mono_directory = = null )
system_mono_directory = RunPkgConfig ( "--variable=prefix" , force_system_mono : true ) ;
return system_mono_directory ;
}
}
2016-04-21 15:57:02 +03:00
static string MonoDirectory {
get {
2020-04-14 10:09:55 +03:00
if ( IsUnifiedFullXamMacFramework | | IsUnifiedMobile )
return FrameworkDirectory ;
return SystemMonoDirectory ;
2016-04-21 15:57:02 +03:00
}
}
static void GeneratePList ( ) {
2017-04-28 19:08:12 +03:00
var sr = new StreamReader ( typeof ( Driver ) . Assembly . GetManifestResourceStream ( App . Embeddinator ? "Info-framework.plist.tmpl" : "Info.plist.tmpl" ) ) ;
2016-04-21 15:57:02 +03:00
var all = sr . ReadToEnd ( ) ;
var icon_str = ( icon ! = null ) ? "\t<key>CFBundleIconFile</key>\n\t<string>" + icon + "</string>\n\t" : "" ;
2017-04-28 19:08:12 +03:00
var path = Path . Combine ( App . Embeddinator ? resources_dir : contents_dir , "Info.plist" ) ;
using ( var sw = new StreamWriter ( path ) ) {
2016-04-21 15:57:02 +03:00
sw . WriteLine (
all . Replace ( "@BUNDLEDISPLAYNAME@" , app_name ) .
Replace ( "@EXECUTABLE@" , app_name ) .
Replace ( "@BUNDLEID@" , string . Format ( "org.mono.bundler.{0}" , app_name ) ) .
Replace ( "@BUNDLEICON@" , icon_str ) .
Replace ( "@BUNDLENAME@" , app_name ) .
2020-05-05 16:35:02 +03:00
Replace ( "@ASSEMBLY@" , App . References . Where ( e = > Path . GetExtension ( e ) = = ".exe" ) . FirstOrDefault ( ) ) ) ;
2016-04-21 15:57:02 +03:00
}
}
// the 'codesign' is provided with OSX, not with Xcode (no need to use xcrun)
// note: by default the monodevelop addin does the signing (not mmp)
static void CodeSign ( ) {
RunCommand ( "codesign" , String . Format ( "-v -s \"{0}\" \"{1}\"" , certificate_name , App . AppDirectory ) ) ;
}
2017-04-28 19:09:03 +03:00
[DllImport (Constants.libSystemLibrary)]
static extern int unlink ( string pathname ) ;
2016-04-21 15:57:02 +03:00
[DllImport (Constants.libSystemLibrary)]
static extern int symlink ( string path1 , string path2 ) ;
[DllImport (Constants.libSystemLibrary)]
static extern IntPtr realpath ( string path , IntPtr buffer ) ;
static string GetRealPath ( string path )
{
2016-10-20 16:34:26 +03:00
if ( path . StartsWith ( "@executable_path/" , StringComparison . Ordinal ) )
2016-04-21 15:57:02 +03:00
path = Path . Combine ( mmp_dir , path . Substring ( 17 ) ) ;
2016-10-20 16:34:26 +03:00
if ( path . StartsWith ( "@rpath/" , StringComparison . Ordinal ) )
2016-04-21 15:57:02 +03:00
path = Path . Combine ( mmp_dir , path . Substring ( 7 ) ) ;
const int PATHMAX = 1024 + 1 ;
IntPtr buffer = IntPtr . Zero ;
try {
buffer = Marshal . AllocHGlobal ( PATHMAX ) ;
var result = realpath ( path , buffer ) ;
if ( result = = IntPtr . Zero )
return path ;
else
return Marshal . PtrToStringAuto ( buffer ) ;
}
finally {
if ( buffer ! = IntPtr . Zero )
Marshal . FreeHGlobal ( buffer ) ;
}
}
2017-08-08 22:08:09 +03:00
static string PartialStaticLibrary {
get {
2020-02-19 17:23:52 +03:00
return Path . Combine ( FrameworkLibDirectory , string . Format ( "mmp/Xamarin.Mac.registrar.{0}.a" , IsUnifiedMobile ? "mobile" : "full" ) ) ;
2017-08-08 22:08:09 +03:00
}
}
2016-04-21 15:57:02 +03:00
static string GenerateMain ( )
{
var sb = new StringBuilder ( ) ;
using ( var sw = new StringWriter ( sb ) ) {
2017-01-11 23:10:39 +03:00
sw . WriteLine ( "#define MONOMAC 1" ) ;
2019-07-24 19:01:14 +03:00
sw . WriteLine ( "#include <xamarin/xamarin.h>" ) ;
2016-04-21 15:57:02 +03:00
sw . WriteLine ( "#import <AppKit/NSAlert.h>" ) ;
sw . WriteLine ( "#import <Foundation/NSDate.h>" ) ; // 10.7 wants this even if not needed on 10.9
2017-09-29 20:45:53 +03:00
if ( Driver . Registrar = = RegistrarMode . PartialStatic )
2017-06-02 10:19:04 +03:00
sw . WriteLine ( "extern \"C\" void xamarin_create_classes_Xamarin_Mac ();" ) ;
2016-04-21 15:57:02 +03:00
sw . WriteLine ( ) ;
sw . WriteLine ( ) ;
sw . WriteLine ( ) ;
sw . WriteLine ( "extern \"C\" int xammac_setup ()" ) ;
2016-12-01 19:18:30 +03:00
2016-04-21 15:57:02 +03:00
sw . WriteLine ( "{" ) ;
if ( custom_bundle_name ! = null ) {
sw . WriteLine ( "extern NSString* xamarin_custom_bundle_name;" ) ;
sw . WriteLine ( "\txamarin_custom_bundle_name = @\"" + custom_bundle_name + "\";" ) ;
}
2016-10-28 20:07:01 +03:00
if ( ! App . IsDefaultMarshalManagedExceptionMode )
sw . WriteLine ( "\txamarin_marshal_managed_exception_mode = MarshalManagedExceptionMode{0};" , App . MarshalManagedExceptions ) ;
2016-05-11 13:47:26 +03:00
sw . WriteLine ( "\txamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionMode{0};" , App . MarshalObjectiveCExceptions ) ;
2016-11-29 21:44:05 +03:00
if ( disable_lldb_attach . HasValue ? disable_lldb_attach . Value : ! App . EnableDebug )
2016-08-25 21:06:38 +03:00
sw . WriteLine ( "\txamarin_disable_lldb_attach = true;" ) ;
2020-02-26 17:49:55 +03:00
if ( disable_omit_fp ? ? App . EnableDebug )
sw . WriteLine ( "\txamarin_disable_omit_fp = true;" ) ;
2016-04-21 15:57:02 +03:00
sw . WriteLine ( ) ;
2016-12-01 19:18:30 +03:00
2017-09-29 20:45:53 +03:00
if ( Driver . Registrar = = RegistrarMode . Static )
2016-04-21 15:57:02 +03:00
sw . WriteLine ( "\txamarin_create_classes ();" ) ;
2017-09-29 20:45:53 +03:00
else if ( Driver . Registrar = = RegistrarMode . PartialStatic )
2016-12-05 23:16:03 +03:00
sw . WriteLine ( "\txamarin_create_classes_Xamarin_Mac ();" ) ;
2016-04-21 15:57:02 +03:00
2016-10-06 08:05:12 +03:00
if ( App . EnableDebug )
sw . WriteLine ( "\txamarin_debug_mode = TRUE;" ) ;
2017-01-24 09:28:15 +03:00
if ( App . EnableSGenConc )
sw . WriteLine ( "\tsetenv (\"MONO_GC_PARAMS\", \"major=marksweep-conc\", 1);" ) ;
else
sw . WriteLine ( "\tsetenv (\"MONO_GC_PARAMS\", \"major=marksweep\", 1);" ) ;
2019-07-24 19:01:14 +03:00
sw . WriteLine ( "\txamarin_supports_dynamic_registration = {0};" , App . DynamicRegistrationSupported ? "TRUE" : "FALSE" ) ;
2018-02-12 18:59:39 +03:00
2017-02-08 22:40:48 +03:00
if ( aotOptions ! = null & & aotOptions . IsHybridAOT )
sw . WriteLine ( "\txamarin_mac_hybrid_aot = TRUE;" ) ;
2017-01-11 23:10:39 +03:00
[Do not merge yet] Update to mono 2017-04 branch (#1960)
* Update to mono 2017-04 branch
* Patch from Zoltan to fix build error with CppSharp.CppParser.dll
* Include new linker files in Makefile, based on mareks commit
* [msbuild] Fix running bgen for Xamarin.Mac.
bgen must be executed with the system mono, not bmac-mobile-mono, and without
the MONO_PATH variable set.
* System.Data tests should act as if they are running on mobile profile
* Add --runtime=mobile to mono flags in Modern
* Move runtime launcher options up
* System.Data tests should use Mobile profile (mac fix)
* Bump 2017-04 to pick up AOT and assembly resolution fixes
* Build fixes for netstandard.dll and System.Drawing.Primitives.dll
The new handling went in with https://github.com/mono/mono/pull/4501.
I also noticed that WatchOS was missing a target for System.Drawing.Primitives.dll, so I added that.
* Add netstandard.dll to 2.1/Facades and System.Drawing.Primitives.dll to WatchOS
* Fix 2.1/Facades/netstandard.dll build
* Fix the netstandard targets
* Bump mono to latest 2017-04 commit
* [xharness] Fix adding defines to csproj by correctly detecting existing defines.
* Bump mono to latest 2017-04 commit
* [mtouch] Update csproj with new files.
* [mtouch] Improve reporting for MarkExceptions from the linker.
* Bump mono to latest 2017-04 commit
* Bump mono to pick up latest 2017-04 branch commit (Fixes #55436)
Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=55436
* Add a missing Makefile dependency
* Chris Hamons patch to apply --runtime=mobile as necessary at AOT time
(It is currently being applied for some configurations at runtime only)
* Bump system mono
* Bump mono for assembly loader changes
* Bump system mono
* Update assemblies list as some where moved to facades
https://github.com/mono/mono/commit/6ca5ec442b494bed8cfb44258c1c73c091ba3122
https://github.com/mono/mono/commit/c38e4d9220b16488e6f8f9e1f05aed4a8af16e62
* Bump mono to latest 2017-04 commit
* Add another new facade
* Bump mono to tip of 2017-04.
* Bump mono to tip of 2017-04.
* [tests][mtouch] Adjust tests to cope with fewer assemblies being included in linked apps. Fixes #56307 and #56308.
System.dll is now completely linked away unless the app actually uses any
System.dll API.
This is the change that caused this to change: https://github.com/mono/mono/commit/4960d5d2a28a08476ee4239e1746f04afce41c13
Previously the following types would always be kept by the linker:
```
$ monodis --typedef System.dll
Typedef Table
1: (null) (flist=1, mlist=1, flags=0x0, extends=0x0)
2: ObjCRuntime.INativeObject (flist=1, mlist=1, flags=0xa0, extends=0x0)
3: Mono.Net.CFObject (flist=1, mlist=2, flags=0x100000, extends=0x5)
4: Mono.Net.CFArray (flist=4, mlist=19, flags=0x100, extends=0xc)
5: Mono.Net.CFNumber (flist=5, mlist=32, flags=0x100100, extends=0xc)
6: Mono.Net.CFRange (flist=5, mlist=41, flags=0x100108, extends=0x25)
7: Mono.Net.CFString (flist=7, mlist=42, flags=0x100100, extends=0xc)
8: Mono.Net.CFData (flist=8, mlist=53, flags=0x100100, extends=0xc)
9: Mono.Net.CFDictionary (flist=8, mlist=63, flags=0x0, extends=0xc)
10: Mono.Net.CFMutableDictionary (flist=10, mlist=75, flags=0x100100, extends=0x24)
11: Mono.Net.CFUrl (flist=10, mlist=80, flags=0x100100, extends=0xc)
12: Mono.Net.CFRunLoop (flist=10, mlist=83, flags=0x100100, extends=0xc)
13: Mono.Net.CFBoolean (flist=10, mlist=94, flags=0x100, extends=0x5)
14: Mono.AppleTls.SecCertificate (flist=13, mlist=106, flags=0x100100, extends=0x5)
15: Mono.AppleTls.SecIdentity (flist=14, mlist=122, flags=0x100, extends=0x5)
16: Mono.AppleTls.SecIdentity/ImportOptions (flist=19, mlist=134, flags=0x100105, extends=0x5)
17: Mono.AppleTls.SecKey (flist=19, mlist=134, flags=0x100100, extends=0x5)
18: Mono.AppleTls.SecStatusCode (flist=21, mlist=141, flags=0x100, extends=0x69)
19: Mono.AppleTls.SecTrustResult (flist=395, mlist=141, flags=0x100, extends=0x69)
20: Mono.AppleTls.SecImportExport (flist=404, mlist=141, flags=0x100100, extends=0x5)
21: Mono.AppleTls.SecImportExport/<>c (flist=404, mlist=144, flags=0x102103, extends=0x5)
22: Mono.AppleTls.SecPolicy (flist=406, mlist=147, flags=0x100100, extends=0x5)
23: Mono.AppleTls.SecTrust (flist=407, mlist=154, flags=0x100100, extends=0x5)
24: System.Security.Cryptography.OidGroup (flist=408, mlist=174, flags=0x101, extends=0x69)
25: System.Security.Cryptography.Oid (flist=420, mlist=174, flags=0x100101, extends=0x5)
26: System.Security.Cryptography.CAPI (flist=423, mlist=176, flags=0x100180, extends=0x5)
27: System.Security.Cryptography.AsnEncodedData (flist=423, mlist=178, flags=0x100101, extends=0x5)
28: System.Security.Cryptography.X509Certificates.X509Utils (flist=424, mlist=179, flags=0x100100, extends=0x5)
29: System.Security.Cryptography.X509Certificates.PublicKey (flist=424, mlist=181, flags=0x100101, extends=0x5)
30: System.Security.Cryptography.X509Certificates.X509Certificate2 (flist=429, mlist=188, flags=0x102101, extends=0x51)
31: System.Security.Cryptography.X509Certificates.X509Certificate2Impl (flist=431, mlist=204, flags=0x100080, extends=0x55)
32: System.Security.Cryptography.X509Certificates.X509CertificateCollection (flist=431, mlist=209, flags=0x102101, extends=0x6d)
33: System.Security.Cryptography.X509Certificates.X509CertificateCollection/X509CertificateEnumerator (flist=431, mlist=212, flags=0x100102, extends=0x5)
34: System.Security.Cryptography.X509Certificates.X509Helper2 (flist=432, mlist=217, flags=0x100180, extends=0x5)
35: <PrivateImplementationDetails> (flist=432, mlist=218, flags=0x100, extends=0x5)
36: <PrivateImplementationDetails>/__StaticArrayInitTypeSize=9 (flist=433, mlist=219, flags=0x113, extends=0x25)
```
Some of the above types from System.dll implemented ObjCRuntime.INativeObject
(from System.dll), which our linker detected as implementing
ObjCRuntime.INativeObject (from Xamarin.iOS.dll), so these types were treated
as custom NSObject subclasses, and the MarkNSObjects linker step would mark
them (which would in turn cause all the other types in the list to be marked).
With that change, these types now implement ObjCRuntimeInternal.INativeObject,
and the linker does not treat them as custom NSObject subclasses anymore.
I think the new behavior is correct: these types do not actually inherit from
the real NSObject/INativeObject, so the linker should not treat them as such.
This may run into different bugs because the linker might now remove more
stuff than before, but that would be a different issue.
This means that the fix is to modify these tests accordingly.
https://bugzilla.xamarin.com/show_bug.cgi?id=56307
https://bugzilla.xamarin.com/show_bug.cgi?id=56308
* Bump mono to latest.
* Fix merge conflict that was missed
* [mtouch] Renumber new error which clashes with an existing error number in master.
2017-05-29 19:39:29 +03:00
if ( IsUnifiedMobile )
sw . WriteLine ( "\txamarin_mac_modern = TRUE;" ) ;
2016-04-21 15:57:02 +03:00
sw . WriteLine ( "\treturn 0;" ) ;
sw . WriteLine ( "}" ) ;
sw . WriteLine ( ) ;
}
return sb . ToString ( ) ;
}
2019-10-14 17:18:46 +03:00
static void HandleFramework ( IList < string > args , string framework , bool weak )
2016-04-21 15:57:02 +03:00
{
string name = Path . GetFileName ( framework ) ;
if ( name . Contains ( '.' ) )
2019-10-14 17:18:46 +03:00
name = name . Remove ( name . IndexOf ( "." , StringComparison . Ordinal ) ) ;
2016-04-21 15:57:02 +03:00
string path = Path . GetDirectoryName ( framework ) ;
2019-10-14 17:18:46 +03:00
if ( ! string . IsNullOrEmpty ( path ) ) {
args . Add ( "-F" ) ;
args . Add ( path ) ;
}
2017-04-05 22:38:40 +03:00
if ( weak )
BuildTarget . WeakFrameworks . Add ( name ) ;
else
BuildTarget . Frameworks . Add ( name ) ;
2016-04-21 15:57:02 +03:00
2016-10-20 16:34:26 +03:00
if ( ! framework . EndsWith ( ".framework" , StringComparison . Ordinal ) )
2016-04-21 15:57:02 +03:00
return ;
2017-04-05 22:38:40 +03:00
// TODO - There is a chunk of code in mtouch that calls Xamarin.MachO.IsDynamicFramework and doesn't copy if framework of static libs
2016-04-21 15:57:02 +03:00
// But IsDynamicFramework is not on XM yet
CreateDirectoryIfNeeded ( frameworks_dir ) ;
Application . UpdateDirectory ( framework , frameworks_dir ) ;
2016-07-28 15:49:21 +03:00
frameworks_copied_to_bundle_dir = true ;
2018-03-01 18:36:06 +03:00
if ( App . Optimizations . TrimArchitectures = = true )
LipoLibrary ( framework , Path . Combine ( name , Path . Combine ( frameworks_dir , name + ".framework" , name ) ) ) ;
2016-04-21 15:57:02 +03:00
}
2020-02-26 02:38:20 +03:00
static void CheckSystemMonoVersion ( )
{
string mono_version ;
2020-04-14 10:09:55 +03:00
var versionFile = Path . Combine ( SystemMonoDirectory , "VERSION" ) ;
2020-02-26 02:38:20 +03:00
if ( File . Exists ( versionFile ) ) {
mono_version = File . ReadAllText ( versionFile ) ;
} else {
mono_version = RunPkgConfig ( "--modversion" , force_system_mono : true ) ;
}
mono_version = mono_version . Trim ( ) ;
if ( ! Version . TryParse ( mono_version , out var mono_ver ) )
return ;
if ( mono_ver < MonoVersions . MinimumMonoVersion )
throw ErrorHelper . CreateError ( 1 , Errors . MM0001 , MonoVersions . MinimumMonoVersion , mono_version ) ;
}
2020-03-17 17:49:39 +03:00
static void Compile ( )
2016-04-21 15:57:02 +03:00
{
2019-10-14 17:18:46 +03:00
string [ ] cflags = Array . Empty < string > ( ) ;
2016-04-21 15:57:02 +03:00
string mainSource = GenerateMain ( ) ;
string registrarPath = null ;
2020-02-26 02:38:20 +03:00
CheckSystemMonoVersion ( ) ;
2017-09-29 20:45:53 +03:00
if ( Registrar = = RegistrarMode . Static ) {
2017-01-03 17:14:47 +03:00
registrarPath = Path . Combine ( App . Cache . Location , "registrar.m" ) ;
var registrarH = Path . Combine ( App . Cache . Location , "registrar.h" ) ;
2016-05-11 14:10:35 +03:00
BuildTarget . StaticRegistrar . Generate ( BuildTarget . Resolver . ResolverCache . Values , registrarH , registrarPath ) ;
2016-04-21 15:57:02 +03:00
2016-12-23 20:50:35 +03:00
var platform_assembly = BuildTarget . Resolver . ResolverCache . First ( ( v ) = > v . Value . Name . Name = = BuildTarget . StaticRegistrar . PlatformAssembly ) . Value ;
Frameworks . Gather ( App , platform_assembly , BuildTarget . Frameworks , BuildTarget . WeakFrameworks ) ;
2016-04-21 15:57:02 +03:00
}
2020-02-26 02:38:20 +03:00
var str_cflags = RunPkgConfig ( "--cflags" ) ;
var libdir = RunPkgConfig ( "--variable=libdir" ) ;
2016-04-21 15:57:02 +03:00
2019-10-14 17:18:46 +03:00
if ( ! StringUtils . TryParseArguments ( str_cflags , out cflags , out var ex ) )
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 147 , ex , Errors . MM0147 , str_cflags , ex . Message ) ;
2016-04-21 15:57:02 +03:00
var libmain = embed_mono ? "libxammac" : "libxammac-system" ;
2020-05-07 17:20:07 +03:00
var libxammac = Path . Combine ( GetXamarinLibraryDirectory ( App ) , libmain + ( App . EnableDebug ? "-debug" : "" ) + ".a" ) ;
2016-04-21 15:57:02 +03:00
if ( ! File . Exists ( libxammac ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 5203 , true , Errors . MM5203 , libxammac ) ;
2016-04-21 15:57:02 +03:00
try {
2019-10-14 17:18:46 +03:00
var args = new List < string > ( ) ;
2016-04-21 15:57:02 +03:00
if ( App . EnableDebug )
2019-10-14 17:18:46 +03:00
args . Add ( "-g" ) ;
if ( App . Embeddinator ) {
args . Add ( "-shared" ) ;
args . Add ( "-install_name" ) ;
args . Add ( $"@loader_path/../Frameworks/{App.Name}.framework/{App.Name}" ) ;
}
args . Add ( $"-mmacosx-version-min={App.DeploymentTarget.ToString ()}" ) ;
args . Add ( "-arch" ) ;
2020-05-11 17:27:19 +03:00
args . Add ( App . Abi . AsArchString ( ) ) ;
args . Add ( $"-fobjc-runtime=macosx-{App.DeploymentTarget.ToString ()}" ) ;
2017-05-22 08:39:10 +03:00
if ( ! embed_mono )
2019-10-14 17:18:46 +03:00
args . Add ( "-DDYNAMIC_MONO_RUNTIME" ) ;
2017-08-04 20:19:37 +03:00
if ( XcodeVersion > = new Version ( 9 , 0 ) )
2019-10-14 17:18:46 +03:00
args . Add ( "-Wno-unguarded-availability-new" ) ;
2017-08-04 20:19:37 +03:00
2019-08-29 18:49:06 +03:00
if ( XcodeVersion . Major > = 11 )
2019-10-14 17:18:46 +03:00
args . Add ( "-std=c++14" ) ;
2019-08-29 18:49:06 +03:00
2017-03-29 02:16:51 +03:00
bool appendedObjc = false ;
2019-08-29 18:49:06 +03:00
var sourceFiles = new List < string > ( ) ;
2016-04-21 15:57:02 +03:00
foreach ( var assembly in BuildTarget . Assemblies ) {
if ( assembly . LinkWith ! = null ) {
foreach ( var linkWith in assembly . LinkWith ) {
2020-02-18 23:44:19 +03:00
Log ( 2 , "Found LinkWith on {0} for {1}" , assembly . FileName , linkWith ) ;
2016-10-20 16:34:26 +03:00
if ( linkWith . EndsWith ( ".dylib" , StringComparison . Ordinal ) ) {
2016-04-21 15:57:02 +03:00
// Link against the version copied into MonoBudle, since we install_name_tool'd it already
string libName = Path . GetFileName ( linkWith ) ;
string finalLibPath = Path . Combine ( mmp_dir , libName ) ;
2019-10-14 17:18:46 +03:00
args . Add ( finalLibPath ) ;
2016-04-21 15:57:02 +03:00
}
else {
2019-10-14 17:18:46 +03:00
args . Add ( linkWith ) ;
2016-04-21 15:57:02 +03:00
}
}
2017-03-29 02:16:51 +03:00
if ( ! appendedObjc ) {
appendedObjc = true ;
2019-10-14 17:18:46 +03:00
args . Add ( "-ObjC" ) ;
2017-03-29 02:16:51 +03:00
}
2016-04-21 15:57:02 +03:00
}
if ( assembly . LinkerFlags ! = null )
foreach ( var linkFlag in assembly . LinkerFlags )
2019-10-14 17:18:46 +03:00
args . Add ( linkFlag ) ;
2017-04-05 22:38:40 +03:00
if ( assembly . Frameworks ! = null ) {
foreach ( var f in assembly . Frameworks ) {
2020-02-18 23:44:19 +03:00
Log ( 2 , $"Adding Framework {f} for {assembly.FileName}" ) ;
2016-04-21 15:57:02 +03:00
HandleFramework ( args , f , false ) ;
2017-04-05 22:38:40 +03:00
}
}
if ( assembly . WeakFrameworks ! = null ) {
foreach ( var f in assembly . WeakFrameworks ) {
2020-02-18 23:44:19 +03:00
Log ( 2 , $"Adding Weak Framework {f} for {assembly.FileName}" ) ;
2016-04-21 15:57:02 +03:00
HandleFramework ( args , f , true ) ;
2017-04-05 22:38:40 +03:00
}
}
2016-04-21 15:57:02 +03:00
}
foreach ( var framework in App . Frameworks )
HandleFramework ( args , framework , false ) ;
foreach ( var lib in native_libraries_copied_in )
{
// Link against the version copied into MonoBudle, since we install_name_tool'd it already
string libName = Path . GetFileName ( lib ) ;
string finalLibPath = Path . Combine ( mmp_dir , libName ) ;
2019-10-14 17:18:46 +03:00
args . Add ( finalLibPath ) ;
2016-04-21 15:57:02 +03:00
}
2019-10-14 17:18:46 +03:00
if ( frameworks_copied_to_bundle_dir ) {
args . Add ( "-rpath" ) ;
args . Add ( "@loader_path/../Frameworks" ) ;
}
if ( dylibs_copied_to_bundle_dir ) {
args . Add ( "-rpath" ) ;
args . Add ( $"@loader_path/../{BundleName}" ) ;
}
2018-12-11 18:28:55 +03:00
Add bindings for NSXpcConnection and related types (#7001)
* Add bindings for NSXpcConnection and related types
* Re-add accidentally deleted file
* Typo fix
* Add NSXpcInterface.CreateForType()
* Add MethodInfo-taking overloads to NSXpcInterface
* Add null check
* Mark methods with wrappers as internal
Also fixed a formatting bug that I didn't catch earlier.
* Change NSXPCProxyCreating methods to be strongly typed
I got rid of the NSXpcProxyCreating interface in this change,
because its only user was NSXpcConnection, and I needed to
inline the protocol methods into the class definition so I
could mark them as [Internal].
* Add missing casts
* Add NSXpcConnectionOptions enum
* Convert NSXpcConnection constructor to use new enum
* Remove now-unneeded manual constructor
* Fix bgen warning
* Typo fix
* Fix selector
* Remove incorrect use of BindAsAttribute
Per the docs, this only works for enums backed
by NSNumber and NSValue, not for enums
passed directly as integers.
* Fix duplicated selector errors
* Throw ArgumentException instead of InvalidOperationException
* Extend AppExtension targets to produce XPC services
Rather than create an entirely new set of targets
(that would require VS and VSMac updates to properly
consume), I have decided to use the existing AppExtension
build targets to produce XPC services as well. All the
user must do is set the $(IsXPCService) property to true in
their project file, and the targets will do The Right Thing™.
Note that this support is Mac-only for now; I may need a bit
of help adjusting them to work on for iOS/watchOS/tvOS, as I
am not as familiar with those platforms.
* Copy XPC service bundles into the correct location
* Move IsXPCService property definition to props file
* Don't pass /extension to mmp for XPC service targets
This would cause the XPC service binary to
be linked incorrectly.
* Add NSXpcConnection/NSXpcInterface.cs files to the build
* Fix build
* Fix build
* Add required type parameter requirements
* Fix type parameter requirements
* Fix return type
* Fix return type of NSXpcInterface.CreateForProtocol ()
* Take ownership of the returned object types
* Adjust XPC service mmp invocation
I need to link the XPC service bundle as if it is an app extension, but
I must not use xamarin_mac_extension_main. I added a new flag to make
this possible.
* Change mmp to correctly construct XPC service bundle
* Set the MonoBundleExecutable Info.plist key for XPC services
* Use the runtime to get the protocol
* Make NSXpcInterface.CreateForProtocol() public
The static registrar must be used for Cocoa to accept the protocol
as a valid XPC interface, but that then seems to break resolving
the protocol from the type. I must therefore hard-code the protocol
name in my code, and that requires I make this constructor public.
* Add XpcInterfaceAttribute
See the doc comment in XpcInterfaceAttribute.cs for why
this type is required. The referenced mmp optimizations
will be added in future commits.
* Add XpcInterfaceAttribute to generator build
* Add support for XpcInterfaceAttribute to the generator
* Force static generation of protocols decorated with XpcInterfaceAttribute
* Change how static registrar translates block parameters
Previously, they would always be marshalled as "id".
This would throw off the XPC subsystem, which parses
the block signature to determine the communication
protocol.
* Undo whitespace noise
* Remove unneeded casts
* Add trailing comma
* Use HasAttribute instead of GetCustomAttribute
* Fix style issues
* Bind NSXpcConnection.auditSessionIdentifier
* Address naming feedback
* Make Get/SetAllowedClasses public
IMHO, passing the selector as a string is just as
usable as passing a MethodInfo, and is also less
verbose if you copy/paste the selector string
from the ExportAttribute. There is no reason why
we cannot have both overloads be public.
* Update overload names to match
* Update more overload names to match
* Make mmp --xpc imply --extension
* Reformat if statement
* Fix build
* Conditionalize creation of PlugIns and XPCServices directories
* Add AutoGeneratedName
Co-Authored-By: Rolf Bjarne Kvinge <rolf@xamarin.com>
* Get rid of ProtocolizeAttribute
* Update availability attributes to please xharness
I actually think xharness is wrong here, since the
NSXPCConnection header lists these types as being
available starting in macOS 10.8.
* Update sharpie ignore files to reflect changes
This should fix the xtro-sharpie test failures CI has been reporting.
* Fix MM4105 error generation
* Adjust error message in test to match mmp
I had to change the error text slightly, because the type of the parameter
cannot be determined where the error is thrown anymore. However, the newer
exception message IMO is just as clear.
* Make exception message match test exactly
* Remove outdated copyright header text
* Remove more outdated copyright header text
* Revert changes to MM4105 error generation
I have a more elegant way of fixing this test now.
* Return "id" if Invoke method cannot be found
This fixes the MM4105 error unit test,
without requiring modification to that test.
* Remove redundant availability attributes
* Add DesignatedInitializerAttribute
* Re-add required code to macOS-Foundation.ignore
* Put DesignatedInitializer on the right constructor
* Update xtro-sharpie ignore files
2019-10-22 16:38:01 +03:00
if ( is_extension & & ! is_xpc_service ) {
2019-10-14 17:18:46 +03:00
args . Add ( "-e" ) ;
args . Add ( "_xamarin_mac_extension_main" ) ;
args . Add ( "-framework" ) ;
args . Add ( "NotificationCenter" ) ;
}
2016-05-26 00:20:33 +03:00
2019-10-14 17:18:46 +03:00
foreach ( var f in BuildTarget . Frameworks ) {
args . Add ( "-framework" ) ;
args . Add ( f ) ;
}
foreach ( var f in BuildTarget . WeakFrameworks ) {
args . Add ( "-weak_framework" ) ;
args . Add ( f ) ;
}
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
var requiredSymbols = BuildTarget . GetRequiredSymbols ( ) ;
2017-08-24 10:42:08 +03:00
Driver . WriteIfDifferent ( Path . Combine ( App . Cache . Location , "exported-symbols-list" ) , string . Join ( "\n" , requiredSymbols . Select ( ( symbol ) = > symbol . Prefix + symbol . Name ) . ToArray ( ) ) ) ;
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
switch ( App . SymbolMode ) {
case SymbolMode . Ignore :
break ;
case SymbolMode . Code :
string reference_m = Path . Combine ( App . Cache . Location , "reference.m" ) ;
reference_m = BuildTarget . GenerateReferencingSource ( reference_m , requiredSymbols ) ;
if ( ! string . IsNullOrEmpty ( reference_m ) )
2019-08-29 18:49:06 +03:00
sourceFiles . Add ( reference_m ) ;
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
break ;
case SymbolMode . Linker :
case SymbolMode . Default :
2019-10-14 17:18:46 +03:00
foreach ( var symbol in requiredSymbols ) {
args . Add ( "-u" ) ;
args . Add ( symbol . Prefix + symbol . Name ) ;
}
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
break ;
default :
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 99 , Errors . MX0099 , $"invalid symbol mode: {App.SymbolMode}" ) ;
[mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417. (#2162)
* [mtouch] Improve how we make sure native symbols aren't stripped away. Fixes #51710 and #54417.
* Refactor required symbol collection to store more information about each
symbol (field, function, Objective-C class), and in general make the code
more straight forward.
* Implement support for generating source code that references these symbols,
and do this whenever we can't ask the native linker to keep these symbols
(when using bitcode). Additionally make it possible to do this manually, so
that the source code can be generated for non-bitcode platforms too (which
is useful if the number of symbols is enormous, in which case we might
surpass the maximum command-line length).
* Also make it possible to completely ignore native symbols, or ignore them on
a per-symbol basis. This provides a fallback for users if we get something
right and we try to preserve something that shouldn't be preserved (for
instance if it doesn't exist), and the user ends up with unfixable linker
errors.
* Don't collect Objective-C classes unless they're in an assembly with
LinkWith attributes. We don't need to preserve Objective-C classes in any
other circumstances.
* Implement everything for both Xamarin.iOS and Xamarin.Mac, and share the
code between them.
* Remove previous workaround for bug #51710, since it's no longer needed.
* Add tests.
https://bugzilla.xamarin.com/show_bug.cgi?id=54417
https://bugzilla.xamarin.com/show_bug.cgi?id=51710
* [mtouch] Make sure to only keep symbols from the current app when code sharing.
This fixes a build problem with the interdependent-binding-projects test when
testing in Today Extension mode.
2017-06-02 19:29:19 +03:00
}
2016-04-21 15:57:02 +03:00
bool linkWithRequiresForceLoad = BuildTarget . Assemblies . Any ( x = > x . ForceLoad ) ;
if ( no_executable | | linkWithRequiresForceLoad )
2019-10-14 17:18:46 +03:00
args . Add ( "-force_load" ) ; // make sure nothing is stripped away if we don't have a root assembly, since anything can end up being used.
args . Add ( libxammac ) ;
args . Add ( "-o" ) ;
args . Add ( AppPath ) ;
args . AddRange ( cflags ) ;
2016-04-21 15:57:02 +03:00
if ( embed_mono ) {
2018-10-15 17:12:56 +03:00
string libmono = Path . Combine ( libdir , "libmonosgen-2.0.a" ) ;
2016-04-21 15:57:02 +03:00
2018-10-15 17:12:56 +03:00
if ( ! File . Exists ( libmono ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 5202 , true , Errors . MM5202 ) ;
2016-04-21 15:57:02 +03:00
2019-10-14 17:18:46 +03:00
args . Add ( libmono ) ;
2018-10-15 17:12:56 +03:00
2019-03-25 18:01:09 +03:00
string libmonoSystemNative = Path . Combine ( libdir , "libmono-system-native.a" ) ;
if ( File . Exists ( libmonoSystemNative ) ) {
// legacy libmono-system-native.a needs to be included if it exists in the mono in question
2019-10-14 17:18:46 +03:00
args . Add ( libmonoSystemNative ) ;
args . Add ( "-u" ) ;
args . Add ( "_SystemNative_RealPath" ) ; // This keeps libmono_system_native_la-pal_io.o symbols
2019-03-25 18:01:09 +03:00
} else {
// add modern libmono-native
2018-10-15 22:39:29 +03:00
string libmono_native_name ;
2019-05-09 22:36:42 +03:00
switch ( BuildTarget . MonoNativeMode ) {
2018-10-15 22:39:29 +03:00
case MonoNativeMode . Unified :
libmono_native_name = "libmono-native-unified" ;
break ;
case MonoNativeMode . Compat :
libmono_native_name = "libmono-native-compat" ;
break ;
default :
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 99 , Errors . MX0099 , $"Invalid mono native type: '{BuildTarget.MonoNativeMode}'" ) ;
2018-10-15 22:39:29 +03:00
}
2019-10-14 17:18:46 +03:00
args . Add ( Path . Combine ( libdir , libmono_native_name + ".a" ) ) ;
args . Add ( "-framework" ) ;
args . Add ( "GSS" ) ;
2018-10-15 22:39:29 +03:00
}
2018-10-10 18:02:28 +03:00
2020-05-11 17:42:21 +03:00
if ( App . EnableProfiling ) {
2019-10-14 17:18:46 +03:00
args . Add ( Path . Combine ( libdir , "libmono-profiler-log.a" ) ) ;
args . Add ( "-u" ) ;
args . Add ( "_mono_profiler_init_log" ) ;
2016-04-21 15:57:02 +03:00
}
2019-10-14 17:18:46 +03:00
args . Add ( "-lz" ) ;
2016-04-21 15:57:02 +03:00
}
2016-12-01 19:18:30 +03:00
2017-09-29 20:45:53 +03:00
if ( Registrar = = RegistrarMode . PartialStatic ) {
2019-10-14 17:18:46 +03:00
args . Add ( PartialStaticLibrary ) ;
args . Add ( "-framework" ) ;
args . Add ( "Quartz" ) ;
2016-12-01 19:18:30 +03:00
}
2019-10-14 17:18:46 +03:00
args . Add ( "-liconv" ) ;
args . Add ( "-lc++" ) ;
args . Add ( "-x" ) ;
args . Add ( "objective-c++" ) ;
2018-08-04 00:06:23 +03:00
if ( XcodeVersion . Major > = 10 ) {
2018-06-28 15:49:22 +03:00
// Xcode 10 doesn't ship with libstdc++
2019-10-14 17:18:46 +03:00
args . Add ( "-stdlib=libc++" ) ;
2018-06-28 15:49:22 +03:00
}
2020-05-08 14:04:32 +03:00
args . Add ( $"-I{GetProductSdkIncludeDirectory (App)}" ) ;
2016-04-21 15:57:02 +03:00
if ( registrarPath ! = null )
2019-10-14 17:18:46 +03:00
args . Add ( registrarPath ) ;
args . Add ( "-fno-caret-diagnostics" ) ;
args . Add ( "-fno-diagnostics-fixit-info" ) ;
2016-04-21 15:57:02 +03:00
if ( link_flags ! = null )
2019-10-14 17:18:46 +03:00
args . AddRange ( link_flags ) ;
2016-04-21 15:57:02 +03:00
if ( ! string . IsNullOrEmpty ( DeveloperDirectory ) )
2016-12-14 00:12:50 +03:00
{
2016-12-23 20:50:35 +03:00
var sysRootSDKVersion = new Version ( App . SdkVersion . Major , App . SdkVersion . Minor ) ; // Sys Root SDKs do not have X.Y.Z, just X.Y
2019-10-14 17:18:46 +03:00
args . Add ( "-isysroot" ) ;
args . Add ( Path . Combine ( DeveloperDirectory , "Platforms" , "MacOSX.platform" , "Developer" , "SDKs" , "MacOSX" + sysRootSDKVersion + ".sdk" ) ) ;
2016-12-14 00:12:50 +03:00
}
2016-04-21 15:57:02 +03:00
2016-05-11 14:27:51 +03:00
if ( App . RequiresPInvokeWrappers ) {
2020-05-07 16:01:26 +03:00
var state = BuildTarget . LinkerOptions . MarshalNativeExceptionsState ;
2016-05-11 14:27:51 +03:00
state . End ( ) ;
2019-10-14 17:18:46 +03:00
args . Add ( state . SourcePath ) ;
2016-05-11 14:27:51 +03:00
}
2017-01-03 17:14:47 +03:00
var main = Path . Combine ( App . Cache . Location , "main.m" ) ;
2016-04-21 15:57:02 +03:00
File . WriteAllText ( main , mainSource ) ;
2019-08-29 18:49:06 +03:00
sourceFiles . Add ( main ) ;
2019-10-14 17:18:46 +03:00
args . AddRange ( sourceFiles ) ;
2019-08-29 18:49:06 +03:00
2020-03-17 17:49:39 +03:00
RunClang ( args ) ;
2016-04-21 15:57:02 +03:00
} catch ( Win32Exception e ) {
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 5103 , true , e , Errors . MM5103 , "driver" ) ;
2016-04-21 15:57:02 +03:00
}
}
2020-02-26 02:38:20 +03:00
static string RunPkgConfig ( string option , bool force_system_mono = false )
{
string [ ] env = null ;
if ( ! IsUnifiedFullSystemFramework & & ! force_system_mono )
env = new [ ] { "PKG_CONFIG_PATH" , Path . Combine ( FrameworkLibDirectory , "pkgconfig" ) } ;
var sb = new StringBuilder ( ) ;
int rv ;
try {
2020-04-14 10:09:55 +03:00
rv = RunCommand ( PkgConfig , new [ ] { option , "mono-2" } , env , sb ) ;
2020-02-26 02:38:20 +03:00
} catch ( Exception e ) {
throw ErrorHelper . CreateError ( 5314 , e , Errors . MX5314 , e . Message ) ;
}
if ( rv ! = 0 )
throw ErrorHelper . CreateError ( 5312 , Errors . MX5312 , rv ) ;
return sb . ToString ( ) . Trim ( ) ;
}
2019-07-24 19:01:14 +03:00
// check that we have a reference to Xamarin.Mac.dll and not to MonoMac.dll.
2016-04-21 15:57:02 +03:00
static void CheckReferences ( )
{
List < Exception > exceptions = new List < Exception > ( ) ;
var cache = BuildTarget . Resolver . ToResolverCache ( ) ;
var incompatibleReferences = new List < string > ( ) ;
var haveValidReference = false ;
foreach ( string entry in cache . Keys ) {
switch ( entry ) {
case "Xamarin.Mac" :
2019-07-24 19:01:14 +03:00
haveValidReference = true ;
2016-04-21 15:57:02 +03:00
break ;
case "XamMac" :
2019-07-24 19:01:14 +03:00
incompatibleReferences . Add ( entry ) ;
2016-04-21 15:57:02 +03:00
break ;
case "MonoMac" :
incompatibleReferences . Add ( entry ) ;
break ;
}
}
if ( ! haveValidReference )
2020-01-31 23:02:52 +03:00
exceptions . Add ( new MonoMacException ( 1401 , true , Errors . MM1401 ) ) ;
2016-04-21 15:57:02 +03:00
foreach ( var refName in incompatibleReferences )
2020-01-31 23:02:52 +03:00
exceptions . Add ( new MonoMacException ( 1402 , true , Errors . MM1402 , refName + ".dll" ) ) ;
2016-04-21 15:57:02 +03:00
if ( exceptions . Count > 0 )
throw new AggregateException ( exceptions ) ;
}
static IDictionary < string , List < MethodDefinition > > Link ( )
{
2017-09-05 21:48:09 +03:00
var cache = ( Dictionary < string , AssemblyDefinition > ) BuildTarget . Resolver . ResolverCache ;
2020-04-14 17:32:42 +03:00
AssemblyResolver resolver ;
if ( UseLegacyAssemblyResolution ) {
if ( cache ! = null ) {
resolver = new Mono . Linker . AssemblyResolver ( cache ) ;
} else {
resolver = new Mono . Linker . AssemblyResolver ( ) ;
}
} else {
resolver = new MonoMacAssemblyResolver ( BuildTarget . Resolver ) ;
}
2016-04-21 15:57:02 +03:00
resolver . AddSearchDirectory ( BuildTarget . Resolver . RootDirectory ) ;
resolver . AddSearchDirectory ( BuildTarget . Resolver . FrameworkDirectory ) ;
var options = new LinkerOptions {
2020-05-05 16:35:02 +03:00
MainAssembly = BuildTarget . Resolver . GetAssembly ( App . References [ App . References . Count - 1 ] ) ,
2016-04-21 15:57:02 +03:00
OutputDirectory = mmp_dir ,
LinkSymbols = App . EnableDebug ,
LinkMode = App . LinkMode ,
Resolver = resolver ,
SkippedAssemblies = App . LinkSkipped ,
I18nAssemblies = App . I18n ,
ExtraDefinitions = App . Definitions ,
RuntimeOptions = App . RuntimeOptions ,
2016-05-11 14:27:51 +03:00
MarshalNativeExceptionsState = ! App . RequiresPInvokeWrappers ? null : new PInvokeWrapperGenerator ( )
{
2016-12-23 20:50:35 +03:00
App = App ,
2017-01-03 17:14:47 +03:00
SourcePath = Path . Combine ( App . Cache . Location , "pinvokes.m" ) ,
HeaderPath = Path . Combine ( App . Cache . Location , "pinvokes.h" ) ,
2016-05-11 14:27:51 +03:00
Registrar = ( StaticRegistrar ) BuildTarget . StaticRegistrar ,
} ,
2016-10-26 13:57:11 +03:00
SkipExportedSymbolsInSdkAssemblies = ! embed_mono ,
2017-05-24 22:04:32 +03:00
Target = BuildTarget ,
2020-02-21 06:25:23 +03:00
WarnOnTypeRef = App . WarnOnTypeRef ,
2016-04-21 15:57:02 +03:00
} ;
2020-05-07 16:01:26 +03:00
BuildTarget . LinkerOptions = options ;
2016-05-11 14:27:51 +03:00
2019-02-07 09:57:01 +03:00
MonoMac . Tuner . Linker . Process ( options , out var context , out resolved_assemblies ) ;
ErrorHelper . Show ( context . Exceptions ) ;
2016-08-16 23:24:01 +03:00
// Idealy, this would be handled by Linker.Process above. However in the non-linking case
// we do not run MobileMarkStep which generates the pinvoke list. Hack around this for now
// https://bugzilla.xamarin.com/show_bug.cgi?id=43419
if ( App . LinkMode = = LinkMode . None )
return ProcessDllImports ( ) ;
else
return BuildTarget . LinkContext . PInvokeModules ;
2016-04-21 15:57:02 +03:00
}
2016-08-16 23:24:01 +03:00
static Dictionary < string , List < MethodDefinition > > ProcessDllImports ( )
2016-04-21 15:57:02 +03:00
{
2016-08-16 23:24:01 +03:00
var pinvoke_modules = new Dictionary < string , List < MethodDefinition > > ( ) ;
2016-04-21 15:57:02 +03:00
foreach ( string assembly_name in resolved_assemblies ) {
AssemblyDefinition assembly = BuildTarget . Resolver . GetAssembly ( assembly_name ) ;
2016-08-16 23:24:01 +03:00
if ( assembly ! = null ) {
foreach ( ModuleDefinition md in assembly . Modules ) {
if ( md . HasTypes ) {
foreach ( TypeDefinition type in md . Types ) {
if ( type . HasMethods ) {
foreach ( MethodDefinition method in type . Methods ) {
if ( ( method ! = null ) & & ! method . HasBody & & method . IsPInvokeImpl ) {
// this happens for c++ assemblies (ref #11448)
if ( method . PInvokeInfo = = null )
continue ;
string module = method . PInvokeInfo . Module . Name ;
if ( ! String . IsNullOrEmpty ( module ) ) {
List < MethodDefinition > methods ;
if ( ! pinvoke_modules . TryGetValue ( module , out methods ) )
pinvoke_modules . Add ( module , methods = new List < MethodDefinition > ( ) ) ;
}
2016-04-21 15:57:02 +03:00
}
}
}
}
}
}
}
}
2016-08-16 23:24:01 +03:00
return pinvoke_modules ;
2016-04-21 15:57:02 +03:00
}
static void CopyDependencies ( IDictionary < string , List < MethodDefinition > > libraries )
{
// Process LinkWith first so we don't have unnecessary warnings
foreach ( var assembly in BuildTarget . Assemblies . Where ( a = > a . LinkWith ! = null ) ) {
2016-10-20 16:34:26 +03:00
foreach ( var linkWith in assembly . LinkWith . Where ( l = > l . EndsWith ( ".dylib" , StringComparison . Ordinal ) ) ) {
2016-04-21 15:57:02 +03:00
string libName = Path . GetFileName ( linkWith ) ;
string finalLibPath = Path . Combine ( mmp_dir , libName ) ;
Application . UpdateFile ( linkWith , finalLibPath ) ;
2020-03-17 17:49:39 +03:00
RunInstallNameTool ( new [ ] { "-id" , "@executable_path/../" + BundleName + "/" + libName , finalLibPath } ) ;
2016-04-21 15:57:02 +03:00
native_libraries_copied_in . Add ( libName ) ;
}
}
var processed = new HashSet < string > ( ) ;
foreach ( var kvp in libraries . Where ( l = > ! native_libraries_copied_in . Contains ( Path . GetFileName ( l . Key ) ) ) )
ProcessNativeLibrary ( processed , kvp . Key , kvp . Value ) ;
// .dylibs might refers to specific paths (e.g. inside Mono framework directory) and/or
// refer to a symlink (pointing to a more specific version of the library)
2019-10-14 17:18:46 +03:00
var sb = new List < string > ( ) ;
2016-04-21 15:57:02 +03:00
foreach ( string library in Directory . GetFiles ( mmp_dir , "*.dylib" ) ) {
foreach ( string lib in Xamarin . MachO . GetNativeDependencies ( library ) ) {
2020-04-14 10:09:55 +03:00
if ( lib . StartsWith ( Path . GetDirectoryName ( MonoPrefix ) , StringComparison . Ordinal ) ) {
2016-04-21 15:57:02 +03:00
string libname = Path . GetFileName ( lib ) ;
string real_lib = GetRealPath ( lib ) ;
string real_libname = Path . GetFileName ( real_lib ) ;
// if a symlink was specified then re-create it inside the .app
if ( libname ! = real_libname )
CreateSymLink ( mmp_dir , real_libname , libname ) ;
2019-10-14 17:18:46 +03:00
sb . Add ( "-change" ) ;
sb . Add ( lib ) ;
sb . Add ( "@executable_path/../" + BundleName + "/" + libname ) ;
2016-04-21 15:57:02 +03:00
}
}
// if required update the paths inside the .dylib that was copied
2019-10-14 17:18:46 +03:00
if ( sb . Count > 0 ) {
2020-03-18 14:15:20 +03:00
sb . Add ( library ) ;
2020-03-17 17:49:39 +03:00
RunInstallNameTool ( sb ) ;
2016-04-21 15:57:02 +03:00
sb . Clear ( ) ;
}
}
}
static string GetLibraryShortenedName ( string name )
{
// GetFileNameWithoutExtension only removes one extension, e.g. libx.so.2 won't work
int start = name . StartsWith ( "lib" , StringComparison . Ordinal ) ? 3 : 0 ;
int end = name . Length ;
if ( name . EndsWith ( ".dylib" , StringComparison . Ordinal ) )
end - = 6 ;
else if ( name . EndsWith ( ".so" , StringComparison . Ordinal ) )
end - = 3 ;
else if ( name . EndsWith ( ".dll" , StringComparison . OrdinalIgnoreCase ) )
end - = 4 ;
return name . Substring ( start , end - start ) ;
}
static bool ShouldSkipNativeLibrary ( string fileName )
{
string shortendName = GetLibraryShortenedName ( fileName ) ;
// well known libraries we do not bundle or warn about
switch ( shortendName . ToLowerInvariant ( ) ) {
case "xammac" : // we have a p/invoke to this library in Runtime.mac.cs, for users that don't bundle with mmp.
case "__internal" : // mono runtime
case "kernel32" : // windows specific
case "gdi32" : // windows specific
case "ole32" : // windows specific
case "user32" : // windows specific
case "advapi32" : // windows specific
case "crypt32" : // windows specific
case "msvcrt" : // windows specific
case "iphlpapi" : // windows specific
case "winmm" : // windows specific
case "winspool" : // windows specific
case "c" : // system provided
2018-12-06 22:16:10 +03:00
case "objc" : // system provided
case "objc.a" : // found in swift core libraries
case "system.b" : // found in swift core libraries
2016-04-21 15:57:02 +03:00
case "system" : // system provided, libSystem.dylib -> CommonCrypto
case "x11" : // msvcrt pulled in
case "winspool.drv" : // msvcrt pulled in
case "cups" : // msvcrt pulled in
case "fam.so.0" : // msvcrt pulled in
case "gamin-1.so.0" : // msvcrt pulled in
case "asound.so.2" : // msvcrt pulled in
case "oleaut32" : // referenced by System.Runtime.InteropServices.Marshal._[S|G]etErrorInfo
2019-02-01 21:40:50 +03:00
case "system.native" : // handled by CopyMonoNative()
2018-10-15 22:39:29 +03:00
case "system.security.cryptography.native.apple" : // same
2019-01-31 13:18:29 +03:00
case "system.net.security.native" : // same
2016-04-21 15:57:02 +03:00
return true ;
}
// Shutup the warning until we decide on bug: 36478
2019-04-08 18:26:23 +03:00
if ( shortendName . ToLowerInvariant ( ) = = "intl" & & ! native_references . Any ( x = > x . Contains ( "libintl.dylib" ) ) & & IsUnifiedFullXamMacFramework )
2016-04-21 15:57:02 +03:00
return true ;
return false ;
}
static void ProcessNativeLibrary ( HashSet < string > processed , string library , List < MethodDefinition > used_by_methods )
{
// We do not bundle system libraries, ever
if ( library . StartsWith ( "/usr/lib/" , StringComparison . Ordinal ) | | library . StartsWith ( "/System/Library/" , StringComparison . Ordinal ) )
return ;
// If we've been required to ignore this library, skip it
if ( ignored_assemblies . Contains ( library ) )
return ;
2018-03-01 18:36:06 +03:00
// If we're passed in a framework, ignore
2016-04-21 15:57:02 +03:00
if ( App . Frameworks . Contains ( library ) )
return ;
// We need to check both the name and the shortened name, since we might get passed:
// full path - /foo/bar/libFoo.dylib
// just name - libFoo
string name = Path . GetFileName ( library ) ;
string libName = "lib" + GetLibraryShortenedName ( name ) + ".dylib" ;
// There is a list of libraries we always skip, honor that
if ( ShouldSkipNativeLibrary ( name ) )
return ;
string src = null ;
// If we've been passed in a full path and it is there, let's just go with that
if ( File . Exists ( library ) )
src = library ;
// Now let's check inside mono/lib
2020-04-16 15:19:45 +03:00
string monoDirPath = Path . Combine ( GetMonoLibraryDirectory ( App ) , libName ) ;
2016-04-21 15:57:02 +03:00
if ( src = = null & & File . Exists ( monoDirPath ) )
src = monoDirPath ;
// Now let's check in path with our libName
string path = Path . GetDirectoryName ( library ) ;
if ( src = = null & & ! String . IsNullOrEmpty ( path ) ) {
string pathWithLibName = Path . Combine ( path , name ) ;
if ( File . Exists ( pathWithLibName ) )
src = pathWithLibName ;
}
// If we can't find it at this point, scream
if ( src = = null ) {
2020-01-31 23:02:52 +03:00
ErrorHelper . Show ( new MonoMacException ( 2006 , false , Errors . MM2006 , name ) ) ;
2016-04-21 15:57:02 +03:00
if ( used_by_methods ! = null & & used_by_methods . Count > 0 ) {
const int referencedByLimit = 25 ;
2020-02-18 23:44:19 +03:00
bool limitReferencedByWarnings = used_by_methods . Count > referencedByLimit & & Verbosity < 4 ;
2016-04-21 15:57:02 +03:00
foreach ( var m in limitReferencedByWarnings ? used_by_methods . Take ( referencedByLimit ) : used_by_methods ) {
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 2009 , Errors . MM2009 , m . DeclaringType . FullName , m . Name ) ;
2016-04-21 15:57:02 +03:00
}
if ( limitReferencedByWarnings )
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 2012 , Errors . MM2012 , referencedByLimit , used_by_methods . Count ) ;
2016-04-21 15:57:02 +03:00
}
return ;
}
string real_src = GetRealPath ( src ) ;
string dest = Path . Combine ( mmp_dir , Path . GetFileName ( real_src ) ) ;
2020-02-18 23:44:19 +03:00
Log ( 2 , "Native library '{0}' copied to application bundle." , Path . GetFileName ( real_src ) ) ;
2016-04-21 15:57:02 +03:00
if ( GetRealPath ( dest ) = = real_src ) {
Console . WriteLine ( "Dependency {0} was already at destination, skipping." , Path . GetFileName ( real_src ) ) ;
}
else {
2016-05-25 23:29:33 +03:00
// install_name_tool gets angry if you copy in a read only native library
CopyFileAndRemoveReadOnly ( real_src , dest ) ;
2016-04-21 15:57:02 +03:00
}
2016-10-20 16:34:26 +03:00
bool isStaticLib = real_src . EndsWith ( ".a" , StringComparison . Ordinal ) ;
2018-03-01 18:36:06 +03:00
bool isDynamicLib = real_src . EndsWith ( ".dylib" , StringComparison . Ordinal ) ;
if ( isDynamicLib & & App . Optimizations . TrimArchitectures = = true )
LipoLibrary ( name , dest ) ;
2016-04-21 15:57:02 +03:00
if ( native_references . Contains ( real_src ) ) {
2020-03-17 17:49:39 +03:00
if ( ! isStaticLib )
RunInstallNameTool ( new [ ] { "-id" , "@executable_path/../" + BundleName + "/" + name , dest } ) ;
2016-04-21 15:57:02 +03:00
native_libraries_copied_in . Add ( name ) ;
}
// if a symlink was used then it might still be needed at runtime
if ( src ! = real_src )
CreateSymLink ( mmp_dir , real_src , src ) ;
// We add both the resolved location and the initial request.
// @executable_path subtitution and other resolving can have these be different
// and we'll loop forever otherwise
processed . Add ( real_src ) ;
processed . Add ( library ) ;
// process native dependencies
if ( ! isStaticLib ) {
foreach ( string dependency in Xamarin . MachO . GetNativeDependencies ( real_src ) ) {
string lib = GetRealPath ( dependency ) ;
if ( ! processed . Contains ( lib ) )
ProcessNativeLibrary ( processed , lib , null ) ;
}
}
}
2018-03-01 18:36:06 +03:00
static void LipoLibrary ( string name , string dest )
{
var existingArchs = Xamarin . MachO . GetArchitectures ( dest ) ;
// If we have less than two, it will either match by default or
// we'll fail a link/launch time with a better error so bail
if ( existingArchs . Count ( ) < 2 )
return ;
2020-05-11 17:27:19 +03:00
var arch = App . Abi . AsString ( ) ;
2020-03-17 17:49:39 +03:00
RunLipo ( new [ ] { dest , "-thin" , arch , "-output" , dest } ) ;
2019-02-01 21:40:50 +03:00
if ( name ! = "MonoPosixHelper" & & name ! = "libmono-native-unified" & & name ! = "libmono-native-compat" )
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 2108 , Errors . MM2108 , name , arch ) ;
2018-03-01 18:36:06 +03:00
}
2016-04-21 15:57:02 +03:00
static void CreateSymLink ( string directory , string real , string link )
{
string cd = Environment . CurrentDirectory ;
Environment . CurrentDirectory = directory ;
symlink ( Path . GetFileName ( real ) , "./" + Path . GetFileName ( link ) ) ;
Environment . CurrentDirectory = cd ;
}
/* Currently we clobber any existing files, perhaps we should error and have a -force flag */
static void CreateDirectoriesIfNeeded ( ) {
2017-04-28 19:09:03 +03:00
if ( App . Embeddinator ) {
App . AppDirectory = Path . Combine ( output_dir , app_name + ".framework" ) ;
contents_dir = Path . Combine ( App . AppDirectory , "Versions" , "A" ) ;
macos_dir = contents_dir ;
} else {
Add bindings for NSXpcConnection and related types (#7001)
* Add bindings for NSXpcConnection and related types
* Re-add accidentally deleted file
* Typo fix
* Add NSXpcInterface.CreateForType()
* Add MethodInfo-taking overloads to NSXpcInterface
* Add null check
* Mark methods with wrappers as internal
Also fixed a formatting bug that I didn't catch earlier.
* Change NSXPCProxyCreating methods to be strongly typed
I got rid of the NSXpcProxyCreating interface in this change,
because its only user was NSXpcConnection, and I needed to
inline the protocol methods into the class definition so I
could mark them as [Internal].
* Add missing casts
* Add NSXpcConnectionOptions enum
* Convert NSXpcConnection constructor to use new enum
* Remove now-unneeded manual constructor
* Fix bgen warning
* Typo fix
* Fix selector
* Remove incorrect use of BindAsAttribute
Per the docs, this only works for enums backed
by NSNumber and NSValue, not for enums
passed directly as integers.
* Fix duplicated selector errors
* Throw ArgumentException instead of InvalidOperationException
* Extend AppExtension targets to produce XPC services
Rather than create an entirely new set of targets
(that would require VS and VSMac updates to properly
consume), I have decided to use the existing AppExtension
build targets to produce XPC services as well. All the
user must do is set the $(IsXPCService) property to true in
their project file, and the targets will do The Right Thing™.
Note that this support is Mac-only for now; I may need a bit
of help adjusting them to work on for iOS/watchOS/tvOS, as I
am not as familiar with those platforms.
* Copy XPC service bundles into the correct location
* Move IsXPCService property definition to props file
* Don't pass /extension to mmp for XPC service targets
This would cause the XPC service binary to
be linked incorrectly.
* Add NSXpcConnection/NSXpcInterface.cs files to the build
* Fix build
* Fix build
* Add required type parameter requirements
* Fix type parameter requirements
* Fix return type
* Fix return type of NSXpcInterface.CreateForProtocol ()
* Take ownership of the returned object types
* Adjust XPC service mmp invocation
I need to link the XPC service bundle as if it is an app extension, but
I must not use xamarin_mac_extension_main. I added a new flag to make
this possible.
* Change mmp to correctly construct XPC service bundle
* Set the MonoBundleExecutable Info.plist key for XPC services
* Use the runtime to get the protocol
* Make NSXpcInterface.CreateForProtocol() public
The static registrar must be used for Cocoa to accept the protocol
as a valid XPC interface, but that then seems to break resolving
the protocol from the type. I must therefore hard-code the protocol
name in my code, and that requires I make this constructor public.
* Add XpcInterfaceAttribute
See the doc comment in XpcInterfaceAttribute.cs for why
this type is required. The referenced mmp optimizations
will be added in future commits.
* Add XpcInterfaceAttribute to generator build
* Add support for XpcInterfaceAttribute to the generator
* Force static generation of protocols decorated with XpcInterfaceAttribute
* Change how static registrar translates block parameters
Previously, they would always be marshalled as "id".
This would throw off the XPC subsystem, which parses
the block signature to determine the communication
protocol.
* Undo whitespace noise
* Remove unneeded casts
* Add trailing comma
* Use HasAttribute instead of GetCustomAttribute
* Fix style issues
* Bind NSXpcConnection.auditSessionIdentifier
* Address naming feedback
* Make Get/SetAllowedClasses public
IMHO, passing the selector as a string is just as
usable as passing a MethodInfo, and is also less
verbose if you copy/paste the selector string
from the ExportAttribute. There is no reason why
we cannot have both overloads be public.
* Update overload names to match
* Update more overload names to match
* Make mmp --xpc imply --extension
* Reformat if statement
* Fix build
* Conditionalize creation of PlugIns and XPCServices directories
* Add AutoGeneratedName
Co-Authored-By: Rolf Bjarne Kvinge <rolf@xamarin.com>
* Get rid of ProtocolizeAttribute
* Update availability attributes to please xharness
I actually think xharness is wrong here, since the
NSXPCConnection header lists these types as being
available starting in macOS 10.8.
* Update sharpie ignore files to reflect changes
This should fix the xtro-sharpie test failures CI has been reporting.
* Fix MM4105 error generation
* Adjust error message in test to match mmp
I had to change the error text slightly, because the type of the parameter
cannot be determined where the error is thrown anymore. However, the newer
exception message IMO is just as clear.
* Make exception message match test exactly
* Remove outdated copyright header text
* Remove more outdated copyright header text
* Revert changes to MM4105 error generation
I have a more elegant way of fixing this test now.
* Return "id" if Invoke method cannot be found
This fixes the MM4105 error unit test,
without requiring modification to that test.
* Remove redundant availability attributes
* Add DesignatedInitializerAttribute
* Re-add required code to macOS-Foundation.ignore
* Put DesignatedInitializer on the right constructor
* Update xtro-sharpie ignore files
2019-10-22 16:38:01 +03:00
string bundle_ext ;
if ( is_extension & & is_xpc_service )
bundle_ext = "xpc" ;
else if ( is_extension )
bundle_ext = "appex" ;
else
bundle_ext = "app" ;
App . AppDirectory = Path . Combine ( output_dir , string . Format ( "{0}.{1}" , app_name , bundle_ext ) ) ;
2017-04-28 19:09:03 +03:00
contents_dir = Path . Combine ( App . AppDirectory , "Contents" ) ;
macos_dir = Path . Combine ( contents_dir , "MacOS" ) ;
}
2016-05-26 00:20:33 +03:00
2016-04-21 15:57:02 +03:00
frameworks_dir = Path . Combine ( contents_dir , "Frameworks" ) ;
resources_dir = Path . Combine ( contents_dir , "Resources" ) ;
mmp_dir = Path . Combine ( contents_dir , BundleName ) ;
CreateDirectoryIfNeeded ( App . AppDirectory ) ;
CreateDirectoryIfNeeded ( contents_dir ) ;
CreateDirectoryIfNeeded ( macos_dir ) ;
CreateDirectoryIfNeeded ( resources_dir ) ;
CreateDirectoryIfNeeded ( mmp_dir ) ;
2017-04-28 19:09:03 +03:00
if ( App . Embeddinator ) {
CreateSymlink ( Path . Combine ( App . AppDirectory , "Versions" , "Current" ) , "A" ) ;
CreateSymlink ( Path . Combine ( App . AppDirectory , app_name ) , $"Versions/Current/{app_name}" ) ;
CreateSymlink ( Path . Combine ( App . AppDirectory , "Resources" ) , "Versions/Current/Resources" ) ;
}
}
// Mono.Unix can't create symlinks to relative paths, it insists on the target to a full path before creating the symlink.
static void CreateSymlink ( string file , string target )
{
unlink ( file ) ; // Delete any existing symlinks.
var rv = symlink ( target , file ) ;
if ( rv ! = 0 )
2020-01-31 23:02:52 +03:00
throw ErrorHelper . CreateError ( 1034 , Errors . MM1034 , file , target , Marshal . GetLastWin32Error ( ) ) ;
2016-04-21 15:57:02 +03:00
}
static void CreateDirectoryIfNeeded ( string dir ) {
if ( ! Directory . Exists ( dir ) )
Directory . CreateDirectory ( dir ) ;
}
static void CopyConfiguration ( ) {
if ( IsUnifiedMobile ) {
CopyResourceFile ( "config_mobile" , "config" ) ;
}
else {
if ( IsUnifiedFullXamMacFramework ) {
CopyResourceFile ( "machine.4_5.config" , "machine.config" ) ;
}
else {
string machine_config = Path . Combine ( MonoDirectory , "etc" , "mono" , "4.5" , "machine.config" ) ;
if ( ! File . Exists ( machine_config ) )
[mtouch/mmp] Improve target framework code. (#8137)
* Unify target framework code between mtouch and mmp.
* Simplify the code in mmp: have three possible valid target frameworks for
most of code, and add special code to handle setting any other valid target
frameworks to redirect to one of those three valid target frameworks (and
warn if given any of those valid, but not "main", target frameworks). Any
other code can then depend on the target framework having exactly one of
those specific values, which means we can make IsUnified* variables
convenience properties instead.
* Unify a bit more of the argument parsing code between mtouch and mmp, since
that made a few other things easier.
* Add TargetFramework.IsValidFramework to have one validation implementation.
* Move the implementation of TargetFramework.MonoFrameworkDirectory to mmp
itself, it's not really related to the target framework.
* Remove Driver.IsUnified and IsClassic from mmp, they're not used anymore.
* Formally deprecate --xamarin-[full|system]-framework in mmp, they've really been deprecated for many years.
* Remove LinkerOptions.TargetFramework, it's not used anymore.
* Get rid of mmp's userTargetFramework fried, it's duplicated with the
targetFramework field.
* Add a few tests, and tweak others a bit.
Breaking changes:
* Both mtouch and mmp require --target-framework now. The only direct
consumers should be the MSBuild tasks, which already pass --target-framework
all the time. This simplifies code, and removes assumptions.
2020-03-19 11:28:09 +03:00
throw new MonoMacException ( 1403 , true , Errors . MM1403 , "File" , machine_config , TargetFramework ) ;
2016-04-21 15:57:02 +03:00
File . Copy ( machine_config , Path . Combine ( mmp_dir , "machine.config" ) , true ) ;
}
CopyResourceFile ( "config" , "config" ) ;
}
2016-10-13 18:42:05 +03:00
if ( machine_config_path ! = null ) {
string machineConfigDestDir = Path . Combine ( mmp_dir , "mono/4.5/" ) ;
string machineConfigDestFile = Path . Combine ( machineConfigDestDir , "machine.config" ) ;
CreateDirectoryIfNeeded ( machineConfigDestDir ) ;
if ( machine_config_path = = String . Empty ) {
File . WriteAllLines ( machineConfigDestFile , new string [ ] { "<?xml version=\"1.0\" encoding=\"utf-8\"?>" , "<configuration>" , "</configuration>" } ) ;
}
else {
if ( ! File . Exists ( machine_config_path ) )
2020-01-31 23:02:52 +03:00
throw new MonoMacException ( 97 , true , Errors . MM0097 , machine_config_path ) ;
2016-10-13 18:42:05 +03:00
File . Copy ( machine_config_path , machineConfigDestFile ) ;
}
}
2016-04-21 15:57:02 +03:00
}
static void CopyResourceFile ( string streamName , string outputFileName ) {
var sr = new StreamReader ( typeof ( Driver ) . Assembly . GetManifestResourceStream ( streamName ) ) ;
var all = sr . ReadToEnd ( ) ;
var config = Path . Combine ( mmp_dir , outputFileName ) ;
using ( var sw = new StreamWriter ( config ) ) {
sw . WriteLine ( all ) ;
}
}
static void CopyI18nAssemblies ( I18nAssemblies i18n )
{
if ( i18n = = I18nAssemblies . None )
return ;
string fx_dir = BuildTarget . Resolver . FrameworkDirectory ;
// always needed (if any is specified)
resolved_assemblies . Add ( Path . Combine ( fx_dir , "I18N.dll" ) ) ;
// optionally needed
if ( ( i18n & I18nAssemblies . CJK ) ! = 0 )
resolved_assemblies . Add ( Path . Combine ( fx_dir , "I18N.CJK.dll" ) ) ;
if ( ( i18n & I18nAssemblies . MidEast ) ! = 0 )
resolved_assemblies . Add ( Path . Combine ( fx_dir , "I18N.MidEast.dll" ) ) ;
if ( ( i18n & I18nAssemblies . Other ) ! = 0 )
resolved_assemblies . Add ( Path . Combine ( fx_dir , "I18N.Other.dll" ) ) ;
if ( ( i18n & I18nAssemblies . Rare ) ! = 0 )
resolved_assemblies . Add ( Path . Combine ( fx_dir , "I18N.Rare.dll" ) ) ;
if ( ( i18n & I18nAssemblies . West ) ! = 0 )
resolved_assemblies . Add ( Path . Combine ( fx_dir , "I18N.West.dll" ) ) ;
}
2016-05-25 23:29:33 +03:00
static void CopyFileAndRemoveReadOnly ( string src , string dest ) {
File . Copy ( src , dest , true ) ;
FileAttributes attrs = File . GetAttributes ( dest ) ;
if ( ( attrs & FileAttributes . ReadOnly ) = = FileAttributes . ReadOnly )
File . SetAttributes ( dest , attrs & ~ FileAttributes . ReadOnly ) ;
}
2016-04-21 15:57:02 +03:00
static void CopyAssemblies ( ) {
foreach ( string asm in resolved_assemblies ) {
var configfile = string . Format ( "{0}.config" , asm ) ;
string filename = Path . GetFileName ( asm ) ;
2016-05-25 23:29:33 +03:00
// The linker later gets angry if you copy in a read only assembly
CopyFileAndRemoveReadOnly ( asm , Path . Combine ( mmp_dir , filename ) ) ;
2017-02-01 03:59:08 +03:00
2020-02-18 23:44:19 +03:00
Log ( 1 , "Added assembly {0}" , asm ) ;
2016-04-21 15:57:02 +03:00
2017-04-13 00:38:54 +03:00
if ( App . EnableDebug ) {
var mdbfile = asm + ".mdb" ;
if ( File . Exists ( mdbfile ) )
2018-03-01 18:36:06 +03:00
CopyFileAndRemoveReadOnly ( mdbfile , Path . Combine ( mmp_dir , Path . GetFileName ( mdbfile ) ) ) ;
2017-04-13 00:38:54 +03:00
var pdbfile = Path . ChangeExtension ( asm , ".pdb" ) ;
if ( File . Exists ( pdbfile ) )
2018-03-01 18:36:06 +03:00
CopyFileAndRemoveReadOnly ( pdbfile , Path . Combine ( mmp_dir , Path . GetFileName ( pdbfile ) ) ) ;
2017-04-13 00:38:54 +03:00
}
2016-04-21 15:57:02 +03:00
if ( File . Exists ( configfile ) )
File . Copy ( configfile , Path . Combine ( mmp_dir , Path . GetFileName ( configfile ) ) , true ) ;
}
2017-02-01 03:59:08 +03:00
foreach ( var assembly in BuildTarget . Assemblies )
assembly . CopySatellitesToDirectory ( mmp_dir ) ;
2016-04-21 15:57:02 +03:00
}
static void CopyResources ( ) {
foreach ( string res in resources ) {
File . Copy ( res , Path . Combine ( resources_dir , Path . GetFileName ( res ) ) , true ) ;
}
}
static void GatherAssemblies ( ) {
2020-05-05 16:35:02 +03:00
foreach ( string asm in App . References ) {
2017-08-23 17:31:02 +03:00
AssemblyDefinition assembly = AddAssemblyPathToResolver ( asm ) ;
2016-04-21 15:57:02 +03:00
ProcessAssemblyReferences ( assembly ) ;
}
if ( BuildTarget . Resolver . Exceptions . Count > 0 )
throw new AggregateException ( BuildTarget . Resolver . Exceptions ) ;
}
static void ProcessAssemblyReferences ( AssemblyDefinition assembly ) {
if ( assembly = = null )
return ;
2016-08-24 16:43:35 +03:00
var fqname = GetRealPath ( assembly . MainModule . FileName ) ;
2016-04-21 15:57:02 +03:00
if ( resolved_assemblies . Contains ( fqname ) )
return ;
[mtouch/mmp] Print assembly references in verbose mode. (#2139)
* [mtouch/mmp] Print assembly references in verbose mode.
Sample output:
Loaded assembly 'unifiedtestapp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' from /Users/rolf/Projects/TestApp/bin/iPhoneSimulator/Debug/unifiedtestapp.exe
References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065
Loaded assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/mscorlib.dll
Loaded assembly 'Xamarin.iOS, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/../../64bits/Xamarin.iOS.dll
References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756
References: System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Loaded assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.dll
References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756
References: System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Loaded assembly 'Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/Mono.Security.dll
References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Loaded assembly 'System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.Xml.dll
References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Loaded assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' from /work/maccore/master/xamarin-macios/_ios-build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/lib/mono/Xamarin.iOS/System.Core.dll
References: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
References: System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
I believe this will make it easier to diagnose cases where something references a desktop assembly.
* [mtouch/mmp] Share more code between mmp and mtouch.
2017-05-29 17:15:22 +03:00
Target . PrintAssemblyReferences ( assembly ) ;
2016-04-21 15:57:02 +03:00
2017-02-01 03:59:08 +03:00
var asm = new Assembly ( BuildTarget , assembly ) ;
asm . ComputeSatellites ( ) ;
BuildTarget . Assemblies . Add ( asm ) ;
2016-04-21 15:57:02 +03:00
resolved_assemblies . Add ( fqname ) ;
foreach ( AssemblyNameReference reference in assembly . MainModule . AssemblyReferences ) {
2020-04-14 17:32:42 +03:00
AssemblyDefinition reference_assembly = AddAssemblyReferenceToResolver ( reference ) ;
2016-04-21 15:57:02 +03:00
ProcessAssemblyReferences ( reference_assembly ) ;
}
}
2017-08-23 17:31:02 +03:00
static AssemblyDefinition AddAssemblyPathToResolver ( string path )
{
if ( AssemblySwapInfo . AssemblyNeedsSwappedOut ( path ) )
path = AssemblySwapInfo . GetSwappedAssemblyPath ( path ) ;
2018-01-13 01:39:38 +03:00
var assembly = BuildTarget . Resolver . Load ( path ) ;
2017-08-23 17:31:02 +03:00
if ( assembly = = null )
2020-01-31 23:02:52 +03:00
ErrorHelper . Warning ( 1501 , Errors . MM1501 , path ) ;
2017-08-23 17:31:02 +03:00
return assembly ;
}
2020-04-14 17:32:42 +03:00
static AssemblyDefinition AddAssemblyReferenceToResolver ( AssemblyNameReference reference )
2017-08-23 17:31:02 +03:00
{
2020-04-14 17:32:42 +03:00
if ( AssemblySwapInfo . ReferencedNeedsSwappedOut ( reference . Name ) )
return BuildTarget . Resolver . Load ( AssemblySwapInfo . GetSwappedReference ( reference . Name ) ) ;
2017-08-23 17:31:02 +03:00
return BuildTarget . Resolver . Resolve ( reference ) ;
}
}
public static class AssemblySwapInfo {
static HashSet < string > xammac_reference_assemblies_names = new HashSet < string > {
"Xamarin.Mac" ,
"Xamarin.Mac.CFNetwork" ,
"OpenTK"
} ;
public static bool AssemblyNeedsSwappedOut ( string path ) = > NeedsSwappedCore ( Path . GetFileNameWithoutExtension ( path ) ) ;
public static bool ReferencedNeedsSwappedOut ( string reference ) = > NeedsSwappedCore ( reference ) ;
static bool NeedsSwappedCore ( string name )
{
if ( name . Contains ( "OpenTK" ) & & Driver . IsUnifiedFullXamMacFramework )
return false ;
2019-07-24 19:01:14 +03:00
return xammac_reference_assemblies_names . Contains ( name ) ;
2017-08-23 17:31:02 +03:00
}
public static string GetSwappedAssemblyPath ( string path ) = > GetSwappedPathCore ( Path . GetFileNameWithoutExtension ( path ) ) ;
public static string GetSwappedReference ( string reference ) = > GetSwappedPathCore ( reference ) ;
static string GetSwappedPathCore ( string name )
2016-04-21 15:57:02 +03:00
{
2017-08-23 17:31:02 +03:00
string flavor = ( Driver . IsUnifiedFullSystemFramework | | Driver . IsUnifiedFullXamMacFramework ) ? "full" : "mobile" ;
2020-05-11 17:27:19 +03:00
var abi = Driver . App . Abi ;
var arch = abi . AsArchString ( ) ;
switch ( abi ) {
case Abi . x86_64 :
return Path . Combine ( Driver . FrameworkLibDirectory , arch , flavor , name + ".dll" ) ;
2016-04-21 15:57:02 +03:00
default :
2020-05-11 17:27:19 +03:00
throw new MonoMacException ( 5205 , true , Errors . MM5205 , arch ) ;
2016-04-21 15:57:02 +03:00
}
}
}
}