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

cpp-library plugin needs suport for cross-compiling for Arm #989

Open swpalmer opened 5 years ago

swpalmer commented 5 years ago

The older c and cpp plugins could be configured with custom tool chains to support building for linux-arm on linux x86_64. The new preferred cpp-library needs this ability.

Expected Behavior

I should be able to add target machines such as:

  library {
    targetMachines = [
      machines.linux.x86, machines.linux.x86_64,  // Linux Intel 32/64-bit
      machines.linux.arm, machines.linux.aarch64  // Linux Arm 32/64-bit
    ]
  }

A new mechanism is needed to define a new machine type or specify the tool chain for a type.

Current Behavior

We can't cross-compile for Arm currently

Context

I want to avoid the old c and cpp plugins (which are very complicated to configure) and adopt the new cpp-library plugin, but I have existing code and future needs to build the same project on Linux, Windows and macOS, both 32- and 64-bit for Linux and windows in addition to 32 and 64-bit Arm for Linux.

I am building for an application framework that uses the same source code for desktops and embedded devices.

Your Environment

Windows 10 64-bit Intel Linux (Ubuntu/CentOS) 64-bit Intel, targeting both Intel and Arm macOS

bmeike commented 5 years ago

+1 . Does anyone have a workaround?

ddresser commented 5 years ago

+1 Also need this. All our current builds use the component model and cross compile for arm. We'd like to start migrating to the new plugins.

For anyone who is interested, I was able to compile a hello world program for arm using the new Gradle cpp-application plugin and clang. I'm not suggesting this is a good solution, but it did compile an arm binary.

Dockerfile:


FROM ubuntu:bionic

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -qq -y \ clang \ openjdk-11-jdk \ g++-aarch64-linux-gnu \ gcc-aarch64-linux-gnu \ g++-7-aarch64-linux-gnu \ gcc-7-aarch64-linux-gnu \ gcc-7-multilib \ g++-7-multilib \ lld-6.0 \ && rm -rf /var/lib/apt/lists/*


build.gradle


plugins { id 'cpp-application' }

application { binaries.configureEach { def compileTask = compileTask.get() def linkTask = linkTask.get()

if (toolChain instanceof Clang) {
  compileTask.compilerArgs = ["-fuse-ld=lld", "--sysroot", "/usr/aarch64-linux-gnu", "-I/usr/aarch64-linux-gnu/include/c++/7/aarch64-linux-gnu", "-march=armv8-a", "-static", "-target", "aarch64-linux-gnueabi"]
  linkTask.linkerArgs = ["-fuse-ld=lld", "--sysroot", "/usr/aarch64-linux-gnu", "-I/usr/aarch64-linux-gnu/include/c++/7/aarch64-linux-gnu", "-march=armv8-a", "-static", "-target", "aarch64-linux-gnueabi"]
}

} }


stephengold commented 2 years ago

Does anyone have a workaround?

My workaround is to use the old "cpp" plugin from Gradle 4 instead of "cpp-library". It's routine to define new platforms in the "cpp" plugin, whereas "cpp-library" seems to be limited to 6 hardcoded ones.

Also note that the Android plugins handle ARM architectures, so it's surprising that "cpp-library" can't!

pedrolamarao commented 2 years ago

This is how I do it based on many helpful hints from @lacasseio and others:

https://github.com/pedrolamarao/psys/blob/master/buildSrc/src/main/groovy/toolchain.groovy

swpalmer commented 2 years ago

@pedrolamarao It looks like that is using a different plugin 'dev.nokee.cpp-library' not 'cpp-library'