diff --git a/src/compiler/gcc.rs b/src/compiler/gcc.rs index f987e0ce02..892380e678 100644 --- a/src/compiler/gcc.rs +++ b/src/compiler/gcc.rs @@ -575,6 +575,9 @@ where }; if split_dwarf { let dwo = output.with_extension("dwo"); + common_args.push(OsString::from( + "-D_gsplit_dwarf_path=".to_owned() + dwo.to_str().unwrap(), + )); // -gsplit-dwarf doesn't guarantee .dwo file if no -g is specified outputs.insert( "dwo", @@ -1075,6 +1078,9 @@ mod test { CompilerArguments::Ok(args) => args, o => panic!("Got unexpected parse result: {:?}", o), }; + let mut common_and_arch_args = common_args.clone(); + common_and_arch_args.extend(common_args.to_vec()); + debug!("common_and_arch_args: {:?}", common_and_arch_args); assert_eq!(Some("foo.cpp"), input.to_str()); assert_eq!(Language::Cxx, language); assert_map_contains!( @@ -1095,7 +1101,10 @@ mod test { ) ); assert!(preprocessor_args.is_empty()); - assert_eq!(ovec!["-gsplit-dwarf"], common_args); + assert!( + common_args.contains(&"-gsplit-dwarf".into()) + && common_args.contains(&"-D_gsplit_dwarf_path=foo.dwo".into()) + ); assert!(!msvc_show_includes); } diff --git a/tests/system.rs b/tests/system.rs index 386805a24b..1f455acac6 100644 --- a/tests/system.rs +++ b/tests/system.rs @@ -438,6 +438,77 @@ int main(int argc, char** argv) { }); } +/* test case like this: + echo "int test(){}" > test.cc + mkdir o1 o2 + sccache g++ -c -g -gsplit-dwarf test.cc -o test1.o + sccache g++ -c -g -gsplit-dwarf test.cc -o test1.o --- > cache hit + sccache g++ -c -g -gsplit-dwarf test.cc -o test2.o --- > cache miss + strings test2.o |grep test2.dwo +*/ +fn test_split_dwarf_object_generate_output_dir_changes(compiler: Compiler, tempdir: &Path) { + let Compiler { + name, + exe, + env_vars, + } = compiler; + trace!("test -g -gsplit-dwarf with different output"); + zero_stats(); + const SRC: &str = "source.c"; + write_source( + tempdir, + SRC, + "int test(){}", + ); + let mut args = compile_cmdline(name, exe.clone(), SRC, "test1.o", Vec::new()); + args.extend(vec_from!(OsString, "-g")); + args.extend(vec_from!(OsString, "-gsplit-dwarf")); + trace!("compile source.c (1)"); + sccache_command() + .args(&args) + .current_dir(tempdir) + .envs(env_vars.clone()) + .assert() + .success(); + get_stats(|info| { + assert_eq!(0, info.stats.cache_hits.all()); + assert_eq!(1, info.stats.cache_misses.all()); + assert_eq!(&1, info.stats.cache_misses.get("C/C++").unwrap()); + }); + // Compile the same source again to ensure we can get a cache hit. + trace!("compile source.c (2)"); + sccache_command() + .args(&args) + .current_dir(tempdir) + .envs(env_vars.clone()) + .assert() + .success(); + get_stats(|info| { + assert_eq!(1, info.stats.cache_hits.all()); + assert_eq!(1, info.stats.cache_misses.all()); + assert_eq!(&1, info.stats.cache_hits.get("C/C++").unwrap()); + assert_eq!(&1, info.stats.cache_misses.get("C/C++").unwrap()); + }); + // Compile the same source again with different output + // to ensure we can force generate new object file. + let mut args2 = compile_cmdline(name, exe, SRC, "test2.o", Vec::new()); + args2.extend(vec_from!(OsString, "-g")); + args2.extend(vec_from!(OsString, "-gsplit-dwarf")); + trace!("compile source.c (2)"); + sccache_command() + .args(&args2) + .current_dir(tempdir) + .envs(env_vars.clone()) + .assert() + .success(); + get_stats(|info| { + assert_eq!(1, info.stats.cache_hits.all()); + assert_eq!(2, info.stats.cache_misses.all()); + assert_eq!(&1, info.stats.cache_hits.get("C/C++").unwrap()); + assert_eq!(&2, info.stats.cache_misses.get("C/C++").unwrap()); + }); +} + fn test_gcc_clang_no_warnings_from_macro_expansion(compiler: Compiler, tempdir: &Path) { let Compiler { name, @@ -505,6 +576,7 @@ fn run_sccache_command_tests(compiler: Compiler, tempdir: &Path, preprocessor_ca } if compiler.name == "clang" || compiler.name == "gcc" { test_gcc_clang_no_warnings_from_macro_expansion(compiler.clone(), tempdir); + test_split_dwarf_object_generate_output_dir_changes(compiler.clone(), tempdir); } if compiler.name == "clang++" { test_clang_multicall(compiler.clone(), tempdir);