2016-04-21 15:19:32 +03:00
// vim : set filetype = objc :
# include < dlfcn . h > // dlsym
# import < Cocoa / Cocoa . h >
# include "shared.h"
# include "product.h"
# include "xamarin/xamarin.h"
# include "xamarin/launch.h"
# include "launcher.h"
2016-05-26 00:20:33 +03:00
# include "runtime-internal.h"
# include "main-internal.h"
2016-04-21 15:19:32 +03:00
# ifdef DYNAMIC_MONO _RUNTIME
# define DEFAULT_MONO _RUNTIME "/Library/Frameworks/Mono.framework/Versions/Current"
static const char * mono_runtime _prefix = NULL ;
bool xamarin_enable _debug = 0 ;
# endif
static char original_working _directory _path [ MAXPATHLEN ] ;
extern "C" const char * const
xamarin_get _original _working _directory _path ( )
{
return original_working _directory _path ;
}
static int
redirect_io ( int from_fd , const char * to_path )
{
int err ;
int fd ;
if ( ( fd = open ( to_path , O_CREAT | O_TRUNC | O_WRONLY , 0644 ) ) = = -1 )
return -1 ;
if ( dup2 ( fd , from_fd ) = = -1 ) {
err = errno ;
close ( fd ) ;
errno = err ;
return -1 ;
}
return 0 ;
}
static void
init_logdir ( void )
{
const char * env ;
size_t dirlen ;
char * path ;
if ( ( env = getenv ( "MONOMAC_LOGDIR" ) ) ! = NULL && * env ) {
// Redirect stdout / err to log files . . .
NSError * error = nil ;
if ( ! [ [ NSFileManager defaultManager ]
createDirectoryAtPath : [ NSString stringWithUTF8String : env ]
withIntermediateDirectories : YES
attributes : @ { NSFilePosixPermissions : [ NSNumber numberWithInt : 0755 ] }
error : & error ] ) {
fprintf ( stderr , PRODUCT ": Could not create log directory: %s\n" , [ [ error description ] UTF8String ] ) ;
return ;
}
dirlen = strlen ( env ) ;
path = ( char * ) malloc ( dirlen + 12 ) ;
strcpy ( path , env ) ;
if ( path [ dirlen - 1 ] ! = ' / ' )
path [ dirlen + + ] = ' / ' ;
strcpy ( path + dirlen , "stdout.log" ) ;
if ( redirect_io ( STDOUT_FILENO , path ) = = -1 )
fprintf ( stderr , PRODUCT ": Could not redirect stdout to `%s': %s\n" , path , strerror ( errno ) ) ;
strcpy ( path + dirlen , "stderr.log" ) ;
if ( redirect_io ( STDERR_FILENO , path ) = = -1 )
fprintf ( stderr , PRODUCT ": Could not redirect stderr to `%s': %s\n" , path , strerror ( errno ) ) ;
free ( path ) ;
}
}
static char *
decode_qstring ( unsigned char * * in , unsigned char qchar )
{
unsigned char * inptr = * in ;
unsigned char * start = * in ;
char * value , * v ;
size_t len = 0 ;
while ( * inptr ) {
if ( * inptr = = qchar )
break ;
if ( * inptr = = ' \ \ ' ) {
if ( inptr [ 1 ] = = ' \ 0 ' )
break ;
inptr + + ;
}
inptr + + ;
len + + ;
}
v = value = ( char * ) malloc ( len + 1 ) ;
while ( start < inptr ) {
if ( * start = = ' \ \ ' )
start + + ;
* v + + = ( char ) * start + + ;
}
* v = ' \ 0 ' ;
if ( * inptr )
inptr + + ;
* in = inptr ;
return value ;
}
typedef struct _ListNode {
struct _ListNode * next ;
char * value ;
} ListNode ;
static char * *
get_mono _env _options ( int * count )
{
const char * env = getenv ( "MONO_ENV_OPTIONS" ) ;
ListNode * list = NULL , * node , * tail = NULL ;
unsigned char * start , * inptr ;
char * value , * * argv ;
int i , n = 0 ;
size_t size ;
if ( env = = NULL ) {
* count = 0 ;
return NULL ;
}
inptr = ( unsigned char * ) env ;
while ( * inptr ) {
while ( isblank ( ( int ) * inptr ) )
inptr + + ;
if ( * inptr = = ' \ 0 ' )
break ;
start = inptr + + ;
switch ( * start ) {
case ' \ ' ' :
case ' " ' :
value = decode_qstring ( & inptr , * start ) ;
break ;
default :
while ( * inptr && ! isblank ( ( int ) * inptr ) )
inptr + + ;
// Note : Mac OS X <= 10.6 .8 do not have strndup ( )
// value = strndup ( ( char * ) start , ( size_t ) ( inptr - start ) ) ;
size = ( size_t ) ( inptr - start ) ;
value = ( char * ) malloc ( size + 1 ) ;
memcpy ( value , start , size ) ;
value [ size ] = ' \ 0 ' ;
break ;
}
node = ( ListNode * ) malloc ( sizeof ( ListNode ) ) ;
node -> value = value ;
node -> next = NULL ;
n + + ;
if ( tail ! = NULL )
tail -> next = node ;
else
list = node ;
tail = node ;
}
// Note : we do not want child processes to inherit this environment variable ,
// so now that we ' ve parsed it ( and each value is strdup ' d ) , we can safely
// unset it .
unsetenv ( "MONO_ENV_OPTIONS" ) ;
* count = n ;
if ( n = = 0 )
return NULL ;
argv = ( char * * ) malloc ( sizeof ( char * ) * ( n + 1 ) ) ;
i = 0 ;
while ( list ! = NULL ) {
node = list -> next ;
argv [ i + + ] = list -> value ;
free ( list ) ;
list = node ;
}
argv [ i ] = NULL ;
return argv ;
}
static void
exit_with _message ( const char * reason , const char * argv0 , bool request_mono )
{
NSString * appName = nil ;
NSDictionary * plist = [ [ NSBundle mainBundle ] infoDictionary ] ;
if ( plist ) {
appName = ( NSString * ) [ plist objectForKey : ( NSString * ) kCFBundleNameKey ] ;
}
if ( ! appName ) {
appName = [ [ NSString stringWithUTF8String : argv0 ] lastPathComponent ] ;
}
NSAlert * alert = [ [ NSAlert alloc ] init ] ;
[ alert setMessageText : [ NSString stringWithFormat : @ "Could not launch %@" , appName ] ] ;
NSString * fmt = request_mono ? @ "%s\n\nPlease download and install the latest version of Mono." : @ "%s\n" ;
NSString * msg = [ NSString stringWithFormat : fmt , reason ] ;
[ alert setInformativeText : msg ] ;
2017-05-16 03:12:34 +03:00
NSLog ( @ "%@" , msg ) ;
2016-04-21 15:19:32 +03:00
if ( request_mono ) {
[ alert addButtonWithTitle : @ "Download Mono Framework" ] ;
[ alert addButtonWithTitle : @ "Cancel" ] ;
} else {
[ alert addButtonWithTitle : @ "OK" ] ;
}
NSInteger answer = [ alert runModal ] ;
[ alert release ] ;
if ( request_mono && answer = = NSAlertFirstButtonReturn ) {
NSString * mono_download _url = @ "http://www.go-mono.com/mono-downloads/download.html" ;
CFURLRef url = CFURLCreateWithString ( NULL , ( CFStringRef ) mono_download _url , NULL ) ;
LSOpenCFURLRef ( url , NULL ) ;
CFRelease ( url ) ;
}
exit ( 1 ) ;
}
static int
check_mono _version ( const char * version , const char * req_version )
{
char * req_end , * end ;
long req_val , val ;
while ( * req_version ) {
req_val = strtol ( req_version , & req_end , 10 ) ;
if ( req_version = = req_end || ( * req_end && * req_end ! = ' . ' ) ) {
fprintf ( stderr , "Bad version requirement string '%s'\n" , req_end ) ;
return FALSE ;
}
req_version = req_end ;
if ( * req_version )
req_version + + ;
val = strtol ( version , & end , 10 ) ;
if ( version = = end || val < req_val )
return FALSE ;
if ( val > req_val )
return TRUE ;
if ( * req_version = = ' . ' && * end ! = ' . ' )
return FALSE ;
version = end + 1 ;
}
return TRUE ;
}
# ifdef DYNAMIC_MONO _RUNTIME
static int
push_env ( const char * variable , NSString * str_value )
{
const char * value = [ str_value UTF8String ] ;
size_t len = strlen ( value ) ;
const char * current ;
int rv ;
if ( ( current = getenv ( variable ) ) && * current ) {
char * buf = ( char * ) malloc ( len + strlen ( current ) + 2 ) ;
memcpy ( buf , value , len ) ;
buf [ len ] = ' : ' ;
strcpy ( buf + len + 1 , current ) ;
rv = setenv ( variable , buf , 1 ) ;
free ( buf ) ;
} else {
rv = setenv ( variable , value , 1 ) ;
}
return rv ;
}
# endif
static void
update_environment ( xamarin_initialize _data * data )
{
if ( xamarin_get _is _mkbundle ( ) )
return ;
// 3 ) Ensure the following environment variables are set : [ . . . ]
2017-04-28 15:17:42 +03:00
NSString * res_dir ;
NSString * monobundle_dir ;
if ( data -> launch_mode = = XamarinLaunchModeEmbedded ) {
monobundle_dir = [ data -> app_dir stringByAppendingPathComponent : @ "Versions/Current/MonoBundle" ] ;
res_dir = [ data -> app_dir stringByAppendingPathComponent : @ "Versions/Current/Resources" ] ;
} else {
monobundle_dir = [ data -> app_dir stringByAppendingPathComponent : @ "Contents/MonoBundle" ] ;
res_dir = [ data -> app_dir stringByAppendingPathComponent : @ "Contents/Resources" ] ;
}
2016-04-21 15:19:32 +03:00
# ifdef DYNAMIC_MONO _RUNTIME
NSString * bin_dir = [ data -> app_dir stringByAppendingPathComponent : @ "Contents/MacOS" ] ;
push_env ( "DYLD_FALLBACK_LIBRARY_PATH" , [ NSString stringWithFormat : @ "%s/lib:/usr/local/lib:/lib:/usr/lib" , getenv ( "HOME" ) ] ) ;
push_env ( "DYLD_FALLBACK_LIBRARY_PATH" , [ res_dir stringByAppendingPathComponent : @ "/lib" ] ) ;
push_env ( "DYLD_FALLBACK_LIBRARY_PATH" , [ [ NSString stringWithUTF8String : mono_runtime _prefix ] stringByAppendingPathComponent : @ "/lib" ] ) ;
/ * Mono "External" directory * /
push_env ( "PKG_CONFIG_PATH" , @ "/Library/Frameworks/Mono.framework/External/pkgconfig" ) ;
/ * Enable the use of stuff bundled into the app bundle * /
push_env ( "PKG_CONFIG_PATH" , [ res_dir stringByAppendingPathComponent : @ "/lib/pkgconfig" ] ) ;
push_env ( "PKG_CONFIG_PATH" , [ res_dir stringByAppendingPathComponent : @ "/share/pkgconfig" ] ) ;
push_env ( "MONO_GAC_PREFIX" , res_dir ) ;
push_env ( "PATH" , bin_dir ) ;
data -> requires_relaunch = true ;
# else
// disable / dev / shm since Apple refuse applications that uses it in the Mac App Store
setenv ( "MONO_DISABLE_SHARED_AREA" , "" , 1 ) ;
unsetenv ( "MONO_PATH" ) ;
mono_set _assemblies _path ( xamarin_get _bundle _path ( ) ) ;
// 3 b ) ( If embedding Mono ) Change the current directory to $ appdir / Contents / Resources
chdir ( [ res_dir UTF8String ] ) ;
// Set up environment variables that need to point to ~ / Library / Application Support ( registry path )
NSFileManager * mgr = [ NSFileManager defaultManager ] ;
NSArray * appSupportDirectories = [ mgr URLsForDirectory : NSApplicationSupportDirectory inDomains : NSSystemDomainMask ] ;
if ( [ appSupportDirectories count ] > 0 ) {
NSString * appBundleID = [ [ NSBundle mainBundle ] bundleIdentifier ] ;
NSURL * appSupport = [ appSupportDirectories objectAtIndex : 0 ] ;
if ( appSupport ! = nil && appBundleID ! = nil ) {
2016-08-01 17:14:21 +03:00
NSURL * appDirectory = [ appSupport URLByAppendingPathComponent : appBundleID isDirectory : YES ] ;
2016-04-21 15:19:32 +03:00
setenv ( "MONO_REGISTRY_PATH" , [ [ appDirectory path ] UTF8String ] , 1 ) ;
}
}
# endif
2016-08-25 21:06:38 +03:00
if ( xamarin_disable _lldb _attach ) {
// Unfortunately the only place to set debug_options . no_gdb _backtrace is in mini_parse _debug _option
// So route through MONO_DEBUG
setenv ( "MONO_DEBUG" , "no-gdb-backtrace" , 0 ) ;
}
2016-10-13 18:42:05 +03:00
setenv ( "MONO_CFG_DIR" , [ monobundle_dir UTF8String ] , 0 ) ;
2016-04-21 15:19:32 +03:00
}
static void
2017-04-28 15:02:38 +03:00
app_initialize ( xamarin_initialize _data * data )
2016-04-21 15:19:32 +03:00
{
// The launch code here is publicly documented in xamarin / launch . h
// The numbers in the comments refer to numbers in xamarin / launch . h .
2017-04-28 15:02:38 +03:00
xamarin_launch _mode = data -> launch_mode ;
2017-03-08 22:00:58 +03:00
2016-04-21 15:19:32 +03:00
# ifndef SYSTEM_LAUNCHER
if ( xammac_setup ( ) ) {
data -> exit_code = -1 ;
return ;
}
# endif
bool mkbundle = xamarin_get _is _mkbundle ( ) ;
2017-04-28 15:17:42 +03:00
NSBundle * bundle ;
if ( data -> launch_mode = = XamarinLaunchModeEmbedded ) {
bundle = [ NSBundle bundleForClass : [ XamarinAssociatedObject class ] ] ;
} else {
bundle = [ NSBundle mainBundle ] ;
}
data -> app_dir = [ bundle bundlePath ] ; // this is good until the autorelease pool releases the bundlePath string .
2016-04-21 15:19:32 +03:00
// 1 ) If found , call the custom initialization function ( xamarin_custom _initialize )
xamarin_custom _initialize _func init = ( xamarin_custom _initialize _func ) dlsym ( RTLD_MAIN _ONLY , "xamarin_app_initialize" ) ;
if ( init ! = NULL )
init ( data ) ;
# ifdef DYNAMIC_MONO _RUNTIME
// 2 ) ( If not embedding Mono ) Search for the system Mono in the following directories :
if ( ! ( mono_runtime _prefix = getenv ( "MONO_RUNTIME" ) ) )
mono_runtime _prefix = DEFAULT_MONO _RUNTIME ;
# endif
// 3 ) Ensure the following environment variables are set : [ . . . ]
if ( ! data -> is_relaunch ) {
update_environment ( data ) ;
if ( data -> requires_relaunch )
return ;
}
data -> app_dir = NULL ; // Make sure nobody ends up using this .
// 4 ) Ensure that the maximum number of open files is least 1024.
struct rlimit limit ;
if ( getrlimit ( RLIMIT_NOFILE , & limit ) = = 0 && limit . rlim_cur < 1024 ) {
limit . rlim_cur = MIN ( limit . rlim_max , 1024 ) ;
setrlimit ( RLIMIT_NOFILE , & limit ) ;
}
// 5 ) Verify the minimum Mono version . The minimum mono version is specified in : [ . . . ]
NSDictionary * plist = [ [ NSBundle mainBundle ] infoDictionary ] ;
NSString * minVersion = NULL ;
if ( plist ! = NULL ) {
minVersion = ( NSString * ) [ plist objectForKey : @ "MonoMinimumVersion" ] ;
if ( minVersion = = NULL )
minVersion = ( NSString * ) [ plist objectForKey : @ "MonoMinVersion" ] ;
} else {
fprintf ( stderr , PRODUCT ": Could not load Info.plist from the bundle." ) ;
}
if ( ! minVersion ) {
// This must be kept in sync with mmp ' s minimum mono version ( in driver . cs )
minVersion = @ "4.2.0" ;
}
char * mono_version ;
# ifdef DYNAMIC_MONO _RUNTIME
const char * err = xamarin_initialize _dynamic _runtime ( mono_runtime _prefix ) ;
if ( err ) {
mono_version = xamarin_get _mono _runtime _build _info ( ) ;
if ( mono_version && ! check_mono _version ( mono_version , [ minVersion UTF8String ] ) ) {
exit_with _message ( [ [ NSString stringWithFormat : @ "This application requires the Mono framework version %@ or newer." , minVersion ] UTF8String ] , data -> basename , true ) ;
} else {
exit_with _message ( err , data -> basename , true ) ;
}
}
# endif
mono_version = mono_get _runtime _build _info ( ) ;
if ( ! check_mono _version ( mono_version , [ minVersion UTF8String ] ) )
exit_with _message ( [ [ NSString stringWithFormat : @ "This application requires the Mono framework version %@ or newer." , minVersion ] UTF8String ] , data -> basename , true ) ;
2017-05-11 18:44:58 +03:00
2016-04-21 15:19:32 +03:00
// 6 ) Find the executable . The name is : [ . . . ]
2017-04-28 15:02:38 +03:00
if ( data -> launch_mode = = XamarinLaunchModeApp ) {
2016-05-26 00:20:33 +03:00
NSString * exeName = NULL ;
NSString * exePath ;
if ( plist ! = NULL )
exeName = ( NSString * ) [ plist objectForKey : @ "MonoBundleExecutable" ] ;
else
fprintf ( stderr , PRODUCT ": Could not find Info.plist in the bundle.\n" ) ;
2016-04-21 15:19:32 +03:00
2016-05-26 00:20:33 +03:00
if ( exeName = = NULL )
exeName = [ [ NSString stringWithUTF8String : data -> basename ] stringByAppendingString : @ ".exe" ] ;
if ( mkbundle ) {
exePath = exeName ;
} else {
exePath = [ [ [ NSString stringWithUTF8String : xamarin_get _bundle _path ( ) ] stringByAppendingString : @ "/" ] stringByAppendingString : exeName ] ;
if ( ! xamarin_file _exists ( [ exePath UTF8String ] ) )
exit_with _message ( [ [ NSString stringWithFormat : @ "Could not find the executable '%@'\n\nFull path: %@" , exeName , exePath ] UTF8String ] , data -> basename , false ) ;
2017-05-11 18:44:58 +03:00
}
xamarin_entry _assembly _path = strdup ( [ exePath UTF8String ] ) ;
} else {
NSString * dllName = [ [ NSString stringWithUTF8String : data -> basename ] stringByAppendingString : @ ".dll" ] ;
NSString * dllPath = [ [ [ NSString stringWithUTF8String : xamarin_get _bundle _path ( ) ] stringByAppendingString : @ "/" ] stringByAppendingString : dllName ] ;
if ( ! xamarin_file _exists ( [ dllPath UTF8String ] ) )
exit_with _message ( [ [ NSString stringWithFormat : @ "Could not find the extension library '%@'\n\nFull path: %@" , dllName , dllPath ] UTF8String ] , data -> basename , false ) ;
2016-05-26 00:20:33 +03:00
2017-05-11 18:44:58 +03:00
xamarin_entry _assembly _path = strdup ( [ dllPath UTF8String ] ) ;
2016-05-26 00:20:33 +03:00
}
2016-04-21 15:19:32 +03:00
// 7 a ) [ If not embedding ] Parse the system Mono ' s config file ( $ monodir / etc / mono / config ) .
// 7 b ) [ If embedding ] Parse $ appdir / Contents / MonoBundle / machine . config and $ appdir / Contents / MonoBundle / config
if ( ! mkbundle ) {
NSString * config_path = nil ;
NSString * machine_config _path = nil ;
NSError * error = nil ;
# ifdef DYNAMIC_MONO _RUNTIME
config_path = [ [ NSString stringWithUTF8String : mono_runtime _prefix ] stringByAppendingPathComponent : @ "/etc/mono/config" ] ;
# else
config_path = [ [ NSString stringWithUTF8String : xamarin_get _bundle _path ( ) ] stringByAppendingPathComponent : @ "config" ] ;
machine_config _path = [ [ NSString stringWithUTF8String : xamarin_get _bundle _path ( ) ] stringByAppendingPathComponent : @ "machine.config" ] ;
# endif
# ifndef DYNAMIC_MONO _RUNTIME
mono_set _dirs ( xamarin_get _bundle _path ( ) , xamarin_get _bundle _path ( ) ) ;
# else
mono_set _dirs ( NULL , NULL ) ;
# endif
if ( machine_config _path ! = nil ) {
NSString * config = [ NSString stringWithContentsOfFile : machine_config _path encoding : NSUTF8StringEncoding error : & error ] ;
if ( config ! = nil ) {
mono_register _machine _config ( strdup ( [ config UTF8String ] ) ) ;
} else {
// fprintf ( stderr , PRODUCT ": Could not load machine.config: %s\n" , [ machine_config _path UTF8String ] ) ;
}
}
if ( config_path ! = nil ) {
NSString * config = [ NSString stringWithContentsOfFile : config_path encoding : NSUTF8StringEncoding error : & error ] ;
if ( config ! = nil ) {
mono_config _parse _memory ( ( char * ) [ config UTF8String ] ) ;
} else {
// fprintf ( stderr , PRODUCT ": Could not load config: %s\n" , [ config_path UTF8String ] ) ;
}
}
}
/ * other non - documented stuff . . . * /
initialize_cocoa _threads ( NULL ) ;
init_logdir ( ) ;
}
# define __XAMARIN _MAC _RELAUNCH _APP __ "__XAMARIN_MAC_RELAUNCH_APP__"
2017-05-11 18:44:58 +03:00
static void
run_application _init ( xamarin_initialize _data * data )
{
if ( ! xamarin_file _exists ( xamarin_entry _assembly _path ) )
exit_with _message ( [ [ NSString stringWithFormat : @ "Could not find the assembly '%s'" , xamarin_entry _assembly _path ] UTF8String ] , data -> basename , false ) ;
// Make sure any output from mono isn ' t lost when launching extensions ,
// etc , by installing the log callbacks early ( xamarin_initialize will
// also do this , but if something goes wrong before we reach
// xamarin_initialize when running as an extension , the output will be
// lost ) .
xamarin_install _log _callbacks ( ) ;
mono_jit _init ( xamarin_entry _assembly _path ) ;
MonoAssembly * assembly = xamarin_open _assembly ( "Xamarin.Mac.dll" ) ;
if ( ! assembly )
xamarin_assertion _message ( "Failed to load %s." , "Xamarin.Mac.dll" ) ;
MonoImage * image = mono_assembly _get _image ( assembly ) ;
MonoClass * app_class = mono_class _from _name ( image , "AppKit" , "NSApplication" ) ;
if ( ! app_class )
xamarin_assertion _message ( "Fatal error: failed to load the NSApplication class" ) ;
MonoMethod * initialize = mono_class _get _method _from _name ( app_class , "Init" , 0 ) ;
if ( ! initialize )
xamarin_assertion _message ( "Fatal error: failed to load the NSApplication.Init method" ) ;
mono_runtime _invoke ( initialize , NULL , NULL , NULL ) ;
}
2017-04-10 07:48:35 +03:00
int xamarin_main ( int argc , char * * argv , enum XamarinLaunchMode launch_mode )
2016-04-21 15:19:32 +03:00
{
xamarin_initialize _data data = { 0 } ;
if ( getcwd ( original_working _directory _path , sizeof ( original_working _directory _path ) ) = = NULL )
original_working _directory _path [ 0 ] = ' \ 0 ' ;
@ autoreleasepool {
data . size = sizeof ( data ) ;
data . argc = argc ;
data . argv = argv ;
2017-04-28 15:02:38 +03:00
data . launch_mode = launch_mode ;
2016-04-21 15:19:32 +03:00
// basename = Path . GetFileName ( argv [ 0 ] )
if ( ! ( data . basename = strrchr ( argv [ 0 ] , ' / ' ) ) ) {
data . basename = argv [ 0 ] ;
} else {
data . basename + + ;
}
data . is_relaunch = getenv ( __XAMARIN _MAC _RELAUNCH _APP __ ) ! = NULL ;
if ( data . is_relaunch )
unsetenv ( __XAMARIN _MAC _RELAUNCH _APP __ ) ;
2017-04-28 15:02:38 +03:00
app_initialize ( & data ) ;
2016-04-21 15:19:32 +03:00
if ( data . exit )
return data . exit_code ;
if ( data . requires_relaunch ) {
setenv ( __XAMARIN _MAC _RELAUNCH _APP __ , "1" , 1 ) ;
return execv ( argv [ 0 ] , argv ) ;
}
}
int rv = 0 ;
@ autoreleasepool {
int env_argc = 0 ;
char * * env_argv = get_mono _env _options ( & env_argc ) ;
int new_argc = env_argc + 2 / * - - debug executable * / + argc ;
2017-02-08 22:40:48 +03:00
if ( xamarin_mac _hybrid _aot )
2017-01-11 23:10:39 +03:00
new_argc + = 1 ;
[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 ( xamarin_mac _modern )
new_argc + = 1 ;
2016-04-21 15:19:32 +03:00
char * * new_argv = ( char * * ) malloc ( sizeof ( char * ) * ( new_argc + 1 / * null terminated * / ) ) ;
const char * * ptr = ( const char * * ) new_argv ;
// binary
* ptr + + = argv [ 0 ] ;
// inject MONO_ENV _OPTIONS
for ( int i = 0 ; i < env_argc ; i + + )
* ptr + + = env_argv [ i ] ;
if ( xamarin_debug _mode ) {
* ptr + + = "--debug" ;
} else {
new_argc - - ;
}
2017-02-08 22:40:48 +03:00
if ( xamarin_mac _hybrid _aot )
2017-01-11 23:10:39 +03:00
* ptr + + = "--hybrid-aot" ;
[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 ( xamarin_mac _modern )
* ptr + + = "--runtime=mobile" ;
2017-01-11 23:10:39 +03:00
2017-05-16 21:29:08 +03:00
// executable assembly
* ptr + + = xamarin_entry _assembly _path ;
2016-04-21 15:19:32 +03:00
// the rest
for ( int i = 1 ; i < argc ; i + + )
* ptr + + = argv [ i ] ;
* ptr = NULL ;
2017-04-10 07:48:35 +03:00
switch ( launch_mode ) {
case XamarinLaunchModeExtension : {
2017-05-11 18:44:58 +03:00
run_application _init ( & data ) ;
2016-06-09 01:19:16 +03:00
void * libExtensionHandle = dlopen ( "/usr/lib/libextension.dylib" , RTLD_LAZY ) ;
if ( libExtensionHandle = = nil )
exit_with _message ( "Unable to load libextension.dylib" , data . basename , false ) ;
typedef int ( * extension_main ) ( int argc , char * argv [ ] ) ;
extension_main extensionMain = ( extension_main ) dlsym ( libExtensionHandle , "NSExtensionMain" ) ;
if ( extensionMain = = nil )
exit_with _message ( "Unable to load NSExtensionMain" , data . basename , false ) ;
rv = ( * extensionMain ) ( new_argc , new_argv ) ;
dlclose ( libExtensionHandle ) ;
2017-04-10 07:48:35 +03:00
break ;
}
case XamarinLaunchModeApp :
2016-05-26 00:20:33 +03:00
rv = mono_main ( new_argc , new_argv ) ;
2017-04-10 07:48:35 +03:00
break ;
case XamarinLaunchModeEmbedded :
2017-05-11 18:44:58 +03:00
run_application _init ( & data ) ;
2017-04-10 07:48:35 +03:00
break ;
default :
xamarin_assertion _message ( "Invalid launch mode: %i." , launch_mode ) ;
break ;
2016-05-26 00:20:33 +03:00
}
2016-04-21 15:19:32 +03:00
free ( new_argv ) ;
}
return rv ;
}
2016-05-26 00:20:33 +03:00
int main ( int argc , char * * argv )
{
2017-04-10 07:48:35 +03:00
return xamarin_main ( argc , argv , XamarinLaunchModeApp ) ;
2016-05-26 00:20:33 +03:00
}
int xamarin_mac _extension _main ( int argc , char * * argv )
{
2017-05-11 11:28:56 +03:00
return xamarin_main ( argc , argv , XamarinLaunchModeExtension ) ;
2016-05-26 00:20:33 +03:00
}