问题
I've written a Curses wrapper module by following the instructions of this page.
However, I do not know how to properly make it work in a module using it.
I have 3 parallel directories: CCurses, CursesWrapper, ModuleUsingCursesWrapper.
CCurses contains an empty Package.swift file and a module.modulemap file containing
module CCurses [system] {
header "/usr/include/curses.h"
link "curses"
export *
}
CursesWrapper contains a Package.swift file containing.
import PackageDescription
let package = Package(dependencies: [.Package(url: "../CCurses", majorVersion: 1)])
and a general.swift file containing
import CCurses
public func startCurses() -> Void{
initscr()}
public func getchar() -> Void{
getch()}
public func endCurses() -> Void{
endwin()}
ModuleUsingCursesWrapper contains a Package.swift file containing
import PackageDescription
let package = dependencies: [.Package(url: "../CursesWrapper", majorVersion: 1)])
and a main.swift file containing
import CursesWrapper
startCurses()
getchar()
endCurses()
When running swift build in ModuleUsingCursesWrapper, I get the following output:
Cloning Packages/CursesWrapper Cloning Packages/CCurses Compiling Swift Module 'CursesWrapper' (1 sources) Linking Library: .build/debug/CursesWrapper.a Compiling Swift Module 'ModuleUsingCursesWrapper' (1 sources) Linking Executable: .build/debug/ModuleUsingCursesWrapper .../ModuleUsingCursesWrapper/.build/debug/CursesWrapper.a(general.swift.o): In function `_TF14CursesWrapper11startCursesFT_T_': .../ModuleUsingCursesWrapper/Packages/CursesWrapper-1.0.0/general.swift:5: undefined reference to `initscr' .../ModuleUsingCursesWrapper/.build/debug/CursesWrapper.a(general.swift.o): In function `_TF1CursesWrapper7getcharFT_T_': .../ModuleUsingCursesWrapper/Packages/CursesWrapper-1.0.0/general.swift:8: undefined reference to `getch' .../ModuleUsingCursesWrapper/.build/debug/CursesWrapper.a(general.swift.o): In function `_TF14CursesWrapper9endCursesFT_T_': .../ModuleUsingCursesWrapper/Packages/CursesWrapper-1.0.0/general.swift:11: undefined reference to `endwin' clang: error: linker command failed with exit code 1 (use -v to see invocation) < unknown >:0: error: link command failed with exit code 1 (use -v to see invocation) < unknown :0: error: build had 1 command failures swift-build: exit(1): [".../Swift/usr/bin/swift-build-tool", "-f", ".../ModuleUsingCursesWrapper/.build/debug/ModuleUsingCursesWrapper.o/llbuild.yaml"]
It seems that when compiling ModuleUsingCursesWrapper, the curses functions cannot be found. How can I solve this problem ?
(I'm on Linux)
回答1:
After playing with your example for awhile on an Ubuntu 14.04 box, I ran into the same error. After some additional experimentation, I was able to solve it by adding the following to main.swift
:
import CCurses
The Package.swift
file of the module using the wrapper references only CursesWrapper, but if CCurses
is not imported into main.swift
, then the undefined reference error occurs.
The need to import dependencies of imported modules can be seen from the link to swift.org that you provided, where a JasPer/JPEG example is discussed. Strictly speaking, JasPer is not a wrapper around JPEG, but is just another system module, yet the idea is the same: if we import module A that depends on module B, then we should also import module B.
BTW I had to change public func getchar()
to public func getChar()
and modify main.swift
accordingly. Otherwise I would get ambiguous use of 'getchar()'
error when compiling main.swift
. Evidently it is already defined in CCurses
, which is no surprise as it is a standard C function.
来源:https://stackoverflow.com/questions/34421200/importing-a-swift-module-using-a-c-library