回答我自己的问题。我只能通过围绕系统库创建一个 C 包装程序包来获得一个可行的解决方案;然后,该 C 包装器包又被另一个 Swift 包装器包装,以公开“Swifty 风格”代码——我无法获得包含所有必需部分的单个包。
我的工作解决方案如下......
包:CGeographicLib
系统库的 C 包装器的文件夹结构是:
.
├── Package.swift
├── README.md
└── Sources
├── CGeographicLib
│ ├── CGeodesic.cpp
│ └── include
│ └── CGeodesic.h
└── geographiclib
├── geographiclib.h
└── module.modulemap
更新Package.swift
:
import PackageDescription
let package = Package(
name: "CGeographicLib",
platforms: [.macOS(.v11)],
products: [
.library(name: "CGeographicLib", targets: ["CGeographicLib"])
],
targets: [
.systemLibrary(name: "geographiclib",
pkgConfig: "geographiclib",
providers: [
.brew(["geographiclib"])
]),
.target(name: "CGeographicLib", dependencies: ["geographiclib"])
],
cxxLanguageStandard: .cxx20
)
我添加platforms: [.macOS(.v11)]
的最新版本的GeographicLib
系统库只支持macOS v11或更高版本。
我正在使用的系统库有一些 C++11 扩展,我添加了语言标准.cxx20
,但这同样可以.cxx11
,它应该仍然适用于我正在使用的系统库。
更新module.modulemap
:
module geographiclib [system] {
umbrella header "geographiclib.h"
link "geographiclib"
export *
}
伞头,geographiclib.h
不变。
对于新的 C 包装器元素
CGeodesic.h
:
#ifdef __cplusplus
extern "C" {
#endif
double geoLibInverse(double lat1, double lon1, double lat2, double lon2);
#ifdef __cplusplus
}
#endif
CGeodesic.cpp
:
#include "include/CGeodesic.h"
#include "../../geographiclib/geographiclib.h"
double geoLibInverse(double lat1, double lon1, double lat2, double lon2) {
using namespace std;
using namespace GeographicLib;
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
double s12;
geod.Inverse(lat1, lon1, lat2, lon2, s12);
return s12;
}
包:SwiftyGeographicLib
使用 C 包装器包的 Swift 包的文件夹结构是:
.
├── Package.swift
├── README.md
├── Sources
│ └── SwiftyGeographicLib
│ └── Geodesic.swift
└── Tests
└── SwiftyGeographicLibTests
└── SwiftyGeographicLibTests.swift
Package.swift
:
import PackageDescription
let package = Package(
name: "SwiftyGeographicLib",
platforms: [.macOS(.v11)],
products: [
.library(
name: "SwiftyGeographicLib",
targets: ["SwiftyGeographicLib"]),
],
dependencies: [
.package(name: "CGeographicLib",
url: "/Users/kieran/codeProjects/z.TestProjects/SPM/CGeographicLib",
branch: "master")
],
targets: [
.target(
name: "SwiftyGeographicLib",
dependencies: ["CGeographicLib"]),
.testTarget(
name: "SwiftyGeographicLibTests",
dependencies: ["SwiftyGeographicLib"]),
]
)
这个例子中的包依赖指向一个本地包——我同样可以在 GitHub 上上传并创建一个版本标签。
Geodesic.swift
:
import Foundation
import CGeographicLib
public func geodesicInverse(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {
return geoLibInverse(lat1, lon1, lat2, lon2)
}