Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static Linking with Swift, XCode6-Beta [duplicate]

Tags:

ios

swift

xcode6

I've been experimenting with porting an Obj-C library to Swift, and I've run into a problem where the linker fails to build a static library when Swift code is in the project.

As a minimal reproducer, go into XCode6 and create a new iOS Static Library. It'll give you a project with a blank .h and .m file. This will compile fine. Then, add a new .swift file to the project (with or without creating a header bridge). This too should compile fine, but instead it fails during linking:

Libtool /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Products/Debug-iphonesimulator/libTest.a normal i386
    cd /Users/alexkarantza/Workspace/Test
    export IPHONEOS_DEPLOYMENT_TARGET=8.0
    export PATH="/Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode6-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only i386 -syslibroot /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk -L/Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Products/Debug-iphonesimulator -filelist /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Intermediates/Test.build/Debug-iphonesimulator/Test.build/Objects-normal/i386/Test.LinkFileList -ObjC -L/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -rpath -Xlinker /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -force_load -Xlinker /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a -Xlinker -sectalign -Xlinker __SWIFT -Xlinker __ast -Xlinker 4 -Xlinker -sectcreate -Xlinker __SWIFT -Xlinker __ast -Xlinker /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Intermediates/Test.build/Debug-iphonesimulator/Test.build/Objects-normal/i386/Test.swiftmodule -o /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Products/Debug-iphonesimulator/libTest.a

error: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `X' in: -Xlinker
Usage: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols]
Usage: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]

This happens if I'm targeting the simulator or the device. It looks like perhaps having the Swift file in the project is causing it to use linker options normally reserved for executables, even though the target is a static library? I don't know enough about the build options to know if this is a bug in the beta, or some option I should be configuring. It seems questionable that the build would legitimately fail on such a trivial example. Any thoughts?

like image 958
karantza Avatar asked Jun 04 '14 15:06

karantza


4 Answers

To answer my own question after some discussion in the comments, it is simply not possible to build static libraries that include Swift code yet. I'm writing this as of Beta 4, and the release notes still say, under "Known issues in Xcode 6 beta 4":

Xcode does not support building static libraries that include Swift code. (17181019)

like image 108
karantza Avatar answered Nov 13 '22 03:11

karantza


I have been looking at this issue too for a while, here is what I found:

First, in Xcode 6 Beta, there is no language selection when you create Cocoa Touch Static Library, the language is set to Objective-C by default, though you can add Swift file to the project, it gives error like in your question as a result. My interpretation is that it is Apple's intention to steer away from creating Swift static library.

So If you intent to build a library that leverages power of Swift, use Cocoa Touch Framework instead of Static Library. I have written steps on creating framework project and app project, you can find it here. Note in that example, I created an Objective-C framework project. Choose Language Swift if want pure Swift framework project.

enter image description here

Also note If you look to import Swift framework into Objective-C project, or mix the languages, there is a good reading here Swift and Objective-C in the Same Project.

Hope this will give you a good direction.

like image 31
vladof81 Avatar answered Nov 13 '22 04:11

vladof81


Look at this threat XCode5 simulator: unknown option character `X' in: -Xlinker

In order to understand the error, you have to understand what the command is attempting to do.

In this case it's using Libtool, which is a slightly altered version of libtool. There are some options that are specified in the command line, but what we're looking for is the destination file, and this is passed in as the -o option, who's argument is /Users/jr/ios/app/iCozi/build/DevOnly-iphonesimulator/libCozi\ Common\ Code.a, and the type of library we're generating, and in this case it's -static. Both options together explicitly state that you're making a static library archive.

Because you're making a static library archive, the only thing you're actually doing is taking .o files and possibly .a files and turning them into another .a file. This can be roughly equated to the creating of a .zip file from a set of files (.o), and the contents of other .zip files (.a). There are very few things you can do while making this archive, for example you can't specify libraries that need to be implicitly linked while building a static archive, you can't specify that you're going to require entitlements.

libtool is complaining because it doesn't understand the options that are being used for a static library that are being passed in. In this case the options are:

-Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/jr/ios/app/iCozi/build/iCozi.build/DevOnly-iphonesimulator/Cozi\ Common\ Code.build/Cozi\ Common\ Code.xcent

These are options that are present when you're trying to link in an entitlements file, which means that some options is specifying the use of an entitlements file. In this case, you found the correct solution yourself, which was to remove the entitlements file specified in the project settings -> Code Signing -> Code Signing Entitlements -> DevOnly.

like image 2
Alberto Barrera Avatar answered Nov 13 '22 03:11

Alberto Barrera


Check out this blog (translation needed)

http://andelf.github.io/blog/2014/06/25/write-swift-module-with-swift-cont/

like image 1
Aggressor Avatar answered Nov 13 '22 03:11

Aggressor