Skip to content

Commit 0613e2a

Browse files
authored
Document CXXSTDLIB and change the Android default (#561)
* Change default C++ stdlib for Android to c++_shared and document it Closes #559. * Clean up documentation
1 parent a7b5e89 commit 0613e2a

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

README.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,31 @@ fn main() {
3333

3434
And that's it! Running `cargo build` should take care of the rest and your Rust
3535
application will now have the C files `foo.c` and `bar.c` compiled into a file
36-
named libfoo.a. You can call the functions in Rust by declaring functions in
36+
named `libfoo.a`. If the C files contain
37+
38+
```c
39+
void foo_function(void) { ... }
40+
```
41+
42+
and
43+
44+
```c
45+
int32_t bar_function(int32_t x) { ... }
46+
```
47+
48+
you can call them from Rust by declaring them in
3749
your Rust code like so:
3850

3951
```rust,no_run
4052
extern {
4153
fn foo_function();
42-
fn bar_function();
54+
fn bar_function(x: i32) -> i32;
4355
}
4456
4557
pub fn call() {
4658
unsafe {
4759
foo_function();
48-
bar_function();
60+
bar_function(42);
4961
}
5062
}
5163
@@ -54,14 +66,16 @@ fn main() {
5466
}
5567
```
5668

69+
See [the Rustonomicon](https://doc.rust-lang.org/nomicon/ffi.html) for more details.
70+
5771
## External configuration via environment variables
5872

5973
To control the programs and flags used for building, the builder can set a
6074
number of different environment variables.
6175

6276
* `CFLAGS` - a series of space separated flags passed to compilers. Note that
6377
individual flags cannot currently contain spaces, so doing
64-
something like: "-L=foo\ bar" is not possible.
78+
something like: `-L=foo\ bar` is not possible.
6579
* `CC` - the actual C compiler used. Note that this is used as an exact
6680
executable name, so (for example) no extra flags can be passed inside
6781
this variable, and the builder must ensure that there aren't any
@@ -70,6 +84,7 @@ number of different environment variables.
7084
common is `-fPIC`).
7185
* `AR` - the `ar` (archiver) executable to use to build the static library.
7286
* `CRATE_CC_NO_DEFAULTS` - the default compiler flags may cause conflicts in some cross compiling scenarios. Setting this variable will disable the generation of default compiler flags.
87+
* `CXX...` - see [C++ Support](#c-support).
7388

7489
Each of these variables can also be supplied with certain prefixes and suffixes,
7590
in the following prioritized order:
@@ -144,10 +159,25 @@ fn main() {
144159
}
145160
```
146161

147-
When using C++ library compilation switch, the `CXX` and `CXXFLAGS` env
148-
variables are used instead of `CC` and `CFLAGS` and the C++ standard library is
149-
linked to the crate target.
150-
Remember that C++ does name mangling so `extern "C"` might be required to enable rust linker to find your functions.
162+
For C++ libraries, the `CXX` and `CXXFLAGS` environment variables are used instead of `CC` and `CFLAGS`.
163+
164+
The C++ standard library may be linked to the crate target. By default it's `libc++` for OS X, FreeBSD, and OpenBSD, `libc++_shared` for Android, nothing for MSVC, and `libstdc++` for anything else. It can be changed in one of two ways:
165+
166+
1. by using the `cpp_link_stdlib` method on `Build`:
167+
```rust,no-run
168+
fn main() {
169+
cc::Build::new()
170+
.cpp(true)
171+
.file("foo.cpp")
172+
.cpp_link_stdlib("stdc++") // use libstdc++
173+
.compile("libfoo.a");
174+
}
175+
```
176+
2. by setting the `CXXSTDLIB` environment variable.
177+
178+
In particular, for Android you may want to [use `c++_static` if you have at most one shared library](https://developer.android.com/ndk/guides/cpp-support).
179+
180+
Remember that C++ does name mangling so `extern "C"` might be required to enable Rust linker to find your functions.
151181
152182
## CUDA C++ support
153183

src/lib.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ mod setup_config;
8181

8282
pub mod windows_registry;
8383

84-
/// A builder for compilation of a native static library.
84+
/// A builder for compilation of a native library.
8585
///
8686
/// A `Build` is the main type of the `cc` crate and is used to control all the
8787
/// various configuration options and such of a compile. You'll find more
@@ -684,11 +684,11 @@ impl Build {
684684
/// Set the standard library to link against when compiling with C++
685685
/// support.
686686
///
687-
/// The default value of this property depends on the current target: On
688-
/// OS X `Some("c++")` is used, when compiling for a Visual Studio based
689-
/// target `None` is used and for other targets `Some("stdc++")` is used.
687+
/// See [`get_cpp_link_stdlib`](cc::Build::get_cpp_link_stdlib) documentation
688+
/// for the default value.
690689
/// If the `CXXSTDLIB` environment variable is set, its value will
691-
/// override the default value.
690+
/// override the default value, but not the value explicitly set by calling
691+
/// this function.
692692
///
693693
/// A value of `None` indicates that no automatic linking should happen,
694694
/// otherwise cargo will link against the specified library.
@@ -698,6 +698,7 @@ impl Build {
698698
/// Common values:
699699
/// - `stdc++` for GNU
700700
/// - `c++` for Clang
701+
/// - `c++_shared` or `c++_static` for Android
701702
///
702703
/// # Example
703704
///
@@ -2241,8 +2242,11 @@ impl Build {
22412242
))
22422243
}
22432244

2244-
/// Returns the default C++ standard library for the current target: `libc++`
2245-
/// for OS X and `libstdc++` for anything else.
2245+
/// Returns the C++ standard library:
2246+
/// 1. If [cpp_link_stdlib](cc::Build::cpp_link_stdlib) is set, uses its value.
2247+
/// 2. Else if the `CXXSTDLIB` environment variable is set, uses its value.
2248+
/// 3. Else the default is `libc++` for OS X and BSDs, `libc++_shared` for Android,
2249+
/// `None` for MSVC and `libstdc++` for anything else.
22462250
fn get_cpp_link_stdlib(&self) -> Result<Option<String>, Error> {
22472251
match self.cpp_link_stdlib.clone() {
22482252
Some(s) => Ok(s),
@@ -2263,6 +2267,8 @@ impl Build {
22632267
Ok(Some("c++".to_string()))
22642268
} else if target.contains("openbsd") {
22652269
Ok(Some("c++".to_string()))
2270+
} else if target.contains("android") {
2271+
Ok(Some("c++_shared".to_string()))
22662272
} else {
22672273
Ok(Some("stdc++".to_string()))
22682274
}

0 commit comments

Comments
 (0)