Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling and linking Swift plus Objective C code from the OS X command-line

Compiling Swift from an OS X command-line:

swift -sdk $(xcrun --show-sdk-path --sdk macosx) test.swift

Compiling Objective C from the command-line:

clang -lobjc -framework Foundation -c testObject.m

I can add the -c option to either compiler to produce .o files.

How can I link these two source files into one app?

Or is more needed to build?

like image 496
hotpaw2 Avatar asked Jun 10 '14 01:06

hotpaw2


People also ask

Can you mix Objective-C and Swift?

You can use Objective-C and Swift files together in a single project, no matter which language the project used originally. This makes creating mixed-language app and framework targets as straightforward as creating an app or framework target written in a single language.

How do I add Objective-C to Xcode?

Add any Objective-C file to your Swift project by choosing File -> New -> New File -> Objective-C File. Upon saving, Xcode will ask if you want to add a bridging header. Choose 'Yes'.

How do I open an Objective-C project in Xcode?

Click on the Xcode icon in the dock to launch the tool. Click Next and on the resulting options panel name the project sampleApp and select Foundation from the Type menu. Also verify that the Use Automatic Reference Counting option is selected.


1 Answers

TL;DR: It's preferable to use the Xcode tooling, since there's a lot of stuff going on. But it's possible to only use command line tools.

I'll warn you that this is a quick and dirty example of how to compile and run a .m and a .swift file, linked against Cocoa and the Swift runtime. I'm not even trying to follow the best practices on either side.

Let's assume you have an Objective-C class:

$ cat C.h
#import <Cocoa/Cocoa.h>
@interface C : NSObject
@property (retain) NSString *c;
@end

$ cat C.m
#import "C.h"

@implementation C

- (id)init {
  self = [super init];
  self.c = @"Hello world!";
  return self;
}

@end

And you have a Swift file that uses that class:

$ cat S.swift
let c = C()

println(c.c)

You just need to compile the Objective-C and Swift files to .o files, separately:

xcrun clang C.m -o C.o -c
# Be sure to import the bridge header (our only header in this example)
xcrun swiftc -c S.swift -import-objc-header C.h -F /System/Library/Frameworks -I/usr/include

As you can see, we had to manually include the framework and header paths, to have the Swift compiler locate the proper files (it might be best to have it look for them in the SDK, not in the currently installed files, btw (with xcrun --show-sdk-path)).

Then we simply need to link them, pulling all the Swift and Objective-C runtime libs. Since swift by default pulls the Objective-C libraries, we don't even need to specify much:

xcrun swiftc -o app C.o S.o

Behold, our executable is linked and we can run it!

$ ./app
Hello world!

This is all very interesting, but I would advise against using these tools directly unless you're actually making a build system for your project that targets them and have a good reason not to use Xcode/xcodebuild.

like image 76
filcab Avatar answered Nov 08 '22 17:11

filcab