Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added env var to disable multi arch caching #1775

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ itertools = "0.10"
predicates = "=3.0.2"
thirtyfour_sync = "0.27"
serial_test = "2.0"
temp-env = "0.3.4"

[target.'cfg(unix)'.dependencies]
daemonize = "0.5"
Expand Down
5 changes: 4 additions & 1 deletion docs/Caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ In parallel, we also take into account in the hash:
For C/C++, the hash is generated with a blake3 digest of the preprocessed
file (-E with gcc/clang). For compilations that specify multiple `-arch` flags,
these flags are rewritten to their corresponding preprocessor defines to allow
pre-processing the file (e.g `-arch x86_64` is rewritten to `-D__X86_64__=1`).
pre-processing the file (e.g `-arch x86_64` is rewritten to `-D__X86_64__=1`),
this can be enabled by setting the environment variable
`SCCACHE_CACHE_MULTIARCH` but is disabled by default as it may not work in all
cases.

We also take into account in the hash:
* Hash of the compiler binary
Expand Down
1 change: 1 addition & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ configuration variables
* `SCCACHE_STARTUP_NOTIFY` specify a path to a socket which will be used for server completion notification
* `SCCACHE_MAX_FRAME_LENGTH` how much data can be transferred between client and server
* `SCCACHE_NO_DAEMON` set to `1` to disable putting the server to the background
* `SCCACHE_CACHE_MULTIARCH` to disable caching of multi architecture builds.

### cache configs

Expand Down
169 changes: 124 additions & 45 deletions src/compiler/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use fs::File;
use fs_err as fs;
use log::Level::Trace;
use std::collections::HashMap;
use std::env;
use std::ffi::OsString;
use std::io::Read;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -275,6 +276,8 @@ where
let mut outputs_gcno = false;
let mut xclangs: Vec<OsString> = vec![];
let mut color_mode = ColorMode::Auto;
let mut seen_arch = None;
let dont_cache_multiarch = env::var("SCCACHE_CACHE_MULTIARCH").is_err();

// Custom iterator to expand `@` arguments which stand for reading a file
// and interpreting it as a list of more arguments.
Expand Down Expand Up @@ -365,7 +368,17 @@ where
_ => cannot_cache!("-x"),
};
}
Some(Arch(_)) => {}
Some(Arch(arch)) => {
match seen_arch {
Some(s) if &s != arch && dont_cache_multiarch => {
Xuanwo marked this conversation as resolved.
Show resolved Hide resolved
cannot_cache!(
"multiple different -arch, and SCCACHE_CACHE_MULTIARCH not set"
)
}
_ => {}
};
seen_arch = Some(arch.clone());
}
Some(XClang(s)) => xclangs.push(s.clone()),
None => match arg {
Argument::Raw(ref val) => {
Expand Down Expand Up @@ -651,11 +664,20 @@ fn preprocess_cmd<T>(
})
.collect::<Vec<OsString>>();

let mut arch_args_to_use = &rewritten_arch_args;
let mut unique_rewritten = rewritten_arch_args.clone();
unique_rewritten.sort();
unique_rewritten.dedup();
if unique_rewritten.len() <= 1 {
// don't use rewritten arch args if there is only one arch
arch_args_to_use = &parsed_args.arch_args;
}

cmd.arg(&parsed_args.input)
.args(&parsed_args.preprocessor_args)
.args(&parsed_args.dependency_args)
.args(&parsed_args.common_args)
.args(&rewritten_arch_args)
.args(arch_args_to_use)
.env_clear()
.envs(env_vars.iter().map(|&(ref k, ref v)| (k, v)))
.current_dir(cwd);
Expand Down Expand Up @@ -884,6 +906,8 @@ mod test {
use crate::mock_command::*;
use crate::test::utils::*;

use temp_env::with_var;

fn parse_arguments_(
arguments: Vec<String>,
plusplus: bool,
Expand Down Expand Up @@ -1428,7 +1452,43 @@ mod test {

#[test]
fn test_preprocess_cmd_rewrites_archs() {
let args = stringvec!["-arch", "arm64", "-arch", "i386", "-c", "foo.cc"];
with_var("SCCACHE_CACHE_MULTIARCH", Some("1"), || {
let args = stringvec!["-arch", "arm64", "-arch", "i386", "-c", "foo.cc"];
let parsed_args = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
let mut cmd = MockCommand {
child: None,
args: vec![],
};
preprocess_cmd(
&mut cmd,
&parsed_args,
Path::new(""),
&[],
true,
CCompilerKind::Gcc,
true,
vec![],
);
// make sure the architectures were rewritten to prepocessor defines
let expected_args = ovec![
"-x",
"c++",
"-E",
"-fdirectives-only",
"foo.cc",
"-D__arm64__=1",
"-D__i386__=1"
];
assert_eq!(cmd.args, expected_args);
});
}

#[test]
fn test_preprocess_cmd_doesnt_rewrite_single_arch() {
let args = stringvec!["-arch", "arm64", "-c", "foo.cc"];
let parsed_args = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
Expand All @@ -1454,8 +1514,8 @@ mod test {
"-E",
"-fdirectives-only",
"foo.cc",
"-D__arm64__=1",
"-D__i386__=1"
"-arch",
"arm64"
];
assert_eq!(cmd.args, expected_args);
}
Expand Down Expand Up @@ -1681,6 +1741,22 @@ mod test {
);
}

#[test]
fn test_parse_arguments_multiarch_cache_disabled() {
assert_eq!(
CompilerArguments::CannotCache(
"multiple different -arch, and SCCACHE_CACHE_MULTIARCH not set",
None
),
parse_arguments_(
stringvec![
"-fPIC", "-arch", "arm64", "-arch", "i386", "-o", "foo.o", "-c", "foo.cpp"
],
false
)
)
}

#[test]
fn test_parse_arguments_multiple_arch() {
match parse_arguments_(
Expand All @@ -1691,47 +1767,50 @@ mod test {
o => panic!("Got unexpected parse result: {:?}", o),
}

match parse_arguments_(
stringvec!["-arch", "arm64", "-arch", "arm64", "-o", "foo.o", "-c", "foo.cpp"],
false,
) {
CompilerArguments::Ok(_) => {}
o => panic!("Got unexpected parse result: {:?}", o),
}
with_var("SCCACHE_CACHE_MULTIARCH", Some("1"), || {
match parse_arguments_(
stringvec!["-arch", "arm64", "-arch", "arm64", "-o", "foo.o", "-c", "foo.cpp"],
false,
) {
CompilerArguments::Ok(_) => {}
o => panic!("Got unexpected parse result: {:?}", o),
}

let args =
stringvec!["-fPIC", "-arch", "arm64", "-arch", "i386", "-o", "foo.o", "-c", "foo.cpp"];
let ParsedArguments {
input,
language,
compilation_flag,
outputs,
preprocessor_args,
msvc_show_includes,
common_args,
arch_args,
..
} = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
assert_eq!(Some("foo.cpp"), input.to_str());
assert_eq!(Language::Cxx, language);
assert_eq!(Some("-c"), compilation_flag.to_str());
assert_map_contains!(
outputs,
(
"obj",
ArtifactDescriptor {
path: "foo.o".into(),
optional: false
}
)
);
assert!(preprocessor_args.is_empty());
assert_eq!(ovec!["-fPIC"], common_args);
assert_eq!(ovec!["-arch", "arm64", "-arch", "i386"], arch_args);
assert!(!msvc_show_includes);
let args = stringvec![
"-fPIC", "-arch", "arm64", "-arch", "i386", "-o", "foo.o", "-c", "foo.cpp"
];
let ParsedArguments {
input,
language,
compilation_flag,
outputs,
preprocessor_args,
msvc_show_includes,
common_args,
arch_args,
..
} = match parse_arguments_(args, false) {
CompilerArguments::Ok(args) => args,
o => panic!("Got unexpected parse result: {:?}", o),
};
assert_eq!(Some("foo.cpp"), input.to_str());
assert_eq!(Language::Cxx, language);
assert_eq!(Some("-c"), compilation_flag.to_str());
assert_map_contains!(
outputs,
(
"obj",
ArtifactDescriptor {
path: "foo.o".into(),
optional: false
}
)
);
assert!(preprocessor_args.is_empty());
assert_eq!(ovec!["-fPIC"], common_args);
assert_eq!(ovec!["-arch", "arm64", "-arch", "i386"], arch_args);
assert!(!msvc_show_includes);
});
}

#[test]
Expand Down