gradle / gradle-native

The home of Gradle's support for natively compiled languages
https://blog.gradle.org/introducing-the-new-cpp-plugins
Apache License 2.0
91 stars 8 forks source link

GCC version detection assumptions lead to Debian and Ubuntus gcc-mingw-w64 versions being unusable #1107

Closed protos-gunzinger closed 5 months ago

protos-gunzinger commented 1 year ago

Expected Behavior

Installed gcc (from gcc-mingw-w64) should be used succesfully. Either by adding a hardcoded-bypass for minor == 0 && patchlevel == 0, or by only relying on the major version to be present in the relevant line.

Current Behavior

The following output is printed when attempting to use the gcc from the gcc-mingw-w64 (x86_64-w64-mingw32-gcc) on Ubuntu or Debian (for cross-compilation to target windows):

> No tool chain is available to build for platform 'pc':
   - Tool chain 'Gcc' (GNU GCC):
       - Could not determine GCC metadata: could not find vendor in output of /usr/bin/x86_64-w64-mingw32-gcc.

Context

This is a blocker for our CI pipeline which uses a docker container based on the eclipse-temurin JDK images. We are trying to build our project which contains native code that should be cross-compiled into .exe binaries.

GCC output using the same flags as gradle calls GCC to identify with (taken from https://github.com/gradle/gradle/blob/master/subprojects/platform-native/src/main/java/org/gradle/nativeplatform/toolchain/internal/gcc/metadata/GccMetadataProvider.java#L81 ):

COLLECT_GCC=x86_64-w64-mingw32-gcc
Target: x86_64-w64-mingw32
Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --disable-option-checking --disable-silent-rules --libdir='/usr/lib/x86_64-linux-gnu' --libexecdir='/usr/lib/x86_64-linux-gnu' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --with-headers --enable-version-specific-runtime-libs --enable-fully-dynamic-string --enable-libgomp --enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-lto --enable-threads=win32 --program-suffix=-win32 --program-prefix=x86_64-w64-mingw32- --target=x86_64-w64-mingw32 --with-as=/usr/bin/x86_64-w64-mingw32-as --with-ld=/usr/bin/x86_64-w64-mingw32-ld --enable-libatomic --enable-libstdcxx-filesystem-ts=yes --enable-dependency-tracking SED=/bin/sed
Thread model: win32
Supported LTO compression algorithms: zlib
gcc version 10-win32 20220113 (GCC) 
COLLECT_GCC_OPTIONS='-dM' '-E' '-v' '-mtune=generic' '-march=x86-64'
[... irrelevant flags ommited and order of defines changed for readability ...]
#define __GNUC__ 10
#define __GNUC_MINOR__ 0
#define __GNUC_PATCHLEVEL__ 0
[...]

Gradle uses the defines __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__ to determine major, minor and patch level versions: https://github.com/gradle/gradle/blob/master/subprojects/platform-native/src/main/java/org/gradle/nativeplatform/toolchain/internal/gcc/metadata/GccMetadataProvider.java#L229

Then it expects the major.minor couple to be present in the a version information line in the vendor check: https://github.com/gradle/gradle/blob/master/subprojects/platform-native/src/main/java/org/gradle/nativeplatform/toolchain/internal/gcc/metadata/GccMetadataProvider.java#L97

Relevant links to the gcc source code (version printing): https://github.com/gcc-mirror/gcc/blob/master/gcc/gcc.cc#L7558 And the debian patches applied to gcc concerning the version: https://salsa.debian.org/mingw-w64-team/gcc-mingw-w64/-/blob/master/debian/patches/gcc-basever.patch

Steps to Reproduce (for bugs)

Use a recent Ubuntu or Debian OS/container image with gradle and try to use the gcc from the gcc-mingw-w64 package (x86_64-w64-mingw32-gcc). Affected versions (at least): Ubuntu 22.04 LTS, Debian Bullseye Probably many more, however no research was done on the package version of other software.

Dockerfile to reproduce the version output of mingw gcc for Debian Bullseye, Ubuntu 22.04 LTS:

# repro debian bullseye
FROM debian:bullseye

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y gcc-mingw-w64

RUN x86_64-w64-mingw32-gcc -dM -E -v -
# repro ubuntu jammy (22.04 LTS)
FROM ubuntu:jammy

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y gcc-mingw-w64

RUN x86_64-w64-mingw32-gcc -dM -E -v -

Focal works as they use GCC 9.3.0 which has a minor patch version -> does not get truncated.

# repro ubuntu focal (20.04 LTS)
FROM ubuntu:focal

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y gcc-mingw-w64

RUN x86_64-w64-mingw32-gcc -dM -E -v -

Your Environment

Can not be published.

cobexer commented 5 months ago

A PR addressing this was merged for 8.7, it will be part of 8.7 RC1. You can already test if your use case is fixed by using the nightly release from https://gradle.org/nightly/

If there is anything missing please feel free to reopen and comment here or file a separate issue with the details.