Hi Lukács,Maybe this is a relevant example. rules_nixpkgs uses a platform constraint so that Bazel can select nixpkgs provided toolchains (e.g. posix toolchain, cc toolchain, go toolchain, python toolchain, ghc toolchain) if the current platform supports Nix.A Nix provided toolchain: https://github.com/tweag/rules_nixpkgs/blob/dc24090573d74adcf38730422941fd69b87682c7/nixpkgs/nixpkgs.bzl#L551-L564Non-Nix counter part: https://github.com/tweag/rules_sh/blob/c6af1fe30e5b83a043d8543defc292b90750e236/sh/posix.bzl#L310-L322Users define --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host to enable the Nix provided toolchain.The Nix provided toolchain has to be defined before the non-Nix counterpart to be selected.I'd be interested to hear if and how your proposal would affect that use-case.Best, Andreas
--
You received this message because you are subscribed to the Google Groups "bazel-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-dev/CAOu%2B0LVAvctpLgyjO6O1RZwkpKNF%3DSMf0Gdfj50KMuFcES5RNg%40mail.gmail.com.
--
Lukacs,I agree that I'd like to get some clarity in this discussion. At this point I'm not entirely sure what specific change to toolchain resolution you are discussing: there have been several in various documents, as well as the (now dropped?) proposal by Ivo at https://github.com/bazelbuild/proposals/blob/master/designs/2020-09-29-new-default-target-constraint.mdI'd like to ask you some questions that I hope will clarify issues, and I'd like to consolidate information in one place:1. Are the only objections to using WORKSPACE to configure the Java toolchains that users will need to modify their WORKSPACE files?
a. In what way is Java different from Go, Rust, Scala, or any other set of rules that currently require this?b. Have you seen the sample repository rules I created in https://github.com/katre/java_repository_rules to mock up example Java repository configuration?
2. What specific changes are you proposing to toolchain resolution and the platforms systems?
a. Why are these needed for Java and not for other languages?
b. How will we migrate other languages that currently use platforms and toolchain resolution as-is? What new features will we gain?
3. I understand that the legacy behavior of Java toolchains (with the --javabase and --java_toolchain parameters) are difficult to reproduce with toolchain resolution. Is that behavior something we specifically wanted, or was it simply an accident of the previous implementation and the addition of remote execution?
On Wed, Oct 28, 2020 at 6:33 PM John Cater <jca...@google.com> wrote:1. Are the only objections to using WORKSPACE to configure the Java toolchains that users will need to modify their WORKSPACE files?a. In what way is Java different from Go, Rust, Scala, or any other set of rules that currently require this?b. Have you seen the sample repository rules I created in https://github.com/katre/java_repository_rules to mock up example Java repository configuration?I think there are three differences:
- The other rule sets don't have the concept "language version" and assume that there is just one canonical version of the toolchain they want to use
- Java sometimes requires multiple "language versions" to be used in the same build (e.g. if you build a server binary and an Android binary in the same build)
- Binaries for the other languages don't require a runtime that may or may not be preinstalled or piggyback on the Java one (like Scala)
Consider that in any build, there are the following "Java versions" in play (there may be one or two more I forgot...):
- The version of JVM javac runs on
- The version of the JDK javac comes from
- The source language version you pass to javac
- The target language version you pass to javac
- The version of JVM the target code runs on
So it's a much more complicated situation.
There seem to be two differing models: one where the WORKSPACE file tells Bazel which toolchains to use and another where the WORKSPACE file tells Bazel which toolchains are available and the selection happens according to the needs of each individual configured target. Initially, I thought that we agreed that we want Bazel to follow the second model, but by now, it looks like that you favor the first one?
The main reason why I am personally in favor of the second model is that it lends itself better to composable builds; the more you decide globally, the more problems you will have when you have to make different decisions for different parts of your transitive sources.
2. What specific changes are you proposing to toolchain resolution and the platforms systems?My understanding is that this document describes it; reading between the lines, I think the main idea is to have some way to influence the toolchain resolution that one can change by configuration transitions and that one can influence for each configured target. Ivo, is this correct?
a. Why are these needed for Java and not for other languages?b. How will we migrate other languages that currently use platforms and toolchain resolution as-is? What new features will we gain?
3. I understand that the legacy behavior of Java toolchains (with the --javabase and --java_toolchain parameters) are difficult to reproduce with toolchain resolution. Is that behavior something we specifically wanted, or was it simply an accident of the previous implementation and the addition of remote execution?I don't think there is any obscure behavior we need to reproduce (Ivo, is there?) It's just that we need to cover a number of use cases with an user experience as simple as possible.
On Thu, Oct 29, 2020 at 4:41 AM Lukács T. Berki <lbe...@google.com> wrote:On Wed, Oct 28, 2020 at 6:33 PM John Cater <jca...@google.com> wrote:1. Are the only objections to using WORKSPACE to configure the Java toolchains that users will need to modify their WORKSPACE files?a. In what way is Java different from Go, Rust, Scala, or any other set of rules that currently require this?b. Have you seen the sample repository rules I created in https://github.com/katre/java_repository_rules to mock up example Java repository configuration?I think there are three differences:
- The other rule sets don't have the concept "language version" and assume that there is just one canonical version of the toolchain they want to use
Have you seen rules_scala's support for different scala versions? See their docs at https://github.com/bazelbuild/rules_scala#selecting-scala-version. I know that they iterated several times on this design, it might be good to ask them for feedback and suggestions.
- Java sometimes requires multiple "language versions" to be used in the same build (e.g. if you build a server binary and an Android binary in the same build)
How often does this happen for Bazel users? Is this a feature in high demand? Is it worth complicating the user experience in order to support this?
- Binaries for the other languages don't require a runtime that may or may not be preinstalled or piggyback on the Java one (like Scala)
Consider that in any build, there are the following "Java versions" in play (there may be one or two more I forgot...):
- The version of JVM javac runs on
- The version of the JDK javac comes from
- The source language version you pass to javac
- The target language version you pass to javac
- The version of JVM the target code runs on
So it's a much more complicated situation.Again: how often does this actually come up? Are there Bazel users who want to run several different versions of JVM in the same build? My understanding is that a JDK at version m can support all language levels <= m, is that not true?
There seem to be two differing models: one where the WORKSPACE file tells Bazel which toolchains to use and another where the WORKSPACE file tells Bazel which toolchains are available and the selection happens according to the needs of each individual configured target. Initially, I thought that we agreed that we want Bazel to follow the second model, but by now, it looks like that you favor the first one?I favor the capability for the second. My main concern is that I don't want to complicate an already confusing system in order to support desired features that no one uses.The main reason why I am personally in favor of the second model is that it lends itself better to composable builds; the more you decide globally, the more problems you will have when you have to make different decisions for different parts of your transitive sources.I definitely agree with this principle.2. What specific changes are you proposing to toolchain resolution and the platforms systems?My understanding is that this document describes it; reading between the lines, I think the main idea is to have some way to influence the toolchain resolution that one can change by configuration transitions and that one can influence for each configured target. Ivo, is this correct?This is the proposal to add a new "config_value" rule, and to re-implement a platform as a collection of configuration values? I remain unconvinced that the value the proposal provides is worth the difficulty of migrating the world to a new form of platforms.
a. Why are these needed for Java and not for other languages?b. How will we migrate other languages that currently use platforms and toolchain resolution as-is? What new features will we gain?These are still unanswered questions about the new platforms proposal.
3. I understand that the legacy behavior of Java toolchains (with the --javabase and --java_toolchain parameters) are difficult to reproduce with toolchain resolution. Is that behavior something we specifically wanted, or was it simply an accident of the previous implementation and the addition of remote execution?I don't think there is any obscure behavior we need to reproduce (Ivo, is there?) It's just that we need to cover a number of use cases with an user experience as simple as possible.I agree with the goal of keeping the user experience as simple as possible. I just want to make sure that we are making the more commonly encountered user experiences the priority.
On Thu, Oct 29, 2020 at 1:43 PM John Cater <jca...@google.com> wrote:On Thu, Oct 29, 2020 at 4:41 AM Lukács T. Berki <lbe...@google.com> wrote:On Wed, Oct 28, 2020 at 6:33 PM John Cater <jca...@google.com> wrote:Again: how often does this actually come up? Are there Bazel users who want to run several different versions of JVM in the same build? My understanding is that a JDK at version m can support all language levels <= m, is that not true?The one huge data point I have is that google3 itself is far from using the latest JDK and JVM version. So it does look like there are reasons. It's true that a newer JDK supports older language levels, but you can have all sorts of reasons to choose older JVMs than the latest available to run your binary and one can make the same case for javac (although it's a weaker case there and I think it mostly rests on compiler bugs and Error Prone compatibility)
a. Why are these needed for Java and not for other languages?b. How will we migrate other languages that currently use platforms and toolchain resolution as-is? What new features will we gain?These are still unanswered questions about the new platforms proposal.A for (a), I thought the above few points about it having multiple axes Java versions was enough. (b) is not a problem to the best of my understanding since it would be a new feature that you can use or not, as you like.
config_value(name = "x86", flag = "cpu", value = "x86")
config_value(name = "linux", flag = "os", value = "os")
config_value(name = "jvm8", flag = "java_release_version", value = "8")
config_value(name = "jvm8", flag = "java_release_version", value = "11")
platform(
name = "autoconfigured_target_and_exec",
configuration = [":x86", ":linux"],
)
platform(
name = "jvm8_platform",
parent = ":autoconfigured_target_and_exec",
configuration = [":jvm8"],
)
toolchain(
name = "local_jvm8",
toolchain_type = ":java_runtime_toolchain",
target_config_values = [":jvm8"],
toolchain = "@local_java//:jdk"
)
toolchain(
name = "jvm11",
toolchain_type = ":java_runtime_toolchain",
target_config_values = [":jvm11"],
toolchain = "@remotejdk11_linux//:jdk",
)
toolchain(
name = "jdk8",
toolchain_type = ":java_toolchain",
target_config_value = [":jvm8"],
exec_config_value = [":x86", ":linux"],
toolchain = "@toolchain_java_linux//:toolchain_8"
)
On Thu, Oct 29, 2020 at 10:03 AM Lukács T. Berki <lbe...@google.com> wrote:On Thu, Oct 29, 2020 at 1:43 PM John Cater <jca...@google.com> wrote:On Thu, Oct 29, 2020 at 4:41 AM Lukács T. Berki <lbe...@google.com> wrote:On Wed, Oct 28, 2020 at 6:33 PM John Cater <jca...@google.com> wrote:Again: how often does this actually come up? Are there Bazel users who want to run several different versions of JVM in the same build? My understanding is that a JDK at version m can support all language levels <= m, is that not true?The one huge data point I have is that google3 itself is far from using the latest JDK and JVM version. So it does look like there are reasons. It's true that a newer JDK supports older language levels, but you can have all sorts of reasons to choose older JVMs than the latest available to run your binary and one can make the same case for javac (although it's a weaker case there and I think it mostly rests on compiler bugs and Error Prone compatibility)So it is a requirement to be able to select the JVM, JDK, and language version independently? Since google's internal repo is already using toolchain resolution for Java, I'm not sure what features are required that don't currently exist.The major difference between a monorepo is that all versions of Java (JVM, JDK, language level, etc) are checked in and known statically. I feel that this is also achievable for non-monorepo projects, by registering all JDKs (locally installed and downloaded), with some helpful repository macros to ease setup.
Let me expound on this a bit more; do I understand correctly that what you are proposing is that the WORKSPACE file would look like this:register_java_toolchain("@jre15//:jre")register_java_toolchain("@jre11//:jre")collate_java_toolchains()And collate_java_toolchains() call would create a repository like this:config_setting(name="java_runtime_v15", values={"java_runtime": "15"})config_setting(name="java_runtime_v11", values={"java_runtime": "11"})toolchain(name = "all_linux_jres",exec_compatible_with = ["@platforms//:linux"]),actual = select({"java_runtime_v15": "@jre15//:jre","java_runtime_v11": "@jre11//:jre",}))
But most importantly, if we go this route, why not also include the OS and CPU into the mix and do the whole toolchain selection in Starlark? (we could probably even add the toolchain type there, but that would require configuration transitions and IMHO it would be definitely a bridge too far)
So I think there are two viable alternatives: either do the toolchain selection fully in Java code or fully in Starlark, but the approach where some axes are in Java and some are in Starlark strikes me as combining the disadvantages of both approaches while summing up their complexity (one could argue that it saves a bit of complexity in Java code, but that's deceptive; whether the code is in Starlark or not, it's still our code to maintain)
--
You received this message because you are subscribed to the Google Groups "bazel-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-dev/CAOu%2B0LUqZqxXEc%2Bwtx%3DYXxCj%2BsPa%3DAcuNBnyEqgBpbqFGJ%2BUeQ%40mail.gmail.com.
Maybe I'm missing something, but can't this all be done today? Have a
"jdk_version" feature_flag which the user can provide, and use
select/starlark in the toolchain definition to adjust what is
registered? Transitions let you have multiple configurations in a
build, and you have all the flexibility you could want. Or, there was
a proposal from a year or two ago which showed how to use platforms to
set a minimum version for something like the JDK, and use that to pick
which toolchain to use? With Transitions to potentially allow
multiple per build?
I understand that the legacy behavior of Java toolchains (with the --javabase and --java_toolchain parameters) are difficult to reproduce with toolchain resolution. Is that behavior something we specifically wanted, or was it simply an accident of the previous implementation and the addition of remote execution?
In some of the proposals I see a desire for --java_runtime_version to both choose the desired JDK runtime and toggle remote vs. local JDKs. That seems like a weird mixture of intentions to me.