mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-22 03:23:05 +00:00
Add build time tooling section
issue #292 - Add new `build_tools.md` file/section - Add a simple `cc` crate example
This commit is contained in:
parent
04e18c0058
commit
403f9e6eca
4 changed files with 141 additions and 0 deletions
|
@ -9,3 +9,4 @@
|
|||
- [Networking](net.md)
|
||||
- [Application development](app.md)
|
||||
- [Logging](logging.md)
|
||||
- [Build Time Tooling](build_tools.md)
|
||||
|
|
128
src/build_tools.md
Normal file
128
src/build_tools.md
Normal file
|
@ -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
|
||||
<a name="ex-cc-static-bundled"></a>
|
||||
## 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 <stdio.h>
|
||||
|
||||
|
||||
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<String> {
|
||||
# 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}}
|
||||
|
||||
<!-- Other Reference -->
|
||||
|
||||
[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
|
||||
|
|
@ -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}}
|
||||
|
||||
<!-- Examples -->
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue