[swift-users] Linking Handmade Swiftmodule with Xcode9

Pascal Schönthier pascal at pixelskull.de
Thu Jul 27 06:46:33 CDT 2017


Hi there,
I want to build a maybe unusual program, goal is to get some LLVM-IR File and compile this from terminal to some type of library and import this one in an wrapper software. This should work like an plugin. Unfortunately there were some problems on the way, which some of that I already were able to solve. But now I'm banging my head to the problem which I will describe now.
For explaining I will give you all Source my prototype project contains, but first the (very basic) project setup.

+ LinkingTestProject
+- Source
+-- main.swift
+-- TestWrapper.swift
+- Build
+- LinkingTestProject.xcodeproj
Which is a very basic setup for an Xcode Project but maybe helpful later on.
So to solve my Problem I found some good looking explanations found here, where the author created some static library and the needed .swiftmodule file. But in my case there is no usable swift file to do this, I came across with some work around.
So to create the needed .o file I am using this little command on terminal:
llc -filetype=obj TestModule.ll
Assuming the .llfile was created using this command, which indeed was used for prototyping:
swiftc -emit-ir TestModule.swift -target "x86_64-apple-macosx10.09"
So now that I get the .ofile, I have to get the .a file – like explained in the link above. Therefore the command ar rcs libTestModule.a TestModule.o was used. Following the given tutorial, I have to had some swift module, so to create one I was using the following:
swiftc -emit-module <file with same interface as ir has> -module-name TestModule
Where I am using a swift file with the same class and functions fingerprint, as the file that was translated to LLVM-IR and submitted to my program. So now (theoretically) I have everything needed to import the module in my project.
The code of the project is the following:
main.swift

import Foundation

print("starting execution!")
let wrapper = TestWrapper()
wrapper.executeModule()
TestWrapper.swift

import Foundations
import TestModule

class TestWrapper {

   var module: TestModuleClass

   init() {
       module = TestModuleClass()
   }

   func executeModule() {
       module.execute()
   }
}
Also the TestModule file contains the following:
TestModule.swift

import Foundation

public class TestModuleClass {
   public init() {}

   public func execute() {
       print("THIS WAS PRINTED IN MODULE")
   }
}
Really straight forward so far. Now I copied the generated files to Source Folder so I am getting something like this.

+ Source
+- libTestModule.a
+- TestModule.swiftmodule
+- main.swift
+- TestWrapper.swift
Then by adding the Source folder to the "Library Search Paths", "Framework Search Paths"and "Header Search Paths" – found under "Target" -> "Build Settings" (like so $(SOURCE_ROOT)/Source. Then I also added to the "Other Linker Flags" section the "-lTestModule" flag to link against my created module(ish) type of thing here. Also the libTestModule.a is in the “Link Binary with Library” section (under Build Phases).
Now Xcode checks the module and highlights absolutely no error in editor mode. So I went down the road an just hit run... After trying to build the project I was facing this error message: Undefined symbols for architecture x86_64:

"__T010TestModule0aB5ClassCACycfC", referenced from:
     __T017Meta_Linking_Test0C7WrapperCACycfc in TestWrapper.o
"__T010TestModule0aB5ClassCMa", referenced from:
     __T017Meta_Linking_Test0C7WrapperCACycfc in TestWrapper.o
     l_get_field_types_TestWrapper in TestWrapper.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Since I have build the LLVM-IR file and used the right target (x86_64) I am wondering why this one was happening. So my research phase started and by checking the files via lipo -info libTestModule.a the result is the following:

input file TestModule.a is not a fat file
Non-fat file: TestModule.a is architecture: x86_64
Digging a little bit deeper brougt me to the nmcommand which outputted me this information:

libTestModule.a(TestModule.o):
                U _OBJC_CLASS_$_SwiftObject
                U _OBJC_METACLASS_$_SwiftObject
0000000000000090 T __T02v315TestModuleClassC7executeyyF
0000000000000010 T __T02v315TestModuleClassCACycfC
0000000000000080 T __T02v315TestModuleClassCACycfc
0000000000000458 s __T02v315TestModuleClassCMF
0000000000000698 b __T02v315TestModuleClassCML
0000000000000040 T __T02v315TestModuleClassCMa
0000000000000270 d __T02v315TestModuleClassCMf
0000000000000248 D __T02v315TestModuleClassCMm
0000000000000408 S __T02v315TestModuleClassCMn
0000000000000280 D __T02v315TestModuleClassCN
00000000000001a0 T __T02v315TestModuleClassCfD
0000000000000190 T __T02v315TestModuleClassCfd
                U __T0BoWV
                U __T0S2SBp21_builtinStringLiteral_Bw17utf8CodeUnitCountBi1_7isASCIItcfC
                U __T0SSN
                U __T0s27_allocateUninitializedArraySayxG_BptBwlF
                U __T0s5printySayypGd_SS9separatorSS10terminatortF
                U __T0s5printySayypGd_SS9separatorSS10terminatortFfA0_
                U __T0s5printySayypGd_SS9separatorSS10terminatortFfA1_
0000000000000240 D __T0ypML
0000000000000140 T __T0ypMa
0000000000000434 S ___swift_reflection_version
                U __objc_empty_cache
                U __swift_FORCE_LOAD_$_swiftCoreFoundation
0000000000000308 D __swift_FORCE_LOAD_$_swiftCoreFoundation_$_v3
                U __swift_FORCE_LOAD_$_swiftCoreGraphics
0000000000000310 D __swift_FORCE_LOAD_$_swiftCoreGraphics_$_v3
                U __swift_FORCE_LOAD_$_swiftDarwin
00000000000002f0 D __swift_FORCE_LOAD_$_swiftDarwin_$_v3
                U __swift_FORCE_LOAD_$_swiftDispatch
0000000000000300 D __swift_FORCE_LOAD_$_swiftDispatch_$_v3
                U __swift_FORCE_LOAD_$_swiftFoundation
00000000000002e0 D __swift_FORCE_LOAD_$_swiftFoundation_$_v3
                U __swift_FORCE_LOAD_$_swiftIOKit
00000000000002f8 D __swift_FORCE_LOAD_$_swiftIOKit_$_v3
                U __swift_FORCE_LOAD_$_swiftObjectiveC
00000000000002e8 D __swift_FORCE_LOAD_$_swiftObjectiveC_$_v3
                U __swift_allocObject
                U __swift_getExistentialTypeMetadata
                U __swift_getInitializedObjCClass
                U __swift_slowAlloc
                U __swift_slowDealloc
0000000000000000 T _main
0000000000000470 s _objc_classes
                U _swift_bridgeObjectRelease
                U _swift_bridgeObjectRetain
                U _swift_deallocClassInstance
0000000000000070 T _swift_rt_swift_allocObject
0000000000000180 T _swift_rt_swift_getExistentialTypeMetadata
0000000000000210 T _swift_rt_swift_getInitializedObjCClass
0000000000000220 T _swift_rt_swift_slowAlloc
0000000000000230 T _swift_rt_swift_slowDealloc
00000000000003a8 s l__DATA__TtC2v315TestModuleClass
0000000000000360 s l__METACLASS_DATA__TtC2v315TestModuleClass
00000000000003f0 s l___unnamed_3
0000000000000406 s l___unnamed_4
00000000000006a0 b l_field_type_vector_TestModuleClass
00000000000001c0 t l_get_field_types_TestModuleClass
0000000000000468 s l_type_metadata_table
I have to mention I'm using Xcode9 and Swift4.0 Compiler (swiftc) under macOS, if the issue can lead to this.
Maybe some of you have an guess what is going wrong here…

Best Regards
Pascal

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170727/03d445bb/attachment.html>


More information about the swift-users mailing list