How do I load `config_setting()` into my `.bzl` file?

Viewed 1279

My motivation: our codebase is scattered across over at least 20 git repos. I want to consolidate everything into a single git repo with a single build system. Currently we use SBT, but we think the build would take too long, so I am examining the possibility of using Bazel instead.

Most of our codebase uses Scala 2.12, some of our codebase uses Scala 2.11, and the rest needs to build under both Scala 2.11 and Scala 2.12.

I'm trying to use bazelbuild/rules_scala.

With the following call to scala_repositories in my WORKSPACE, I can build using Scala 2.12:

scala_repositories(("2.12.6", {
    "scala_compiler": "3023b07cc02f2b0217b2c04f8e636b396130b3a8544a8dfad498a19c3e57a863",
    "scala_library": "f81d7144f0ce1b8123335b72ba39003c4be2870767aca15dd0888ba3dab65e98",
    "scala_reflect": "ffa70d522fc9f9deec14358aa674e6dd75c9dfa39d4668ef15bb52f002ce99fa"
}))

If I have the following call instead, I can build using Scala 2.11:

scala_repositories(("2.11.12", {
    "scala_compiler": "3e892546b72ab547cb77de4d840bcfd05c853e73390fed7370a8f19acb0735a0",
    "scala_library": "0b3d6fd42958ee98715ba2ec5fe221f4ca1e694d7c981b0ae0cd68e97baf6dce",
    "scala_reflect": "6ba385b450a6311a15c918cf8688b9af9327c6104f0ecbd35933cfcd3095fe04"
}))

However, it is not possible to specify in my BUILD files on a package level which version(s) of Scala to build with. I must specify this globally in my WORKSPACE.

To workaround this, my plan is to set up configurable attributes, so I can specify --define scala=2.11 to build with Scala 2.11, and specify --define scala=2.12 to build with Scala 2.12.

First I tried by putting this code in my WORKSPACE:

config_setting(
    name = "scala-2.11",
    define_values = {
        "scala": "2.11"
    }
)

config_setting(
    name = "scala-2.12",
    define_values = {
        "scala": "2.12"
    }
)

scala_repositories(
    select(
        {
            "scala-2.11": "2.11.12",
            "scala-2.12": "2.12.6"
        }
    ),
    select(
        {
            "scala-2.11": {
                "scala_compiler": "3e892546b72ab547cb77de4d840bcfd05c853e73390fed7370a8f19acb0735a0",
                "scala_library": "0b3d6fd42958ee98715ba2ec5fe221f4ca1e694d7c981b0ae0cd68e97baf6dce",
                "scala_reflect": "6ba385b450a6311a15c918cf8688b9af9327c6104f0ecbd35933cfcd3095fe04",
            },
            "scala-2.12": {
                "scala_compiler": "3023b07cc02f2b0217b2c04f8e636b396130b3a8544a8dfad498a19c3e57a863",
                "scala_library": "f81d7144f0ce1b8123335b72ba39003c4be2870767aca15dd0888ba3dab65e98",
                "scala_reflect": "ffa70d522fc9f9deec14358aa674e6dd75c9dfa39d4668ef15bb52f002ce99fa"
            }
        }
    )
)

But this gave me the error config_setting cannot be in the WORKSPACE file.

So then I tried moving code into a Starlark file.

In tools/build_rules/scala.bzl:

config_setting(
    name = "scala-2.11",
    define_values = {
        "scala": "2.11"
    }
)

config_setting(
    name = "scala-2.12",
    define_values = {
        "scala": "2.12"
    }
)

def scala_version():
    return select(
        {
            "scala-2.11": "2.11.12",
            "scala-2.12": "2.12.6"
        }
    )

def scala_machinery():
    return select(
        {
        "scala-2.11": {
            "scala_compiler": "3e892546b72ab547cb77de4d840bcfd05c853e73390fed7370a8f19acb0735a0",
            "scala_library": "0b3d6fd42958ee98715ba2ec5fe221f4ca1e694d7c981b0ae0cd68e97baf6dce",
            "scala_reflect": "6ba385b450a6311a15c918cf8688b9af9327c6104f0ecbd35933cfcd3095fe04",
        },
        "scala-2.12": {
            "scala_compiler": "3023b07cc02f2b0217b2c04f8e636b396130b3a8544a8dfad498a19c3e57a863",
            "scala_library": "f81d7144f0ce1b8123335b72ba39003c4be2870767aca15dd0888ba3dab65e98",
            "scala_reflect": "ffa70d522fc9f9deec14358aa674e6dd75c9dfa39d4668ef15bb52f002ce99fa"
            }
        }
    )

And back in my WORKSPACE:

load("//tools/build_rules:scala.bzl", "scala_version", "scala_machinery")
scala_repositories(scala_version(), scala_machinery())

But now I get this error:

tools/build_rules/scala.bzl:1:1: name 'config_setting' is not defined

This confuses me, because I thought config_setting() was built in. I can't find where I should load it in from.

So, my questions:

  • How do I load config_setting() into my .bzl file?
  • Or, is there a better way of controlling from the command line which arguments get passed to scala_repositories()?
  • Or, is this just not possible?
$ bazel version
Build label: 0.17.2-homebrew
Build target: bazel-out/darwin-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Fri Sep 28 10:42:37 2018 (1538131357)
Build timestamp: 1538131357
Build timestamp as int: 1538131357
1 Answers

If you call native code from a bzl file, you must use the native. prefix, so in this case you would call native.config_setting.

However, this is going to lead to the same error: config_setting is a BUILD rule, not a WORKSPACE rule.

If you want to change the build tool used for a particular target, you can change the toolchain, and this seems to be supported via the scala_toolchain

And I believe you can use a config to select the toolchain.

I'm unfamiliar with what scala_repositories does. I hope it defines the toolchain with a proper versioned name, so that you can reference the wanted toolchain correctly. And I hope you can invoke it twice in the same workspace, otherwise I think there is no solution.

Related