Need help with cargo-c?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

lu-zero
284 Stars 28 Forks MIT License 312 Commits 19 Opened issues

Description

build and install C-compatible libraries

Services available

!
?

Need anything else?

Contributors list

Cargo C-ABI helpers

LICENSE Crates.io Build Status cargo-c chat

cargo applet to build and install C-ABI compatible dynamic and static libraries.

It produces and installs a correct pkg-config file, a static library and a dynamic library, and a C header to be used by any C (and C-compatible) software.

Installation

cargo-c may be installed from crates.io.

sh
cargo install cargo-c

You must have the cargo build requirements satisfied in order to build cargo-c: *

git
*
pkg-config
(on Unix, used to figure out the host-provided headers/libraries) *
curl
(on Unix) * OpenSSL headers (only for Unix, this is the
libssl-dev
package on deb-based distributions)

You may pass

--features=vendored-openssl
if you have problems building openssl-sys using the host-provided OpenSSL.
cargo install cargo-c --features=vendored-openssl

Usage

# 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

For a more in-depth explanation of how

cargo-c
works and how to use it for your crates, read Building Crates so they Look Like C ABI Libraries.

The TL;DR:

  • Create a
    capi.rs
    with the C-API you want to expose and use ~~
    #[cfg(cargo_c)]
    ~~
    #[cfg(feature="capi")]
    to hide it when you build a normal rust library.
  • Make sure you have a lib target and if you are using a workspace the first member is the crate you want to export, that means that you might have to add a "." member at the start of the list.
  • ~~Since Rust 1.38, also add "staticlib" to the "lib"
    crate-type
    .~~ Do not specify the
    crate-type
    , cargo-c will add the correct library target by itself.
  • You may use the feature
    capi
    to add C-API-specific optional dependencies. > NOTE: It must be always present in
    Cargo.toml
  • Remember to add a
    cbindgen.toml
    and fill it with at least the include guard and probably you want to set the language to C (it defaults to C++)
  • Once you are happy with the result update your documentation to tell the user to install
    cargo-c
    and do
    cargo cinstall --prefix=/usr
    --destdir=/tmp/some-place
    or something along those lines.

Advanced

You may override various aspects of

cargo-c
via settings in
Cargo.toml
under the
package.metadata.capi
key
[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"

Header Generation

[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
File Generation

[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

Library Generation

[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
# 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"

Custom data install

[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}/{subdirectory}
assets = [{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}/{subdirectory}
generated = [{from="pattern/with/or/without/**/*", to="destination"]

Notes

Do not pass

RUSTFLAGS
that are managed by cargo through other means, (e.g. the flags driven by
[profiles]
or the flags driven by
[target.<>]
), cargo-c effectively builds as if the target is always explicitly passed.

Users

Status

  • [x] cli
    • [x] build command
    • [x] install command
    • [x] test command
    • [x] cargo applet support
  • [x] build targets
    • [x] pkg-config generation
    • [x] header generation (cbindgen integration)
  • [x]
    staticlib
    support
  • [x]
    cdylib
    support
  • [x] Generate version information in the header
    • [ ] Make it tunable
  • [x] Extra Cargo.toml keys
  • [x] Better status reporting

Acknowledgements

This software has been partially developed in the scope of the H2020 project SIFIS-Home with GA n. 952652.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.