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

Compiler version doesn't include clang or GCC: "cc" "--version" #958

Closed
zh-jq-b opened this issue Feb 21, 2024 · 20 comments · Fixed by #1000
Closed

Compiler version doesn't include clang or GCC: "cc" "--version" #958

zh-jq-b opened this issue Feb 21, 2024 · 20 comments · Fixed by #1000

Comments

@zh-jq-b
Copy link

zh-jq-b commented Feb 21, 2024

On Debian Sid:
Output of cc --version, which is different from gcc --version:

cc (Debian 13.2.0-13) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Output of cc -v, which is the same as gcc -v:

Using built-in specs.
COLLECT_GCC=cc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 13.2.0-13' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/reproducible-path/gcc-13-13.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/reproducible-path/gcc-13-13.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (Debian 13.2.0-13) 

So it's may be better to use -v to check the compiler type?

@NobodyXu
Copy link
Collaborator

That may be a good idea, however I'm not sure how it affects msvc and other compilers.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 21, 2024

I am also seeing this on GitHub Actions' Ubuntu 22.04 runner: https://github.com/KDAB/cxx-qt/actions/runs/7986404801/job/21806762461?pr=848#step:14:93

I cannot reproduce the warning locally on Fedora 39.

@edg-l
Copy link

edg-l commented Feb 23, 2024

I'm seeing this too

❯ c++ --version
c++ (Gentoo 13.2.1_p20240113-r1 p12) 13.2.1 20240113
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

@willkill07
Copy link

willkill07 commented Feb 28, 2024

The standard way to check what version of compiler you have is to analyze the preprocessor definitions defined by the compiler for a trivial program. Simply relying on the output of --version is never used in any sane C++ build system.

For instance, CMake looks at preprocessor definitions emitted by the compiler to detect compiler versions. It's usually pretty complex for the more difficult compilers, but this is more reasonable than relying on inspecting the output of --version. Note: you would have to check clang before gcc since clang pretends to be gcc.

Clang:

$ /bin/cat /usr/share/cmake/Modules/Compiler/Clang-DetermineCompiler.cmake

set(_compiler_id_pp_test "defined(__clang__)")

include("${CMAKE_CURRENT_LIST_DIR}/Clang-DetermineCompilerInternal.cmake")

GCC:

$ /bin/cat /usr/share/cmake/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake

set(_compiler_id_pp_test "defined(__GNUC__) || defined(__GNUG__)")

set(_compiler_id_version_compute "
# if defined(__GNUC__)
#  define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__GNUC__)
# else
#  define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
#  define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
#  define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__GNUC_PATCHLEVEL__)
# endif")

@NobodyXu
Copy link
Collaborator

Thanks, I will work on a patch once I fixed the make problem.

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 2, 2024

Ok so for clang we can use:

#define XSTR(x) STR(x)
#define STR(x) #x

#pragma message "COMPILER_VERSION_MAJOR = " XSTR(__clang_major__)
#pragma message "COMPILER_VERSION_MINOR = " XSTR(__clang_minor__)
#pragma message "COMPILER_VERSION_PATCH = " XSTR(__clang_patchlevel__)


#if defined(_MSC_VER)
  /* _MSC_VER = VVRR */
# pragma message "SIMULATE_VERSION_MAJOR = " XSTR(_MSC_VER / 100)
# pragma message "SIMULATE_VERSION_MINOR = " XSTR(_MSC_VER % 100)
#endif

#if defined(_MSC_VER)
# pragma message "SIMULATE_ID = MSVC"
#endif

on my macOS system, using the homebrew clang, clang -c a.c gives me:

a.c:4:9: warning: COMPILER_VERSION_MAJOR = 17 [-W#pragma-messages]
    4 | #pragma message "COMPILER_VERSION_MAJOR = " XSTR(__clang_major__)
      |         ^
a.c:5:9: warning: COMPILER_VERSION_MINOR = 0 [-W#pragma-messages]
    5 | #pragma message "COMPILER_VERSION_MINOR = " XSTR(__clang_minor__)
      |         ^
a.c:6:9: warning: COMPILER_VERSION_PATCH = 6 [-W#pragma-messages]
    6 | #pragma message "COMPILER_VERSION_PATCH = " XSTR(__clang_patchlevel__)
      |         ^
3 warnings generated.

Using the gcc imposted by apple clang, gcc -c a.c (cc -c a.c gives the same output):

a.c:4:9: warning: COMPILER_VERSION_MAJOR = 15 [-W#pragma-messages]
#pragma message "COMPILER_VERSION_MAJOR = " XSTR(__clang_major__)
        ^
a.c:5:9: warning: COMPILER_VERSION_MINOR = 0 [-W#pragma-messages]
#pragma message "COMPILER_VERSION_MINOR = " XSTR(__clang_minor__)
        ^
a.c:6:9: warning: COMPILER_VERSION_PATCH = 0 [-W#pragma-messages]
#pragma message "COMPILER_VERSION_PATCH = " XSTR(__clang_patchlevel__)
        ^
3 warnings generated.

Running real gcc, gcc-13 -c a.c:

a.c:4:9: note: '#pragma message: COMPILER_VERSION_MAJOR = __clang_major__'
    4 | #pragma message "COMPILER_VERSION_MAJOR = " XSTR(__clang_major__)
      |         ^~~~~~~
a.c:5:9: note: '#pragma message: COMPILER_VERSION_MINOR = __clang_minor__'
    5 | #pragma message "COMPILER_VERSION_MINOR = " XSTR(__clang_minor__)
      |         ^~~~~~~
a.c:6:9: note: '#pragma message: COMPILER_VERSION_PATCH = __clang_patchlevel__'
    6 | #pragma message "COMPILER_VERSION_PATCH = " XSTR(__clang_patchlevel__)
      |         ^~~~~~~

Same output when using clang++, c++, g++, for g++-13 though g++-13 -c a.c gives:

a.c:4:65: note: '#pragma message: COMPILER_VERSION_MAJOR = __clang_major__'
    4 | #pragma message "COMPILER_VERSION_MAJOR = " XSTR(__clang_major__)
      |                                                                 ^
a.c:2:17: note: in definition of macro 'STR'
    2 | #define STR(x) #x
      |                 ^
a.c:4:45: note: in expansion of macro 'XSTR'
    4 | #pragma message "COMPILER_VERSION_MAJOR = " XSTR(__clang_major__)
      |                                             ^~~~
a.c:5:65: note: '#pragma message: COMPILER_VERSION_MINOR = __clang_minor__'
    5 | #pragma message "COMPILER_VERSION_MINOR = " XSTR(__clang_minor__)
      |                                                                 ^
a.c:2:17: note: in definition of macro 'STR'
    2 | #define STR(x) #x
      |                 ^
a.c:5:45: note: in expansion of macro 'XSTR'
    5 | #pragma message "COMPILER_VERSION_MINOR = " XSTR(__clang_minor__)
      |                                             ^~~~
a.c:6:70: note: '#pragma message: COMPILER_VERSION_PATCH = __clang_patchlevel__'
    6 | #pragma message "COMPILER_VERSION_PATCH = " XSTR(__clang_patchlevel__)
      |                                                                      ^
a.c:2:17: note: in definition of macro 'STR'
    2 | #define STR(x) #x
      |                 ^
a.c:6:45: note: in expansion of macro 'XSTR'
    6 | #pragma message "COMPILER_VERSION_PATCH = " XSTR(__clang_patchlevel__)
      |                                             ^~~~

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 2, 2024

For GCC:

#define XSTR(x) STR(x)
#define STR(x) #x

#if defined(__GNUC__)
# pragma message "COMPILER_VERSION_MAJOR = " XSTR(__GNUC__)
#else
# pragma message "COMPILER_VERSION_MAJOR = " XSTR(__GNUG__)
#endif

#if defined(__GNUC_MINOR__)
# pragma message "COMPILER_VERSION_MINOR = " XSTR(__GNUC_MINOR__)
#endif

#if defined(__GNUC_PATCHLEVEL__)
# pragma message "COMPILER_VERSION_PATCH = " XSTR(__GNUC_PATCHLEVEL__)
#endif

For gcc-13 -c b.c:

b.c:5:10: note: '#pragma message: COMPILER_VERSION_MAJOR = 13'
    5 | # pragma message "COMPILER_VERSION_MAJOR = " XSTR(__GNUC__)
      |          ^~~~~~~
b.c:11:10: note: '#pragma message: COMPILER_VERSION_MINOR = 2'
   11 | # pragma message "COMPILER_VERSION_MINOR = " XSTR(__GNUC_MINOR__)
      |          ^~~~~~~
b.c:15:10: note: '#pragma message: COMPILER_VERSION_PATCH = 0'
   15 | # pragma message "COMPILER_VERSION_PATCH = " XSTR(__GNUC_PATCHLEVEL__)
      |          ^~~~~~~

g++-13 -c b.c:

b.c:5:59: note: '#pragma message: COMPILER_VERSION_MAJOR = 13'
    5 | # pragma message "COMPILER_VERSION_MAJOR = " XSTR(__GNUC__)
      |                                                           ^
b.c:2:17: note: in definition of macro 'STR'
    2 | #define STR(x) #x
      |                 ^
b.c:5:46: note: in expansion of macro 'XSTR'
    5 | # pragma message "COMPILER_VERSION_MAJOR = " XSTR(__GNUC__)
      |                                              ^~~~
b.c:11:65: note: '#pragma message: COMPILER_VERSION_MINOR = 2'
   11 | # pragma message "COMPILER_VERSION_MINOR = " XSTR(__GNUC_MINOR__)
      |                                                                 ^
b.c:2:17: note: in definition of macro 'STR'
    2 | #define STR(x) #x
      |                 ^
b.c:11:46: note: in expansion of macro 'XSTR'
   11 | # pragma message "COMPILER_VERSION_MINOR = " XSTR(__GNUC_MINOR__)
      |                                              ^~~~
b.c:15:70: note: '#pragma message: COMPILER_VERSION_PATCH = 0'
   15 | # pragma message "COMPILER_VERSION_PATCH = " XSTR(__GNUC_PATCHLEVEL__)
      |                                                                      ^
b.c:2:17: note: in definition of macro 'STR'
    2 | #define STR(x) #x
      |                 ^
b.c:15:46: note: in expansion of macro 'XSTR'
   15 | # pragma message "COMPILER_VERSION_PATCH = " XSTR(__GNUC_PATCHLEVEL__)
      |                                              ^~~~

For clang, clang++ and clang-imposed cc, c++, gcc, g++ , they all give version 4.2.0 on my machine.

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 2, 2024

TODO for myself: Also test zig-cc output

Would also be great to test different compilers in CI

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 6, 2024

Output of zig cc and zig c++ is basically the same as clang and clang++, only way of telling the difference is by running zig cc --version/zig cc -v which gives:

clang version 16.0.6 (https://github.com/ziglang/zig-bootstrap 1dda86241204c4649f668d46b6a37feed707c7b4)
Target: aarch64-unknown-darwin23.2.0
Thread model: posix
InstalledDir: /usr/bin

slightly different from clang -v

@dargueta
Copy link

dargueta commented Mar 6, 2024

I don't know Rust and have never seen this repo before, but it's affecting some third-party software I'm using that needs this library. (I am, however, very familiar with C/C++.)

Since we're invoking the compiler to begin with, perhaps we could do a little more work to get something more reliable? For example, we could compile and run a small program like this:

#ifdef __cplusplus
#    include <cstdio>
#else
#    include <stdio.h>
#endif

int main() {
    /* Always check Clang before __GNUC__ because it defines that too */
#ifdef __clang__
    printf("clang | %s\n", __clang_version__);
    return 0;
#endif

#ifdef __GNUC_VERSION__
    /* Could be TCC or another compiler professing compatibility, so we may need
       to do further checks, especially if we're choosing CLI arguments based on
       the compiler and version. */
    printf(
        "GCC | %d.%d.%d\n",
        __GNUC_VERSION__ / 10000,
        __GNUC_VERSION__ / 100,
        __GNUC_VERSION__ % 100
    );
    return 0;
#endif

#ifdef _MSC_VER
    printf("MSVC | %d.%d\n", _MSC_VER / 100, _MSC_VER % 100);
    return 0;
#endif

    /* Unrecognized compiler */
    return 1;
}

We could get detailed information from this, such as the width of int and so on. Since we completely control the output, we could construct JSON if we wanted to.

I've found this list highly useful for compiler detection. There are other lists for detecting OS and host/target architecture.

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 6, 2024

Thanks @dargueta I would open a PR for this soon.

@dargueta
Copy link

dargueta commented Mar 7, 2024

Don't copy and paste that, I just noticed a bug (missing return statements).

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 7, 2024

I will probably just use the macro-only and use -E to only run pre-processing.

@NobodyXu

This comment was marked as resolved.

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 7, 2024

Ok I decided to use the following .c file for detecting compiler family:

#ifdef __clang__
# pragma message "clang"
#else

# ifdef __GNUC__
#  pragma message "gcc"
# endif

# ifdef _MSC_VER
#  pragma message "msvc"
# endif
#endif

Tested with clang, apple clang and gcc on macOS, mingw gcc and msvc on windows

@dargueta
Copy link

dargueta commented Mar 8, 2024

Tested Clang and GCC on Ubuntu 23.10 and it works. Thanks!

@AlexanderSchuetz97
Copy link

I have this problem in our CI Containers. They are based on Ubuntu 20.04 and I will never be able to change that for reasons irrelevant to this issue so I would appreciate if this gets fixed for older versions of ubuntu/debian too.

This is the output from cc --version.
root@44cb3afd915b:/# cc --version cc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The cargo build still succeeds but the log message is spammed 1000 times which makes looking for a genuine error take longer.

@NobodyXu
Copy link
Collaborator

NobodyXu commented Mar 16, 2024

For everyone subscribing, #1000 should fix this and once it is merged, I will cut a new release.

@fgsch
Copy link

fgsch commented Mar 19, 2024

@NobodyXu do you have a estimate for the new release? Thank you!

@NobodyXu
Copy link
Collaborator

Waiting for #1015 to merge

bors added a commit to rust-lang-ci/rust that referenced this issue Apr 13, 2024
Update non-bootstrap `cc` dependency to fix compile family detection warning

`x.py check compiler/rustc_llvm` **Before:**

(rust-lang/cc-rs#958)

<pre>
Checking stage0 compiler artifacts {rustc_llvm} (x86_64-unknown-linux-gnu)
   Compiling cc v1.0.90
   Compiling libc v0.2.153
   Compiling rustc_llvm v0.0.0
<b>warning: rustc_llvm@0.0.0: Compiler version doesn't include clang or GCC: "c++" "--version"</b>
    Finished `release` profile [optimized] target(s) in 28.09s
</pre>

**After:**

<pre>
Checking stage0 compiler artifacts {rustc_llvm} (x86_64-unknown-linux-gnu)
   Compiling libc v0.2.153
   Compiling cc v1.0.92
   Compiling rustc_llvm v0.0.0
    Finished `release` profile [optimized] target(s) in 29.06s
</pre>
RalfJung pushed a commit to RalfJung/miri that referenced this issue Apr 15, 2024
Update non-bootstrap `cc` dependency to fix compile family detection warning

`x.py check compiler/rustc_llvm` **Before:**

(rust-lang/cc-rs#958)

<pre>
Checking stage0 compiler artifacts {rustc_llvm} (x86_64-unknown-linux-gnu)
   Compiling cc v1.0.90
   Compiling libc v0.2.153
   Compiling rustc_llvm v0.0.0
<b>warning: rustc_llvm@0.0.0: Compiler version doesn't include clang or GCC: "c++" "--version"</b>
    Finished `release` profile [optimized] target(s) in 28.09s
</pre>

**After:**

<pre>
Checking stage0 compiler artifacts {rustc_llvm} (x86_64-unknown-linux-gnu)
   Compiling libc v0.2.153
   Compiling cc v1.0.92
   Compiling rustc_llvm v0.0.0
    Finished `release` profile [optimized] target(s) in 29.06s
</pre>
mqudsi added a commit to fish-shell/fish-shell that referenced this issue Apr 17, 2024
Under Ubuntu 23.10 (gcc 13), older cc crate versions would complain that the
compiler could not be identified.

See rust-lang/cc-rs#958
vertesians pushed a commit to vertesians/fish-shell that referenced this issue Apr 17, 2024
Under Ubuntu 23.10 (gcc 13), older cc crate versions would complain that the
compiler could not be identified.

See rust-lang/cc-rs#958
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants