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
92 stars 8 forks source link

Toolchain confusion for native executables on Linux/ppc64 #1044

Open zeldin opened 5 years ago

zeldin commented 5 years ago

I'm running Gradle on Linux/ppc64. It appears that Gradle is not able to correctly map the default toolchain on the system to the correct os/arch pair. It seems to believe that the system toolchain is for the architecture 'x86_64', even though it correctly identifies the arch of OperatingSystem.current() as "ppc64".

Please observe the following:

hakua:/tmp/gradle-test% uname -s -m
Linux ppc64
hakua:/tmp/gradle-test% cat build.gradle
apply plugin: 'c'
task printNative {
    doLast {
        println org.gradle.internal.os.OperatingSystem.current().getFamilyName()
        println org.gradle.internal.os.OperatingSystem.current().getArch()
    }
}
model {
    platforms {
        x86 {
            architecture 'x86_64'
            operatingSystem 'linux'
        }
        ppc {
            architecture 'ppc64'
            operatingSystem 'linux'
        }
    }
    components {
        main(NativeExecutableSpec) {
            targetPlatform "x86"
            targetPlatform "ppc"
        }
     }
}
hakua:/tmp/gradle-test% /tmp/gradle-5.3.1/bin/gradle -q printNative
linux
ppc64
hakua:/tmp/gradle-test% /tmp/gradle-5.3.1/bin/gradle -q installMainX86Executable 
hakua:/tmp/gradle-test% file build/install/main/x86/lib/main
build/install/main/x86/lib/main: ELF 64-bit MSB pie executable, 64-bit PowerPC or cisco 7500, version 1 (SYSV), dynamically linked, interpreter /lib64/ld64.so.1, for GNU/Linux 3.2.0, not stripped
hakua:/tmp/gradle-test% ./build/install/main/x86/main 
Hello, world!
hakua:/tmp/gradle-test% /tmp/gradle-5.3.1/bin/gradle -q installMainPpcExecutable 

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileMainPpcExecutableMainC'.
> No tool chain is available to build for platform 'ppc':
    - Tool chain 'visualCpp' (Visual Studio):
        - Visual Studio is not available on this operating system.
    - Tool chain 'gcc' (GNU GCC):
        - Don't know how to build for platform 'ppc'.
    - Tool chain 'clang' (Clang):
        - Don't know how to build for platform 'ppc'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s
hakua:/tmp/gradle-test% 

Expected Behavior

I would expect installMainPpcExecutable to build a binary for PPC, and installMainX86Executable to fail due to lack of an X86 cross-compiler.

Current Behavior

instalMainPpcExecutable fails with "no tool chain available", and installMainX86Excutable builds a PPC binary. So it's the wrong way around.

Context

I'm building NSA:s Ghidra and actually everything works fine with the original models where only a platform with architecture x86_64 is specified; Gradle happily builds ppc64 binaries with the system toolchain. The problem starts when I want to differentiate between x86_64 and ppc64 builds in order to have the binaries installed under different paths. (The Ghidra build system needs the installation directory name to match the name of the targetPlatform due to the way it interacts with the generated task names.)

Steps to Reproduce

The build.gradle presented above should be sufficient to reproduce the issue. Just run Gradle on Linux/ppc64. The same behaviour can also be observed on ARM64, just change architecture 'ppc64' into architecture 'aarch64'. The C source itself is completely arbitrary.

Your Environment

Gentoo Linux, stock kernel 4.19.29. The JVM is OpenJDK 1.8.0_191. The "build scan" thingy seems to be broken, sorry. (After I answer "yes" to the ToS question I just get the shell prompt back, no URL.)

lacasseio commented 5 years ago

It's a known limitation that we hope to start addressing soon. Gradle handles x86 and x86_64 out of the box. For other architecture, you need to guide the tool chain a little bit, see the cross-compilation section of the user guide.

lacasseio commented 5 years ago

Just to make sure I correctly understand, you are running Gradle on a PPC64 machine with a tool chain building for the host (PPC64)? Basically, no cross-compilation?

zeldin commented 5 years ago

Yes, it is native compilation that I want to work. I could create explicit toolchain declarations saying that /usr/bin/gcc should be used for both x86_64 and ppc64, but apart from it being rather confusing to have two tasks "installMainX86Executable" and "installMainPpcExecutable" which both build the same native binary, it would also not work correctly in the intended scenario, because "gradle build" would build the "X86Executable", which would be a PPC64 executable but placed in the wrong directory.

zeldin commented 5 years ago

I guess the workaround with current Gradle would be to have the packaging step recognize "x86_64" as "Gradle speak" for native, and rename the directory to the actual native platform. That would break cross-compilation to x86_64 though. (Not a problem for me personally since I'm not interested in x86_64 systems, but someone might like to try it...)