Struct Build
struct Build { ... }
A builder for compilation of a native library.
A Build is the main type of the cc crate and is used to control all the
various configuration options and such of a compile. You'll find more
documentation on each method itself.
Implementations
impl Build
fn is_flag_supported<impl AsRef<OsStr>: AsRef<OsStr>>(self: &Self, flag: impl AsRef<OsStr>) -> Result<bool, Error>Run the compiler to test if it accepts the given flag.
For a convenience method for setting flags conditionally, see
flag_if_supported().It may return error if it's unable to run the compiler with a test file (e.g. the compiler is missing or a write to the
out_dirfailed).Note: Once computed, the result of this call is stored in the
known_flag_supportfield. Ifis_flag_supported(flag)is called again, the result will be read from the hash table.fn try_compile(self: &Self, output: &str) -> Result<(), Error>Run the compiler, generating the file
outputThis will return a result instead of panicking; see [
Self::compile()] for the complete description.fn compile(self: &Self, output: &str)Run the compiler, generating the file
outputLibrary name
The
outputstring argument determines the file name for the compiled library. The Rust compiler will create an assembly named "lib"+output+".a". MSVC will create a file named output+".lib".The choice of
outputis close to arbitrary, but:- must be nonempty,
- must not contain a path separator (
/), - must be unique across all
compileinvocations made by the same build script.
If your build script compiles a single source file, the base name of that source file would usually be reasonable:
cc::Build::new().file("blobstore.c").compile("blobstore");Compiling multiple source files, some people use their crate's name, or their crate's name + "-cc".
Otherwise, please use your imagination.
For backwards compatibility, if
outputstarts with "lib" and ends with ".a", a second "lib" prefix and ".a" suffix do not get added on, but this usage is deprecated; please omitliband.ain the argument that you pass.Panics
Panics if
outputis not formatted correctly or if one of the underlying compiler commands fails. It can also panic if it fails reading file names or creating directories.fn compile_intermediates(self: &Self) -> Vec<PathBuf>Run the compiler, generating intermediate files, but without linking them into an archive file.
This will return a list of compiled object files, in the same order as they were passed in as
file/filesmethods.fn try_compile_intermediates(self: &Self) -> Result<Vec<PathBuf>, Error>Run the compiler, generating intermediate files, but without linking them into an archive file.
This will return a result instead of panicking; see
compile_intermediates()for the complete description.fn try_expand(self: &Self) -> Result<Vec<u8>, Error>This will return a result instead of panicking; see [
Self::expand()] for the complete description.fn expand(self: &Self) -> Vec<u8>Run the compiler, returning the macro-expanded version of the input files.
This is only relevant for C and C++ files.
Panics
Panics if more than one file is present in the config, or if compiler path has an invalid file name.
Example
let out = cc::Build::new().file("src/foo.c").expand();fn get_compiler(self: &Self) -> ToolGet the compiler that's in use for this configuration.
This function will return a
Toolwhich represents the culmination of this configuration at a snapshot in time. The returned compiler can be inspected (e.g. the path, arguments, environment) to forward along to other tools, or theto_commandmethod can be used to invoke the compiler itself.This method will take into account all configuration such as debug information, optimization level, include directories, defines, etc. Additionally, the compiler binary in use follows the standard conventions for this path, e.g. looking at the explicitly set compiler, environment variables (a number of which are inspected here), and then falling back to the default configuration.
Panics
Panics if an error occurred while determining the architecture.
fn try_get_compiler(self: &Self) -> Result<Tool, Error>Get the compiler that's in use for this configuration.
This will return a result instead of panicking; see
get_compiler()for the complete description.fn get_archiver(self: &Self) -> CommandGet the archiver (ar) that's in use for this configuration.
You can use
Command::get_programto get just the path to the command.This method will take into account all configuration such as debug information, optimization level, include directories, defines, etc. Additionally, the compiler binary in use follows the standard conventions for this path, e.g. looking at the explicitly set compiler, environment variables (a number of which are inspected here), and then falling back to the default configuration.
Panics
Panics if an error occurred while determining the architecture.
fn try_get_archiver(self: &Self) -> Result<Command, Error>Get the archiver that's in use for this configuration.
This will return a result instead of panicking; see
Self::get_archiverfor the complete description.fn get_ranlib(self: &Self) -> CommandGet the ranlib that's in use for this configuration.
You can use
Command::get_programto get just the path to the command.This method will take into account all configuration such as debug information, optimization level, include directories, defines, etc. Additionally, the compiler binary in use follows the standard conventions for this path, e.g. looking at the explicitly set compiler, environment variables (a number of which are inspected here), and then falling back to the default configuration.
Panics
Panics if an error occurred while determining the architecture.
fn try_get_ranlib(self: &Self) -> Result<Command, Error>Get the ranlib that's in use for this configuration.
This will return a result instead of panicking; see
Self::get_ranlibfor the complete description.
impl Build
fn new() -> BuildConstruct a new instance of a blank set of configuration.
This builder is finished with the
compilefunction.fn include<P: AsRef<Path>>(self: &mut Self, dir: P) -> &mut BuildAdd a directory to the
-Ior include path for headersExample
use std::path::Path; let library_path = Path::new("/path/to/library"); cc::Build::new() .file("src/foo.c") .include(library_path) .include("src") .compile("foo");fn includes<P>(self: &mut Self, dirs: P) -> &mut Build where P: IntoIterator, <P as >::Item: AsRef<Path>Add multiple directories to the
-Iinclude path.Example
# use std::path::Path; # let condition = true; # let mut extra_dir = None; if condition { extra_dir = Some(Path::new("/path/to")); } cc::Build::new() .file("src/foo.c") .includes(extra_dir) .compile("foo");fn define<'a, V: Into<Option<&'a str>>>(self: &mut Self, var: &str, val: V) -> &mut BuildSpecify a
-Dvariable with an optional value.Example
cc::Build::new() .file("src/foo.c") .define("FOO", "BAR") .define("BAZ", None) .compile("foo");fn object<P: AsRef<Path>>(self: &mut Self, obj: P) -> &mut BuildAdd an arbitrary object file to link in
fn objects<P>(self: &mut Self, objs: P) -> &mut Build where P: IntoIterator, <P as >::Item: AsRef<Path>Add arbitrary object files to link in
fn flag<impl AsRef<OsStr>: AsRef<OsStr>>(self: &mut Self, flag: impl AsRef<OsStr>) -> &mut BuildAdd an arbitrary flag to the invocation of the compiler
Example
cc::Build::new() .file("src/foo.c") .flag("-ffunction-sections") .compile("foo");fn flags<Iter>(self: &mut Self, flags: Iter) -> &mut Build where Iter: IntoIterator, <Iter as >::Item: AsRef<OsStr>Add multiple flags to the invocation of the compiler. This is equivalent to calling
flagfor each item in the iterator.Example
cc::Build::new() .file("src/foo.c") .flags(["-Wall", "-Wextra"]) .compile("foo");fn remove_flag(self: &mut Self, flag: &str) -> &mut BuildRemoves a compiler flag that was added by
Build::flag.Will not remove flags added by other means (default flags, flags from env, and so on).
Example
new .file .flag .remove_flag;fn ar_flag<impl AsRef<OsStr>: AsRef<OsStr>>(self: &mut Self, flag: impl AsRef<OsStr>) -> &mut BuildAdd a flag to the invocation of the ar
Example
cc::Build::new() .file("src/foo.c") .file("src/bar.c") .ar_flag("/NODEFAULTLIB:libc.dll") .compile("foo");fn asm_flag<impl AsRef<OsStr>: AsRef<OsStr>>(self: &mut Self, flag: impl AsRef<OsStr>) -> &mut BuildAdd a flag that will only be used with assembly files.
The flag will be applied to input files with either a
.sor.asmextension (case insensitive).Example
cc::Build::new() .asm_flag("-Wa,-defsym,abc=1") .file("src/foo.S") // The asm flag will be applied here .file("src/bar.c") // The asm flag will not be applied here .compile("foo");fn flag_if_supported<impl AsRef<OsStr>: AsRef<OsStr>>(self: &mut Self, flag: impl AsRef<OsStr>) -> &mut BuildAdd an arbitrary flag to the invocation of the compiler if it supports it
Example
cc::Build::new() .file("src/foo.c") .flag_if_supported("-Wlogical-op") // only supported by GCC .flag_if_supported("-Wunreachable-code") // only supported by clang .compile("foo");fn try_flags_from_environment(self: &mut Self, environ_key: &str) -> Result<&mut Build, Error>Add flags from the specified environment variable.
Normally the
cccrate will consult with the standard set of environment variables (such asCFLAGSandCXXFLAGS) to construct the compiler invocation. Use of this method provides additional levers for the end user to use when configuring the build process.Just like the standard variables, this method will search for an environment variable with appropriate target prefixes, when appropriate.
Examples
This method is particularly beneficial in introducing the ability to specify crate-specific flags.
cc::Build::new() .file("src/foo.c") .try_flags_from_environment(concat!(env!("CARGO_PKG_NAME"), "_CFLAGS")) .expect("the environment variable must be specified and UTF-8") .compile("foo");fn shared_flag(self: &mut Self, shared_flag: bool) -> &mut BuildSet the
-sharedflag.This will typically be ignored by the compiler when calling [
Self::compile()] since it only produces static libraries.Example
// This will create a library named "liblibfoo.so.a" cc::Build::new() .file("src/foo.c") .shared_flag(true) .compile("libfoo.so");fn static_flag(self: &mut Self, static_flag: bool) -> &mut BuildSet the
-staticflag.This will typically be ignored by the compiler when calling [
Self::compile()] since it only produces static libraries.Example
cc::Build::new() .file("src/foo.c") .shared_flag(true) .static_flag(true) .compile("foo");fn no_default_flags(self: &mut Self, no_default_flags: bool) -> &mut BuildDisables the generation of default compiler flags. The default compiler flags may cause conflicts in some cross compiling scenarios.
Setting the
CRATE_CC_NO_DEFAULTSenvironment variable has the same effect as setting this totrue. The presence of the environment variable and the value ofno_default_flagswill be OR'd together.fn file<P: AsRef<Path>>(self: &mut Self, p: P) -> &mut BuildAdd a file which will be compiled
fn files<P>(self: &mut Self, p: P) -> &mut Build where P: IntoIterator, <P as >::Item: AsRef<Path>Add files which will be compiled
fn get_files(self: &Self) -> impl Iterator<Item = &Path>Get the files which will be compiled
fn cpp(self: &mut Self, cpp: bool) -> &mut BuildSet C++ support.
The other
cpp_*options will only become active if this is set totrue.The name of the C++ standard library to link is decided by:
- If
cpp_link_stdlibis set, use its value. - Else if the
CXXSTDLIBenvironment variable is set, use its value. - Else the default is
c++for OS X and BSDs,c++_sharedfor Android,Nonefor MSVC andstdc++for anything else.
- If
fn cuda(self: &mut Self, cuda: bool) -> &mut BuildSet CUDA C++ support.
Enabling CUDA will invoke the CUDA compiler, NVCC. While NVCC accepts the most common compiler flags, e.g.
-std=c++17, some project-specific flags might have to be prefixed with "-Xcompiler" flag, for example as.flag("-Xcompiler").flag("-fpermissive"). See the documentation fornvcc, the CUDA compiler driver, at https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/ for more information.If enabled, this also implicitly enables C++ support.
fn cudart(self: &mut Self, cudart: &str) -> &mut BuildLink CUDA run-time.
This option mimics the
--cudartNVCC command-line option. Just like the original it accepts{none|shared|static}, with default beingstatic. The method has to be invoked after.cuda(true), or not at all, if the default is right for the project.fn ccbin(self: &mut Self, ccbin: bool) -> &mut BuildSet CUDA host compiler.
By default, a
-ccbinflag will be passed to NVCC to specify the underlying host compiler. The value of-ccbinis the same as the chosen C++ compiler. This is not always desired, because NVCC might not support that compiler. In this case, you can remove the-ccbinflag so that NVCC will choose the host compiler by itself.fn std(self: &mut Self, std: &str) -> &mut BuildSpecify the C or C++ language standard version.
These values are common to modern versions of GCC, Clang and MSVC:
c11for ISO/IEC 9899:2011c17for ISO/IEC 9899:2018c++14for ISO/IEC 14882:2014c++17for ISO/IEC 14882:2017c++20for ISO/IEC 14882:2020
Other values have less broad support, e.g. MSVC does not support
c++11(c++14is the minimum),c89(omit the flag instead) orc99.For compiling C++ code, you should also set
.cpp(true).The default is that no standard flag is passed to the compiler, so the language version will be the compiler's default.
Example
cc::Build::new() .file("src/modern.cpp") .cpp(true) .std("c++17") .compile("modern");fn warnings_into_errors(self: &mut Self, warnings_into_errors: bool) -> &mut BuildSet warnings into errors flag.
Disabled by default.
Warning: turning warnings into errors only make sense if you are a developer of the crate using cc-rs. Some warnings only appear on some architecture or specific version of the compiler. Any user of this crate, or any other crate depending on it, could fail during compile time.
Example
cc::Build::new() .file("src/foo.c") .warnings_into_errors(true) .compile("libfoo.a");fn warnings(self: &mut Self, warnings: bool) -> &mut BuildSet warnings flags.
Adds some flags:
- "-Wall" for MSVC.
- "-Wall", "-Wextra" for GNU and Clang.
Enabled by default.
Example
cc::Build::new() .file("src/foo.c") .warnings(false) .compile("libfoo.a");fn extra_warnings(self: &mut Self, warnings: bool) -> &mut BuildSet extra warnings flags.
Adds some flags:
- nothing for MSVC.
- "-Wextra" for GNU and Clang.
Enabled by default.
Example
// Disables -Wextra, -Wall remains enabled: cc::Build::new() .file("src/foo.c") .extra_warnings(false) .compile("libfoo.a");fn cpp_link_stdlib<'a, V: Into<Option<&'a str>>>(self: &mut Self, cpp_link_stdlib: V) -> &mut BuildSet the standard library to link against when compiling with C++ support.
If the
CXXSTDLIBenvironment variable is set, its value will override the default value, but not the value explicitly set by calling this function.A value of
Noneindicates that no automatic linking should happen, otherwise cargo will link against the specified library.The given library name must not contain the
libprefix.Common values:
stdc++for GNUc++for Clangc++_sharedorc++_staticfor Android
Example
cc::Build::new() .file("src/foo.c") .shared_flag(true) .cpp_link_stdlib("stdc++") .compile("libfoo.so");fn cpp_link_stdlib_static(self: &mut Self, is_static: bool) -> &mut BuildForce linker to statically link C++ stdlib. By default cc-rs will emit rustc-link flag to link against system C++ stdlib (e.g. libstdc++.so, libc++.so) Provide value of
trueif linking against system library is not desiredNote that for
wasm32target C++ stdlib will always be linked staticallyExample
cc::Build::new() .file("src/foo.cpp") .cpp(true) .cpp_link_stdlib("stdc++") .cpp_link_stdlib_static(true) .compile("foo");fn cpp_set_stdlib<'a, V: Into<Option<&'a str>>>(self: &mut Self, cpp_set_stdlib: V) -> &mut BuildForce the C++ compiler to use the specified standard library.
Setting this option will automatically set
cpp_link_stdlibto the same value.The default value of this option is always
None.This option has no effect when compiling for a Visual Studio based target.
This option sets the
-stdlibflag, which is only supported by some compilers (clang, icc) but not by others (gcc). The library will not detect which compiler is used, as such it is the responsibility of the caller to ensure that this option is only used in conjunction with a compiler which supports the-stdlibflag.A value of
Noneindicates that no specific C++ standard library should be used, otherwise-stdlibis added to the compile invocation.The given library name must not contain the
libprefix.Common values:
stdc++for GNUc++for Clang
Example
cc::Build::new() .file("src/foo.c") .cpp_set_stdlib("c++") .compile("libfoo.a");fn target(self: &mut Self, target: &str) -> &mut BuildConfigures the
rustctarget this configuration will be compiling for.This will fail if using a target not in a pre-compiled list taken from
rustc +nightly --print target-list. The list will be updated periodically.You should avoid setting this in build scripts, target information will instead be retrieved from the environment variables
TARGETandCARGO_CFG_TARGET_*that Cargo sets.Example
cc::Build::new() .file("src/foo.c") .target("aarch64-linux-android") .compile("foo");fn host(self: &mut Self, host: &str) -> &mut BuildConfigures the host assumed by this configuration.
This option is automatically scraped from the
HOSTenvironment variable by build scripts, so it's not required to call this function.Example
cc::Build::new() .file("src/foo.c") .host("arm-linux-gnueabihf") .compile("foo");fn opt_level(self: &mut Self, opt_level: u32) -> &mut BuildConfigures the optimization level of the generated object files.
This option is automatically scraped from the
OPT_LEVELenvironment variable by build scripts, so it's not required to call this function.fn opt_level_str(self: &mut Self, opt_level: &str) -> &mut BuildConfigures the optimization level of the generated object files.
This option is automatically scraped from the
OPT_LEVELenvironment variable by build scripts, so it's not required to call this function.fn debug(self: &mut Self, debug: bool) -> &mut BuildConfigures whether the compiler will emit debug information when generating object files.
This option is automatically scraped from the
DEBUGenvironment variable by build scripts, so it's not required to call this function.fn debug_str(self: &mut Self, debug: &str) -> &mut BuildConfigures whether the compiler will emit debug information when generating object files.
This should be one of the values accepted by Cargo's
debugprofile setting, which cc-rs will try to map to the appropriate C compiler flag.This option is automatically scraped from the
DEBUGenvironment variable by build scripts, so it's not required to call this function.fn force_frame_pointer(self: &mut Self, force: bool) -> &mut BuildConfigures whether the compiler will emit instructions to store frame pointers during codegen.
This option is automatically enabled when debug information is emitted. Otherwise the target platform compiler's default will be used. You can use this option to force a specific setting.
fn out_dir<P: AsRef<Path>>(self: &mut Self, out_dir: P) -> &mut BuildConfigures the output directory where all object files and static libraries will be located.
This option is automatically scraped from the
OUT_DIRenvironment variable by build scripts, so it's not required to call this function.fn compiler<P: AsRef<Path>>(self: &mut Self, compiler: P) -> &mut BuildConfigures the compiler to be used to produce output.
This option is automatically determined from the target platform or a number of environment variables, so it's not required to call this function.
fn archiver<P: AsRef<Path>>(self: &mut Self, archiver: P) -> &mut BuildConfigures the tool used to assemble archives.
This option is automatically determined from the target platform or a number of environment variables, so it's not required to call this function.
fn ranlib<P: AsRef<Path>>(self: &mut Self, ranlib: P) -> &mut BuildConfigures the tool used to index archives.
This option is automatically determined from the target platform or a number of environment variables, so it's not required to call this function.
fn cargo_metadata(self: &mut Self, cargo_metadata: bool) -> &mut BuildDefine whether metadata should be emitted for cargo allowing it to automatically link the binary. Defaults to
true.The emitted metadata is:
rustc-link-lib=static=compiled librustc-link-search=native=target folder- When target is MSVC, the ATL-MFC libs are added via
rustc-link-search=native= - When C++ is enabled, the C++ stdlib is added via
rustc-link-lib - If
emit_rerun_if_env_changedis notfalse,rerun-if-env-changed=env
fn cargo_warnings(self: &mut Self, cargo_warnings: bool) -> &mut BuildDefine whether compile warnings should be emitted for cargo. Defaults to
true.If disabled, compiler messages will not be printed. Issues unrelated to the compilation will always produce cargo warnings regardless of this setting.
fn cargo_debug(self: &mut Self, cargo_debug: bool) -> &mut BuildDefine whether debug information should be emitted for cargo. Defaults to whether or not the environment variable
CC_ENABLE_DEBUG_OUTPUTis set.If enabled, the compiler will emit debug information when generating object files, such as the command invoked and the exit status.
fn cargo_output(self: &mut Self, cargo_output: bool) -> &mut BuildDefine whether compiler output (to stdout) should be emitted. Defaults to
true(forward compiler stdout to this process' stdout)Some compilers emit errors to stdout, so if you really need stdout to be clean you should also set this to
false.fn link_lib_modifier<impl AsRef<OsStr>: AsRef<OsStr>>(self: &mut Self, link_lib_modifier: impl AsRef<OsStr>) -> &mut BuildAdds a native library modifier that will be added to the
rustc-link-lib=static:MODIFIERS=LIBRARY_NAMEmetadata line emitted for cargo ifcargo_metadatais enabled. See https://doc.rust-lang.org/rustc/command-line-arguments.html#-l-link-the-generated-crate-to-a-native-library for the list of modifiers accepted by rustc.fn pic(self: &mut Self, pic: bool) -> &mut BuildConfigures whether the compiler will emit position independent code.
This option defaults to
falseforwindows-gnuand bare metal targets and totruefor all other targets.fn use_plt(self: &mut Self, use_plt: bool) -> &mut BuildConfigures whether the Procedure Linkage Table is used for indirect calls into shared libraries.
The PLT is used to provide features like lazy binding, but introduces a small performance loss due to extra pointer indirection. Setting
use_plttofalsecan provide a small performance increase.Note that skipping the PLT requires a recent version of GCC/Clang.
This only applies to ELF targets. It has no effect on other platforms.
fn emit_rerun_if_env_changed(self: &mut Self, emit_rerun_if_env_changed: bool) -> &mut BuildDefine whether metadata should be emitted for cargo to only trigger rebuild when detected environment changes, by default build script is always run on every compilation if no rerun cargo metadata is emitted.
NOTE that cc does not emit metadata to detect changes for
PATH, since it could be changed every compilation yet does not affect the result of compilation (i.e. rust-analyzer adds temporary directory toPATH).cc in general, has no way detecting changes to compiler, as there are so many ways to change it and sidestep the detection, for example the compiler might be wrapped in a script so detecting change of the file, or using checksum won't work.
We recommend users to decide for themselves, if they want rebuild if the compiler has been upgraded or changed, and how to detect that.
This has no effect if the
cargo_metadataoption isfalse.This option defaults to
true.fn static_crt(self: &mut Self, static_crt: bool) -> &mut BuildConfigures whether the /MT flag or the /MD flag will be passed to msvc build tools.
This option defaults to
false, and affect only msvc targets.fn shell_escaped_flags(self: &mut Self, shell_escaped_flags: bool) -> &mut BuildConfigure whether *FLAGS variables are parsed using
shlex, similarly tomakeandcmake.This option defaults to
false.fn inherit_rustflags(self: &mut Self, inherit_rustflags: bool) -> &mut BuildConfigure whether cc should automatically inherit compatible flags passed to rustc from
CARGO_ENCODED_RUSTFLAGS.This option defaults to
true.fn prefer_clang_cl_over_msvc(self: &mut Self, prefer_clang_cl_over_msvc: bool) -> &mut BuildPrefer to use clang-cl over msvc.
This option defaults to
false.
impl Clone for Build
fn clone(self: &Self) -> Build
impl Debug for Build
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<'_>) -> $crate::fmt::Result
impl Default for Build
fn default() -> Build
impl Freeze for Build
impl RefUnwindSafe for Build
impl Send for Build
impl Sync for Build
impl Unpin for Build
impl UnwindSafe for Build
impl<T> Any for Build
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for Build
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for Build
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for Build
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> From for Build
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for Build
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T, U> Into for Build
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for Build
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for Build
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>