apple: the App Store builds compile without warnings, and their uploads stop failing on one bad core

Built the way Xcode builds them - the App Store floors (macOS 12,
iOS/tvOS 15), the projects' warnings, every translation unit - the
tree still warned:

- Delegate methods the SDK deprecates that an older OS still calls
  are no longer implemented in source.  apple_rt_add_method() gives
  the class each one at run time, from +initialize and only on the
  releases that call it: -locationManager:didChangeAuthorizationStatus:
  before macOS 11 / iOS 14 (-locationManagerDidChangeAuthorization:
  from there), -documentPicker:didPickDocumentAtURL: before iOS 11
  (the URL-array method from there), -shouldAutorotateTo-
  InterfaceOrientation: before iOS 6, and NSView's
  -layer:shouldInheritContentsScale:fromWindow: from 10.7.
  class_addMethod is looked up by name, as the 10.4 binary may not
  import it.  CocoaView no longer declares UIDocumentPickerDelegate,
  whose pre-11 SDKs require the method it now adds at run time, and
  -prefersPointerLocked is not built for tvOS, where it is
  unavailable.
- The open panel's file types, the companion's folder icon and the
  cores folder's open are -setAllowedContentTypes:, -iconForContent-
  Type: and -openURL: from macOS 11, the 10.x methods before it, by
  selector where they are not on every release.
- The alert's end selector is looked up by name, and on SDKs older
  than the selectors ui_cocoa.m names (10.6, 10.7, 10.9) they are
  declared in an unimplemented NSObject category, so @selector()
  stays a constant.
- size_t and 64-bit values narrowed without a cast in configuration.c,
  gl3.c, cdrom.c, media_detect_cd.c and vfs_implementation_cdrom.c;
  rchd_read_extent() rejects an extent past the last 32-bit frame
  instead of wrapping into the wrong track.

App Store uploads: one iOS or tvOS core without an unencrypted
LC_ENCRYPTION_INFO_64 - written by Apple's ld, not by other linkers -
fails the whole upload (ITMS-90125).  make-frameworks.sh leaves such a
core out of an App Store build with a warning naming it.  The
Fastfile's check for a build already in TestFlight review passed
Build.all a filter it does not take, so it always failed and the
upload went on to external distribution and stopped there; it asks
App Store Connect for the newest five builds of the platform with
their review submissions instead.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-10-07 09:38:29 +02:00
1 parent bf1f5a4a70
commit e5fc0a50e4
13 files changed
+228 -43

No files matched your search

+17
View File
@@ -242,6 +242,23 @@ typedef id (*apple_rt_init_id_long_fn)(APPLE_RT_CONSUMED id, SEL, id, long)
/* A class by name, nil when this OS (or this binary) does not have it. */
#define apple_rt_class(name) ((id)objc_getClass(name))
/* Gives a class a method at run time. For a delegate method the SDK
* marks deprecated or unavailable that an older OS still calls: the
* class answers it only on the releases that need it, done once from
* +initialize, and implementing it does not warn. @fn is a C function
* taking (id self, SEL _cmd, ...) and @types its Objective-C type
* encoding, which must outlive the call. class_addMethod is 10.5 and
* the 10.4 binary may not import it at all, so it is found by name; on
* 10.4 nothing is added. */
#define apple_rt_add_method(cls, name, fn, types) \
do { \
BOOL (*add_)(Class, SEL, IMP, const char *) = \
(BOOL (*)(Class, SEL, IMP, const char *)) \
dlsym(RTLD_DEFAULT, "class_addMethod"); \
if (add_) \
add_((Class)(cls), sel_registerName(name), (IMP)(fn), (types)); \
} while (0)
/* The address of an exported object constant (an NSString * such as
* AVCaptureDeviceTypeExternal) by name, NULL when this OS does not
* export it; apple_rt_obj_at reads the object, which stays the
+1 -1
View File
@@ -10863,7 +10863,7 @@ uint8_t input_config_bind_map_get_retro_key(unsigned bind_index)
void input_config_reset_autoconfig_binds(unsigned port)
{
size_t i;
unsigned i;
input_sensor_map_t map;
if (port >= MAX_USERS)
+1 -1
View File
@@ -4385,7 +4385,7 @@ static bool gl3_read_viewport_hdr(void *data, uint16_t *buffer,
static bool gl3_read_viewport(void *data, uint8_t *buffer, bool is_idle)
{
gl3_t *gl = (gl3_t*)data;
unsigned num_pixels = 0;
size_t num_pixels = 0;
if (!gl)
return false;
+1 -1
View File
@@ -1362,7 +1362,7 @@ static int cdrom_read_track_info(libretro_vfs_implementation_file *stream, unsig
pregap_lba_len = (toc->track[track - 1].audio ? 0 : (toc->track[track - 1].lba - toc->track[track - 1].lba_start));
toc->track[track - 1].track_bytes = (track_size - pregap_lba_len) * 2352;
toc->track[track - 1].track_bytes = (unsigned)((track_size - pregap_lba_len) * 2352);
toc->track[track - 1].mode = buf[6] & 0xF;
#ifdef CDROM_DEBUG
+6 -2
View File
@@ -2656,10 +2656,14 @@ int rchd_read_extent(const rchd_t *chd, uint32_t lba, uint32_t count,
if (!chd->track_count)
return RCHD_ERROR_STATE;
/* Frame numbers are 32-bit: an extent running past the last one
* cannot be in the image. */
if ((uint64_t)lba + count > 0xFFFFFFFFu + (uint64_t)1)
return RCHD_ERROR_PARAM;
for (i = 0; i < count; i++)
{
const rchd_track_t *t = rchd_track_for_lba(chd,
(uint64_t)lba + i);
const rchd_track_t *t = rchd_track_for_lba(chd, lba + i);
if (!t)
return RCHD_ERROR_PARAM;
+1 -1
View File
@@ -34,7 +34,7 @@
static void media_zero_trailing_spaces(char *s, size_t len)
{
int i;
for (i = len - 1; i >= 0; i--)
for (i = (int)len - 1; i >= 0; i--)
{
if (s[i] == ' ')
s[i] = '\0';
@@ -82,7 +82,7 @@ int64_t retro_vfs_file_seek_cdrom(
&& (ext[2] == 'n' || ext[2] == 'N')
&& ext[3] == '\0')
{
int lba = (offset / 2352);
int lba = (int)(offset / 2352);
unsigned char min = 0;
unsigned char sec = 0;
unsigned char frame = 0;
@@ -99,7 +99,7 @@ int64_t retro_vfs_file_seek_cdrom(
seek_type = "SEEK_CUR";
#endif
stream->cdrom->byte_pos += offset;
new_lba = vfs_cdrom_toc.track[stream->cdrom->cur_track - 1].lba + (stream->cdrom->byte_pos / 2352);
new_lba = vfs_cdrom_toc.track[stream->cdrom->cur_track - 1].lba + (unsigned)(stream->cdrom->byte_pos / 2352);
cdrom_lba_to_msf(new_lba, &min, &sec, &frame);
}
break;
@@ -112,7 +112,7 @@ int64_t retro_vfs_file_seek_cdrom(
#ifdef CDROM_DEBUG
seek_type = "SEEK_END";
#endif
cdrom_lba_to_msf(lba_len + lba, &min, &sec, &frame);
cdrom_lba_to_msf((unsigned)(lba_len + lba), &min, &sec, &frame);
stream->cdrom->byte_pos = lba_len * 2352;
}
break;
@@ -123,7 +123,7 @@ int64_t retro_vfs_file_seek_cdrom(
seek_type = "SEEK_SET";
#endif
stream->cdrom->byte_pos = offset;
cdrom_lba_to_msf(vfs_cdrom_toc.track[stream->cdrom->cur_track - 1].lba + (stream->cdrom->byte_pos / 2352), &min, &sec, &frame);
cdrom_lba_to_msf(vfs_cdrom_toc.track[stream->cdrom->cur_track - 1].lba + (unsigned)(stream->cdrom->byte_pos / 2352), &min, &sec, &frame);
}
break;
}
@@ -604,7 +604,7 @@ int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream,
stream->cdrom->byte_pos += len;
stream->cdrom->cur_lba =
vfs_cdrom_toc.track[stream->cdrom->cur_track - 1].lba
+ (stream->cdrom->byte_pos / 2352);
+ (unsigned)(stream->cdrom->byte_pos / 2352);
cdrom_lba_to_msf(stream->cdrom->cur_lba,
&stream->cdrom->cur_min,
+23 -2
View File
@@ -31,8 +31,28 @@
- (void)applyAuthorizationStatus:(CLAuthorizationStatus)status;
@end
/* -locationManager:didChangeAuthorizationStatus:, which macOS 11 / iOS 14
* replaced with -locationManagerDidChangeAuthorization: and deprecated:
* installed by +initialize on the releases before, the only ones that
* call it. */
static void corelocation_did_change_status(id self, SEL _cmd,
id manager, int status)
{
[(CoreLocationManager*)self
applyAuthorizationStatus:(CLAuthorizationStatus)status];
}
@implementation CoreLocationManager
+ (void)initialize {
if (self != [CoreLocationManager class])
return;
if (!apple_runtime_available(APPLE_RUNTIME_VER(11, 0, 0), APPLE_RUNTIME_VER(14, 0, 0), APPLE_RUNTIME_VER(14, 0, 0)))
apple_rt_add_method(self,
"locationManager:didChangeAuthorizationStatus:",
corelocation_did_change_status, "v@:@i");
}
+ (instancetype)sharedInstance {
static CoreLocationManager *sharedInstance = nil;
static dispatch_once_t onceToken;
@@ -93,8 +113,9 @@
NSLog(@"Location manager failed with error: %@", error);
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
[self applyAuthorizationStatus:status];
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
[self applyAuthorizationStatus:(CLAuthorizationStatus)apple_rt_get_int(
manager, @selector(authorizationStatus))];
}
- (void)applyAuthorizationStatus:(CLAuthorizationStatus)status {
+7 -4
View File
@@ -190,12 +190,15 @@ private_lane :ra_prior_build_in_review do
in_review = false
begin
app = Spaceship::ConnectAPI::App.find(app_id)
builds = Spaceship::ConnectAPI::Build.all(
app_id: app.id,
filter: { "preReleaseVersion.platform" => plat },
# Build.all takes no filter and pages through every build the app
# has; one page of the newest few, with their review submissions,
# is all this needs.
builds = Spaceship::ConnectAPI.get_builds(
filter: { app: app.id, "preReleaseVersion.platform" => plat },
includes: "preReleaseVersion,betaAppReviewSubmission",
sort: "-uploadedDate",
limit: 5
)
).to_models
in_review = builds.any? do |b|
state = b.beta_app_review_submission&.beta_review_state
state == "WAITING_FOR_REVIEW" || state == "IN_REVIEW"
+18 -1
View File
@@ -48,6 +48,23 @@ process_one() {
intermediate="${intermediate/%$SUFFIX/}"
fi
fwName="${intermediate//_/.}"
# App Store Connect takes an iOS/tvOS binary only with an
# LC_ENCRYPTION_INFO_64 that is not yet encrypted (cryptid 0), which
# Apple's ld writes and other linkers do not; one core without it
# fails the whole upload (ITMS-90125). Leave such a core out of an
# App Store build and name it, rather than lose every other core.
if [ -n "$APPSTORE_BUILD" ] && [ "$PLATFORM_FAMILY_NAME" = "iOS" -o "$PLATFORM_FAMILY_NAME" = "tvOS" ] ; then
cryptid=$(otool -l "$dylib" | awk '/cmd LC_ENCRYPTION_INFO/ { f = 1 } f && $1 == "cryptid" { print $2; exit }')
if [ -z "$cryptid" ] ; then
echo "warning: leaving $fwName out of the App Store build: $(basename "$dylib") has no LC_ENCRYPTION_INFO_64 (not linked by Apple's ld)"
return 0
elif [ "$cryptid" != "0" ] ; then
echo "warning: leaving $fwName out of the App Store build: $(basename "$dylib") is already encrypted (cryptid $cryptid)"
return 0
fi
fi
echo Making framework $fwName from $dylib
fwDir="${OUTDIR}/${fwName}.framework"
@@ -94,7 +111,7 @@ process_one() {
}
export -f process_one
export OUTDIR DSYM_OUTDIR SUFFIX PLATFORM_FAMILY_NAME PLATFORM \
DEPLOYMENT_TARGET CODE_SIGN_IDENTITY_FOR_ITEMS
DEPLOYMENT_TARGET CODE_SIGN_IDENTITY_FOR_ITEMS APPSTORE_BUILD
JOBS=$(sysctl -n hw.ncpu)
if [ "$JOBS" -gt 8 ] ; then JOBS=8 ; fi
+73 -16
View File
@@ -130,14 +130,45 @@ static CocoaView* g_instance;
void *glkitview_init(void);
void cocoa_file_load_with_detect_core(const char *filename);
@interface CocoaView()<GCDWebUploaderDelegate, GCDWebDAVServerDelegate, UIGestureRecognizerDelegate
/* Not declared a UIDocumentPickerDelegate: SDKs before iOS 11 make
* -documentPicker:didPickDocumentAtURL: a required method, and the
* view gives itself that one at run time (see +initialize). The
* picker asks its delegate with -respondsToSelector:. */
@interface CocoaView()<GCDWebUploaderDelegate, GCDWebDAVServerDelegate, UIGestureRecognizerDelegate>
#if TARGET_OS_IOS
,UIDocumentPickerDelegate
- (void)importDocumentAtURL:(NSURL *)url;
#endif
>
@end
#endif
/* Methods a release before the deployment target's SDK still calls but
* the SDK marks deprecated or unavailable: +initialize installs each
* only on the releases that call it (apple_rt_add_method). */
#if TARGET_OS_OSX
/* NSView's own -layer:shouldInheritContentsScale:fromWindow: (10.7,
* asked when the view hosts a layer such as the Vulkan CAMetalLayer),
* deprecated in 11.0 for the NSViewLayerContentScaleDelegate method
* of the same name. */
static BOOL cocoa_view_inherit_contents_scale(id self, SEL _cmd,
id layer, CGFloat scale, id window)
{
return YES;
}
#elif TARGET_OS_IOS
/* Before iOS 6 the only rotation question. */
static BOOL cocoa_view_autorotate_to(id self, SEL _cmd, NSInteger orientation)
{
return YES;
}
/* The iOS 8 - 10 document picker's answer; 11 sends the URL array. */
static void cocoa_view_picked_document(id self, SEL _cmd,
id controller, NSURL *url)
{
[(CocoaView*)self importDocumentAtURL:url];
}
#endif
static CFRunLoopObserverRef iterate_observer;
static void rarch_draw_observer(CFRunLoopObserverRef observer,
@@ -205,11 +236,33 @@ void rarch_stop_draw_observer(void)
@implementation CocoaView
+ (void)initialize
{
if (self != [CocoaView class])
return;
#if TARGET_OS_OSX
if (apple_runtime_available(APPLE_RUNTIME_VER(10, 7, 0), 0, 0))
{
static char types[32];
snprintf(types, sizeof(types), "%s@:@%s@", @encode(BOOL), @encode(CGFloat));
apple_rt_add_method(self, "layer:shouldInheritContentsScale:fromWindow:",
cocoa_view_inherit_contents_scale, types);
}
#elif TARGET_OS_IOS
if (!apple_runtime_available(0, APPLE_RUNTIME_VER(6, 0, 0), 0))
{
static char types[32];
snprintf(types, sizeof(types), "%s@:%s", @encode(BOOL), @encode(NSInteger));
apple_rt_add_method(self, "shouldAutorotateToInterfaceOrientation:",
cocoa_view_autorotate_to, types);
}
if (!apple_runtime_available(0, APPLE_RUNTIME_VER(11, 0, 0), 0))
apple_rt_add_method(self, "documentPicker:didPickDocumentAtURL:",
cocoa_view_picked_document, "v@:@@");
#endif
}
#if TARGET_OS_OSX
/* CALayerDelegate, asked from 10.7 on when the view hosts a layer (the
* Vulkan CAMetalLayer); a plain method that older releases never
* call. */
- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)newScale fromWindow:(NSWindow *)window { return YES; }
- (void)scrollWheel:(NSEvent *)theEvent { }
#endif
@@ -597,8 +650,16 @@ retro_time_t cocoa_last_vblank_time(void)
#pragma mark UIDocumentPickerViewController
/* The document picker is iOS 8: UIKit calls these only there, and
* ios_show_file_sheet() checks the OS before it asks for one. */
-(void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url API_AVAILABLE(ios(8.0))
* ios_show_file_sheet() checks the OS before it asks for one. iOS 11
* answers with an array; 8 - 10 with the one URL, through the method
* +initialize installs there. */
-(void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls API_AVAILABLE(ios(11.0))
{
if ([urls count])
[self importDocumentAtURL:[urls objectAtIndex:0]];
}
-(void)importDocumentAtURL:(NSURL *)url
{
NSFileManager *manager = [NSFileManager defaultManager];
NSString *filename = (NSString*)url.path.lastPathComponent;
@@ -639,7 +700,7 @@ retro_time_t cocoa_last_vblank_time(void)
UIDocumentPickerViewController *documentPicker = apple_rt_init_id_long(
[UIDocumentPickerViewController alloc],
sel_registerName("initWithDocumentTypes:inMode:"), types, 0);
documentPicker.delegate = self;
documentPicker.delegate = (id<UIDocumentPickerDelegate>)self;
documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:documentPicker animated:YES completion:nil];
}
@@ -894,20 +955,16 @@ retro_time_t cocoa_last_vblank_time(void)
return NO;
return YES;
}
/* NOTE: This version runs on iOS2-iOS5, but not iOS6+. */
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#endif
#ifdef HAVE_COCOATOUCH
#if !TARGET_OS_TV
-(BOOL) prefersPointerLocked API_AVAILABLE(ios(14.0))
{
return cocoa_input_mouse_grabbed() ? YES : NO;
}
#endif
#pragma mark - UIViewController Lifecycle
+47 -3
View File
@@ -75,6 +75,28 @@
#include "../../steam/steam.h"
#endif
/* Selectors this file names with @selector() for methods newer than an
* old SDK (each call is behind -respondsToSelector: or a version
* check): declared for -Wundeclared-selector only where the SDK has
* none, and never implemented, so @selector() stays a constant. */
#if !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
@interface NSObject (RetroArchSelectors106)
- (void)setDirectoryURL:(NSURL *)url;
- (void)setActivationPolicy:(NSInteger)policy;
@end
#endif
#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
@interface NSObject (RetroArchSelectors107)
- (void)toggleFullScreen:(id)sender;
@end
#endif
#if !defined(MAC_OS_X_VERSION_10_9) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9
@interface NSObject (RetroArchSelectors109)
- (id)beginActivityWithOptions:(unsigned long long)options reason:(NSString *)reason;
- (void)endActivity:(id)activity;
@end
#endif
typedef struct ui_application_cocoa
{
void *empty;
@@ -214,7 +236,27 @@ static bool ui_browser_window_cocoa_open(ui_browser_window_state_t *state)
* under ARC, required under MRC or the array leaks every time
* the picker opens with a filter). */
NSArray *filetypes = [[NSArray alloc] initWithObjects:BOXSTRING(state->filters), BOXSTRING(state->filters_title), nil];
[panel setAllowedFileTypes:filetypes];
id utt;
/* -setAllowedFileTypes: (10.3) is deprecated in 12.0 for
* -setAllowedContentTypes: and UTTypes (11.0): 11 on gives the
* panel content types, earlier releases the extensions; both by
* selector. */
if ( apple_runtime_available(APPLE_RUNTIME_VER(11, 0, 0), 0, 0)
&& (utt = apple_rt_class("UTType")))
{
NSUInteger i;
NSMutableArray *types = [NSMutableArray array];
SEL by_ext = sel_registerName("typeWithFilenameExtension:");
for (i = 0; i < [filetypes count]; i++)
{
id t = apple_rt_get_id_arg(utt, by_ext, [filetypes objectAtIndex:i]);
if (t)
[types addObject:t];
}
apple_rt_send_id(panel, sel_registerName("setAllowedContentTypes:"), types);
}
else
apple_rt_send_id(panel, sel_registerName("setAllowedFileTypes:"), filetypes);
RARCH_RELEASE(filetypes);
}
@@ -342,7 +384,7 @@ static enum ui_msg_window_response ui_msg_window_cocoa_dialog(ui_msg_window_stat
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
[alert beginSheetModalForWindow:main_window
modalDelegate:apple_platform
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
didEndSelector:sel_registerName("alertDidEnd:returnCode:contextInfo:")
contextInfo:nil];
#pragma GCC diagnostic pop
response = [[NSApplication sharedApplication] runModalForWindow:[alert window]];
@@ -1333,7 +1375,9 @@ static void open_document_handler(
{
settings_t *settings = config_get_ptr();
const char *path_dir_libretro = settings->paths.directory_libretro;
[[NSWorkspace sharedWorkspace] openFile:BOXSTRING(path_dir_libretro)];
/* -openFile: is deprecated in 11.0; -openURL: with a file URL opens
* the folder the same way on every release. */
[[NSWorkspace sharedWorkspace] openURL:[NSURL fileURLWithPath:BOXSTRING(path_dir_libretro)]];
}
- (IBAction)basicEvent:(id)sender
+28 -6
View File
@@ -110,6 +110,32 @@ static NSString *companion_filenames_type(void)
#endif
}
/* The generic folder icon. -iconForFileType: (10.0) is deprecated in
* 12.0 for -iconForContentType: and a UTType (11.0), so 11 on asks by
* content type and earlier releases by the 'fldr' HFS type (the named
* constant is in Carbon's Icons.h, not pulled in here); both by
* selector. Autoreleased, as both methods return it. */
static NSImage *companion_folder_icon(void)
{
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
#ifdef GNUSTEP
return [ws iconForFileType:NSFileTypeForHFSTypeCode('fldr')];
#else
id utt;
if ( apple_runtime_available(APPLE_RUNTIME_VER(11, 0, 0), 0, 0)
&& (utt = apple_rt_class("UTType")))
{
id folder = apple_rt_get_id_arg(utt,
sel_registerName("typeWithIdentifier:"), @"public.folder");
if (folder)
return apple_rt_get_id_arg(ws,
sel_registerName("iconForContentType:"), folder);
}
return apple_rt_get_id_arg(ws, sel_registerName("iconForFileType:"),
NSFileTypeForHFSTypeCode('fldr'));
#endif
}
#include "../../command.h"
#include "../../configuration.h"
#include "../../retroarch.h"
@@ -894,10 +920,7 @@ static const companion_callbacks_t cc_callbacks = {
if (wimp && playlistIcons)
{
size_t i, n = companion_core_playlist_count(wimp->core);
/* 'fldr' is the generic folder HFS type; the named constant lives
* in Carbon's Icons.h, which is not pulled in here. */
NSImage *folder = [[NSWorkspace sharedWorkspace] iconForFileType:
NSFileTypeForHFSTypeCode('fldr')];
NSImage *folder = companion_folder_icon();
[playlistIcons removeAllObjects];
for (i = 0; i < n; i++)
{
@@ -1427,8 +1450,7 @@ static void cc_thumb_done(void *ud, const char *path, unsigned dims,
if (companion_core_folder_icon_path(wimp->core, icon, sizeof(icon)))
folderIcon = [[NSImage alloc] initWithContentsOfFile:BOXSTRING(icon)];
if (!folderIcon)
folderIcon = RETAIN_COMPAT([[NSWorkspace sharedWorkspace]
iconForFileType:NSFileTypeForHFSTypeCode('fldr')]);
folderIcon = RETAIN_COMPAT(companion_folder_icon());
}
browserTabs = [[NSTabView alloc] initWithFrame:NSMakeRect(0, 0, CC_PANE_W, 300)];