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.85k stars 552 forks source link

sccache doesn't seem to support wrapping ar, something that regular ccache seems to be able to do. #550

Open emilio opened 5 years ago

emilio commented 5 years ago

It seems this used to work, somehow. This broke Servo's build with sccache, see https://github.com/servo/servo/pull/24491.

STR:

$ sccache --version
sccache 0.2.12
$ sccache ar
$ sccache ar -x libfoo.a
error: failed to execute compile
caused by: Compiler not supported: "/usr/bin/ar: invalid option -- \'E\'\nUsage: /usr/bin/ar [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file...\n       /usr/bin/ar -M [<mri-script]\n commands:\n  d            - delete file(s) from the archive\n  m[ab]        - move file(s) in the archive\n  p            - print file(s) found in the archive\n  q[f]         - quick append file(s) to the archive\n  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n  s            - act as ranlib\n  t[O][v]      - display contents of the archive\n  x[o]         - extract file(s) from the archive\n command specific modifiers:\n  [a]          - put file(s) after [member-name]\n  [b]          - put file(s) before [member-name] (same as [i])\n  [D]          - use zero for timestamps and uids/gids\n  [U]          - use actual timestamps and uids/gids (default)\n  [N]          - use instance [count] of name\n  [f]          - truncate inserted file names\n  [P]          - use full path names when matching\n  [o]          - preserve original dates\n  [O]          - display offsets of files in the archive\n  [u]          - only replace files that are newer than current archive contents\n generic modifiers:\n  [c]          - do not warn if the library had to be created\n  [s]          - create an archive index (cf. ranlib)\n  [S]          - do not build a symbol table\n  [T]          - make a thin archive\n  [v]          - be verbose\n  [V]          - display the version number\n  @<file>      - read options from <file>\n  --target=BFDNAME - specify the target object format as BFDNAME\n optional:\n  --plugin <p> - load the specified plugin\n emulation options: \n  No emulation specific options\n/usr/bin/ar: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex\n"

With older sccache, I get the expected output:

$ wget https://github.com/mozilla/sccache/releases/download/0.2.7/sccache-0.2.7-x86_64-unknown-linux-musl.tar.gz
$ ./sccache-0.2.7-x86_64-unknown-linux-musl/sccache ar -x libfoo.a                                                                                                                                                                         
/usr/bin/ar: libfoo.a: No such file or directory

Servo isn't the only project that was using CCACHE=sccache and relying on sccache to work as ccache does.

See https://github.com/servo/skia/pull/180 / https://github.com/EOSIO/eosio.cdt/commit/d70cfd0ac707ad3cb4f82996f5c9ca632c6e98ea

emilio commented 5 years ago

ccache seems to just forward everything that doesn't quack as a compiler I guess:

$ ccache echo "foo"
foo
emilio commented 5 years ago

I was going to send a patch just handling the compile locally, but this looks like intentional, per caf08a7fd2d4449d7c6299c21c991721be38c8e4.

@luser do you know to what extent we care about ccache parity / this case? I'm ok wontfixing this I guess, though it seems to have caused problems.

luser commented 5 years ago

It looks like when ccache's argument parsing fails it calls failed: https://github.com/ccache/ccache/blob/8bf69a1dd9dec1d3f8bcd161b50c86924b9bc464/src/ccache.cpp#L3785-L3788

which just runs the command as-is: https://github.com/ccache/ccache/blob/8bf69a1dd9dec1d3f8bcd161b50c86924b9bc464/src/ccache.cpp#L326-L340

I made this change in sccache because we actually hit this case when switching to clang-cl on Windows builds--sccache decided it was an unsupported compiler and we were failing to cache, but we weren't reporting those stats anywhere so we didn't notice until much later. I'd be fine with providing an opt-out environment variable here, but also what part of the servo build system is running ccache ar? That isn't ever going to be useful.

SimonSapin commented 5 years ago

This happened when using set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK sccache) in CMake while compiling a C++ library. This appears to be something built-in to CMake.

luser commented 5 years ago

Ah! You should remove that. ccache doesn't cache linker invocations either so it's not actually doing anyone any good. Some light Googling for RULE_LAUNCH_LINK turned up this blog post which says the same thing: https://crascit.com/2016/04/09/using-ccache-with-cmake/

emilio commented 5 years ago

Yeah, it is the accepted answer here too: https://stackoverflow.com/questions/1815688/how-to-use-ccache-with-cmake