Search code examples
objective-cxcodemetal

objective-c working in xcode but not on command line


I have a program that compiles in Xcode and behaves as expected, but when compiled on the command line doesn't behave as expected. This is on MacOS 13.0.1 (not sure what other version information is relevant), and I've compiled with clang main.m -fobjc-arc -fmodules and gcc -framework Foundation -framework Metal main.m. What other compiler or compiler options should I try, or what settings (somewhere) should I change? Looking through the Xcode build settings I can't figure out exactly how it's invoking the compiler.

Here's the program:

#import <Foundation/Foundation.h>
#import <Metal/Metal.h>
int main() {
    @autoreleasepool {
        id<MTLDevice> device = MTLCreateSystemDefaultDevice();
        NSLog(@"%@", [device name]);
        BOOL ctp = [device conformsToProtocol:@protocol(MTLDevice)];
        NSLog(@"%@", ctp ? @"true" : @"false");
    }
    return 0;
}

When on Xcode I get the expected output lines "Intel(R) UHD Graphics 617" and "true". When on the command line I get the unexpected output lines "(null)" and "false".


Solution

  • As per documentation:

    In macOS, in order for the system to provide a default Metal device object, you must link to the Core Graphics framework. You usually need to do this explicitly if you’re writing apps that don’t use graphics by default, such as command line tools.

    Thus, you have to additionally link CoreGraphics when compiling the code:

    % clang -fobjc-arc -fmodules -framework CoreGraphics -framework Metal -o main main.m