Как создать локальную библиотеку C как статическую библиотеку и связать со Swift?

#c #swift #linker #static-libraries #packaging

#c #swift #компоновщик #статические библиотеки #упаковка

Вопрос:

Как следует из названия, у меня возникли небольшие проблемы с созданием статической библиотеки из кода C и ее использованием в проекте Swift.

Вот процесс создания C-кода:

 make
# Making the static library
clang -c Sources/nuklear.c -o nuklear.o
clang -c Sources/test.c -o test.o
libtool -static nuklear.o test.o -o libNuklear.a
cp libNuklear.a /usr/local/lib
❯ ls /usr/local/lib | grep Nuk
libNuklear.a
 

Вот ошибка:

 swift build -Xlinker -L/usr/local/lib
'CNuklear' /Users/pprovins/Projects/CNuklearTest/.build/checkouts/CNuklear: warning: system packages are deprecated; use system library targets instead
ld: warning: Could not find or use auto-linked library 'libNuklear'
Undefined symbols for architecture x86_64:
  "_test_doit", referenced from:
      _main in main.swift.o
ld: symbol(s) not found for architecture x86_64
[0/1] Linking CNuklearTest
 

Ошибка предполагает, что библиотека не может быть найдена или библиотека недоступна для использования (невозможно определить, какая именно).

Запуск nm libNuklear.a показывает:

 libNuklear.a(test.o):
                 U _printf
0000000000000000 T _test_doit
 

Похоже, что символы действительно существуют, поэтому я склоняюсь к тому, что может возникнуть проблема с поиском библиотеки для ссылки, поэтому я опишу свой процесс соединения следующим. C-код помещается в модуль / пакет системной библиотеки отдельно от создаваемого исполняемого файла. Он содержит связующий заголовок и определение пакета. Вот module.modulemap определение:

 module CNuklear [system] {
  header "Includes/CNuklear.h"
  link "libNuklear"
  export *
}
 

Соединительный заголовок ( CNuklear.h ):

 #import "Includes/nuklear.h"
#import "Includes/test.h"
 

В настоящее время я создаю статическую библиотеку, затем пытаюсь создать исполняемый файл swift; однако у него возникают проблемы со связыванием со статической библиотекой, которую я создал. Вот как я пытаюсь включить и выполнить код в main.swift :

 import CNuklear

test_doit()

print("Hello, world!")
 

Есть ли способ дальнейшей отладки проблемы со связыванием, с которой я сталкиваюсь? Заранее спасибо!

Ответ №1:

В module.modulemap файле:

Если создается статическая библиотека с именем libNuklear.a , link спецификация для модуля должна быть:

 module CNuklear [system] {
  header "Includes/CNuklear.h"
  link "Nuklear"
  export *
}
 

Вы также должны работать swift build с -Xlinker -L/usr/local/lib или -Xlinker -L/dir/which/lib/resides