• Stars
    star
    452
  • Rank 96,761 (Top 2 %)
  • Language
    Rust
  • License
    MIT License
  • Created over 5 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

build and install C-compatible libraries

Cargo C-ABI helpers

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

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.

cargo install cargo-c

The rustc version supported is the same as the one supported by the cargo version embedded in the package version, or as set in the rust-version field.

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"
# Used to disable the generation of additional import library file in platforms
# that have the concept such as Windows
import_library = false

Custom data install

[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"}]

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

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

Acknowledgements

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

More Repositories

1

bmdtools

Basic capture and play programs for Blackmagic Design Decklink
C++
198
star
2

mfx_dispatch

Intel media sdk dispatcher
C++
149
star
3

opus

pure rust opus decoder
Rust
41
star
4

autotools-rs

build.rs helper to configure and compile autotools and configure/make projects
Rust
23
star
5

rtmpdump

rtmpdump git mirror
C
15
star
6

cdylib-link-lines

Helper to build correctly cdylibs
Rust
13
star
7

tcptunnel

Simple udp -> tcp -> udp tunnel
Rust
10
star
8

crav1e

C-bindings for rav1e
Rust
10
star
9

libbmd

C wrapper over Blackmagic Devices Decklink C++ api
C++
9
star
10

nut

NUT container format documentation and reference implementation
C
7
star
11

plaid

Patchwork workalike made using Flask
Python
6
star
12

udev

Random experiments and study over udev stand-alone codebase
C
6
star
13

libvpx

Local libvpx changes (POWER8 Altivec/VSX support)
C
5
star
14

compiler_error

Triggerable compiler errors for rustc < 1.20
Rust
5
star
15

speed-levels-rs

Speed-levels benchmarking
Rust
5
star
16

autotools-cargo-example

Simple examples on how to wire in rust code built by cargo in an autotools-based project
M4
5
star
17

dvdtools

Random tools to edit DVD.
C
4
star
18

arg_enum_proc_macro

clap.rs arg_enum made procedural
Rust
4
star
19

vex

LibVEX mirror from valgrind.org svn
C
4
star
20

wait4-rs

Rust idiomatic wrapper around wait4
Rust
3
star
21

dolt

Fork of http://dolt.freedesktop.org/
3
star
22

net-tools

ifconfig, route and friends. In rust
Rust
3
star
23

valgrind

Mirror of valgrind svn - updated hourly
C
3
star
24

rustlab-it-2019

From C to Rust and Back
Rust
3
star
25

interpolate_name

Do not repeat yourself when writing tests
Rust
3
star
26

ffmpeg

OLD libav.org local topic branches please use my libav mirror now!
C
3
star
27

nvidia-video-codec

Redistributable headers to build cuvid and nvenc
C
2
star
28

fate-samples

git-lfs mirror
TypeScript
2
star
29

eselect

Gentoo eselect experiments
Shell
2
star
30

cow_struct

Derive per-field Cow Structures
Rust
2
star
31

noop_proc_macro

Does nothing with style
Rust
2
star
32

libav.org

CSS
2
star
33

avscale

AVScale proof of concept
C
2
star
34

testcase-wasi-alloc

Testcase for a strange allocation problem
Rust
1
star
35

rust-optimization-example

Code companion of a blog post about optimizing and rust
Rust
1
star
36

sz2019LiveVideoStack

rav1e 0.2.0 presentation during the LiveVideoStack 2019 Shenzhen event
1
star
37

moin-2.0

Git automirror of http://bitbucket.org/thomaswaldmann/moin-2.0
Python
1
star
38

capi-testcase

Small testcase regarding cbindgen signature generation
Rust
1
star
39

dav1d

C
1
star
40

aravis

Hack over Aravis
C
1
star
41

async-srt-rs

async bindings for srt
Rust
1
star
42

lz4

automirror of http://lz4.googlecode.com/svn/trunk/
C
1
star
43

code-bench

Benchmarking some multimedia loops
Rust
1
star
44

linuxday-2018

My presentation for the Turin Linuxday
1
star
45

moinmoin-bootstrap

moinmoin bootstrap theme
CSS
1
star
46

ndplus

NaturalDocPlus mirror
Perl
1
star
47

libdwarf-bsd

C
1
star
48

restreamer

Simple data 1->N restreamer
Rust
1
star