diff --git a/CHANGELOG.md b/CHANGELOG.md index 58dc08ee7..db745520d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - #722 - boolean environment variables are evaluated as truthy or falsey. +- #721 - add support for running doctests on nightly if `CROSS_UNSTABLE_ENABLE_DOCTESTS=true`. - #718 - remove deb subcommand. - #714 - use host target directory when falling back to host cargo. - #713 - convert relative target directories to absolute paths. diff --git a/README.md b/README.md index 80f6f437a..fb76f317f 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,15 @@ passthrough = [ ] ``` +### Unstable Features + +Certain unstable features can enable additional functionality useful to +cross-compiling. Note that these are unstable, and may be removed at any +time (particularly if the feature is stabilized or removed), and will +only be used on a nightly channel. + +- `CROSS_UNSTABLE_ENABLE_DOCTESTS=true`: also run doctests. + ### Mounting volumes into the build environment In addition to passing environment variables, you can also specify environment diff --git a/src/cli.rs b/src/cli.rs index 6221324f8..ae461885d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -14,6 +14,7 @@ pub struct Args { pub target: Option, pub target_dir: Option, pub docker_in_docker: bool, + pub enable_doctests: bool, } // Fix for issue #581. target_dir must be absolute. @@ -85,6 +86,9 @@ pub fn parse(target_list: &TargetList) -> Result { let docker_in_docker = env::var("CROSS_DOCKER_IN_DOCKER") .map(|s| bool_from_envvar(&s)) .unwrap_or_default(); + let enable_doctests = env::var("CROSS_UNSTABLE_ENABLE_DOCTESTS") + .map(|s| bool::from_str(&s).unwrap_or_default()) + .unwrap_or_default(); Ok(Args { all, @@ -93,5 +97,6 @@ pub fn parse(target_list: &TargetList) -> Result { target, target_dir, docker_in_docker, + enable_doctests, }) } diff --git a/src/main.rs b/src/main.rs index ad7ca7f11..747bbe717 100644 --- a/src/main.rs +++ b/src/main.rs @@ -279,6 +279,7 @@ fn run() -> Result { let host_version_meta = rustc_version::version_meta().wrap_err("couldn't fetch the `rustc` version")?; + let is_nightly = rustc::is_nightly(&args.channel, &host_version_meta); if let Some(root) = cargo::root()? { let host = host_version_meta.host(); let toml = toml(&root)?; @@ -358,7 +359,7 @@ fn run() -> Result { .map(|sc| sc.needs_interpreter()) .unwrap_or(false); - let filtered_args = if args + let mut filtered_args = if args .subcommand .map_or(false, |s| !s.needs_target_in_command()) { @@ -384,6 +385,14 @@ fn run() -> Result { args.all.clone() }; + let is_test = args + .subcommand + .map(|sc| sc == Subcommand::Test) + .unwrap_or(false); + if is_test && args.enable_doctests && is_nightly { + filtered_args.push("-Zdoctest-xcompile".to_string()); + } + if target.needs_docker() && args.subcommand.map(|sc| sc.needs_docker()).unwrap_or(false) { if host_version_meta.needs_interpreter() diff --git a/src/rustc.rs b/src/rustc.rs index 49ef6e45e..562aa9a93 100644 --- a/src/rustc.rs +++ b/src/rustc.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use std::process::Command; -use rustc_version::{Version, VersionMeta}; +use rustc_version::{Channel, Version, VersionMeta}; use crate::errors::*; use crate::extensions::CommandExt; @@ -33,6 +33,14 @@ impl VersionMetaExt for VersionMeta { } } +pub fn is_nightly(channel: &Option, host_version_meta: &VersionMeta) -> bool { + if let Some(channel) = channel { + channel.contains("nightly") + } else { + host_version_meta.channel == Channel::Nightly + } +} + pub fn target_list(verbose: bool) -> Result { Command::new("rustc") .args(&["--print", "target-list"])