Xcode、clang、c++ stdlib:Swift 使用系统库的包,构建失败,未找到 'stdexcept' 文件
Xcode, clang, c++ stdlib: Swift Package using a system library, build fails with 'stdexcept' file not found
我正在编写一个可执行文件 Swift 包,我需要在其中使用系统库(用 C++ 编写)。
AFAIK 我正确编写了 package.swift、module.modulemap 和伞头文件。
当我在 main.swift
文件中为库添加 import
时,出现错误 'stdexcept' file not found
。错误来自系统库的 public 头文件之一中的 #include <stdexcept>
。
目前运行:
- Xcode v13.2.1
- macOS v12.2.1(蒙特雷)
我认为问题与 Xcode 的命令行工具有关,但我该如何解决?
Package.swift
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "GeodesicApp",
platforms: [.macOS(.v11)],
dependencies: [
],
targets: [
.systemLibrary(name: "geographiclib",
pkgConfig: "geographiclib",
providers: [
.brew(["geographiclib"])
]
),
.executableTarget(
name: "GeodesicApp",
dependencies: ["geographiclib"])
]
)
module.modulemap
module geographiclib {
umbrella header "geographiclib.h"
export *
link "geographiclib"
}
伞头(geographiclib.h)
#include <GeographicLib/Config.h>
#include <GeographicLib/Geodesic.hpp>
main.swift
import geographiclib // error: 'stdexcept' file not found
... //
错误。
回答我自己的问题。
我只能通过围绕系统库创建一个 C 包装程序包来获得一个可行的解决方案;然后,该 C 包装器包又被另一个 Swift 包装器包装以公开 'Swifty-style' 代码 - 我无法获得包含所有必需部分的单个包。
我的工作解决方案如下...
包: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)
}
我正在编写一个可执行文件 Swift 包,我需要在其中使用系统库(用 C++ 编写)。
AFAIK 我正确编写了 package.swift、module.modulemap 和伞头文件。
当我在 main.swift
文件中为库添加 import
时,出现错误 'stdexcept' file not found
。错误来自系统库的 public 头文件之一中的 #include <stdexcept>
。
目前运行:
- Xcode v13.2.1
- macOS v12.2.1(蒙特雷)
我认为问题与 Xcode 的命令行工具有关,但我该如何解决?
Package.swift
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "GeodesicApp",
platforms: [.macOS(.v11)],
dependencies: [
],
targets: [
.systemLibrary(name: "geographiclib",
pkgConfig: "geographiclib",
providers: [
.brew(["geographiclib"])
]
),
.executableTarget(
name: "GeodesicApp",
dependencies: ["geographiclib"])
]
)
module.modulemap
module geographiclib {
umbrella header "geographiclib.h"
export *
link "geographiclib"
}
伞头(geographiclib.h)
#include <GeographicLib/Config.h>
#include <GeographicLib/Geodesic.hpp>
main.swift
import geographiclib // error: 'stdexcept' file not found
... //
错误。
回答我自己的问题。 我只能通过围绕系统库创建一个 C 包装程序包来获得一个可行的解决方案;然后,该 C 包装器包又被另一个 Swift 包装器包装以公开 'Swifty-style' 代码 - 我无法获得包含所有必需部分的单个包。
我的工作解决方案如下...
包: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)
}