我想构建一个可能不寻常的程序,目标是获取一些LLVM-IR文件并将其从终端编译到某种类型的库并将其导入到包装器软件中。这应该像插件一样工作。不幸的是,路上有一些问题,其中一些我已经能够解决了。但是现在我正在试着解决我现在要描述的问题。
为了解释我会给你所有Source我的原型项目包含,但首先是(非常基本的)项目设置。
+ LinkingTestProject
+- Source
+-- main.swift
+-- TestWrapper.swift
+- Build
+- LinkingTestProject.xcodeproj
这是Xcode项目的一个非常基本的设置,但稍后可能会有所帮助。
因此,为了解决我的问题,我找到了一些好看的解释found here,其中作者创建了一些静态库和所需的.swiftmodule
文件。但就我而言,没有可用的swift文件可以做到这一点,我遇到了一些解决方法。
所以要创建所需的.o
文件,我在终端上使用这个小命令:
llc -filetype=obj TestModule.ll
假设.ll
文件是使用此命令创建的,该命令确实用于原型设计:
swiftc -emit-ir TestModule.swift -target "x86_64-apple-macosx10.09"
现在我得到了.o
文件,我必须得到.a
文件 - 就像上面的链接中所解释的那样。因此使用了命令ar rcs libTestModule.a TestModule.o
。根据给定的教程,我必须有一些swift模块,所以要创建一个我使用以下内容:
swiftc -emit-module <file with same interface as ir has> -module-name TestModule
我正在使用具有相同类和功能指纹的swift文件,作为已转换为LLVM-IR并提交给我的程序的文件。所以现在(理论上)我拥有在项目中导入模块所需的一切。
项目代码如下:
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()
}
}
TestModule文件也包含以下内容:
TestModule.swift
import Foundation
public class TestModuleClass {
public init() {}
public func execute() {
print("THIS WAS PRINTED IN MODULE")
}
}
到目前为止真的很直接。现在我将生成的文件复制到源文件夹,所以我得到这样的东西。
+ Source
+- libTestModule.a
+- TestModule.swiftmodule
+- main.swift
+- TestWrapper.swift
然后将Source文件夹添加到“图书馆搜索路径”,“框架搜索路径”和“页眉搜索路径” - 在“目标”下找到 - &gt; “构建设置”(如此$(SOURCE_ROOT)/Source
。然后我还在“其他链接标记”部分添加了“ - lTestModule”标记到链接到我创建的模块(ish)类型的东西。
现在Xcode检查模块并在编辑器模式下突出显示没有错误。所以我走了一条刚刚开始的路......
尝试构建项目后,我遇到了以下错误消息:
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)
由于我已经构建了LLVM-IR文件并使用了正确的目标(x86_64),我想知道为什么会发生这种情况。
所以我的研究阶段开始了,通过lipo -info libTestModule.a
检查文件,结果如下:
input file TestModule.a is not a fat file
Non-fat file: TestModule.a is architecture: x86_64
更深入地挖掘我的nm
命令,它向我输出了这些信息:
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
也许你们中的一些人对我有一些答案。如何解决这个问题?我不知道在那里找不到任何解决方案......哦,我必须提到我正在使用Xcode9和Swift4.0编译器(swiftc),如果问题导致这个......
感谢您的回答。