Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal cross-build support #1546

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
24 changes: 24 additions & 0 deletions examples/crossbuild/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
load("@io_bazel_rules_scala//scala:scala.bzl", "scala_binary", "scala_library")

scala_library(
name = "hello211",
srcs = ["Hello211.scala"],
scala_version = "2.11.12",
)

scala_library(
name = "hello213",
srcs = ["Hello213.scala"],
scala_version = "2.13.12",
)

# scala 3.3.1 is default for this workspace
scala_binary(
name = "main",
srcs = ["Main.scala"],
main_class = "hello",
deps = [
":hello211",
":hello213",
],
)
5 changes: 5 additions & 0 deletions examples/crossbuild/Hello211.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package examples.crossbuild

class Hello211 {
def hello = "Hello"
}
5 changes: 5 additions & 0 deletions examples/crossbuild/Hello213.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package examples.crossbuild

class Hello213 {
def hello = "Hello"
}
4 changes: 4 additions & 0 deletions examples/crossbuild/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import examples.crossbuild.Hello211
import examples.crossbuild.Hello213

@main def hello = println(s"${(new Hello211).hello} from scala 2.11, ${(new Hello213).hello} from scala 2.13")
47 changes: 47 additions & 0 deletions examples/crossbuild/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
workspace(name = "cross_build")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add this workspace to /test/shell/test_examples.sh


load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "bazel_skylib",
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
],
)

local_repository(
name = "io_bazel_rules_scala",
path = "../..",
)

load("@io_bazel_rules_scala//:scala_config.bzl", "scala_config")

scala_config(
scala_version = "3.3.1",
scala_versions = [
"2.11.12",
"2.13.12",
],
)

load(
"@io_bazel_rules_scala//scala:scala.bzl",
"rules_scala_setup",
"rules_scala_toolchain_deps_repositories",
)

rules_scala_setup()

rules_scala_toolchain_deps_repositories(fetch_sources = True)

load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")

rules_proto_dependencies()

rules_proto_toolchains()

load("@io_bazel_rules_scala//scala:toolchains.bzl", "scala_register_toolchains")

scala_register_toolchains()
102 changes: 3 additions & 99 deletions scala/BUILD
Original file line number Diff line number Diff line change
@@ -1,68 +1,12 @@
load("@rules_java//java:defs.bzl", "java_import", "java_library")
load("//scala:providers.bzl", "declare_deps_provider")
load("//scala:scala.bzl", "setup_scala_toolchain")
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION")
load("//scala:scala.bzl", "declare_dep_providers", "setup_scala_toolchains")

toolchain_type(
name = "toolchain_type",
visibility = ["//visibility:public"],
)

_SCALA_COMPILE_CLASSPATH_DEPS = [
"@io_bazel_rules_scala_scala_compiler",
"@io_bazel_rules_scala_scala_library",
] + (["@io_bazel_rules_scala_scala_reflect"] if SCALA_MAJOR_VERSION.startswith("2") else [
"@io_bazel_rules_scala_scala_interfaces",
"@io_bazel_rules_scala_scala_tasty_core",
"@io_bazel_rules_scala_scala_asm",
"@io_bazel_rules_scala_scala_library_2",
])

_SCALA_LIBRARY_CLASSPATH_DEPS = [
"@io_bazel_rules_scala_scala_library",
] + (["@io_bazel_rules_scala_scala_reflect"] if SCALA_MAJOR_VERSION.startswith("2") else [
"@io_bazel_rules_scala_scala_library_2",
])

_SCALA_MACRO_CLASSPATH_DEPS = [
"@io_bazel_rules_scala_scala_library",
] + (["@io_bazel_rules_scala_scala_reflect"] if SCALA_MAJOR_VERSION.startswith("2") else [
"@io_bazel_rules_scala_scala_library_2",
])

_PARSER_COMBINATORS_DEPS = ["@io_bazel_rules_scala_scala_parser_combinators"]

_SCALA_XML_DEPS = ["@io_bazel_rules_scala_scala_xml"]

_SEMANTICDB_DEPS = ["@org_scalameta_semanticdb_scalac"] if SCALA_MAJOR_VERSION.startswith("2") else []

setup_scala_toolchain(
name = "default_toolchain",
scala_compile_classpath = _SCALA_COMPILE_CLASSPATH_DEPS,
scala_library_classpath = _SCALA_LIBRARY_CLASSPATH_DEPS,
scala_macro_classpath = _SCALA_MACRO_CLASSPATH_DEPS,
use_argument_file_in_runner = True,
)

setup_scala_toolchain(
name = "unused_dependency_checker_error_toolchain",
dependency_tracking_method = "ast-plus",
scala_compile_classpath = _SCALA_COMPILE_CLASSPATH_DEPS,
scala_library_classpath = _SCALA_LIBRARY_CLASSPATH_DEPS,
scala_macro_classpath = _SCALA_MACRO_CLASSPATH_DEPS,
unused_dependency_checker_mode = "error",
)

setup_scala_toolchain(
name = "minimal_direct_source_deps",
dependency_mode = "plus-one",
dependency_tracking_method = "ast",
scala_compile_classpath = _SCALA_COMPILE_CLASSPATH_DEPS,
scala_library_classpath = _SCALA_LIBRARY_CLASSPATH_DEPS,
scala_macro_classpath = _SCALA_MACRO_CLASSPATH_DEPS,
strict_deps_mode = "error",
unused_dependency_checker_mode = "error",
)
setup_scala_toolchains()

java_import(
name = "bazel_test_runner_deploy",
Expand All @@ -76,44 +20,4 @@ java_library(
visibility = ["//visibility:public"],
)

declare_deps_provider(
name = "scala_compile_classpath_provider",
deps_id = "scala_compile_classpath",
visibility = ["//visibility:public"],
deps = _SCALA_COMPILE_CLASSPATH_DEPS,
)

declare_deps_provider(
name = "scala_library_classpath_provider",
deps_id = "scala_library_classpath",
visibility = ["//visibility:public"],
deps = _SCALA_LIBRARY_CLASSPATH_DEPS,
)

declare_deps_provider(
name = "scala_macro_classpath_provider",
deps_id = "scala_macro_classpath",
visibility = ["//visibility:public"],
deps = _SCALA_MACRO_CLASSPATH_DEPS,
)

declare_deps_provider(
name = "scala_xml_provider",
deps_id = "scala_xml",
visibility = ["//visibility:public"],
deps = _SCALA_XML_DEPS,
)

declare_deps_provider(
name = "parser_combinators_provider",
deps_id = "parser_combinators",
visibility = ["//visibility:public"],
deps = _PARSER_COMBINATORS_DEPS,
)

declare_deps_provider(
name = "semanticdb_provider",
deps_id = "semanticdb",
visibility = ["//visibility:public"],
deps = _SEMANTICDB_DEPS,
)
declare_dep_providers()
24 changes: 24 additions & 0 deletions scala/private/common_attributes.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,30 @@ implicit_deps = {
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac"),
allow_files = True,
),
"_scalac_before_2_12_13": attr.label(
Copy link
Collaborator

@simuons simuons Feb 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, @mateuszkuta256, thanks for PR. Does that mean that every scala version needs to be setup in workspace for this toolchain to work? ie all flavours of scalac worker needs to be compiled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey, let me explain this change in detail, as I am searching for an alternative solution anyway...
sources for scalac are defined here
these are conditional upon: if SCALA_MAJOR_VERSION.startswith("2")
so I simply made a few scalac_... targets, separate for 2.11, 2 and 3
would love to keep a single scalac, but missing an idea of how to achieve that...
if we don't specify e.g. scala 3.3.1 in a config setting then I believe _scalac3 is skipped (?)
at least the build is successful without complaining that scala3 deps are missing

Copy link
Collaborator

@simuons simuons Feb 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I see. At this point it's just a label and magic happens on action when you select scalac.

As for alternatives I was playing with toolchain setup where each scala version is encapsulated/scoped in it's own repository and compiles it's own scalac (similar to remote_java_repository). simuons@919471a Still not sure where this leads to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you got rid of the circular dependency between toolchain and scalac caused by toolchain_deps:scala_compile_classpath dep. It is something that I was missing in my first drafts and allows to apply nice solutions 👍
in the meantime, I tested something like this mateuszkuta256@f247cc8
_scalac is removed from implicit attributes and attached to scala_library and other rules. Then we can make a version specific implementations, e.g.
scala_3_3_binary = make_scala_binary(scala_version = "3.3.1")
since you found a way to remove circular dependencies, the same thing can be applied directly on the toolchain here
from the user perspective, it's even nicer, because can use regular scala_library without making version specific one

executable = True,
cfg = "exec",
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac:scalac_before_2_12_13"),
allow_files = True,
),
"_scalac_after_2_12_13_and_before_2_13_12": attr.label(
executable = True,
cfg = "exec",
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac:scalac_after_2_12_13_and_before_2_13_12"),
allow_files = True,
),
"_scalac_after_2_13_12": attr.label(
executable = True,
cfg = "exec",
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac:scalac_after_2_13_12"),
allow_files = True,
),
"_scalac_3": attr.label(
executable = True,
cfg = "exec",
default = Label("@io_bazel_rules_scala//src/java/io/bazel/rulesscala/scalac:scalac_3"),
allow_files = True,
),
"_exe": attr.label(
executable = True,
cfg = "exec",
Expand Down
51 changes: 31 additions & 20 deletions scala/private/macros/scala_repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ load(
"@io_bazel_rules_scala//scala:scala_cross_version.bzl",
_default_maven_server_urls = "default_maven_server_urls",
)
load("//third_party/repositories:repositories.bzl", "repositories")
load("//third_party/repositories:repositories.bzl", "repositories", "toolchain_repositories")
load(
"@io_bazel_rules_scala_config//:config.bzl",
"SCALA_MAJOR_VERSION",
"SCALA_MINOR_VERSION",
"SCALA_VERSION",
"SCALA_VERSIONS",
)

def _dt_patched_compiler_impl(rctx):
Expand Down Expand Up @@ -122,36 +123,27 @@ def rules_scala_setup(scala_compiler_srcjar = None):

dt_patched_compiler_setup(scala_compiler_srcjar)

ARTIFACT_IDS = [
"io_bazel_rules_scala_scala_library",
"io_bazel_rules_scala_scala_compiler",
"io_bazel_rules_scala_scala_reflect",
"io_bazel_rules_scala_scala_xml",
"io_bazel_rules_scala_scala_parser_combinators",
"org_scalameta_semanticdb_scalac",
] if SCALA_MAJOR_VERSION.startswith("2") else [
"io_bazel_rules_scala_scala_library",
"io_bazel_rules_scala_scala_compiler",
"io_bazel_rules_scala_scala_interfaces",
"io_bazel_rules_scala_scala_tasty_core",
"io_bazel_rules_scala_scala_asm",
"io_bazel_rules_scala_scala_xml",
"io_bazel_rules_scala_scala_parser_combinators",
"io_bazel_rules_scala_scala_library_2",
]

def rules_scala_toolchain_deps_repositories(
maven_servers = _default_maven_server_urls(),
overriden_artifacts = {},
fetch_sources = False,
validate_scala_version = True):
repositories(
for_artifact_ids = ARTIFACT_IDS,
for_artifact_ids = _artifact_ids(SCALA_VERSION),
maven_servers = maven_servers,
fetch_sources = fetch_sources,
overriden_artifacts = overriden_artifacts,
validate_scala_version = validate_scala_version,
)
for scala_version in SCALA_VERSIONS:
toolchain_repositories(
scala_version,
for_artifact_ids = _artifact_ids(scala_version),
maven_servers = maven_servers,
fetch_sources = fetch_sources,
overriden_artifacts = overriden_artifacts,
validate_scala_version = validate_scala_version,
)

def scala_repositories(
maven_servers = _default_maven_server_urls(),
Expand All @@ -168,3 +160,22 @@ def scala_repositories(
overriden_artifacts,
fetch_sources,
)

def _artifact_ids(scala_version):
return [
"io_bazel_rules_scala_scala_library",
"io_bazel_rules_scala_scala_compiler",
"io_bazel_rules_scala_scala_reflect",
"io_bazel_rules_scala_scala_xml",
"io_bazel_rules_scala_scala_parser_combinators",
"org_scalameta_semanticdb_scalac",
] if scala_version.startswith("2") else [
"io_bazel_rules_scala_scala_library",
"io_bazel_rules_scala_scala_compiler",
"io_bazel_rules_scala_scala_interfaces",
"io_bazel_rules_scala_scala_tasty_core",
"io_bazel_rules_scala_scala_asm",
"io_bazel_rules_scala_scala_xml",
"io_bazel_rules_scala_scala_parser_combinators",
"io_bazel_rules_scala_scala_library_2",
]
Loading