diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/common/cli.hpp | 4 | ||||
-rw-r--r-- | src/buildtool/main/TARGETS | 1 | ||||
-rw-r--r-- | src/buildtool/main/main.cpp | 71 | ||||
-rw-r--r-- | src/buildtool/profile/TARGETS | 9 | ||||
-rw-r--r-- | src/buildtool/profile/profile.cpp | 35 | ||||
-rw-r--r-- | src/buildtool/profile/profile.hpp | 40 |
6 files changed, 145 insertions, 15 deletions
diff --git a/src/buildtool/common/cli.hpp b/src/buildtool/common/cli.hpp index a8acea87..26b284d9 100644 --- a/src/buildtool/common/cli.hpp +++ b/src/buildtool/common/cli.hpp @@ -77,6 +77,7 @@ struct AnalysisArguments { std::vector<std::filesystem::path> graph_file_plain; std::optional<std::filesystem::path> artifacts_to_build_file; std::optional<std::filesystem::path> serve_errors_file; + std::optional<std::string> profile; }; /// \brief Arguments required for describing targets/rules. @@ -345,6 +346,9 @@ static inline auto SetupAnalysisArguments( "File path for dumping the blob identifiers of serve " "errors as json.") ->type_name("PATH"); + app->add_option( + "--profile", clargs->profile, "Location to write the profile to.") + ->type_name("PATH"); if (with_graph) { app->add_option_function<std::string>( "--dump-graph", diff --git a/src/buildtool/main/TARGETS b/src/buildtool/main/TARGETS index 756e275a..0d2cd0ef 100644 --- a/src/buildtool/main/TARGETS +++ b/src/buildtool/main/TARGETS @@ -57,6 +57,7 @@ , ["src/buildtool/logging", "log_level"] , ["src/buildtool/logging", "logging"] , ["src/buildtool/multithreading", "task_system"] + , ["src/buildtool/profile", "profile"] , ["src/buildtool/progress_reporting", "progress"] , ["src/buildtool/progress_reporting", "progress_reporter"] , ["src/buildtool/serve_api/remote", "config"] diff --git a/src/buildtool/main/main.cpp b/src/buildtool/main/main.cpp index b8579b55..2f41ca72 100644 --- a/src/buildtool/main/main.cpp +++ b/src/buildtool/main/main.cpp @@ -68,6 +68,7 @@ #include "src/buildtool/main/install_cas.hpp" #include "src/buildtool/main/version.hpp" #include "src/buildtool/multithreading/task_system.hpp" +#include "src/buildtool/profile/profile.hpp" #include "src/buildtool/progress_reporting/progress.hpp" #include "src/buildtool/serve_api/remote/serve_api.hpp" #include "src/buildtool/storage/config.hpp" @@ -720,6 +721,7 @@ void DumpArtifactsToBuild( } // namespace auto main(int argc, char* argv[]) -> int { + std::optional<gsl::not_null<Profile*>> profile{}; SetupDefaultLogging(); try { auto arguments = ParseCommandLineArguments(argc, argv); @@ -910,6 +912,12 @@ auto main(int argc, char* argv[]) -> int { return kExitFailure; } + // Setup profile logging, if requested + Profile profile_data(arguments.analysis.profile); + if (arguments.analysis.profile) { + profile = &profile_data; + } + // If no execution endpoint was given, the client should default to the // serve endpoint, if given. if (not arguments.endpoint.remote_execution_address.has_value() and @@ -927,6 +935,9 @@ auto main(int argc, char* argv[]) -> int { auto remote_exec_config = CreateRemoteExecutionConfig(arguments.endpoint, arguments.rebuild); if (not remote_exec_config) { + if (profile) { + (*profile)->Write(kExitFailure); + } return kExitFailure; } @@ -946,6 +957,9 @@ auto main(int argc, char* argv[]) -> int { arguments.endpoint, arguments.protocol.hash_type); #endif // BOOTSTRAP_BUILD_TOOL if (not storage_config) { + if (profile) { + (*profile)->Write(kExitFailure); + } return kExitFailure; } auto const storage = Storage::Create(&*storage_config); @@ -1031,6 +1045,9 @@ auto main(int argc, char* argv[]) -> int { traverse_args, &exec_context, eval_root_jobs)) { + if (profile) { + (*profile)->Write(kExitFailure); + } return kExitFailure; } #else @@ -1040,6 +1057,9 @@ auto main(int argc, char* argv[]) -> int { #ifndef BOOTSTRAP_BUILD_TOOL auto lock = GarbageCollector::SharedLock(*storage_config); if (not lock) { + if (profile) { + (*profile)->Write(kExitFailure); + } return kExitFailure; } @@ -1072,18 +1092,25 @@ auto main(int argc, char* argv[]) -> int { main_ws_root, &repo_config, arguments.analysis)) { - return arguments.describe.describe_rule - ? DescribeUserDefinedRule( - id->target, - &repo_config, - arguments.common.jobs, - arguments.describe.print_json) - : DescribeTarget(*id, - &repo_config, - serve, - main_apis, - arguments.common.jobs, - arguments.describe.print_json); + auto result = + arguments.describe.describe_rule + ? DescribeUserDefinedRule(id->target, + &repo_config, + arguments.common.jobs, + arguments.describe.print_json) + : DescribeTarget(*id, + &repo_config, + serve, + main_apis, + arguments.common.jobs, + arguments.describe.print_json); + if (profile) { + (*profile)->Write(result); + } + return result; + } + if (profile) { + (*profile)->Write(kExitFailure); } return kExitFailure; } @@ -1091,6 +1118,10 @@ auto main(int argc, char* argv[]) -> int { #endif // BOOTSTRAP_BUILD_TOOL auto id = ReadConfiguredTarget( main_repo, main_ws_root, &repo_config, arguments.analysis); + if (profile) { + (*profile)->SetTarget(id.target.ToJson()); + (*profile)->SetConfiguration(id.config.ToJson()); + } auto serve_errors = nlohmann::json::array(); std::mutex serve_errors_access{}; BuildMaps::Target::ServeFailureLogReporter collect_serve_errors = @@ -1170,6 +1201,9 @@ auto main(int argc, char* argv[]) -> int { TaskSystem ts{arguments.common.jobs}; analyse_result->result_map.Clear(&ts); } + if (profile) { + (*profile)->Write(kExitSuccess); + } return kExitSuccess; } #ifndef BOOTSTRAP_BUILD_TOOL @@ -1225,9 +1259,13 @@ auto main(int argc, char* argv[]) -> int { Logger::Log(LogLevel::Warning, "Build result contains failed artifacts."); } - return build_result->failed_artifacts - ? kExitSuccessFailedArtifacts - : kExitSuccess; + auto result = build_result->failed_artifacts + ? kExitSuccessFailedArtifacts + : kExitSuccess; + if (profile) { + (*profile)->Write(result); + } + return result; } #endif // BOOTSTRAP_BUILD_TOOL } @@ -1235,5 +1273,8 @@ auto main(int argc, char* argv[]) -> int { Logger::Log( LogLevel::Error, "Caught exception with message: {}", ex.what()); } + if (profile) { + (*profile)->Write(kExitFailure); + } return kExitFailure; } diff --git a/src/buildtool/profile/TARGETS b/src/buildtool/profile/TARGETS new file mode 100644 index 00000000..c2bde05e --- /dev/null +++ b/src/buildtool/profile/TARGETS @@ -0,0 +1,9 @@ +{ "profile": + { "type": ["@", "rules", "CC", "library"] + , "name": ["profile"] + , "hdrs": ["profile.hpp"] + , "srcs": ["profile.cpp"] + , "deps": [["@", "json", "", "json"]] + , "stage": ["src", "buildtool", "profile"] + } +} diff --git a/src/buildtool/profile/profile.cpp b/src/buildtool/profile/profile.cpp new file mode 100644 index 00000000..543cd681 --- /dev/null +++ b/src/buildtool/profile/profile.cpp @@ -0,0 +1,35 @@ +// Copyright 2025 Huawei Cloud Computing Technology Co., Ltd. +// +// 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. + +#include "src/buildtool/profile/profile.hpp" + +#include <fstream> + +void Profile::Write(int exit_code) { + if (not output_file_) { + return; + } + profile_["exit code"] = exit_code; + + std::ofstream os(*output_file_); + os << profile_.dump(2) << std::endl; +} + +void Profile::SetTarget(nlohmann::json target) { + profile_["target"] = std::move(target); +} + +void Profile::SetConfiguration(nlohmann::json configuration) { + profile_["configuration"] = std::move(configuration); +} diff --git a/src/buildtool/profile/profile.hpp b/src/buildtool/profile/profile.hpp new file mode 100644 index 00000000..0d4e14b6 --- /dev/null +++ b/src/buildtool/profile/profile.hpp @@ -0,0 +1,40 @@ +// Copyright 2025 Huawei Cloud Computing Technology Co., Ltd. +// +// 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. + +#ifndef INCLUDED_SRC_BUILDTOOL_PROFILE_PROFILE_HPP +#define INCLUDED_SRC_BUILDTOOL_PROFILE_PROFILE_HPP + +#include <optional> +#include <string> +#include <utility> + +#include "nlohmann/json.hpp" + +class Profile { + public: + explicit Profile(std::optional<std::string> output_file) + : output_file_{std::move(output_file)} { + profile_ = nlohmann::json::object(); + } + + void Write(int exit_code); + void SetTarget(nlohmann::json target); + void SetConfiguration(nlohmann::json configuration); + + private: + std::optional<std::string> output_file_; + nlohmann::json profile_; +}; + +#endif |