#66188 closed defect (fixed)

libsdl2: re-enable universal building i386/x86_64

Reported by: kencu (Ken) Owned by: jmroot (Joshua Root)
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc:
Port: libsdl2

Description

universal building as above was recently disabled due to an issue with objective C capabilities for i386 systems.

[07d84ee8eaadedb05408d845d62b85c3265e1ba3/macports-ports]

I believe there are a number of ports that need libsdl2 available as universal, however, to build universal themselves.

Although the system clang does not support ObjC-arc on these systems, somewhere along the line this capability was added, and newer MacPorts' clangs do seem to support it.

Blacklisting the system clang leads to a successful universal build.

compiler.blacklist *gcc* {clang < 426}
$ port -v installed libsdl2
The following ports are currently installed:
  libsdl2 @2.24.2_0+universal (active) requested_variants='+universal' platform='darwin 11' archs='i386 x86_64' date='2022-11-06T23:10:36-0800'

I need to do a little more experimenting to see just what OS version has the system clang that can support this, to know where the clang cutoff needs to be set.

Change History (22)

comment:1 Changed 18 months ago by jmroot (Joshua Root)

Have you checked that the i386 slice works correctly? AIUI the issue is not the compiler but the ObjC runtime, which is part of the OS, and just doesn't have ARC support in the 32-bit version.

comment:2 Changed 18 months ago by kencu (Ken)

I would test ARC in the i386 slice, if I can see how to.

I believe that at first there was no autoreleasepool support for i386, but later on they added it to libobjc. My theory is that the ancient clang that comes with 10.7 doesn't know this, but newer clangs do.

This is on 10.7.5:

$ nm -arch i386 /usr/lib/libobjc.A.dylib | grep autorelease
000d8798 s _SEL_autorelease
0000bdb2 t __ZN12_GLOBAL__N_119AutoreleasePoolPage15autoreleaseSlowEP11objc_object
00009a9d T __objc_autoreleasePoolPop
0001eb25 T __objc_autoreleasePoolPrint
00008fc8 T __objc_autoreleasePoolPush
0001e5a0 T _objc_autorelease
0001e92c t _objc_autoreleaseNoPool
0001eb00 T _objc_autoreleasePoolPop
00008fd1 T _objc_autoreleasePoolPush
0000b3be T _objc_autoreleaseReturnValue
0001e5c6 T _objc_retain_autorelease

example file:

$ cat writeback.m
// clang -fobjc-arc -arch i386  -o writeback writeback.m


#import <Foundation/Foundation.h>
#import <Foundation/NSObjCRuntime.h>

__weak id weak;

int writeBack(id *aValue)
{
  *aValue = [NSObject new];
  weak = *aValue;
  return 0;
}

int main(void)
{
  @autoreleasepool
  {
    id object;
    writeBack(&object);
    NSLog(@"Object: %@", object);
    object = nil;
    NSLog(@"Object: %@", weak);
  }
  NSLog(@"Object: %@", weak);
  return 0;  
}

system clang build works x86_64:

$ /usr/bin/clang -fobjc-arc -arch x86_64  -o writeback writeback.m
$ ./writeback
2022-11-07 18:44:28.328 writeback[387:707] Object: <NSObject: 0x10b014050>
2022-11-07 18:44:28.333 writeback[387:707] Object: <NSObject: 0x10b014050>
2022-11-07 18:44:28.337 writeback[387:707] Object: (null)

but fails i386:

$ /usr/bin/clang -fobjc-arc -arch i386  -o writeback writeback.m
error: -fobjc-arc is not supported on platforms using the legacy runtime

but macports-clang-11 works i386:

$ clang-mp-11  -fobjc-arc -arch i386   -o writeback writeback.m
$ file writeback
writeback: Mach-O executable i386
$ ./writeback
2022-11-07 18:47:55.544 writeback[399:507] Object: <NSObject: 0x148160>
2022-11-07 18:47:55.549 writeback[399:507] Object: <NSObject: 0x148160>
2022-11-07 18:47:55.552 writeback[399:507] Object: (null)

Aside: for obscure reasons, the clang-mp-11 x86_64 build has to be done a little differently, in two stages. That's not relevant here to this so I left that bit out for now.

Last edited 18 months ago by kencu (Ken) (previous) (diff)

comment:3 Changed 18 months ago by kencu (Ken)

let me try a few simple ports and see what happens IRL.

comment:4 in reply to:  2 ; Changed 18 months ago by jmroot (Joshua Root)

Replying to kencu:

I would test ARC in the i386 slice, if I can see how to.

If i386 SDL games run usably at all I guess that's good enough to allow it. The symptom of missing ARC support could be memory leaks though.

Did the system clang ever start allowing -fobjc-arc together with -arch i386? The report that prompted the change was on 10.9.

comment:5 Changed 18 months ago by kencu (Ken)

Hmm... even if the ARC bit is working, the ports I tried built i386 but died with this error:

$ arch -i386 /opt/local/libexec/blobwars/blobwars
2022-11-07 19:43:24.274 blobwars[51390:4d03] -[SDL_VideoData key_layout]: unrecognized selector sent to instance 0x7ca817b0
2022-11-07 19:43:24.277 blobwars[51390:4d03] An uncaught exception was raised
2022-11-07 19:43:24.280 blobwars[51390:4d03] -[SDL_VideoData key_layout]: unrecognized selector sent to instance 0x7ca817b0
2022-11-07 19:43:24.282 blobwars[51390:4d03] (
	0   CoreFoundation                      0x93453a67 __raiseError + 231
	1   libobjc.A.dylib                     0x91197149 objc_exception_throw + 155
	2   CoreFoundation                      0x93457070 -[NSObject doesNotRecognizeSelector:] + 256
	3   CoreFoundation                      0x933a5cd9 ___forwarding___ + 457
	4   CoreFoundation                      0x933a5aa2 _CF_forwarding_prep_0 + 50
	5   libSDL2-2.0.0.dylib                 0x001d397c UpdateKeymap + 83
	6   libSDL2-2.0.0.dylib                 0x001d386a Cocoa_InitKeyboard + 42
	7   libSDL2-2.0.0.dylib                 0x001d8cb3 Cocoa_VideoInit + 58
	8   libSDL2-2.0.0.dylib                 0x001abf38 SDL_VideoInit_REAL + 552
	9   libSDL2-2.0.0.dylib                 0x00119d65 SDL_InitSubSystem_REAL + 183
	10  blobwars                            0x00036c48 _Z10initSystemv + 69
	11  blobwars                            0x0004b5ce main + 851
	12  blobwars                            0x000185f5 start + 53
)
2022-11-07 19:43:24.285 blobwars[51390:4d03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SDL_VideoData key_layout]: unrecognized selector sent to instance 0x7ca817b0'
*** Call stack at first throw:
(
	0   CoreFoundation                      0x93453a67 __raiseError + 231
	1   libobjc.A.dylib                     0x91197149 objc_exception_throw + 155
	2   CoreFoundation                      0x93457070 -[NSObject doesNotRecognizeSelector:] + 256
	3   CoreFoundation                      0x933a5cd9 ___forwarding___ + 457
	4   CoreFoundation                      0x933a5aa2 _CF_forwarding_prep_0 + 50
	5   libSDL2-2.0.0.dylib                 0x001d397c UpdateKeymap + 83
	6   libSDL2-2.0.0.dylib                 0x001d386a Cocoa_InitKeyboard + 42
	7   libSDL2-2.0.0.dylib                 0x001d8cb3 Cocoa_VideoInit + 58
	8   libSDL2-2.0.0.dylib                 0x001abf38 SDL_VideoInit_REAL + 552
	9   libSDL2-2.0.0.dylib                 0x00119d65 SDL_InitSubSystem_REAL + 183
	10  blobwars                            0x00036c48 _Z10initSystemv + 69
	11  blobwars                            0x0004b5ce main + 851
	12  blobwars                            0x000185f5 start + 53
)
Trace/BPT trap: 5

I don't know why UpdateKeymap would be failing. Nothing fancy there <https://github.com/libsdl-org/SDL/blob/02bc359b6454acac743693962eaf506ccf863a82/src/video/cocoa/SDL_cocoakeyboard.m#L231>.

I could guess how it might be related to ARC issues (the object might have been purged), but it could be something very different too.

Well, until we see that things run properly as i386 with this version of SDL2, no point enabling it.

Last edited 18 months ago by kencu (Ken) (previous) (diff)

comment:6 in reply to:  4 Changed 18 months ago by kencu (Ken)

Replying to jmroot:

Did the system clang ever start allowing -fobjc-arc together with -arch i386? The report that prompted the change was on 10.9.

So far, not up to 10.10 at least:

$ /usr/bin/clang -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

$ /usr/bin/clang -fobjc-arc -arch i386 writeback.m
error: -fobjc-arc is not supported on platforms using the legacy runtime
Last edited 18 months ago by kencu (Ken) (previous) (diff)

comment:7 Changed 18 months ago by kencu (Ken)

clang-1100 allows it:

$ /usr/bin/clang -v
Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ /usr/bin/clang -isysroot /Library/Developer/SDKs/MacOSX10.13.sdk -arch i386 -fobjc-arc writeback.m

$ ./a.out
2022-11-07 20:24:33.489 a.out[5851:549240] Object: <NSObject: 0x7a04c3e0>
2022-11-07 20:24:33.490 a.out[5851:549240] Object: <NSObject: 0x7a04c3e0>
2022-11-07 20:24:33.490 a.out[5851:549240] Object: (null)

so somewhere in between those.

comment:8 in reply to:  5 Changed 18 months ago by jmroot (Joshua Root)

Replying to kencu:

I don't know why UpdateKeymap would be failing. Nothing fance there <https://github.com/libsdl-org/SDL/blob/02bc359b6454acac743693962eaf506ccf863a82/src/video/cocoa/SDL_cocoakeyboard.m#L231>.

I could guess how it might be related to ARC issues (the object might have been purged), but it could be something very different too.

Could be a symptom of targeting a newer runtime than is available.

comment:9 in reply to:  7 Changed 18 months ago by jmroot (Joshua Root)

Replying to kencu:

clang-1100 allows it: so somewhere in between those.

OK, so if i386 SDL apps work in addition to compiling, that's something. We could allow i386 on the OS versions where it works, and extend the libsdl2-snowleopard to cover i386 build everywhere else.

comment:10 Changed 18 months ago by Gcenx

Copy/paste from the old issue

https://clang.llvm.org/docs/AutomaticReferenceCounting.html#evolution

ARC applies to Objective-C pointer types, block pointer types, and
[beginning Apple 8.0, LLVM 3.8] BPTRs declared within extern "BCPL"
blocks.

That would line up with QT requirement of 10.12 for 32Bit ARC as macOS Sierra shipped with Xcode-8. https://wiki.qt.io/Apple_Platforms_Coding_Conventions

comment:11 Changed 18 months ago by Gcenx

Not done too much testing of this but once libsdl2 was deactivated wine-7.20 no longer found any controllers (Switch Prp controller via usb) this being in OS X 10.9

comment:12 Changed 18 months ago by jmroot (Joshua Root)

Also relevant is:

The runtime must provide a number of new entrypoints which the compiler may emit

https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support

comment:13 in reply to:  12 Changed 18 months ago by kencu (Ken)

Replying to jmroot:

Also relevant is:

The runtime must provide a number of new entrypoints which the compiler may emit

https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support

Lots of those (all?) are available on 10.7, both 32b and 64b:

$ nm -arch i386 /usr/lib/libobjc.A.dylib | grep autorelease
000d8798 s _SEL_autorelease
0000bdb2 t __ZN12_GLOBAL__N_119AutoreleasePoolPage15autoreleaseSlowEP11objc_object
00009a9d T __objc_autoreleasePoolPop
0001eb25 T __objc_autoreleasePoolPrint
00008fc8 T __objc_autoreleasePoolPush
0001e5a0 T _objc_autorelease
0001e92c t _objc_autoreleaseNoPool
0001eb00 T _objc_autoreleasePoolPop
00008fd1 T _objc_autoreleasePoolPush
0000b3be T _objc_autoreleaseReturnValue
0001e5c6 T _objc_retain_autorelease

comment:14 Changed 18 months ago by kencu (Ken)

At the moment I don't see anything 10.12 specific about this.

Too bad about that UpdateKeymap crash above, otherwise we could just re-enable universal on 10.7+ and update the compiler requirement.

comment:15 Changed 18 months ago by Gcenx

The 10.12 assumption by QT would have been due to Xcode-8 as that’s the first version that supported ARC according to LLVM.

comment:16 Changed 18 months ago by jmroot (Joshua Root)

The docs are only saying that ARC applies to BPTRs declared within extern "BCPL" blocks as of Xcode 8. ARC was first supported in Xcode 4.2.

comment:17 in reply to:  15 Changed 18 months ago by kencu (Ken)

Replying to Gcenx:

The 10.12 assumption by QT would have been due to Xcode-8 as that’s the first version that supported ARC according to LLVM.

ARC was fully supported by the OS as of 10.7.

We're trying to be sure that i386 support is fully complete all the way back to 10.7 as well -- I'm pretty sure it is, haven't seen anything to suggest otherwise so far.

The clang compiler that compiles to ARC i386 may well need to be something newish though.

comment:19 in reply to:  18 Changed 18 months ago by Gcenx

Replying to jmroot:

Relevant https://github.com/llvm/llvm-project/commit/09ec1ecf03db8ad73284552b1b93e1e3968dbf46

So going off that it’s OS X 10.7 with LLVM-3.8 minimum

comment:20 Changed 18 months ago by jmroot (Joshua Root)

In 123b943de91fae82b7d70f32854b9006d9fc302f/macports-ports (master):

libsdl2: allow i386 but restrict compilers

See: #66188

comment:21 Changed 18 months ago by jmroot (Joshua Root)

It's "supported*". Really not sure if the blobwars crash Ken saw is a consequence of that asterisk or not. Optimistically allowing 10.7 i386 until someone figures that out.

comment:22 Changed 17 months ago by kencu (Ken)

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.