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

Support multiple execution platforms with system_cxx_toolchain #629

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

Overhatted
Copy link
Contributor

@Overhatted Overhatted commented Apr 28, 2024

As mentioned in #612, I have a C++ project that can be built for either Linux or Windows, without any cross-compilation so Linux and Windows are also the two execution platforms. Since there is remote execution, I wanted to be able to build for Linux from my Windows machine using RE, and vice versa.

From the response I got in the above issue, I need to add an exec_dep to the toolchain, pointing a compiler target, that then has a target_compatible_with with the execution platform the compiler can run on.

I tried to add the target_compatible_with directly to the toolchain but it didn't work, probably intentional.

So I moved some parts of the current system_cxx_toolchain to a separate NativeCompiler provider that is then returned by some rules defining a compiler. This compiler target then has the target_compatible_with attribute.

Can this be merged or should I just have this toolchain in my own repository? It seems useful for everyone, the only disadvantage I can see being that it is not fully backwards compatible. Hopefully I didn't completely misunderstand how execution platforms are supposed to be used.

I improved the Visual Studio example to use this new updated toolchain to easily support remote execution.

Manual testing

I used the Visual Studio example and setup my RE workers with Buildbarn. Unfortunately Buildbarn's Windows workers don't currently work with the linking step, I haven't investigated why. The build targeting Windows made from a Windows host works because the linking is done locally but the one done from a Linux host fails.

Local builds

Windows

buck2 build --target-platforms //buck2_utils/platforms:windows_debug :main

Passes

Linux

buck2 build --target-platforms //buck2_utils/platforms:linux_debug :main

Passes

Remote builds

From Windows

Target Windows
buck2 build --no-remote-cache -c buck2_re_client.enabled=true --target-platforms //buck2_utils/platforms:windows_debug :main

Passes

Target Linux
buck2 build --no-remote-cache -c buck2_re_client.enabled=true --target-platforms //buck2_utils/platforms:linux_debug :main

Passes

From Linux

Target Windows
buck2 build --no-remote-cache -c buck2_re_client.enabled=true --target-platforms //buck2_utils/platforms:windows_debug :main

Linking fails (The system cannot open the device or file specified.)

Target Linux
buck2 build --no-remote-cache -c buck2_re_client.enabled=true --target-platforms //buck2_utils/platforms:linux_debug :main

Passes

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 28, 2024
@Overhatted Overhatted changed the title Multiple target platforms Support multiple execution platforms with system_cxx_toolchain Apr 30, 2024
@Overhatted Overhatted marked this pull request as ready for review April 30, 2024 21:11
@Overhatted Overhatted force-pushed the multiple_target_platforms branch 2 times, most recently from 065fe34 to 5e3b181 Compare May 22, 2024 19:47
@Overhatted
Copy link
Contributor Author

Hello @KapJI, can someone take a look at this PR?

Comment on lines +32 to +33
New-Item -ItemType File -Path $TargetPath -Force | Out-Null
Copy-Item $SourcePath -Destination $TargetPath | Out-Null
Copy link
Member

Choose a reason for hiding this comment

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

Why 2 steps instead of 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because Copy-Item doesn't create the target directory if it doesn't exist: https://stackoverflow.com/questions/7523497/should-copy-item-create-the-destination-directory-structure
For example the first time the install script is ran, the target "$InstallDirectory" does not exist which makes Copy-Item fail when it tries to copy "main.exe" to "install/main.exe".

path_clang_tools = rule(
impl = _path_clang_tools_impl,
attrs = {
"os": attrs.string(default = _get_current_os()),
Copy link
Member

Choose a reason for hiding this comment

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

This means when you want to target Linux from Windows, it's still be "windows" here. You probably want to have something like _exec_os_type in prelude.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the tip. I had't realised that the default could also be a select. But here, since the system_cxx_toolchain doesn't do cross-compilation, we want the "os" to be the target OS so I changed this to buck.target_os_type_arg.

@@ -11,7 +11,14 @@ fbsource = none
buck = none

[parser]
target_platform_detector_spec = target:root//...->toolchains//:default
target_platform_detector_spec = target:root//...->root//buck2_utils/platforms:windows_debug
Copy link
Member

Choose a reason for hiding this comment

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

Why change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Previously the visual_studio example was using a single target platform (toolchains//:default) that would change one of the constraint_values (debug/release) depending on a read_config call. In this PR I changed the example by creating 4 different target platforms (windows/linux and debug/release) in root//buck2_utils/platforms/BUCK. I only changed this because it seemed like the intended way to use Buck2. Now the target platform is specified by using the "--target-platforms" command line option.

@@ -0,0 +1,38 @@
load(":defs.bzl", "execution_platform")

execution_platform(
Copy link
Member

Choose a reason for hiding this comment

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

To make it less confusing.

Suggested change
execution_platform(
execution_platforms(

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 did this change manually because I also needed to make the change in buck2_utils/platforms/defs.bzl.

load("@prelude//toolchains/msvc:tools.bzl", "VisualStudio")
load("@prelude//utils:cmd_script.bzl", "ScriptOs", "cmd_script")

NativeCompiler = provider(
Copy link
Member

Choose a reason for hiding this comment

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

"Compiler" usually means single tool, maybe something like "SystemCxxToolchainInfo"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

def _run_info(args):
return None if args == None else RunInfo(args = [args])

def _get_default_compiler() -> str:
Copy link
Member

Choose a reason for hiding this comment

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

Should this be selectified?

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 selectified this.

"c_flags": attrs.list(attrs.string(), default = []),
"compiler": attrs.string(default = "cl.exe" if host_info().os.is_windows else "clang"),
Copy link
Member

Choose a reason for hiding this comment

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

This is a breaking change for anyone who uses these attributes in system_cxx_toolchain. I don't think we should remove them.

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 reintroduced the attributes and I think the end result is fully backwards compatible. I did some tests on Linux and Windows using those parameters.

@Overhatted Overhatted force-pushed the multiple_target_platforms branch 3 times, most recently from f97fbe4 to f1e1010 Compare June 4, 2024 21:21
In an earlier version of Buck2, read_config would only work if the cell of the BUCK file had a .buckconfig.
That behavior has now changed so the empty .buckconfig file is no longer needed.
link_binaries_locally=True and archive_objects_locally=True were already there.
It's probably better to enable local only for all.
@Overhatted
Copy link
Contributor Author

After the review, I made all the changes to this PR in the last 7 commits where the first 6 were done to fix issues pointed out in the review and the last one was done as another change.

@Overhatted
Copy link
Contributor Author

@KapJI Not sure if I'm supposed to ping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants