diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2bbea83..33916fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,6 +48,28 @@ jobs: export LD_LIBRARY_PATH=$(dirname $(find /opt/mongoc -name 'libmongoc2.so' | head -1)) swift test + linux-apt: + # The oldest libmongoc we support, from the distribution package the README recommends. + name: Linux (Ubuntu 26.04, apt libmongoc) + runs-on: ubuntu-24.04 + container: swift:6.4-resolute + services: + mongo: + image: mongo:8 + env: + MONGODB_URI: mongodb://mongo:27017 + steps: + - uses: actions/checkout@v7 + + - name: Install libmongoc from apt + run: | + apt-get update + apt-get install -y --no-install-recommends pkg-config libmongoc-dev libbson-dev + echo "libmongoc $(pkg-config --modversion mongoc2)" + + - name: Test + run: swift test + macos: name: macOS (build + server-independent tests) runs-on: macos-15 diff --git a/Package.swift b/Package.swift index 1799972..4e4ab4c 100644 --- a/Package.swift +++ b/Package.swift @@ -32,16 +32,18 @@ let package = Package( name: "PerfectCBSON", pkgConfig: "bson2", providers: [ - .brew(["mongo-c-driver"]), - .apt(["libbson-dev"]) + // No apt provider: SwiftPM can't vary it by release, and libmongoc-dev is 2.x only on + // Ubuntu 26.04+ / Debian forky+; on Ubuntu 24.04 it installs 1.x. See the README. + .brew(["mongo-c-driver"]) ] ), .systemLibrary( name: "PerfectCMongo", pkgConfig: "mongoc2", providers: [ - .brew(["mongo-c-driver"]), - .apt(["libmongoc-dev"]) + // No apt provider: SwiftPM can't vary it by release, and libmongoc-dev is 2.x only on + // Ubuntu 26.04+ / Debian forky+; on Ubuntu 24.04 it installs 1.x. See the README. + .brew(["mongo-c-driver"]) ] ), .target( diff --git a/README.md b/README.md index 81a4384..761236a 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ targets: [ ## Requirements -libmongoc **2.x** must be installed where pkg-config can find `mongoc2` and `bson2`. +libmongoc **2.x** must be installed where pkg-config can find `mongoc2` and `bson2`. Tested with 2.2.2 and 2.5.5. **macOS** ([Homebrew](https://brew.sh)): @@ -45,9 +45,15 @@ brew install mongo-c-driver On Apple silicon, if SwiftPM can't find the library, set `PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig`. -**Linux:** most distributions still package libmongoc 1.x (for example Ubuntu's `libmongoc-dev`), which -this version doesn't support. Build libmongoc 2 from source, as the CI workflow in -`.github/workflows/ci.yml` does: +**Linux:** whether your distribution's package is new enough depends on the release: + +| Distribution | `libmongoc-dev` version | What to do | +|---|---|---| +| Ubuntu 26.04 LTS and later | 2.2 or later | `apt-get install libmongoc-dev libbson-dev` | +| Debian forky / sid | 2.5 | `apt-get install libmongoc-dev libbson-dev` | +| Ubuntu 24.04 LTS (used by the `swift:*-noble` images), Debian 13 and older | 1.x, not supported | Build from source (below) | + +To build libmongoc 2 from source, as the CI workflow in `.github/workflows/ci.yml` does: ```sh apt-get install cmake libssl-dev libsasl2-dev libzstd-dev diff --git a/README.zh_CN.md b/README.zh_CN.md index e5f299d..5393e91 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -33,7 +33,7 @@ targets: [ ## 环境要求 -必须安装 libmongoc **2.x**,并确保 pkg-config 能找到 `mongoc2` 和 `bson2`。 +必须安装 libmongoc **2.x**,并确保 pkg-config 能找到 `mongoc2` 和 `bson2`。已在 2.2.2 和 2.5.5 上测试。 **macOS**([Homebrew](https://brew.sh)): @@ -43,8 +43,15 @@ brew install mongo-c-driver 在 Apple 芯片的 Mac 上,如果 SwiftPM 找不到该库,请设置 `PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig`。 -**Linux:** 大多数发行版仍只提供 libmongoc 1.x(例如 Ubuntu 的 `libmongoc-dev`),本版本不支持。请参照 -`.github/workflows/ci.yml` 中 CI 的做法,从源码编译 libmongoc 2: +**Linux:** 发行版自带的软件包是否够新取决于版本: + +| 发行版 | `libmongoc-dev` 版本 | 做法 | +|---|---|---| +| Ubuntu 26.04 LTS 及更新版本 | 2.2 或更新 | `apt-get install libmongoc-dev libbson-dev` | +| Debian forky / sid | 2.5 | `apt-get install libmongoc-dev libbson-dev` | +| Ubuntu 24.04 LTS(`swift:*-noble` 镜像所用)、Debian 13 及更早版本 | 1.x,不支持 | 从源码编译(见下文) | + +参照 `.github/workflows/ci.yml` 中 CI 的做法,从源码编译 libmongoc 2: ```sh apt-get install cmake libssl-dev libsasl2-dev libzstd-dev diff --git a/Sources/PerfectCBSON/shim.h b/Sources/PerfectCBSON/shim.h index 42ee4b4..e358a55 100644 --- a/Sources/PerfectCBSON/shim.h +++ b/Sources/PerfectCBSON/shim.h @@ -1,2 +1,14 @@ #define BCON_H_ #include + +// libbson 2.3 added bson_append_array_unsafe_begin and deprecated bson_append_array_begin +// (same signature and behaviour). Use whichever this libbson has, so the package builds +// warning-free on current libbson and still builds on 2.0-2.2 (e.g. Ubuntu 26.04's 2.2.2). +static inline bool _perfect_bson_append_array_begin(bson_t *bson, const char *key, int key_length, bson_t *child) +{ +#if BSON_CHECK_VERSION(2, 3, 0) + return bson_append_array_unsafe_begin(bson, key, key_length, child); +#else + return bson_append_array_begin(bson, key, key_length, child); +#endif +} diff --git a/Sources/PerfectMongoDB/BSON.swift b/Sources/PerfectMongoDB/BSON.swift index 8ee199b..e10bb36 100644 --- a/Sources/PerfectMongoDB/BSON.swift +++ b/Sources/PerfectMongoDB/BSON.swift @@ -472,7 +472,7 @@ public class BSON: CustomStringConvertible { guard let doc = self.doc, let cdoc = child.doc else { return false } - return bson_append_array_unsafe_begin(toOpaque(doc), k, -1, toOpaque(cdoc)) + return _perfect_bson_append_array_begin(toOpaque(doc), k, -1, toOpaque(cdoc)) } /** diff --git a/Sources/PerfectMongoDB/BSONCodable.swift b/Sources/PerfectMongoDB/BSONCodable.swift index 38c7511..b47c873 100644 --- a/Sources/PerfectMongoDB/BSONCodable.swift +++ b/Sources/PerfectMongoDB/BSONCodable.swift @@ -219,7 +219,7 @@ public struct BSONEncoder: Sendable { case .array(let storage)?: let child = UnsafeMutablePointer.allocate(capacity: 1) defer { child.deallocate() } - guard bson_append_array_unsafe_begin(doc, key, -1, child) else { + guard _perfect_bson_append_array_begin(doc, key, -1, child) else { throw MongoError("could not start array '\(key)'") } for (index, box) in storage.boxes.enumerated() {