diff --git a/buck2/cpp/.buckconfig b/buck2/cpp/.buckconfig index 3a5c999f..c3ac155e 100644 --- a/buck2/cpp/.buckconfig +++ b/buck2/cpp/.buckconfig @@ -1,3 +1,17 @@ +# Copyright 2022 EngFlow Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + [cells] root = . prelude = prelude diff --git a/buck2/cpp/BUCK b/buck2/cpp/BUCK index 6e91ee49..2fa862fd 100644 --- a/buck2/cpp/BUCK +++ b/buck2/cpp/BUCK @@ -19,3 +19,33 @@ cxx_binary( exec_compatible_with = ["//platforms:remote_platform"], default_target_platform = "//platforms:remote_platform", ) + +cxx_binary( + name = "cpp", + srcs = ["main.cc"], + deps = [":cpp_lib"], + exec_compatible_with = ["//platforms:remote_platform"], + default_target_platform = "//platforms:remote_platform", +) + +cxx_library( + name = "cpp_lib", + srcs = [ + "hello.cc", + ], + exported_headers = glob(["**/*.h"]), + visibility = ["PUBLIC"], + exec_compatible_with = ["//platforms:remote_platform"], + default_target_platform = "//platforms:remote_platform", +) + +cxx_test( + name = "cpp_test", + srcs = ["hello_test.cc"], + deps = [ + ":cpp_lib", + ], + exec_compatible_with = ["//platforms:remote_platform"], + default_target_platform = "//platforms:remote_platform", + remote_execution_action_key_providers = "//platforms:remote_execution_action_keys", +) diff --git a/buck2/cpp/README.md b/buck2/cpp/README.md index 347ce918..f75bbd7f 100644 --- a/buck2/cpp/README.md +++ b/buck2/cpp/README.md @@ -11,15 +11,19 @@ It is based on two existing samples in the Buck2 upstream repo: In the `platforms` cell we specify: * The platform used for remote execution in this project `root//platforms:remote_platform`, which includes the definition of the Docker image used for remote execution, and that defines constraints for targets to run in the remote execution environment. This platform provides an `ExecutionPlatformRegistrationInfo` a `ConfigurationInfo` and a `PlatformInfo` to be able to be used in the `.buckconfig`, and in the `exec_compatible_with` and `default_target_platform` of `cxx_*` rules. +* The `root//platforms:remote_execution_action_keys` target that provides a `BuildModeInfo` which is necessary for the prelude to correctly configure remote execution of tests. It defines two attributes that can be used as cache silo keys. In the `toolchains` cell we specify: * The c++ toolchain `root//toolchains:cxx_tools_info_toolchain` that is compatible with the remote execution environment. * The clang tools, `root//toolchains:path_clang_tools, which is used by the c++ toolchain, and specifies the tools installed in the Docker image. +* The remote test execution toolchain, `root//toolchains:remote_test_execution_toolchain`. This toolchain defines platform options in the form of `capabilities`. Critically these include the `container-image`. The main `BUCK` file defines: -* A `cxx_binary` binary target that has the `exec_compatible_with` attr pointing to the `root//platforms:remote_platform` target and the `default_target_platform` attr pointing to the `root//platforms:remote` target. +* A `cxx_binary` target that has the `exec_compatible_with` as well as the `default_target_platform` attrs pointing to the `root//platforms:remote_platform`. +* A `cxx_library`target that has the `exec_compatible_with` as well as the `default_target_platform` attrs pointing to the `root//platforms:remote_platform`. +* A `cxx_test` target that has the `exec_compatible_with` as well as the `default_target_platform` attrs pointing to the `root//platforms:remote_platform`. It also has a `remote_execution_action_key_providers` attr that points to the `root//platforms:remote_execution_action_keys` target. ### Relevant configs in `.buckconfig` @@ -40,9 +44,14 @@ http_headers = x-engflow-auth-method:jwt-v0,x-engflow-auth-token:LONG_JW Clone the repository and replace the relevant configs in `.buckconfig`. -Build and run the example: +Build the example: ``` -buck2 build //:main -buck2 run -v 4 //:main +buck2 build //:cpp_lib +``` + +Test the example: + +``` +buck2 test //:cpp_test ``` diff --git a/buck2/cpp/hello.cc b/buck2/cpp/hello.cc new file mode 100644 index 00000000..631a7fd0 --- /dev/null +++ b/buck2/cpp/hello.cc @@ -0,0 +1,7 @@ +#include "hello.h" + +#include + +std::string hello() { + return "hello"; +} diff --git a/buck2/cpp/hello.h b/buck2/cpp/hello.h new file mode 100644 index 00000000..8df9418b --- /dev/null +++ b/buck2/cpp/hello.h @@ -0,0 +1,8 @@ +#ifndef cpp_hello_h +#define cpp_hello_h + +#include + +std::string hello(); + +#endif diff --git a/buck2/cpp/hello_test.cc b/buck2/cpp/hello_test.cc new file mode 100644 index 00000000..97b455a2 --- /dev/null +++ b/buck2/cpp/hello_test.cc @@ -0,0 +1,11 @@ +#include +#include "hello.h" + +int main() { + auto got = hello(); + if (got != "hello") { + std::cerr << "got '" << got << "', want 'hello'" << std::endl; + return 1; + } + return 0; +} diff --git a/buck2/cpp/main.cc b/buck2/cpp/main.cc new file mode 100644 index 00000000..57010349 --- /dev/null +++ b/buck2/cpp/main.cc @@ -0,0 +1,7 @@ +#include +#include "hello.h" + +int main() { + std::cout << hello() << std::endl; + return 0; +} diff --git a/buck2/cpp/platforms/BUCK b/buck2/cpp/platforms/BUCK index 790deec2..8e4f659a 100644 --- a/buck2/cpp/platforms/BUCK +++ b/buck2/cpp/platforms/BUCK @@ -1,4 +1,19 @@ +# Copyright 2022 EngFlow Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + load(":defs.bzl", "platforms") +load(":defs.bzl", "action_keys") # This platform configures details of remote execution. platforms( @@ -6,3 +21,12 @@ platforms( cpu_configuration = "config//cpu:x86_64", os_configuration = "config//os:linux", ) + +# This action_key provides a default BuildModeInfo that is needed for RE of tests to function properly. +# The values in `cell` and `mode` can be used, in practice, to create cache silos. Any values can be given to these attributes. +action_keys( + name = "remote_execution_action_keys", + cell = "standard", + mode = "standard", + visibility = ["PUBLIC"], +) diff --git a/buck2/cpp/platforms/defs.bzl b/buck2/cpp/platforms/defs.bzl index 9da90572..830d53fb 100644 --- a/buck2/cpp/platforms/defs.bzl +++ b/buck2/cpp/platforms/defs.bzl @@ -14,6 +14,8 @@ # This platform is essentially the same as the one provided in https://github.com/facebook/buck2/blob/804d62242214455d51787f7c8c96a1e12c75ec32/examples/remote_execution/engflow/platforms/defs.bzl # The main difference is we enable passing CPU and OS constraints and we use the sample EngFlow RE image. +load("@prelude//:build_mode.bzl", "BuildModeInfo") + def _platforms(ctx): constraints = dict() constraints.update(ctx.attrs.cpu_configuration[ConfigurationInfo].constraints) @@ -49,6 +51,12 @@ def _platforms(ctx): PlatformInfo(label = str(name), configuration = configuration), ] +def _action_keys(ctx): + return [ + DefaultInfo(), + BuildModeInfo(cell = ctx.attrs.cell, mode = ctx.attrs.mode), + ] + platforms = rule( attrs = { "cpu_configuration": attrs.dep(providers = [ConfigurationInfo]), @@ -56,3 +64,11 @@ platforms = rule( }, impl = _platforms ) + +action_keys = rule( + attrs = { + "cell": attrs.string(), + "mode": attrs.string(), + }, + impl = _action_keys +) diff --git a/buck2/cpp/toolchains/BUCK b/buck2/cpp/toolchains/BUCK index b4e48701..96b30a3b 100644 --- a/buck2/cpp/toolchains/BUCK +++ b/buck2/cpp/toolchains/BUCK @@ -13,6 +13,8 @@ # limitations under the License. load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain") load("@prelude//toolchains:cxx.bzl", "cxx_tools_info_toolchain") +load("@prelude//toolchains:remote_test_execution.bzl", "remote_test_execution_toolchain") +load("@prelude//tests:test_toolchain.bzl", "noop_test_toolchain") load("tools.bzl", "path_clang_tools") # We use the default system python toolchain in this example, focusing only on configuring the cpp toolchain. @@ -33,6 +35,28 @@ cxx_tools_info_toolchain( name = "cxx", target_compatible_with = ["config//os:linux"], cxx_tools_info = ":clang_tools", - link_style = "static", + visibility = ["PUBLIC"], +) + +# Default toolchain for remote execution of tests. +# Note it defines a profile with a capability that defines the `container-image` that matches the one defined in //platforms:remote_platform. +# Capabilities are passed to the RE service to find workers that match them as Platform options. +remote_test_execution_toolchain( + name = "remote_test_execution", + visibility = ["PUBLIC"], + default_profile = "cxx_re_toolchain", + profiles = { + "cxx_re_toolchain": { + "use_case": "cxx-testing", + "capabilities": { + "container-image" : "docker://gcr.io/bazel-public/ubuntu2004-java11@sha256:69a78f121230c6d5cbfe2f4af8ce65481aa3f2acaaaf8e899df335f1ac1b35b5", + }, + } + }, +) + +# In newer versions of buck2 this toolchain is needed `noop_test_toolchain`. +noop_test_toolchain( + name = "test", visibility = ["PUBLIC"], ) diff --git a/buck2/cpp/toolchains/tools.bzl b/buck2/cpp/toolchains/tools.bzl index b62e65bd..1c3bc720 100644 --- a/buck2/cpp/toolchains/tools.bzl +++ b/buck2/cpp/toolchains/tools.bzl @@ -38,4 +38,4 @@ def _path_clang_tools_impl(_ctx) -> list[Provider]: path_clang_tools = rule( impl = _path_clang_tools_impl, attrs = {}, -) \ No newline at end of file +)