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.69k stars 540 forks source link

sccache chooses the -x flag to the compiler based on extension only #748

Open mathstuf opened 4 years ago

mathstuf commented 4 years ago

I'm seeing this affecting a line like this:

sccache /usr/bin/c++    -o CMakeFiles/SetLang.dir/bar.c.o -c "/builds/gitlab-kitware-cmake ci/Tests/SetLang/bar.c"
/builds/gitlab-kitware-cmake ci/Tests/SetLang/bar.c:4:1: error: unknown type name 'class'
    4 | class A
      | ^~~~~
/builds/gitlab-kitware-cmake ci/Tests/SetLang/bar.c:5:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
    5 | {
      | ^
/builds/gitlab-kitware-cmake ci/Tests/SetLang/bar.c: In function 'main':
/builds/gitlab-kitware-cmake ci/Tests/SetLang/bar.c:13:3: error: unknown type name 'A'
   13 |   A a;
      |   ^
/builds/gitlab-kitware-cmake ci/Tests/SetLang/bar.c:14:8: error: request for member 'i' in something not a structure or union
   14 |   if (a.i == 21) {
      |        ^

Should sccache choose the -x flag based on the compiler used rather than the extension? If the compiler is ambiguous or unknown to be a specific language, the extension can then be used.

Related: #163 (@luser @glandium @mikeconley @rillian) Related: ee10eae2ea4b9fed663400836acb508840f20d0a

Full log of the test: https://open.cdash.org/testDetails.php?test=883197977&build=6530941

froydnj commented 4 years ago

g++ seems to always compile as C++; clang++ gives a warning (clang 9.0-ish), but compiles as C++ anyway. I guess we should be compatible with this behavior, then.

robertmaynard commented 4 years ago

Should this be closed now that #803 has been closed?

monsdar commented 4 years ago

I'm having a thirdparty code generator that generates a C++ library for me. Unfortunately the files getting generated are named like C-files: generated_akm.c etc.

So far we've worked around this by setting the file properties using CMake like so: set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/generated_akm.c PROPERTIES GENERATED true LANGUAGE CXX). This builds as it should, though admittedly it's a dirty hack.

Now when turning on sccache we're not able to compile anymore. sccache is ignoring what CMake sets for us and tries to compile the sources with the C compiler.

Is there an easy way around this? It'd be very helpful if there's a way to make sscache use the correct compiler instead of having to touch a lot of legacy code.

robertmaynard commented 4 years ago

This builds as it should, though admittedly it's a dirty hack.

FYI, this isn't a dirty hack but the intended way for CMake projects to state that the language extension of a file should be ignored

froydnj commented 4 years ago

Is there an easy way around this? It'd be very helpful if there's a way to make sscache use the correct compiler instead of having to touch a lot of legacy code.

Does this behavior still happen with sccache compiled from git?

mathstuf commented 4 years ago

I think #803 might have fixed the C/C++ confusion, but I suspect this is a larger problem than just that. I haven't tested since #803 was closed though.

robertmaynard commented 4 years ago

You might also need to wait for CMake 3.19 ( https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4780 ). Before 3.19 when compiling a file with a C extension for C++ CMake would presume that calling g++ || clang++ was sufficient. Starting in 3.19 we will add an explicit -x c++ to the command line.

Note: This -x c++ is only added when somebody has explicitly specified the LANGUAGE property

froydnj commented 4 years ago

I think #803 might have fixed the C/C++ confusion, but I suspect this is a larger problem than just that.

What is the "larger problem" here? I guess that sccache only implements the language-switching behavior for clang and gcc and not for other compilers? Or something else?

monsdar commented 4 years ago

I'll check with latest revision of sccache. Thanks for the fast responses!

monsdar commented 3 years ago

Before setting up a Rust toolchain etc: Is there a prebuilt master available somewhere? Is travis only building releases? /update: Using the official Rust Docker image works like a charm, sccache master is building right now

cr1901 commented 3 years ago

I'm still having problems compiling based on file extension as of 6628e1f:

William@DESKTOP-H0PMN4M MINGW64 ~/Projects/FPGA/build-rv32i/build-gcc-newlib-stage1/build-x86_64-w64-mingw32/libcpp
$ sccache g++  -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp -I. -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/../include -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include  -g -O2 -W -Wall -Wno-narrowing -Wwrite-strings -Wmissing-format-attribute -pedantic -Wno-long-long  -fno-exceptions -fno-rtti -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp -I. -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/../include -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include   -c -o directives.o -MT directives.o -MMD -MP -MF .deps/directives.Tpo ../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/directives.c
cc1.exe: warning: command line option '-fno-rtti' is valid for C++/D/ObjC++ but not for C In file included from ../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include/cpplib.h:27,
                 from ../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/directives.c:23:
../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include/line-map.h:329:3: error: expected specifier-qualifier-list before 'static'
  329 |   static source_range from_location (location_t loc)
      |   ^~~~~~
../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include/line-map.h:402:43: error: expected identifier or '(' before ':' token
  402 | struct GTY((tag ("1"))) line_map_ordinary : public line_map {
      |                                           ^
../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include/line-map.h:446:2: warning: ISO C does not allow extra ';' outside of a function [-Wpedantic]
  446 | };

Source file compiles successfully if I remove the sccache invocation:

William@DESKTOP-H0PMN4M MINGW64 ~/Projects/FPGA/build-rv32i/build-gcc-newlib-stage1/build-x86_64-w64-mingw32/libcpp
$ g++  -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp -I. -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/../include -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include  -g -O2 -W -Wall -Wno-narrowing -Wwrite-strings -Wmissing-format-attribute -pedantic -Wno-long-long  -fno-exceptions -fno-rtti -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp -I. -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/../include -I../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/include   -c -o directives.o -MT directives.o -MMD -MP -MF .deps/directives.Tpo ../../../../riscv-gnu-toolchain/riscv-gcc/libcpp/directives.c

William@DESKTOP-H0PMN4M MINGW64 ~/Projects/FPGA/build-rv32i/build-gcc-newlib-stage1/build-x86_64-w64-mingw32/libcpp

EDIT: To duplicate this, checkout the riscv-gnu-toolchain repo, export CC="sccache gcc" and export CXX="sccache g++" and configure in another directory using something like: ../riscv-gnu-toolchain/configure --with-arch=rv32i --prefix=/opt/riscv32i. The binutils build will succeed, but the gcc build will choke due to numerous C++ files having a .c extension. More than I can manually alter, unfortunately.