EimaMei / Silicon

An alternative, purely C-focused wrapper to Apple's Cocoa API for OS X app development and basic iOS programming. Requires little to no Objective-C knowledge to use.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Good idea but cannot build

g40 opened this issue · comments

Any thoughts on this? It's a good idea and building on the previous work gets a big tick.

I'd like to see if up and running. N.B. Only tried building for MacOSX.

Thanks for listening.

Sonoma 14.1.1
XCode 15.0.1
% clang --version
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: arm64-apple-darwin23.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Running make runExamples 2>&1 | tee out.log results in a good number of errors, as shown below:

clang -O2 -std=c99 -I"include" -Wno-deprecated-declarations  source/mac/NSGeometry.m -c -o build/NSGeometry.o
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:56:15: error: typedef redefinition with different types ('char *' vs 'NSString *')
typedef char* NSNotificationName; /* Note: originally this was NSString* */
              ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSNotification.h:7:19: note: previous definition is here
typedef NSString *NSNotificationName NS_TYPED_EXTENSIBLE_ENUM;
                  ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:59:17: error: redefinition of 'NSAutoreleasePool' as different kind of symbol
mac_type_define(NSAutoreleasePool);
                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSAutoreleasePool.h:10:12: note: previous definition is here
@interface NSAutoreleasePool : NSObject {
           ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:61:17: error: redefinition of 'NSView' as different kind of symbol
mac_type_define(NSView);
                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/ApplicationServices.framework/Frameworks/PrintCore.framework/Headers/PDEPluginInterface.h:28:8: note: previous definition is here
@class NSView;
       ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:64:17: error: redefinition of 'NSNotification' as different kind of symbol
mac_type_define(NSNotification);
                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSNotificationQueue.h:8:8: note: previous definition is here
@class NSNotification, NSNotificationCenter, NSArray<ObjectType>, NSString;
       ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:68:17: error: redefinition of 'NSFileManager' as different kind of symbol
mac_type_define(NSFileManager);
                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSFileManager.h:96:12: note: previous definition is here
@interface NSFileManager : NSObject
           ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:69:17: error: redefinition of 'NSProcessInfo' as different kind of symbol
mac_type_define(NSProcessInfo);
                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSProcessInfo.h:29:12: note: previous definition is here
@interface NSProcessInfo : NSObject {
           ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:33:
include/Silicon/mac/types.h:76:17: error: redefinition of 'NSImage' as different kind of symbol
mac_type_define(NSImage);
                ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSUserNotification.h:8:112: note: previous definition is here
@class NSString, NSDictionary<KeyType, ObjectType>, NSArray<ObjectType>, NSDateComponents, NSDate, NSTimeZone, NSImage, NSAttributedString, NSUserNotificationAction;
                                                                                                               ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:14:29: error: redefinition of 'NSSearchPathDirectory'
typedef NS_ENUM(NSUInteger, NSSearchPathDirectory) {
                            ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:61:29: note: previous definition is here
typedef NS_ENUM(NSUInteger, NSSearchPathDirectory) {
                            ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:15:5: error: redefinition of enumerator 'NSApplicationDirectory'
    NSApplicationDirectory = 1,             // supported applications (Applications)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:62:5: note: previous definition is here
    NSApplicationDirectory = 1,             // supported applications (Applications)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:16:5: error: redefinition of enumerator 'NSDemoApplicationDirectory'
    NSDemoApplicationDirectory,             // unsupported applications, demonstration versions (Demos)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:63:5: note: previous definition is here
    NSDemoApplicationDirectory,             // unsupported applications, demonstration versions (Demos)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:17:5: error: redefinition of enumerator 'NSDeveloperApplicationDirectory'
    NSDeveloperApplicationDirectory,        // developer applications (Developer/Applications). DEPRECATED - there is no one single Developer directory.
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:64:5: note: previous definition is here
    NSDeveloperApplicationDirectory,        // developer applications (Developer/Applications). DEPRECATED - there is no one single Developer directory.
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:18:5: error: redefinition of enumerator 'NSAdminApplicationDirectory'
    NSAdminApplicationDirectory,            // system and network administration applications (Administration)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:65:5: note: previous definition is here
    NSAdminApplicationDirectory,            // system and network administration applications (Administration)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:19:5: error: redefinition of enumerator 'NSLibraryDirectory'
    NSLibraryDirectory,                     // various documentation, support, and configuration files, resources (Library)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:66:5: note: previous definition is here
    NSLibraryDirectory,                     // various documentation, support, and configuration files, resources (Library)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:20:5: error: redefinition of enumerator 'NSDeveloperDirectory'
    NSDeveloperDirectory,                   // developer resources (Developer) DEPRECATED - there is no one single Developer directory.
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:67:5: note: previous definition is here
    NSDeveloperDirectory,                   // developer resources (Developer) DEPRECATED - there is no one single Developer directory.
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:21:5: error: redefinition of enumerator 'NSUserDirectory'
    NSUserDirectory,                        // user home directories (Users)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:68:5: note: previous definition is here
    NSUserDirectory,                        // user home directories (Users)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:22:5: error: redefinition of enumerator 'NSDocumentationDirectory'
    NSDocumentationDirectory,               // documentation (Documentation)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:69:5: note: previous definition is here
    NSDocumentationDirectory,               // documentation (Documentation)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:23:5: error: redefinition of enumerator 'NSDocumentDirectory'
    NSDocumentDirectory,                    // documents (Documents)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:70:5: note: previous definition is here
    NSDocumentDirectory,                    // documents (Documents)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:24:5: error: redefinition of enumerator 'NSCoreServiceDirectory'
    NSCoreServiceDirectory,                 // location of CoreServices directory (System/Library/CoreServices)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:71:5: note: previous definition is here
    NSCoreServiceDirectory,                 // location of CoreServices directory (System/Library/CoreServices)
    ^
In file included from source/mac/NSGeometry.m:9:
In file included from include/Silicon/silicon.h:53:
In file included from include/Silicon/mac/silicon.h:34:
In file included from include/Silicon/mac/enums.h:40:
include/Silicon/mac/headers/NSPathUtilities.h:25:5: error: redefinition of enumerator 'NSAutosavedInformationDirectory'
    NSAutosavedInformationDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 11,   // location of autosaved documents (Documents/Autosaved)
    ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSPathUtilities.h:72:5: note: previous definition is here
    NSAutosavedInformationDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 11,   // location of autosaved documents (Documents/Autosaved)
    ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [build/NSGeometry.o] Error 1

Unfortunately, I am not too sure why Clang complains so much about the 'redefinitions' of types and enums despite the C Silicon headers not having any Cocoa includes. Maybe removing '#include <CoreServices/CoreServices.h>' in include/silicon.h and replacing it with some other header would fix the issue, but not only do I doubt that, but I also cannot even test that out, as I am not using MacOS as my primary OS anymore. This also might be a compiler thing, where Apple's Clang auto-includes these headers, but that's going into pure speculation.

However, as an actual alternative to silicon, I recommend trying out a fork of silicon instead. It's more-or-less the same thing but single-header and 100% C, which should get rid of those errors.

Hello @EimaMei,

Thanks for the comment. The failure to compile is odd, I agree. I had found the fork and tried that too. It compiles but all of the examples crash at startup. And there is no issues page on the fork so reporting is a trifle difficult. I will pursue further and see if the cause can be fixed. @ColleagueRiley: do you have any comments? I'm building on M2 silicon/Sonoma using Clang 15.0.0

Thanks!

I believe I used to have a similar issue as you when compiling newer versions of MacOS using [the original] Silicon. I ended up just used per-compiled binaries instead of compiling it by hand.

In terms of Silicon.h crashing, I'm not sure what the problem is.

Hello @EimaMei,

Thanks for the comment. The failure to compile is odd, I agree. I had found the fork and tried that too. It compiles but all of the examples crash at startup. And there is no issues page on the fork so reporting is a trifle difficult. I will pursue further and see if the cause can be fixed. @ColleagueRiley: do you have any comments? I'm building on M2 silicon/Sonoma using Clang 15.0.0

Thanks!

I’ll definitely attempt to look into it either on the following days or the weekend. As for silicon.h crashing, I’ve read awhile back that the way you declare objc_msgSend in x86-64 MacOS would crash in ARM64 MacOS due to ABI differences (sadly I cannot find that source at the moment). Either way I’ll probably have to setup docker and to debug either issue.

Hello @ColleagueRiley

Your comment re objc_msgSend is absolutely on the money. On Apple ARM64 all you need is that, and not the stret/fpret varieties. See https://stackoverflow.com/questions/24003327/objc-msgsend-macro-on-arm64 and (the slightly madcap) https://felixk15.github.io/posts/c_ocoa/

Sadly all of the examples fail in one way or another. I'll investigate further.

Silicon-h % lldb menu    
(lldb) target create "menu"
Current executable set to '/Users/jevans/src/osx/Silicon-h/menu' (arm64).
(lldb) r
Process 4607 launched: '/Users/jevans/src/osx/Silicon-h/menu' (arm64)
Process 4607 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x40)
    frame #0: 0x000000018d8c9578 libobjc.A.dylib`objc_opt_isKindOfClass + 12
libobjc.A.dylib`objc_opt_isKindOfClass:
->  0x18d8c9578 <+12>: ldr    x8, [x0]
    0x18d8c957c <+16>: and    x16, x8, #0x7ffffffffffff8
    0x18d8c9580 <+20>: mov    x17, x0
    0x18d8c9584 <+24>: movk   x17, #0x6ae1, lsl #48
Target 0: (menu) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x40)
  * frame #0: 0x000000018d8c9578 libobjc.A.dylib`objc_opt_isKindOfClass + 12
    frame #1: 0x0000000191524b98 AppKit`-[NSApplication setMainMenu:] + 96
    frame #2: 0x00000001000053cc menu`NSApplication_setMainMenu + 68
    frame #3: 0x0000000100004d80 menu`main + 468
    frame #4: 0x000000018d9010e0 dyld`start + 2360

and a picture to complement the last post (You can invoke the TUI mode by typing 'gui' at the lldb command line):

image

I'm not too sure what the problem is, it seems like ARM likes to use objc_msgSend and not the fpret or stret varieties. But Silicon only uses objc_msgSend anyway, so I don't know how it would be causing a crash.

Silicon.h works well on x86 systems, so it's 100% something to do with ARM.
It'll be kind of hard for me to figure out the problem because I don't have an computer with an ARM processor.

I think the problem could be with how I cast objc_msgSend but that's just a guess.

A couple of things worth mentioning, though perhaps not so interesting if you are only interested in a C API. Apple have a very clever C++ wrapper for Metal: https://developer.apple.com/metal/cpp/.

Some of the (many) nice features useful in this context are wrappers for SEL and ownership. So, using their string construction, the code below returns the expected result: i.e. the objc_msgSend invocation returns true, and the receiving buffer will contain "Hello World".

It is essential to cast to the correct form of function pointer prior to calling.

{
        // source string 
        NS::String* s = MTLSTR("Hello World");
        // receiving buffer    
        char buffer[512] = {0};
        //-----------------------------
        const char* sel = "getCString:maxLength:encoding:";
    	SEL methodSelector = sel_registerName( sel);
        // note typedef and cast. *must* match ObjC signature.
        typedef bool (*pfn)(id,SEL,char*,unsigned long long,unsigned long long);
        // set up function pointer
        pfn p = (pfn)objc_msgSend;
        // call it. note use of metal string as argument.
        bool b = p(s,methodSelector,buffer,512,NS::UTF8StringEncoding);
        //-----------------------------
        printf("%s => %s (%s)\n",sel,(b?"true":"false"),buffer);
    }

It looks interesting I guess, but I'd be worried about any extra performance issues that C++ brings. Cocoa already isn't that great of a API in terms of performance issues. I really wish apple would stop being weird with their products.

As for Silicon.h's crash issue, I should have a commit in the next few hours that fixes any potential casting issues. Would you be willing to test it? I'm not 100% sure if @EimaMei has an ARM device or not.

I suspect the c++ overhead is absolutely minimal. This is basically for games!

in terms of testing, yes absolutely. Let me know.

Thanks for listening.

@g40 I believe the C++ overhead has a little bit of extra OOP to it. It seems relatively minimal though, yes.

Also, the update with the fixed casting has been committed if you want to test it.

@ColleagueRiley. Latest fails to compile. AIUI, there is no need for the fpret flavour on Apple ARM64.

Silicon-h % make
make opengl
gcc examples/graphics/opengl.c -I./ -framework Cocoa -framework OpenGL -framework CoreVideo -o opengl
In file included from examples/graphics/opengl.c:3:
./silicon.h:2151:21: error: use of undeclared identifier 'objc_msgSend_fpret'
    return (CGFloat)objc_msgSend_float(window, func);
                    ^
./silicon.h:1187:53: note: expanded from macro 'objc_msgSend_float'
#define objc_msgSend_float                      ((CGFloat (*)(id, SEL))objc_msgSend_fpret)
                                                                       ^
1 error generated.
make[1]: *** [opengl] Error 1
make: *** [example] Error 2

OK, if I edit that, the example apps compile and run. Sweet.

@ColleagueRiley. Latest fails to compile. AIUI, there is no need for the fpret flavour on Apple ARM64.


Silicon-h % make

make opengl

gcc examples/graphics/opengl.c -I./ -framework Cocoa -framework OpenGL -framework CoreVideo -o opengl

In file included from examples/graphics/opengl.c:3:

./silicon.h:2151:21: error: use of undeclared identifier 'objc_msgSend_fpret'

    return (CGFloat)objc_msgSend_float(window, func);

                    ^

./silicon.h:1187:53: note: expanded from macro 'objc_msgSend_float'

#define objc_msgSend_float                      ((CGFloat (*)(id, SEL))objc_msgSend_fpret)

                                                                       ^

1 error generated.

make[1]: *** [opengl] Error 1

make: *** [example] Error 2

This is because I accidentally put objc_msgSend_fpret instead of abi_objc_msgSend_fpret. It's fixed now though.