Создание проекта с библиотекой ручной работы из LLVM-IR под Xcode9 не будет правильно связываться
Я хочу создать необычную программу, цель которой - получить файл LLVM-IR, скомпилировать его из терминала в какую-нибудь библиотеку и импортировать в программу-оболочку. Это должно работать как плагин. К сожалению, на пути были некоторые проблемы, некоторые из которых я уже смог решить. Но сейчас я бьюсь головой о проблеме, которую я сейчас опишу.
Для объяснения я дам вам все исходные тексты, которые содержит мой проект-прототип, но сначала (очень базовая) настройка проекта.
+ LinkingTestProject
+- Source
+-- main.swift
+-- TestWrapper.swift
+- Build
+- LinkingTestProject.xcodeproj
Что является очень простой настройкой для проекта XCode, но может быть полезным позже.
Таким образом, чтобы решить мою проблему, я нашел несколько симпатичных объяснений, найденных здесь, где автор создал статическую библиотеку и необходимые .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
использовался. Следуя данному уроку, у меня должен быть какой-то быстрый модуль, поэтому для его создания я использовал следующее:
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_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 Compiler (swiftc), если проблема может привести к этому...
Спасибо за ваши ответы.