diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d610309d..139b2ac6 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -9,3 +9,4 @@ - [Networking](net.md) - [Application development](app.md) - [Logging](logging.md) +- [Build Time Tooling](build_tools.md) diff --git a/src/build_tools.md b/src/build_tools.md new file mode 100644 index 00000000..18d8a290 --- /dev/null +++ b/src/build_tools.md @@ -0,0 +1,128 @@ +# Build Time Tooling + +This section covers "build-time" tooling, or code that is run prior to compiling a crate's source code. +Conventionally, build-time code lives in a **build.rs** file and is commonly referred to as a "build script". +Common use cases include rust code generation and compilation of bundled C/C++/asm code. +See crates.io's [documentation on the matter][build-script-docs] for more information. + + +| Recipe | Crates | Categories | +|--------|--------|------------| +| [Compile and link statically to a bundled C library][ex-cc-static-bundled] | [![cc-badge]][cc] | [![cat-development-tools-badge]][cat-development-tools] | + + +[ex-cc-static-bundled]: #ex-cc-static-bundled + +## Compile and link statically to a bundled C library + +[![cc-badge]][cc] [![cat-development-tools-badge]][cat-development-tools] + +To accommodate scenarios where additional C, C++, or assembly is required in a project, the [**cc**][cc] crate +offers a simple api for compiling bundled C/C++/asm code into static libraries (**.a**) that can be statically linked to by **rustc**. + +The following example has some bundled C code (**src/hello.c**) that will be used from rust. +Before compiling our rust source code, the "build" file (**build.rs**) specified in **Cargo.toml** will run. +Using the [**cc**][cc] crate, a static library file will be produced (in this case, **libhello.a**, see +[`compile` docs][cc-build-compile]) which can then be used from rust by declaring the external function signatures in an `extern` block. + +Since the bundled C is very simple, only a single source file needs to be passed to [`cc::Build`][cc-build]. +For more complex build requirements, [`cc::Build`][cc-build] offers a full suite of builder methods for specifying +[`include`][cc-build-include] paths and extra compiler [`flag`][cc-build-flag]s. + +### `Cargo.toml` + +```toml +[package] +... +build = "build.rs" + +[build-dependencies] +cc = "1" + +[dependencies] +error-chain = "0.11" +``` + +### `build.rs` + +```rust,no_run +extern crate cc; + +fn main() { + cc::Build::new() + .file("src/hello.c") + .compile("hello"); // outputs `libhello.a` +} +``` + +### `src/hello.c` + +```c +#include + + +void hello() { + printf("Hello from C!\n"); +} + +void greet(const char* name) { + printf("Hello, %s!\n", name); +} +``` + +### `src/main.rs` + +```rust,no_run +# #[macro_use] extern crate error_chain; +use std::ffi::CString; +use std::os::raw::c_char; + +# +# error_chain! { +# foreign_links { +# NulError(::std::ffi::NulError); +# Io(::std::io::Error); +# } +# } +# +# +# fn prompt(s: &str) -> Result { +# use std::io::Write; +# print!("{}", s); +# std::io::stdout().flush()?; +# let mut input = String::new(); +# std::io::stdin().read_line(&mut input)?; +# Ok(input.trim().to_string()) +# } +# + +extern { + fn hello(); + fn greet(name: *const c_char); +} + + +fn run() -> Result<()> { + unsafe { hello() } + let name = prompt("What's your name? ")?; + let c_name = CString::new(name)?; + unsafe { greet(c_name.as_ptr()) } + Ok(()) +} + +# +# quick_main!(run); +``` + + +{{#include links.md}} + + + +[build-script-docs]: http://doc.crates.io/build-script.html +[playground]: https://play.rust-lang.org +[cc-build]: https://docs.rs/cc/*/cc/struct.Build.html +[cc-build-include]: https://docs.rs/cc/*/cc/struct.Build.html#method.include +[cc-build-flag]: https://docs.rs/cc/*/cc/struct.Build.html#method.flag +[cc-build-compile]: https://docs.rs/cc/*/cc/struct.Build.html#method.compile + diff --git a/src/intro.md b/src/intro.md index 2b6f838e..5043942f 100644 --- a/src/intro.md +++ b/src/intro.md @@ -117,6 +117,13 @@ community. It needs and welcomes help. For details see | [Log to the Unix syslog][ex-log-syslog] | [![log-badge]][log] [![syslog-badge]][syslog] | [![cat-debugging-badge]][cat-debugging] | | [Log messages to a custom location][ex-log-custom] | [![log-badge]][log] | [![cat-debugging-badge]][cat-debugging] | +## [Build Time Tooling](build_tools.html) + +| Recipe | Crates | Categories | +|--------|--------|------------| +| [Compile and link statically to a bundled C library][ex-cc-static-bundled] | [![cc-badge]][cc] | [![cat-development-tools-badge]][cat-development-tools] | + + {{#include links.md}} @@ -125,6 +132,7 @@ community. It needs and welcomes help. For details see [ex-base64]: encoding.html#ex-base64 [ex-bitflags]: basics.html#ex-bitflags [ex-byteorder-le]: basics.html#ex-byteorder-le +[ex-cc-static-bundled]: build_tools.html#ex-cc-static-bundled [ex-clap-basic]: app.html#ex-clap-basic [ex-crossbeam-spawn]: concurrency.html#ex-crossbeam-spawn [ex-csv-serde]: encoding.html#ex-csv-serde diff --git a/src/links.md b/src/links.md index 9fa7a557..1f78dc65 100644 --- a/src/links.md +++ b/src/links.md @@ -17,6 +17,8 @@ Keep lines sorted. [cat-cryptography]: https://crates.io/categories/cryptography [cat-debugging-badge]: https://badge-cache.kominick.com/badge/debugging--x.svg?style=social [cat-debugging]: https://crates.io/categories/debugging +[cat-development-tools-badge]: https://badge-cache.kominick.com/badge/development_tools--x.svg?style=social +[cat-development-tools]: https://crates.io/categories/development-tools [cat-encoding-badge]: https://badge-cache.kominick.com/badge/encoding--x.svg?style=social [cat-encoding]: https://crates.io/categories/encoding [cat-filesystem-badge]: https://badge-cache.kominick.com/badge/filesystem--x.svg?style=social @@ -44,6 +46,8 @@ Keep lines sorted. [bitflags]: https://docs.rs/bitflags/ [byteorder-badge]: https://badge-cache.kominick.com/crates/v/byteorder.svg?label=byteorder [byteorder]: https://docs.rs/byteorder/ +[cc-badge]: https://badge-cache.kominick.com/crates/v/cc.svg?label=cc +[cc]: https://docs.rs/cc [chrono-badge]: https://badge-cache.kominick.com/crates/v/chrono.svg?label=chrono [chrono]: https://docs.rs/chrono/ [clap-badge]: https://badge-cache.kominick.com/crates/v/clap.svg?label=clap