Skip to content

Conversation

@agluszak
Copy link
Contributor

@agluszak agluszak commented Nov 25, 2025

Implement automatic generation of kotlinc options using the official kotlin-compiler-arguments-description artifact from JetBrains.

  • Auto-generated options: WriteKotlincCapabilities generates both capabilities.bzl (flag existence/stability metadata) and generated_opts.bzl (full typed Starlark options) from the compiler metadata artifact.
  • Simplified maintenance: Manual _KOPTS dict replaced with GENERATED_KOPTS import, with _MANUAL_KOPTS for special cases only.

Changes:

  • Add kotlin-compiler-arguments-description dependency (version must match kotlin compiler version)
  • Rewrite WriteKotlincCapabilities to use the new artifact
  • Generate generated_opts_X.Y.bzl with attr.bool for booleans, attr.string for strings, attr.string_list for arrays
  • Simplify opts.kotlinc.bzl to merge generated + manual options

Closes #1444

Copy link
Collaborator

@restingbull restingbull left a comment

Choose a reason for hiding this comment

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

Aside from a few small backward compatibility issues, the approach looks ok.

Need to be solved:

  • Enumerated flags will need a set of valid values -- because you'd rather have the build fail in analysis that compiler invocation. Some invocations can live very deep in a build graph, which will cause maintenance headaches.
  • Flags must live on an allow list. The friends flag is the best example, as it pretty much cannot be used correctly, and overlaps with existing rule functionality.

Finally, please remove extra_kotlinc_args. That will inevitably be misused in large code repositories for all the reasons that the flags are treated as attributes.

… kotlin-compiler-arguments-description artifact from JetBrains.

  - Auto-generated options: WriteKotlincCapabilities generates both capabilities.bzl (flag existence/stability metadata) and generated_opts.bzl (full typed Starlark options) from the compiler metadata artifact.
  - Simplified maintenance: Manual _KOPTS dict replaced with GENERATED_KOPTS import, with _MANUAL_KOPTS for special cases only.

  Changes:

  - Add kotlin-compiler-arguments-description dependency (version must match kotlin compiler version)
  - Rewrite WriteKotlincCapabilities to use the new artifact
  - Generate generated_opts_X.Y.bzl with attr.bool for booleans, attr.string for strings, attr.string_list for arrays
  - Simplify opts.kotlinc.bzl to merge generated + manual options
map_value_to_flag = _map_string_flag("-jvm-default"),
),
"jvm_target": struct(
flag = "-jvm-target",
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is set by the task, so it shouldn't be visible.

@shalupov
Copy link

shalupov commented Jan 9, 2026

@agluszak if we are making incompatible release anyway (Boolean -> String), it's worth comparing compiler arguments before and after, including default values, so it won't be a complete surprise (and document those changes in changelog).

@agluszak
Copy link
Contributor Author

@agluszak if we are making incompatible release anyway (Boolean -> String)

that's reverted

@agluszak
Copy link
Contributor Author

@restingbull okay, I think everything's been addressed

# Conflicts:
#	docs/kotlin.md
#	src/main/starlark/core/options/opts.kotlinc.bzl
#	src/main/starlark/core/repositories/kotlin/capabilities_2.3.bzl.com_github_jetbrains_kotlin.bazel
type = attr.bool,
value_to_flag = {True: ["-Xallow-unstable-dependencies"]},
),
"x_annotation_default_target": struct(
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be an enum

type = attr.bool,
value_to_flag = {True: ["-Xcheck-phase-conditions"]},
),
"x_common_sources": struct(
Copy link
Collaborator

Choose a reason for hiding this comment

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

This adds source files to the compilation -- it's not a reasonable option for the compiler.

value_to_flag = {True: ["-Xexplicit-backing-fields"]},
),
"x_fragment_dependency": struct(
flag = "-Xfragment-dependency",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another path flag.

value_to_flag = None,
map_value_to_flag = _map_string_list_flag("-Xfragment-dependency"),
),
"x_fragment_friend_dependency": struct(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Path.

map_value_to_flag = _map_string_list_flag("-Xfragment-friend-dependency"),
),
"x_fragment_refines": struct(
flag = "-Xfragment-refines",
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a wierd one. I'm not sure this make sense to be exposed as an option -- it seems more like a feature that should be defined in the rules.

value_to_flag = None,
map_value_to_flag = _map_string_list_flag("-Xfragment-refines"),
),
"x_fragment_sources": struct(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Path flag.

value_to_flag = None,
map_value_to_flag = _map_string_list_flag("-Xfragment-sources"),
),
"x_fragments": struct(
Copy link
Collaborator

Choose a reason for hiding this comment

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

See other -Xfragment flags. Pretty sure this are difficult, if not impossible to use correct when compiling via the rules.

Copy link
Collaborator

@restingbull restingbull left a comment

Choose a reason for hiding this comment

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

Given how often flags that do not make sense within the rules are sneaking into the generated options, it seems like having an allow list would make a lot more sense than a disallow list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support the new -jvm-default option along with existing -Xjvm-default

3 participants