Revision: 762 http://trac.macosforge.org/projects/ruby/changeset/762 Author: lsansonetti@apple.com Date: 2008-11-30 22:41:49 -0800 (Sun, 30 Nov 2008) Log Message: ----------- BridgeSupport files and dylibs can now be located inside the executable bundle, in Resources/bridgeSupport Modified Paths: -------------- MacRuby/trunk/bs.c MacRuby/trunk/bs.h MacRuby/trunk/objc.m Modified: MacRuby/trunk/bs.c =================================================================== --- MacRuby/trunk/bs.c 2008-12-01 03:13:32 UTC (rev 761) +++ MacRuby/trunk/bs.c 2008-12-01 06:41:49 UTC (rev 762) @@ -65,12 +65,42 @@ return name; } -bool -bs_find_path(const char *framework_path, char *path, const size_t path_len) +static inline const char * +_bs_main_bundle_bs_path(void) { + static bool done = false; + static char *path = NULL; + /* XXX not thread-safe */ + if (!done) { + CFBundleRef bundle; + + done = true; + bundle = CFBundleGetMainBundle(); + if (bundle != NULL) { + CFURLRef url; + + url = CFBundleCopyResourceURL(bundle, CFSTR("BridgeSupport"), + NULL, NULL); + if (url != NULL) { + CFStringRef str = CFURLCopyPath(url); + path = (char *)malloc(sizeof(char) * PATH_MAX); + CFStringGetFileSystemRepresentation(str, path, PATH_MAX); + CFRelease(str); + CFRelease(url); + } + } + } + return path; +} + +static bool +_bs_find_path(const char *framework_path, char *path, const size_t path_len, + const char *ext) +{ + const char *main_bundle_bs_path; char *framework_name; char *home; - + if (framework_path == NULL || *framework_path == '\0' || path == NULL || path_len == 0) return false; @@ -88,23 +118,30 @@ if (framework_name == NULL) return false; - snprintf(path, path_len, "%s/Resources/BridgeSupport/%s.bridgesupport", - framework_path, framework_name); + main_bundle_bs_path = _bs_main_bundle_bs_path(); + if (main_bundle_bs_path != NULL) { + snprintf(path, path_len, "%s/%s.%s", main_bundle_bs_path, + framework_name, ext); + CHECK_IF_EXISTS(); + } + + snprintf(path, path_len, "%s/Resources/BridgeSupport/%s.%s", + framework_path, framework_name, ext); CHECK_IF_EXISTS(); home = getenv("HOME"); if (home != NULL) { - snprintf(path, path_len, "%s/Library/BridgeSupport/%s.bridgesupport", - home, framework_name); + snprintf(path, path_len, "%s/Library/BridgeSupport/%s.%s", + home, framework_name, ext); CHECK_IF_EXISTS(); } - snprintf(path, path_len, "/Library/BridgeSupport/%s.bridgesupport", - framework_name); + snprintf(path, path_len, "/Library/BridgeSupport/%s.%s", + framework_name, ext); CHECK_IF_EXISTS(); - snprintf(path, path_len, "/System/Library/BridgeSupport/%s.bridgesupport", - framework_name); + snprintf(path, path_len, "/System/Library/BridgeSupport/%s.%s", + framework_name, ext); CHECK_IF_EXISTS(); #undef CHECK_IF_EXISTS @@ -113,6 +150,12 @@ return false; } +bool +bs_find_path(const char *framework_path, char *path, const size_t path_len) +{ + return _bs_find_path(framework_path, path, path_len, "bridgesupport"); +} + static inline char * get_attribute(xmlTextReaderPtr reader, const char *name) { @@ -383,8 +426,8 @@ bool bs_parser_parse(bs_parser_t *parser, const char *path, - bs_parse_options_t options, bs_parse_callback_t callback, - void *context, char **error) + const char *framework_path, bs_parse_options_t options, + bs_parse_callback_t callback, void *context, char **error) { xmlTextReaderPtr reader; bs_element_function_t *func; @@ -501,12 +544,14 @@ bs_path_found = bs_find_path(depends_on_path, bs_path, sizeof bs_path); - free(depends_on_path); if (bs_path_found) { - if (!bs_parser_parse(parser, bs_path, options, callback, context, - error)) + if (!bs_parser_parse(parser, bs_path, depends_on_path, options, + callback, context, error)) { + free(depends_on_path); return false; + } } + free(depends_on_path); break; } @@ -1123,15 +1168,14 @@ } CFRelease(cf_path); - if (success && options == BS_PARSE_OPTIONS_LOAD_DYLIBS) { - char *p, buf[PATH_MAX]; - strncpy(buf, path, sizeof buf); - p = strrchr(buf, '.'); - assert(p != NULL); - strlcpy(p, ".dylib", p - path - 1); - if (access(buf, R_OK) == 0) { + if (success && options == BS_PARSE_OPTIONS_LOAD_DYLIBS && framework_path != NULL) { + char buf[PATH_MAX]; + + if (_bs_find_path(framework_path, buf, sizeof buf, "dylib")) { if (dlopen(buf, RTLD_LAZY) == NULL) { - *error = dlerror(); + if (error != NULL) { + *error = dlerror(); + } success = false; } } Modified: MacRuby/trunk/bs.h =================================================================== --- MacRuby/trunk/bs.h 2008-12-01 03:13:32 UTC (rev 761) +++ MacRuby/trunk/bs.h 2008-12-01 06:41:49 UTC (rev 762) @@ -185,6 +185,7 @@ * * Finds the path of a framework's bridge support file, by looking at the * following locations, in order of priority: + * - inside the main executable bundle (if any), in the Resources/BridgeSupport directory ; * - inside the framework bundle, in the Resources/BridgeSupport directory ; * - in ~/Library/BridgeSupport ; * - in /Library/BridgeSupport ; @@ -232,6 +233,10 @@ * * parser: the parser object. * path: the full path of the bridge support file to parse. + * framework_path: the full path of the framework this bridge support file + * comes from. This is only required if options is BS_PARSE_OPTIONS_LOAD_DYLIBS + * in order to locate the dylib files. Pass NULL if you are passing the + * default BS_PARSE_OPTIONS_DEFAULT option. * options: parsing options. * callback: a callback function pointer. * context: a contextual data pointer that will be passed to the callback @@ -241,8 +246,8 @@ * don't need it. */ bool bs_parser_parse(bs_parser_t *parser, const char *path, - bs_parse_options_t options, bs_parse_callback_t callback, void *context, - char **error); + const char *framework_path, bs_parse_options_t options, + bs_parse_callback_t callback, void *context, char **error); /* bs_element_free() * Modified: MacRuby/trunk/objc.m =================================================================== --- MacRuby/trunk/objc.m 2008-12-01 03:13:32 UTC (rev 761) +++ MacRuby/trunk/objc.m 2008-12-01 06:41:49 UTC (rev 762) @@ -2760,7 +2760,8 @@ static bs_parser_t *bs_parser = NULL; static void -rb_objc_load_bridge_support(const char *path, int options) +rb_objc_load_bridge_support(const char *path, const char *framework_path, + int options) { char *error; bool ok; @@ -2774,7 +2775,7 @@ assert(rb_cObject_dict != NULL); enable_method_added = Qfalse; - ok = bs_parser_parse(bs_parser, path, options, + ok = bs_parser_parse(bs_parser, path, framework_path, options, bs_parse_cb, rb_cObject_dict, &error); enable_method_added = Qtrue; if (!ok) { @@ -2827,7 +2828,7 @@ static VALUE rb_objc_load_bs(VALUE recv, VALUE path) { - rb_objc_load_bridge_support(StringValuePtr(path), 0); + rb_objc_load_bridge_support(StringValuePtr(path), NULL, 0); return recv; } @@ -2837,7 +2838,8 @@ char path[PATH_MAX]; if (bs_find_path(framework_path, path, sizeof path)) { - rb_objc_load_bridge_support(path, BS_PARSE_OPTIONS_LOAD_DYLIBS); + rb_objc_load_bridge_support(path, framework_path, + BS_PARSE_OPTIONS_LOAD_DYLIBS); } } @@ -3640,7 +3642,7 @@ - (void)loadBridgeSupportFileAtPath:(NSString *)path { - rb_objc_load_bridge_support([path fileSystemRepresentation], 0); + rb_objc_load_bridge_support([path fileSystemRepresentation], NULL, 0); } - (void)loadBridgeSupportFileAtURL:(NSURL *)URL