Multiple platforms and multiple toolchains for native binary compiling


(Brian Krische) #1

I’m using Gradle 2.4 and I’m trying to compile a native C++ application for two different platforms (desktop and embedded) using two different GCC toolchains; one toolchain for one platform and another toolchain for the other platform. However, Gradle seems to be using the one GCC toolchain for both platforms. Here’s an example:

model {
    platforms {
        desktop {
            operatingSystem 'linux'
            architecture 'x86'
        }
        embedded {
            operatingSystem 'linux'
            architecture 'x86'
        }
    }
    toolChains {
        desktop_gcc(Gcc) {
            target('desktop')
        }
        embedded_gcc(Gcc) {
            target('embedded')
            path '/path/to/embedded/gcc'
        }
    }
}

When I run the example above, the desktop_gcc compiles both platforms. If I remove desktop_gcc, then embedded_gcc compiles both platforms.

Is this the expected behavior? I assumed that the desktop_gcc would be used to compile the desktop platform, and the embedded_gcc would be used to compile the embedded platform.


(Brian Krische) #2

I suppose the problem I’m really trying to solve is, how do I change the Gcc path for only specific platforms? I’ve tried this:

toolChains {
    gcc(Gcc) {
        target('embedded') {
            path '/path/to/embedded/gcc'
        }
        target('desktop')
    }
}

and it just uses the ‘/path/to/embedded/gcc’ for both platforms.


(Spencer Connaughton) #3

Did you ever figure this out?


(Brian Krische) #4

I did not. I haven’t tried it again since Gradle 2.4 though.


(Mark Vieira) #5

We are simply picking the first compatible toolchain we can find. We consider both equally capable of building your binary since they are both targeting the same OS and architecture. In the future we may decide to add more dimensions of compatibility. In the meantime you should be able to assign the appropriate toolchain to your binary by keying off of targetPlatform.

model {
    toolChains {
        gcc_foo(Gcc)
        gcc_bar(Gcc)
    }
    platforms {
        foo
        bar 
    }
    components {
        main(NativeExecutableSpec) {
            targetPlatform "foo"
            targetPlatform "bar"
            
            binaries.all {
                toolChain = toolChains["gcc_${targetPlatform.name}"]
            }
        }
    }
}

(Sterling Greene) #6

My only other suggestion is if the GCC executables are distinguished by different names (e.g., embedded-gcc vs desktop-gcc), you can do everything as a single tool chain:

	toolChains {
		gcc(Gcc) {
			target("embedded") {
				cppCompiler.executable = "${platform}-gcc"
			}
			target("desktop")
		}
	}

The tool chain selection process isn’t very configurable right now.


(Spencer Connaughton) #7

Thanks! Is this also still a valid solution? I’m using 2.2.1 in Android Studio.


(David Cowden) #8

According to the docs the toolChain property on a binary is read-only (https://docs.gradle.org/current/dsl/org.gradle.nativeplatform.NativeBinarySpec.html#org.gradle.nativeplatform.NativeBinarySpec:toolChain). Does this really work?