72 个版本

0.10.3+cargo-0.81.02024 年 7 月 30 日
0.9.32+cargo-0.79.02024 年 5 月 4 日
0.9.31+cargo-0.78.02024 年 3 月 22 日
0.9.29+cargo-0.76.02023 年 12 月 29 日
0.2.1 2019 年 7 月 10 日

#24Cargo 插件

Download history 3114/week @ 2024-05-04 1680/week @ 2024-05-11 1570/week @ 2024-05-18 1502/week @ 2024-05-25 1841/week @ 2024-06-01 1581/week @ 2024-06-08 2861/week @ 2024-06-15 2521/week @ 2024-06-22 3523/week @ 2024-06-29 2748/week @ 2024-07-06 3010/week @ 2024-07-13 2649/week @ 2024-07-20 2940/week @ 2024-07-27 2457/week @ 2024-08-03 2825/week @ 2024-08-10 1337/week @ 2024-08-17

9,825 每月下载量
用于 cskk

MIT 许可证

110KB
2.5K SLoC

Cargo C-ABI 辅助程序

LICENSE Crates.io Build Status cargo-c chat dependency status

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一样构建。

用户

状态

  • cli
    • 构建命令
    • 安装命令
    • 测试命令
    • cargo applet支持
  • 构建目标
    • pkg-config生成
    • 头文件生成(cbindgen集成)
  • staticlib支持
  • cdylib支持
  • 在头文件中生成版本信息
    • 使其可调整
  • 额外的Cargo.toml键
  • 更好的状态报告

可用性

Packaging status

故障排除

在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-clibdir上的默认值在这种情况下是lib/<triplet>。可以通过传递显式的--libdir或传递--target来返回常见的libdir=lib默认值。

致谢

此软件部分在H2020项目SIFIS-Home的范围内开发,GA编号为952652。

依赖项

~87MB
~1.5M SLoC