Skip to content

Latest commit

 

History

History
128 lines (116 loc) · 6.68 KB

2020-02-07-toolchain-transition-migration.md

File metadata and controls

128 lines (116 loc) · 6.68 KB
created last updated status reviewers title authors discussion thread
2020-02-07
2020-09-30
Implemented
gregce
cparsons (for Starlark API implications)
Toolchain Transition Migration
katre

Migrating to Toolchain Transitions

For several years, rule authors have been asking for more nuance in how targets depend on their toolchains via toolchain resolution:

  • Some authors want their dependencies in the execution configuration (of the parent target)
  • Some want the target configuration (again, of the parent target)
  • Some want both, depending on what part of the toolchain is being built: bazelbuild/bazel#4067

This is addressed in the proposal for Toolchain Transitions, which is currently being implemented. However, the migration plan in that proposal is out of date and won't easily work: too many different rule sets are using toolchains, and there's no way to coordinate a "flag day" flip of all of them at once. Instead, it is possible to have a new migration plan for the toolchain transition, that will allow rule authors to independently migrate their rules (with some additional work). The plan is to add a new attribute during rule creation, so that individual rules can declare whether or not they are ready for the toolchain transition. There will also be an incompatible flag that overrides that attribute, so that we can assess the overall progress towards migration and begin removing the attribute.

This migration will take at least one, and probably two, major Bazel releases (so, realistically, three to six months), plus an additional release for cleanup.

Migration Steps

Here is the proposed timeline:

  1. Finish implementing the toolchain transition, along with sufficient tests to be comfortable with it.
  2. Add a new attribute, incompatible_use_toolchain_transition, on both Starlark's rule function and the native RuleClass.Builder.
    1. If the rule attribute is true, the rule will depend on toolchains via the toolchain transition.
  3. Add a new incompatible flag, --incompatible_override_toolchain_transition.
    1. If the flag is set to true, the rule attribute is ignored and all rules use the toolchain transition.
  4. Wait for the above to be released.
  5. Rule authors migrate their rules to use toolchain transitions.
    1. See details below.
    2. Create tracking issues against rule sets to alert them of the work needed.
  6. When all rules covered in Bazel's CI are ready, flip the --incompatible_override_toolchain_transition flag to true.
  7. Wait for release.
  8. Remove flag and attribute functionality, leave the incompatible_use_toolchain_transition rule attribute as a no-op.
  9. Rule authors remove use of incompatible_use_toolchain_transition.
  10. Wait for release.
  11. Remove the rule attribute entirely.

Migrating Starlark Rules

Starlark rules can migrate with the following steps:

  1. Add cfg = "exec" or cfg = "target" to all label attributes of your toolchain rule. (ie, to go_toolchain or scala_toolchain)
    1. Use the execution transition for dependencies that will execute as part of the target build.
    2. Use the target transition for dependencies that should be in the same configuration as the target build.
      1. Technically cfg = "target" is not needed, as it is the default, but it is useful to document this clearly.
    3. These changes are permanent.
    4. One possible migration path is the following:
      1. Add cfg = "exec" to every dependency. This is a no-op since currently all dependencies are in the host configuration.
      2. Enable the --incompatible_override_toolchain_transition flag and test builds. The change should be minor, given the similarities between exec and host dependencies, but this will reveal any cases where this isn't true. Typically, this has been seen where the dependency itself has further dependencies, which are now free to transition to unforseen configurations. Feel free to ask for assistance on the bazel-discuss mailing list or on the tracking issue for toolchain transition implementation.
      3. Add cfg = "target" to dependencies where this makes sense. This change can be done individually for each dependency and tested/released separately, if desired, to ensure build correctness.
  2. Add incompatible_use_toolchain_transition = True to every rule that uses a toolchain.
    1. That is, every rule that sets toolchains = ["//your/rule:toolchain_type"].
    2. This change will be reverted when the global migration is complete.
  3. Test and release your rules as normal.
  4. When the global toolchain transition migration is complete, remove the incompatible_use_toolchain_transition attribute from your rules.

Note: We have seen failures with the execution transition, specifically in cases where Android and iOS targets depend on a library which uses the execution transition, where the configuration ends up in a confused state and the Android/iOS flags are applied inappropriately. If this should happen, please file an issue and ping @katre to investigate. You can also work around this by temporarily using cfg = 'host' for the attribute, to simulate the current behavior, instead of cfg = 'exec'.

Migrating Native Rules

Native rules migrate similarly to Starlark rules:

  1. Add cfg(ExecutionTransitionFactory.create()) to the correct attributes of your toolchain rule. (ie, to cc_toolchain or java_toolchain)
    1. Use the execution transition for dependencies that will execute as part of the target build.
    2. Dependencies that should be in the same configuration as the target build do not need anything.
    3. These changes are permanent.
  2. Add builder.useToolchainTransition(true) to every rule that uses a toolchain.
    1. That is, every rule that calls builder.addRequiredToolchains().
    2. This is inherited by child rules and so can be set at a high level.
    3. This change will be reverted when the global migration is complete.
  3. Test your rules as normal, and wait for a Bazel release.
  4. As part of the global toolchain transition migration, your useToolchainTransition calls will be removed.