mozilla / sccache

Sccache is a ccache-like tool. It is used as a compiler wrapper and avoids compilation when possible. Sccache has the capability to utilize caching in remote storage environments, including various cloud storage options, or alternatively, in local storage.
Apache License 2.0
5.83k stars 548 forks source link

Seeing reason "multiple input files" although only a single file is given #1899

Open exoosh opened 1 year ago

exoosh commented 1 year ago

In the log file I see this when attempting to use sccache on OpenSSL (1.1.1w):

parse_arguments: CannotCache(multiple input files, ["crypto\asn1\x_sig.c"]): ["/MT", "/Zl", "/Gs0", "/GF", "/Gy", "/W3", "/wd4090", "/nologo", "/O2", "/I", ".", "/I", "include", "-DL_ENDIAN", "-DOPENSSL_PIC", "-DOPENSSL_CPUID_OBJ", "-DOPENSSL_BN_ASM_PART_WORDS", "-DOPENSSL_IA32_SSE2", "-DOPENSSL_BN_ASM_MONT", "-DOPENSSL_BN_ASM_GF2m", "-DSHA1_ASM", "-DSHA256_ASM", "-DSHA512_ASM", "-DRC4_ASM", "-DMD5_ASM", "-DRMD160_ASM", "-DAESNI_ASM", "-DVPAES_ASM", "-DWHIRLPOOL_ASM", "-DGHASH_ASM", "-DECP_NISTZ256_ASM", "-DPOLY1305_ASM", "-DOPENSSLDIR=\"C:\\Program Files (x86)\\Common Files\\SSL\"", "-DENGINESDIR=\"C:\\Program Files (x86)\\OpenSSL\\lib\\engines-1_1\"", "-DOPENSSL_SYS_WIN32", "-DWIN32_LEAN_AND_MEAN", "-DUNICODE", "-D_UNICODE", "-D_CRT_SECURE_NO_DEPRECATE", "-D_WINSOCK_DEPRECATED_NO_WARNINGS", "-DNDEBUG", "-DOPENSSL_API_COMPAT=0x10100000L", "-c", "/Focrypto\asn1\x_sig.obj", "crypto\asn1\x_sig.c"]

As you can see /Fo agrees with the name passed for the translation unit. Why is it not cacheable then?

assarbad commented 1 year ago

Turns out the reason "multiple input files" is totally misleading, unfortunately.

Instead the switches /Zl (that's a small L) to omit the default library name and /d1trimfile: to trim the leading path for the __FILE__ and aid in reproducibility was the blocker for this to cache nicely!

Here's a patch to resolve the issue, although admittedly I am not enough acquainted with the code to judge whether this makes sense or whether instead of PathBuf an OsString should have been used etc.

diff --git a/src/compiler/msvc.rs b/src/compiler/msvc.rs
index 7298d93..ac200ac 100644
--- a/src/compiler/msvc.rs
+++ b/src/compiler/msvc.rs
@@ -458,6 +458,7 @@ msvc_args!(static ARGS: [ArgInfo<ArgData>; _] = [
     msvc_take_arg!("Zc:", OsString, Concatenated, PassThroughWithSuffix),
     msvc_flag!("Ze", PassThrough),
     msvc_flag!("Zi", DebugInfo),
+    msvc_flag!("Zl", PassThrough), // omit default library name in .obj
     msvc_take_arg!("Zm", OsString, Concatenated, PassThroughWithSuffix),
     msvc_flag!("Zo", PassThrough),
     msvc_flag!("Zo-", PassThrough),
@@ -479,6 +480,7 @@ msvc_args!(static ARGS: [ArgInfo<ArgData>; _] = [
     msvc_flag!("clr", PassThrough),
     msvc_take_arg!("clr:", OsString, Concatenated, PassThroughWithSuffix),
     msvc_take_arg!("constexpr:", OsString, Concatenated, PassThroughWithSuffix),
+    msvc_take_arg!("d1trimfile:", PathBuf, Concatenated, PreprocessorArgumentPath), // used to trim leading path for __FILE__ macro: see https://stackoverflow.com/questions/8487986/file-macro-shows-full-path
     msvc_take_arg!("deps", PathBuf, Concatenated, DepFile),
     msvc_take_arg!("diagnostics:", OsString, Concatenated, PassThroughWithSuffix),
     msvc_take_arg!("doc", PathBuf, Concatenated, TooHardPath), // Creates an .xdc file.

I confirmed that this works and it works nicely.

Rationale for using PreprocessorArgumentPath: without knowing too much of the innards of sccache I went by the assumption that much like /D affects the outcome of the preprocess step, so does /d1trimfile:. Consequently it should fall into this category, I thought.

PS: I am also actively working on discovering further compiler and linker switches and I plan to go through the list hardcoded into sccache once I am done over there.