72 个版本
0.10.3+cargo-0.81.0 | 2024 年 7 月 30 日 |
---|---|
0.9.32+cargo-0.79.0 | 2024 年 5 月 4 日 |
0.9.31+cargo-0.78.0 | 2024 年 3 月 22 日 |
0.9.29+cargo-0.76.0 | 2023 年 12 月 29 日 |
0.2.1 | 2019 年 7 月 10 日 |
#24 在 Cargo 插件
9,825 每月下载量
用于 cskk
110KB
2.5K SLoC
Cargo C-ABI 辅助程序
cargo 小程序,用于构建和安装与 C-ABI 兼容的动态和静态库。
它生成并安装正确的 pkg-config 文件、静态库和动态库,以及一个 C 头文件,供任何 C(和 C 兼容)软件使用。
安装
cargo-c 可以从 crates.io 安装。
cargo install cargo-c
支持的 rustc
版本与包版本中嵌入的 cargo
版本支持的版本相同,或者与在 rust-version 字段中设置的版本相同。
为了构建 cargo-c,您必须满足 cargo 构建的要求
git
pkg-config
(在 Unix 上,用于确定主机提供的头文件/库)curl
(在 Unix 上)- OpenSSL 头文件(仅限 Unix,这是基于 deb 的发行版上的
libssl-dev
包)
如果您在构建 openssl-sys 时使用主机提供的 OpenSSL 遇到问题,可以传递 --features=vendored-openssl
cargo install cargo-c --features=vendored-openssl
用法
# build the library, create the .h header, create the .pc file
$ cargo cbuild --destdir=${D} --prefix=/usr --libdir=/usr/lib64
# build the library, create the .h header, create the .pc file, build and run the tests
$ cargo ctest
# build the library, create the .h header, create the .pc file and install all of it
$ cargo cinstall --destdir=${D} --prefix=/usr --libdir=/usr/lib64
要深入了解 cargo-c
的工作原理以及如何将其用于您的软件包,请阅读 构建看起来像 C ABI 库的软件包。
简要说明
- 创建一个包含您希望公开的C-API的
capi.rs
文件,并使用#[cfg(cargo_c)]
#[cfg(feature="capi")]
来在构建普通的Rust库时隐藏它。 - 确保您有一个lib目标,如果您正在使用一个工作区,第一个成员是您想要导出的crate,这意味着您可能需要在列表的开头添加一个"."成员。
由于Rust 1.38,还需要将"staticlib"添加到"lib"不要指定crate-type
。crate-type
,cargo-c将自动添加正确的库目标。- 您可以使用
capi
功能添加C-API特定的可选依赖。注意:它必须在
Cargo.toml
中始终存在 - 请记住添加一个
cbindgen.toml
并将其至少包含include guard,并且您可能希望将语言设置为C(默认为C++) - 一旦您对结果满意,更新您的文档,告诉用户安装
cargo-c
并执行cargo cinstall --prefix=/usr --destdir=/tmp/some-place
或类似的内容。
高级
您可以通过在Cargo.toml
中的package.metadata.capi
键下设置来覆盖cargo-c
的各个方面
[package.metadata.capi]
# Configures the minimum required cargo-c version. Trying to run with an
# older version causes an error.
min_version = "0.6.10"
头文件生成
[package.metadata.capi.header]
# Used as header file name. By default this is equal to the crate name.
# The name can be with or without the header filename extension `.h`
name = "new_name"
# Install the header into a subdirectory with the name of the crate. This
# is enabled by default, pass `false` or "" to disable it.
subdirectory = "libfoo-2.0/foo"
# Generate the header file with `cbindgen`, or copy a pre-generated header
# from the `assets` subdirectory. By default a header is generated.
generation = true
# Can be use to disable header generation completely.
# This can be used when generating dynamic modules instead of an actual library.
enabled = true
pkg-config
文件生成
[package.metadata.capi.pkg_config]
# Used as the package name in the pkg-config file and defaults to the crate name.
name = "libfoo"
# Used as the pkg-config file name and defaults to the crate name.
filename = "libfoo-2.0"
# Used as the package description in the pkg-config file and defaults to the crate description.
description = "some description"
# Used as the package version in the pkg-config file and defaults to the crate version.
version = "1.2.3"
# Used as the Requires field in the pkg-config file, if defined
requires = "gstreamer-1.0, gstreamer-base-1.0"
# Used as the Requires.private field in the pkg-config file, if defined
requires_private = "gobject-2.0, glib-2.0 >= 2.56.0, gmodule-2.0"
# Strip the include search path from the last n components, useful to support installing in a
# subdirectory but then include with the path. By default it is 0.
strip_include_path_components = 1
库生成
[package.metadata.capi.library]
# Used as the library name and defaults to the crate name. This might get
# prefixed with `lib` depending on the target platform.
name = "new_name"
# Used as library version and defaults to the crate version. How this is used
# depends on the target platform.
version = "1.2.3"
# Used to install the library to a subdirectory of `libdir`.
install_subdir = "gstreamer-1.0"
# Used to disable versioning links when installing the dynamic library
versioning = false
# Instead of using semver, select a fixed number of version components for your SONAME version suffix:
# Setting this to 1 with a version of 0.0.0 allows a suffix of `.so.0`
# Setting this to 3 always includes the full version in the SONAME (indicate any update is ABI breaking)
#version_suffix_components = 2
# Add `-Cpanic=abort` to the RUSTFLAGS automatically, it may be useful in case
# something might panic in the crates used by the library.
rustflags = "-Cpanic=abort"
# Used to disable the generation of additional import library file in platforms
# that have the concept such as Windows
import_library = false
自定义数据安装
[package.metadata.capi.install.data]
# Used to install the data to a subdirectory of `datadir`. By default it is the same as `name`
subdirectory = "foodata"
# Copy the pre-generated data files found in {root_dir}/{from} to {datadir}/{to}/{matched subdirs}
# If {from} is a single path instead of a glob, the destination is {datapath}/{to}.
# datapath is {datadir}/{subdirectory}
asset = [{from="pattern/with/or/without/**/*", to="destination"}]
# Copy the pre-generated data files found in {OUT_DIR}/{from} to {includedir}/{to}/{matched subdirs}
# If {from} is a single path instead of a glob, the destination is {datapath}/{to}.
# datapath is {datadir}/{subdirectory}
generated = [{from="pattern/with/or/without/**/*", to="destination"}]
[package.metadata.capi.install.include]
# Copy the pre-generated includes found in {root_dir}/{from} to {includedir}/{to}/{matched subdirs}
# If {from} is a single path instead of a glob, the destination is {includepath}/{to}.
# includepath is {includedir}/{header.subdirectory}
asset = [{from="pattern/with/or/without/**/*", to="destination"}]
# Copy the pre-generated includes found in {OUT_DIR}/{from} to {includedir}/{to}/{matched subdirs}
# If {from} is a single path instead of a glob, the destination is {includedpath}/{to}.
# includepath is {includedir}/{header.subdirectory}
generated = [{from="pattern/with/or/without/**/*", to="destination"}]
注意
不要传递由cargo通过其他方式管理的RUSTFLAGS
,例如由[profiles]
或由[target.<>]
驱动的标志),cargo-c实际上会像始终明确传递target一样构建。
用户
- ebur128
- gcode-rs
- gst-plugins-rs
- lewton
- libdovi
- libimagequant
- rav1e
- rustls-ffi
- sled
- pathfinder
- udbserver
状态
- cli
- 构建命令
- 安装命令
- 测试命令
- cargo applet支持
- 构建目标
- pkg-config生成
- 头文件生成(cbindgen集成)
-
staticlib
支持 -
cdylib
支持 - 在头文件中生成版本信息
- 使其可调整
- 额外的Cargo.toml键
- 更好的状态报告
可用性
故障排除
在musl系统上不构建共享库
在基于musl的系统(例如Alpine Linux)上运行时,使用cdylib
库类型可能会导致以下错误(如此处所报告的)
错误:CliError { error: Some(cannot produce cdylib for as the target x86_64-unknown-linux-musl does not support these crate types), exit_code: 101 }
这表明Rust没有使用crt-static=false
构建,通常发生在通过rustup安装Rust时。
在这种情况下,可以通过编辑文件.cargo/config
来手动启用共享库
# .cargo/config
[target.x86_64-unknown-linux-musl]
rustflags = [
"-C", "target-feature=-crt-static",
]
然而,建议通过系统包管理器安装Rust而不是使用rustup(例如使用apk add rust
),因为提供的包应该已经处理了这个问题(例如,请参阅此处)。
在类似Debian的系统上,libdir默认包含主机三元组
为了适应Debian的多架构方法,cargo-c
在libdir
上的默认值在这种情况下是lib/<triplet>
。可以通过传递显式的--libdir
或传递--target
来返回常见的libdir=lib
默认值。
致谢
此软件部分在H2020项目SIFIS-Home的范围内开发,GA编号为952652。
依赖项
~87MB
~1.5M SLoC