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

Unbuildable architecture for a given OS should not fail the build #961

Closed lacasseio closed 5 years ago

lacasseio commented 5 years ago

Expected Behavior

We should not fail the build.

Current Behavior

Specifying targetMachines = [machines.windows().x86(), machines.windows().x86_64(), machines.windows().architecture('bob')] generate the following error on Windows:

* What went wrong:
A problem occurred configuring project ':app'.
> No tool chain is available to build C++ for host operating system 'Windows 10' architecture 'bob':
    - Tool chain 'visualCpp' (Visual Studio): Don't know how to build for host operating system 'Windows 10' architecture 'bob'.
    - Tool chain 'gcc' (GNU GCC): Don't know how to build for host operating system 'Windows 10' architecture 'bob'.
    - Tool chain 'clang' (Clang): Don't know how to build for host operating system 'Windows 10' architecture 'bob'.

* 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.

Context

Steps to Reproduce (for bugs)

Your Environment

adammurdoch commented 5 years ago

There's a difference between an unsupported architecture and a supported but unbuildable architecture. I think we should fail at configuration time for unsupported architectures, as this variant will never be built, but not for unbuildable architectures.

We should never fail configuration for an unbuildable architecture, but we definitely want to fail the build if an unbuildable architecture is requested or if all of the architectures are not buildable.

ghale commented 5 years ago

Another question (which may have the same answer) is what should happen with IDE metadata generation when I have an unbuildable architecture. For instance, if I declare that a component should be buildable for 32 and 64 bit architectures, but I have a toolchain that only builds 64-bit, should the IDE metadata generation task fail?

adammurdoch commented 5 years ago

The degree of leniency wrt missing things depends on what the user intends to do with the IDE project. If they just want to look at the code, it doesn't particularly matter that the toolchains are missing. If they want to test some changes, it doesn't matter that some variants cannot be built or tested on their machine. It's only if they really want to build and test all the architectures from the IDE that it's a problem.

There's a similar question with other kinds of dependencies beyond the toolchain: it's probably ok in some cases to successfully import even when some dependency's headers cannot be resolved, or an incorrect version of the tool chain is available, or the standard C++ library doesn't quite match, or even that the current OS isn't supported.

We might define a couple of levels of functionality and choose one of them as the "goal" for the IDE import for now. We can use this to make decisions about what should happen when a particular thing goes wrong. Later we might add ways to select a different "goal".

Some options:

I suspect it would probably be best to lean more towards the lenient options with some good diagnostics. In the short term, however, while we're just trying to get things working, I think it would be ok to be strict wrt to all problems and see what specific feedback we get from people using it.

lacasseio commented 5 years ago

Reading all the comments, I can't seem to figure out how we would want to determine if an architecture is unsupported. In the example, bob is obviously an unsupported architecture. However, in a cross-compilation context, we could have tool chains to compile for bob which would make it supported. Right now, we don't support cross-compilation so we can assume cross-compilation as unsupported.

Following this building x64 on Windows x86 would be unsupported or unbuildable? It's like cross-compiling bob on the host OS.

I would probably ignore unsupported architecture at the moment and treat anything that doesn't resolve a tool chain as unbuildable. Would that be a fair step forward for this issue?

adammurdoch commented 5 years ago

An unsupported architecture would be one for which there is no tool chain that knows how to build it on the current host machine. This is different to whether the tools are installed or not.

So, if I haven't defined a tool chain that knows how to build bob on Windows, it's unsupported when I run on any Windows machine.

If I have defined a tool chain that knows how to build bob on Windows, but the tools it needs are not installed on my Windows machine, then it is supported but not buildable on my machine.

If I have defined a tool chain that knows how to build bob on Windows, and the tools (and system libraries) are installed on my Windows machine, then bob is buildable on my machine.

In other words, "unsupported" means "cannot build this on any machine of this type, it doesn't make sense" and "unbuildable" means "can build if the tools are installed correctly".

ghale commented 5 years ago

@lacasseio Is there a PR for this?

lacasseio commented 5 years ago

I'm almost done on this one. There was some unexpected change to be made so it works properly. Sadly, some tests for Swift had to be removed given they behave the same way as unsupported instead of unbuildable.

lacasseio commented 5 years ago

Here is the PR for this work: https://github.com/gradle/gradle/pull/8303

lacasseio commented 5 years ago

Unsupported architecture will now cause Gradle to fail configuration. The concept of unsupported operating systems has yet to be defined.