@@ -27,10 +27,12 @@ module Motion; module Project;
27
27
class Builder
28
28
include Rake ::DSL if Rake . const_defined? ( :DSL )
29
29
30
- def build ( config , platform )
30
+ def build ( config , platform , opts )
31
31
datadir = config . datadir
32
32
archs = config . archs [ platform ]
33
33
34
+ static_library = opts . delete ( :static )
35
+
34
36
ruby = File . join ( config . bindir , 'ruby' )
35
37
llc = File . join ( config . bindir , 'llc' )
36
38
@@ -160,15 +162,15 @@ def build(config, platform)
160
162
FileUtils . touch ( objs_build_dir ) if project_file_changed
161
163
162
164
app_objs = objs
165
+ spec_objs = [ ]
163
166
if config . spec_mode
164
167
# Build spec files too, but sequentially.
165
- objs << build_file . call ( File . expand_path ( File . join ( File . dirname ( __FILE__ ) , '../spec.rb' ) ) )
166
168
spec_objs = config . spec_files . map { |path | build_file . call ( path ) }
167
169
objs += spec_objs
168
170
end
169
171
170
- # Generate main file.
171
- main_txt = <<EOS
172
+ # Generate init file.
173
+ init_txt = <<EOS
172
174
#import <UIKit/UIKit.h>
173
175
174
176
extern "C" {
@@ -184,8 +186,72 @@ def build(config, platform)
184
186
void rb_rb2oc_exc_handler(void);
185
187
void rb_exit(int);
186
188
EOS
187
- objs . each do |_ , init_func |
188
- main_txt << "void #{ init_func } (void *, void *);\n "
189
+ app_objs . each do |_ , init_func |
190
+ init_txt << "void #{ init_func } (void *, void *);\n "
191
+ end
192
+ init_txt << <<EOS
193
+ }
194
+
195
+ extern "C"
196
+ void
197
+ RubyMotionInit(int argc, char **argv)
198
+ {
199
+ static bool initialized = false;
200
+ if (!initialized) {
201
+ ruby_init();
202
+ ruby_init_loadpath();
203
+ if (argc > 0) {
204
+ const char *progname = argv[0];
205
+ ruby_script(progname);
206
+ }
207
+ try {
208
+ void *self = rb_vm_top_self();
209
+ EOS
210
+ app_objs . each do |_ , init_func |
211
+ init_txt << "#{ init_func } (self, 0);\n "
212
+ end
213
+ init_txt << <<EOS
214
+ }
215
+ catch (...) {
216
+ rb_rb2oc_exc_handler();
217
+ }
218
+ initialized = true;
219
+ }
220
+ }
221
+ EOS
222
+
223
+ # Compile init file.
224
+ init = File . join ( objs_build_dir , 'init.mm' )
225
+ init_o = File . join ( objs_build_dir , 'init.o' )
226
+ if !( File . exist? ( init ) and File . exist? ( init_o ) and File . read ( init ) == init_txt )
227
+ File . open ( init , 'w' ) { |io | io . write ( init_txt ) }
228
+ sh "#{ cxx } \" #{ init } \" #{ config . cflags ( platform , true ) } -c -o \" #{ init_o } \" "
229
+ end
230
+
231
+ if static_library
232
+ # Create a static archive with all object files + the runtime.
233
+ lib = File . join ( config . versionized_build_dir ( platform ) , config . name + '.a' )
234
+ App . info 'Create' , lib
235
+ cp File . join ( datadir , platform , 'libmacruby-static.a' ) , lib
236
+ objs_list = objs . map { |path , _ | path } . unshift ( init_o , *config . frameworks_stubs_objects ( platform ) ) . map { |x | "\" #{ x } \" " } . join ( ' ' )
237
+ sh "/usr/bin/ar -cr \" #{ lib } \" #{ objs_list } "
238
+ return lib
239
+ end
240
+
241
+ # Generate main file.
242
+ main_txt = <<EOS
243
+ #import <UIKit/UIKit.h>
244
+
245
+ extern "C" {
246
+ void rb_define_const(void *, const char *, void *);
247
+ void rb_rb2oc_exc_handler(void);
248
+ void rb_exit(int);
249
+ void RubyMotionInit(int argc, char **argv);
250
+ EOS
251
+ if config . spec_mode
252
+ spec_objs . each do |_ , init_func |
253
+ main_txt << "void #{ init_func } (void *, void *);\n "
254
+ end
189
255
end
190
256
main_txt << <<EOS
191
257
}
@@ -196,11 +262,31 @@ def build(config, platform)
196
262
@interface SpecLauncher : NSObject
197
263
@end
198
264
265
+ #include <dlfcn.h>
266
+
199
267
@implementation SpecLauncher
200
268
201
269
+ (id)launcher
202
270
{
203
271
[UIApplication sharedApplication];
272
+
273
+ // Enable simulator accessibility.
274
+ // Thanks http://www.stewgleadow.com/blog/2011/10/14/enabling-accessibility-for-ios-applications/
275
+ NSString *simulatorRoot = [[[NSProcessInfo processInfo] environment] objectForKey:@"IPHONE_SIMULATOR_ROOT"];
276
+ if (simulatorRoot != nil) {
277
+ void *appSupportLibrary = dlopen([[simulatorRoot stringByAppendingPathComponent:@"/System/Library/PrivateFrameworks/AppSupport.framework/AppSupport"] fileSystemRepresentation], RTLD_LAZY);
278
+ CFStringRef (*copySharedResourcesPreferencesDomainForDomain)(CFStringRef domain) = (CFStringRef (*)(CFStringRef)) dlsym(appSupportLibrary, "CPCopySharedResourcesPreferencesDomainForDomain");
279
+
280
+ if (copySharedResourcesPreferencesDomainForDomain != NULL) {
281
+ CFStringRef accessibilityDomain = copySharedResourcesPreferencesDomainForDomain(CFSTR("com.apple.Accessibility"));
282
+
283
+ if (accessibilityDomain != NULL) {
284
+ CFPreferencesSetValue(CFSTR("ApplicationAccessibilityEnabled"), kCFBooleanTrue, accessibilityDomain, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
285
+ CFRelease(accessibilityDomain);
286
+ }
287
+ }
288
+ }
289
+
204
290
SpecLauncher *launcher = [[self alloc] init];
205
291
[[NSNotificationCenter defaultCenter] addObserver:launcher selector:@selector(appLaunched:) name:UIApplicationDidBecomeActiveNotification object:nil];
206
292
return launcher;
@@ -230,18 +316,20 @@ def build(config, platform)
230
316
main(int argc, char **argv)
231
317
{
232
318
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
233
- const char *progname = argv[0];
234
- ruby_init();
235
- ruby_init_loadpath();
236
- ruby_script(progname);
237
319
int retval = 0;
238
320
try {
239
- void *self = rb_vm_top_self();
240
321
EOS
241
322
main_txt << "[SpecLauncher launcher];\n " if config . spec_mode
242
- app_objs . each do |_ , init_func |
243
- main_txt << "#{ init_func } (self, 0);\n "
244
- end
323
+ main_txt << <<EOS
324
+ RubyMotionInit(argc, argv);
325
+ EOS
326
+ rubymotion_env =
327
+ if config . spec_mode
328
+ 'test'
329
+ else
330
+ config . development? ? 'development' : 'release'
331
+ end
332
+ main_txt << "rb_define_const([NSObject class], \" RUBYMOTION_ENV\" , @\" #{ rubymotion_env } \" );\n "
245
333
main_txt << <<EOS
246
334
retval = UIApplicationMain(argc, argv, nil, @"#{ config . delegate_class } ");
247
335
rb_exit(retval);
@@ -279,14 +367,9 @@ def build(config, platform)
279
367
or vendor_libs . any? { |lib | File . mtime ( lib ) > File . mtime ( main_exec ) } \
280
368
or File . mtime ( File . join ( datadir , platform , 'libmacruby-static.a' ) ) > File . mtime ( main_exec )
281
369
App . info 'Link' , main_exec
282
- objs_list = objs . map { |path , _ | path } . unshift ( main_o ) . map { |x | "\" #{ x } \" " } . join ( ' ' )
370
+ objs_list = objs . map { |path , _ | path } . unshift ( init_o , main_o , * config . frameworks_stubs_objects ( platform ) ) . map { |x | "\" #{ x } \" " } . join ( ' ' )
283
371
frameworks = config . frameworks_dependencies . map { |x | "-framework #{ x } " } . join ( ' ' )
284
- framework_stubs_objs = [ ]
285
- config . frameworks_dependencies . each do |framework |
286
- stubs_obj = File . join ( datadir , platform , "#{ framework } _stubs.o" )
287
- framework_stubs_objs << "\" #{ stubs_obj } \" " if File . exist? ( stubs_obj )
288
- end
289
- sh "#{ cxx } -o \" #{ main_exec } \" #{ objs_list } #{ framework_stubs_objs . join ( ' ' ) } #{ config . ldflags ( platform ) } -L#{ File . join ( datadir , platform ) } -lmacruby-static -lobjc -licucore #{ frameworks } #{ config . libs . join ( ' ' ) } #{ vendor_libs . map { |x | '-force_load "' + x + '"' } . join ( ' ' ) } "
372
+ sh "#{ cxx } -o \" #{ main_exec } \" #{ objs_list } #{ config . ldflags ( platform ) } -L#{ File . join ( datadir , platform ) } -lmacruby-static -lobjc -licucore #{ frameworks } #{ config . libs . join ( ' ' ) } #{ vendor_libs . map { |x | '-force_load "' + x + '"' } . join ( ' ' ) } "
290
373
main_exec_created = true
291
374
end
292
375
0 commit comments