From 7f4a68265cb897d15b04fc772639234554ba79e8 Mon Sep 17 00:00:00 2001
From: Sean McArthur <sean@seanmonstar.com>
Date: Fri, 22 Nov 2024 12:46:09 -0500
Subject: [PATCH] feat(ffi): add cargo-c support (#3787)

Closes #3786
---
 .github/workflows/CI.yml | 26 ++++++++++++++++++++++++++
 Cargo.toml               |  8 ++++++++
 capi/README.md           |  8 ++++++++
 3 files changed, 42 insertions(+)

diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index cb4ec13ea5..90ed20818a 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -23,6 +23,7 @@ jobs:
       - features
       - ffi
       - ffi-header
+      - ffi-cargo-c
       - doc
       - check-external-types
       - udeps
@@ -226,6 +227,31 @@ jobs:
       - name: Ensure that hyper.h is up to date
         run: ./capi/gen_header.sh --verify
 
+  ffi-cargo-c:
+    name: Test cargo-c support (FFI)
+    needs: [style]
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Install Rust
+        uses: dtolnay/rust-toolchain@stable
+
+      - uses: Swatinem/rust-cache@v2
+
+      - name: Install cargo-c
+        env:
+          LINK: https://github.com/lu-zero/cargo-c/releases/latest/download
+          CARGO_C_FILE: cargo-c-x86_64-unknown-linux-musl.tar.gz
+        run: |
+          curl -L $LINK/$CARGO_C_FILE | tar xz -C ~/.cargo/bin
+
+      - name: Build with cargo-c
+        env:
+          RUSTFLAGS: --cfg hyper_unstable_ffi
+        run: cargo cbuild --features client,http1,http2,ffi
+
   doc:
     name: Build docs
     needs: [style, test]
diff --git a/Cargo.toml b/Cargo.toml
index 2249331915..46843a7b88 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -85,6 +85,7 @@ server = ["dep:httpdate", "dep:pin-project-lite", "dep:smallvec"]
 
 # C-API support (currently unstable (no semver))
 ffi = ["dep:http-body-util", "futures-util?/alloc"]
+capi = []
 
 # Utilize tracing (currently unstable)
 tracing = ["dep:tracing"]
@@ -106,6 +107,13 @@ rustdoc-args = ["--cfg", "hyper_unstable_ffi", "--cfg", "hyper_unstable_tracing"
 [package.metadata.playground]
 features = ["full"]
 
+[package.metadata.capi.header]
+generation = false
+subdirectory = false
+
+[package.metadata.capi.install.include]
+asset = [{ from="capi/include/hyper.h" }]
+
 [profile.release]
 codegen-units = 1
 incremental = false
diff --git a/capi/README.md b/capi/README.md
index 0f88d31ee4..becd57862f 100644
--- a/capi/README.md
+++ b/capi/README.md
@@ -15,3 +15,11 @@ The C API is part of the Rust library, but isn't compiled by default. Using `car
 ```
 RUSTFLAGS="--cfg hyper_unstable_ffi" cargo rustc --features client,http1,http2,ffi --crate-type cdylib
 ```
+
+### (Optional) With `cargo-c`
+
+If using `cargo-c`, you can build and install a shared library with the following command:
+
+```
+RUSTFLAGS="--cfg hyper_unstable_ffi" cargo cbuild --features client,http1,http2,ffi --release
+```