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

Fix Linux to Windows cross compilation of py_binary, java_binary and sh_binary using MinGW #16019

Conversation

jesseschalken
Copy link

@jesseschalken jesseschalken commented Aug 2, 2022

This branch

  • Fixes various compilation and runtime errors when building the C++ Windows launcher using a MinGW toolchain on Linux
  • Fixes Windows target platform detection to use the target platform instead of the host platform
  • Removes the execution platform configuration from the $launcher attributes so that the launcher is compiled for the target platform
  • Adds target platform constraints to the autogenerated Windows toolchains so that they can be selected with target platform constraints as a replacement for --compiler=... when using --incompatible_enable_cc_toolchain_resolution


static {
try {
Label osConstraintSettingLabel = Label.parseAbsolute("@platforms//os:os", ALWAYS_FALLBACK);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This will probably fail with Bzlmod as it doesn't use a repository mapping - with Bzlmod, the platforms module will manifest as a repository named something like @platforms~0.0.4.

You should be able to use:

Label.parseWithRepoContext("@platforms//os:os", repoContext.of(RepositoryName.MAIN, getRule.getPackage().getRepositoryMapping()));

but that won't work from a static context.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks. Should I just parse the labels directly in isTargetOsWindows?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I unfortunately don't know enough about constraint handling in Java code to answer that question - I would leave it for the reviewer.

Copy link
Collaborator

@fmeum fmeum Aug 2, 2022

Choose a reason for hiding this comment

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

Thinking about this some more, it's more involved and what I suggested above is incorrect: The rule may be instantiated in any repository, not necessarily the main repository. But these repositories may not depend on the platforms module and thus may not even see @platforms in their repository mapping.

@Wyverald can probably help here, but may still be OOO.

Edit: A possible solution could be to introduce aliases for the constraint values in bazel_tools, which AFAIK is always available under that name. This would probably allow you to keep using Label.parseAbsolute, so better keep that code around until someone more knowledgeable suggests a solution.

Copy link
Author

Choose a reason for hiding this comment

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

@Wyverald Do you happen to know the best way to test for the @platforms//os:windows constraint on the target platform inside a Java rule implementation?

Copy link
Member

Choose a reason for hiding this comment

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

@comius would be the best person to answer this, I think. I really don't know whether we're supposed to grab labels like this in Java code.

With that said, what @fmeum pointed out still stands -- we can't rely on the current repository having visibility into the @platforms repo. Depending on the answer to the previous question, we might have ways to work around this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please move all references to Windows out of RuleContext.

RuleContext should remain a general device, and is no place for specifics. You can either put the code into into each rule or providing a helper class under rules or bazel/rules package.

This will allso make it possible to Starlarkify the rule's your modifying. There's already available API in Starlark ctx.target_platform_has_constraint.

Creating a providers instead of using an implicit dependency to @platforms//os:windows is also not rewritable to Starlark (you can't create a ConstraintInfoProvider). Please use the example you found in copy_file.

Copy link
Author

Choose a reason for hiding this comment

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

@comius Thanks. How do I get a Label for @platforms//os:windows to use in Bazel{Sh,Py,Java}BinaryRule.build? It looks like RuleDefinitionEnvironment can only give Labels for things in @bazel_tools. Will this work?

.add(
    attr("_windows_constraint", LABEL)
        .value(Label.parseAbsoluteUnchecked("@platforms//os:windows")))

Copy link
Member

Choose a reason for hiding this comment

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

the above will likely not work with Bzlmod (same reason as @fmeum described earlier). @bazel_tools is special since it's a "built-in module" which is shipped with the Bazel binary; @platforms is not.

You would be able to use labels from @platforms if you were defining these rules in Starlark (in the builtins_bzl stuff, for example). Not sure where we are on that front -- I think java_binary is already Starlarkified?

Copy link
Contributor

@comius comius Sep 2, 2022

Choose a reason for hiding this comment

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

It think this would work, except if I'm missing some bzlmod machinery that is invoked on Labels in Starlark. It's not different from other implicit dependencies - which also point at various different location outside of Bazel.

There's another problem: it will only work in Bazel, not in a monorepo. We use getToolsRepository to map it to absolute label. Can you extend it with getPlatfromsRepository()? This should make it possible to remap @platforms as well.

@jesseschalken
Copy link
Author

@sgowroji Thanks. I've merged master but I am yet to fix the Windows test failures (I'm still trying to get them to pass locally on master). Hoping someone beats me to it.

Copy link
Contributor

@comius comius left a comment

Choose a reason for hiding this comment

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

Thanks for your changes! I'm just working on C++ plaformisation and your change probably fixes a couple of more things than expected, judging from the title :)


static {
try {
Label osConstraintSettingLabel = Label.parseAbsolute("@platforms//os:os", ALWAYS_FALLBACK);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please move all references to Windows out of RuleContext.

RuleContext should remain a general device, and is no place for specifics. You can either put the code into into each rule or providing a helper class under rules or bazel/rules package.

This will allso make it possible to Starlarkify the rule's your modifying. There's already available API in Starlark ctx.target_platform_has_constraint.

Creating a providers instead of using an implicit dependency to @platforms//os:windows is also not rewritable to Starlark (you can't create a ConstraintInfoProvider). Please use the example you found in copy_file.

@@ -37,25 +37,24 @@ private AnalysisTestActionBuilder() {}
*/
public static void writeAnalysisTestAction(
RuleContext ruleContext, AnalysisTestResultInfo testResultInfo) {
// TODO(laszlocsomor): Use the execution platform, not the host platform.
boolean isExecutedOnWindows = OS.getCurrent() == OS.WINDOWS;
boolean isTargetOsWindows = ruleContext.isTargetOsWindows();
Copy link
Contributor

Choose a reason for hiding this comment

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

cc @brandjon @tetromino
No need to do anything (maybe a TODO) otherwise just a driveby comment.

Do you know why we need special casingAnalysisTestResultInfo for Windows? This should also be general like RuleContext.

@@ -26,7 +26,11 @@ private OsUtils() {
}

public static String executableExtension(OS os) {
return os == OS.WINDOWS ? ".exe" : "";
return executableExtension(os == OS.WINDOWS);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please mark this function private. We don't want to encourage people to use it.

Comment on lines 35 to 36

/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Please mark the following function executableExtension() @deprecated. There are some uses left, that should be cleaned up if we want C++ platformization to fully work.

@comius
Copy link
Contributor

comius commented Sep 1, 2022

Tests might be failing because --platforms=windows isn't passed (or some autodetection is failing).

@meteorcloudy meteorcloudy added awaiting-user-response Awaiting a response from the author and removed awaiting-review PR is awaiting review from an assigned reviewer labels Oct 18, 2022
@comius
Copy link
Contributor

comius commented Aug 22, 2023

I'm closing this, becuase there's a lack of response for about a year. Feel free to reopen it, if you want to move it along.

@comius comius closed this Aug 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Windows Windows-specific issues and feature requests awaiting-user-response Awaiting a response from the author team-Rules-CPP Issues for C++ rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants