diff options
| -rw-r--r-- | toolsrc/include/PostBuildLint.h | 3 | ||||
| -rw-r--r-- | toolsrc/include/PostBuildLint_BuildInfo.h | 21 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Build.h | 60 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Commands.h | 35 | ||||
| -rw-r--r-- | toolsrc/src/PostBuildLint.cpp | 14 | ||||
| -rw-r--r-- | toolsrc/src/PostBuildLint_BuildInfo.cpp | 60 | ||||
| -rw-r--r-- | toolsrc/src/commands_available_commands.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/commands_build.cpp | 139 | ||||
| -rw-r--r-- | toolsrc/src/commands_build_external.cpp | 2 | ||||
| -rw-r--r-- | toolsrc/src/commands_ci.cpp | 3 | ||||
| -rw-r--r-- | toolsrc/src/commands_env.cpp | 1 | ||||
| -rw-r--r-- | toolsrc/src/commands_install.cpp | 13 | ||||
| -rw-r--r-- | toolsrc/src/vcpkg_Build.cpp | 203 | ||||
| -rw-r--r-- | toolsrc/vcpkglib/vcpkglib.vcxproj | 4 | ||||
| -rw-r--r-- | toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 18 |
15 files changed, 300 insertions, 278 deletions
diff --git a/toolsrc/include/PostBuildLint.h b/toolsrc/include/PostBuildLint.h index b8afdd5a6..0ee47d0c1 100644 --- a/toolsrc/include/PostBuildLint.h +++ b/toolsrc/include/PostBuildLint.h @@ -1,8 +1,9 @@ #pragma once #include "PackageSpec.h" #include "VcpkgPaths.h" +#include "vcpkg_Build.h" namespace vcpkg::PostBuildLint { - size_t perform_all_checks(const PackageSpec& spec, const VcpkgPaths& paths); + size_t perform_all_checks(const PackageSpec& spec, const VcpkgPaths& paths, const Build::BuildInfo& build_info); } diff --git a/toolsrc/include/PostBuildLint_BuildInfo.h b/toolsrc/include/PostBuildLint_BuildInfo.h deleted file mode 100644 index 29fa09e6c..000000000 --- a/toolsrc/include/PostBuildLint_BuildInfo.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "PostBuildLint_BuildPolicies.h" -#include "PostBuildLint_LinkageType.h" -#include "filesystem_fs.h" -#include "vcpkg_Files.h" - -namespace vcpkg::PostBuildLint -{ - struct BuildInfo - { - static BuildInfo create(std::unordered_map<std::string, std::string> pgh); - - LinkageType crt_linkage; - LinkageType library_linkage; - - std::map<BuildPolicies, bool> policies; - }; - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); -} diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h new file mode 100644 index 000000000..f4b9300c5 --- /dev/null +++ b/toolsrc/include/vcpkg_Build.h @@ -0,0 +1,60 @@ +#pragma once + +#include "PackageSpec.h" +#include "PostBuildLint_BuildPolicies.h" +#include "PostBuildLint_LinkageType.h" +#include "StatusParagraphs.h" +#include "VcpkgPaths.h" +#include "vcpkg_Files.h" +#include <map> +#include <string> +#include <unordered_map> +#include <vector> + +namespace vcpkg::Build +{ + enum class BuildResult + { + NULLVALUE = 0, + SUCCEEDED, + BUILD_FAILED, + POST_BUILD_CHECKS_FAILED, + CASCADED_DUE_TO_MISSING_DEPENDENCIES + }; + + static constexpr std::array<BuildResult, 4> BuildResult_values = { + BuildResult::SUCCEEDED, + BuildResult::BUILD_FAILED, + BuildResult::POST_BUILD_CHECKS_FAILED, + BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; + + const std::string& to_string(const BuildResult build_result); + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); + std::string create_user_troubleshooting_message(const PackageSpec& spec); + + std::wstring make_build_env_cmd(const Triplet& triplet, const Toolset& toolset); + + struct ExtendedBuildResult + { + BuildResult code; + std::vector<PackageSpec> unmet_dependencies; + }; + + ExtendedBuildResult build_package(const SourceParagraph& source_paragraph, + const PackageSpec& spec, + const VcpkgPaths& paths, + const fs::path& port_dir, + const StatusParagraphs& status_db); + + struct BuildInfo + { + static BuildInfo create(std::unordered_map<std::string, std::string> pgh); + + PostBuildLint::LinkageType crt_linkage; + PostBuildLint::LinkageType library_linkage; + + std::map<PostBuildLint::BuildPolicies, bool> policies; + }; + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); +} diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 6099918ce..14d468352 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -14,41 +14,8 @@ namespace vcpkg::Commands using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); using CommandTypeC = void (*)(const VcpkgCmdArguments& args); - namespace Build + namespace BuildCommand { - enum class BuildResult - { - NULLVALUE = 0, - SUCCEEDED, - BUILD_FAILED, - POST_BUILD_CHECKS_FAILED, - CASCADED_DUE_TO_MISSING_DEPENDENCIES - }; - - static constexpr std::array<BuildResult, 4> BuildResult_values = { - BuildResult::SUCCEEDED, - BuildResult::BUILD_FAILED, - BuildResult::POST_BUILD_CHECKS_FAILED, - BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; - - const std::string& to_string(const BuildResult build_result); - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); - std::string create_user_troubleshooting_message(const PackageSpec& spec); - - std::wstring make_build_env_cmd(const Triplet& triplet, const Toolset& toolset); - - struct ExtendedBuildResult - { - BuildResult code; - std::vector<PackageSpec> unmet_dependencies; - }; - - ExtendedBuildResult build_package(const SourceParagraph& source_paragraph, - const PackageSpec& spec, - const VcpkgPaths& paths, - const fs::path& port_dir, - const StatusParagraphs& status_db); - void perform_and_exit(const PackageSpec& spec, const fs::path& port_dir, const std::unordered_set<std::string>& options, diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 7df74cf31..295a8a3b4 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -2,14 +2,16 @@ #include "PackageSpec.h" #include "PostBuildLint.h" -#include "PostBuildLint_BuildInfo.h" #include "PostBuildLint_BuildType.h" #include "VcpkgPaths.h" #include "coff_file_reader.h" +#include "vcpkg_Build.h" #include "vcpkg_Files.h" #include "vcpkg_System.h" #include "vcpkg_Util.h" +using vcpkg::Build::BuildInfo; + namespace vcpkg::PostBuildLint { static auto has_extension_pred(const Files::Filesystem& fs, const std::string& ext) @@ -715,14 +717,14 @@ namespace vcpkg::PostBuildLint static void operator+=(size_t& left, const LintStatus& right) { left += static_cast<size_t>(right); } - static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, const VcpkgPaths& paths) + static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, + const VcpkgPaths& paths, + const BuildInfo& build_info) { const auto& fs = paths.get_filesystem(); // for dumpbin const Toolset& toolset = paths.get_toolset(); - - BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec)); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; @@ -823,10 +825,10 @@ namespace vcpkg::PostBuildLint return error_count; } - size_t perform_all_checks(const PackageSpec& spec, const VcpkgPaths& paths) + size_t perform_all_checks(const PackageSpec& spec, const VcpkgPaths& paths, const BuildInfo& build_info) { System::println("-- Performing post-build validation"); - const size_t error_count = perform_all_checks_and_return_error_count(spec, paths); + const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, build_info); if (error_count != 0) { diff --git a/toolsrc/src/PostBuildLint_BuildInfo.cpp b/toolsrc/src/PostBuildLint_BuildInfo.cpp deleted file mode 100644 index 22d312398..000000000 --- a/toolsrc/src/PostBuildLint_BuildInfo.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "PostBuildLint_BuildInfo.h" -#include "vcpkg_Checks.h" -#include "vcpkg_optional.h" -#include "vcpkglib_helpers.h" - -namespace vcpkg::PostBuildLint -{ - namespace BuildInfoRequiredField - { - static const std::string CRT_LINKAGE = "CRTLinkage"; - static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; - } - - BuildInfo BuildInfo::create(std::unordered_map<std::string, std::string> pgh) - { - BuildInfo build_info; - const std::string crt_linkage_as_string = - details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE); - build_info.crt_linkage = LinkageType::value_of(crt_linkage_as_string); - Checks::check_exit(VCPKG_LINE_INFO, - build_info.crt_linkage != LinkageTypeC::NULLVALUE, - "Invalid crt linkage type: [%s]", - crt_linkage_as_string); - - const std::string library_linkage_as_string = - details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE); - build_info.library_linkage = LinkageType::value_of(library_linkage_as_string); - Checks::check_exit(VCPKG_LINE_INFO, - build_info.library_linkage != LinkageTypeC::NULLVALUE, - "Invalid library linkage type: [%s]", - library_linkage_as_string); - - // The remaining entries are policies - for (const std::unordered_map<std::string, std::string>::value_type& p : pgh) - { - const BuildPolicies policy = BuildPolicies::parse(p.first); - Checks::check_exit( - VCPKG_LINE_INFO, policy != BuildPoliciesC::NULLVALUE, "Unknown policy found: %s", p.first); - if (p.second == "enabled") - build_info.policies.emplace(policy, true); - else if (p.second == "disabled") - build_info.policies.emplace(policy, false); - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second); - } - - return build_info; - } - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) - { - const Expected<std::unordered_map<std::string, std::string>> pghs = - Paragraphs::get_single_paragraph(fs, filepath); - Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); - return BuildInfo::create(*pghs.get()); - } -} diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/commands_available_commands.cpp index ec80fea5d..87cc43dca 100644 --- a/toolsrc/src/commands_available_commands.cpp +++ b/toolsrc/src/commands_available_commands.cpp @@ -10,7 +10,7 @@ namespace vcpkg::Commands {"install", &Install::perform_and_exit}, {"ci", &CI::perform_and_exit}, {"remove", &Remove::perform_and_exit}, - {"build", &Build::perform_and_exit}, + {"build", &BuildCommand::perform_and_exit}, {"env", &Env::perform_and_exit}, {"build-external", &BuildExternal::perform_and_exit}, {"export", &Export::perform_and_exit}, diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 0a73a8551..b6be68f02 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -13,143 +13,15 @@ #include "vcpkg_Util.h" #include "vcpkglib.h" -namespace vcpkg::Commands::Build +using vcpkg::Build::BuildResult; + +namespace vcpkg::Commands::BuildCommand { using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; static const std::string OPTION_CHECKS_ONLY = "--checks-only"; - static void create_binary_control_file(const VcpkgPaths& paths, - const SourceParagraph& source_paragraph, - const Triplet& triplet) - { - const BinaryParagraph bpgh = BinaryParagraph(source_paragraph, triplet); - const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL"; - paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh)); - } - - std::wstring make_build_env_cmd(const Triplet& triplet, const Toolset& toolset) - { - const wchar_t* tonull = L" >nul"; - if (g_debugging) - { - tonull = L""; - } - - return Strings::wformat( - LR"("%s" %s %s 2>&1)", toolset.vcvarsall.native(), Strings::utf8_to_utf16(triplet.architecture()), tonull); - } - - ExtendedBuildResult build_package(const SourceParagraph& source_paragraph, - const PackageSpec& spec, - const VcpkgPaths& paths, - const fs::path& port_dir, - const StatusParagraphs& status_db) - { - Checks::check_exit( - VCPKG_LINE_INFO, spec.name() == source_paragraph.name, "inconsistent arguments to build_package()"); - - const Triplet& triplet = spec.triplet(); - { - std::vector<PackageSpec> missing_specs; - for (auto&& dep : filter_dependencies(source_paragraph.depends, triplet)) - { - if (status_db.find_installed(dep, triplet) == status_db.end()) - { - missing_specs.push_back( - PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); - } - } - // Fail the build if any dependencies were missing - if (!missing_specs.empty()) - { - return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; - } - } - - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path& git_exe_path = paths.get_git_exe(); - - const fs::path ports_cmake_script_path = paths.ports_cmake; - const Toolset& toolset = paths.get_toolset(); - const auto cmd_set_environment = make_build_env_cmd(triplet, toolset); - - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - {{L"CMD", L"BUILD"}, - {L"PORT", source_paragraph.name}, - {L"CURRENT_PORT_DIR", port_dir / "/."}, - {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, - {L"GIT", git_exe_path}}); - - const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); - - const ElapsedTime timer = ElapsedTime::create_started(); - - int return_code = System::cmd_execute_clean(command); - auto buildtimeus = timer.microseconds(); - Metrics::track_metric("buildtimeus-" + spec.to_string(), buildtimeus); - - if (return_code != 0) - { - Metrics::track_property("error", "build failed"); - Metrics::track_property("build_error", spec.to_string()); - return {BuildResult::BUILD_FAILED, {}}; - } - - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths); - - if (error_count != 0) - { - return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; - } - - create_binary_control_file(paths, source_paragraph, triplet); - - // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; - // delete_directory(port_buildtrees_dir); - - return {BuildResult::SUCCEEDED, {}}; - } - - const std::string& to_string(const BuildResult build_result) - { - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); - static const std::string SUCCEEDED_STRING = "SUCCEEDED"; - static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; - static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; - static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; - - switch (build_result) - { - case BuildResult::NULLVALUE: return NULLVALUE_STRING; - case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; - case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; - case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) - { - return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); - } - - std::string create_user_troubleshooting_message(const PackageSpec& spec) - { - return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" - "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" - " Package: %s\n" - " Vcpkg version: %s\n" - "\n" - "Additionally, attach any relevant sections from the log files above.", - spec, - Version::version()); - } - void perform_and_exit(const PackageSpec& spec, const fs::path& port_dir, const std::unordered_set<std::string>& options, @@ -157,7 +29,8 @@ namespace vcpkg::Commands::Build { if (options.find(OPTION_CHECKS_ONLY) != options.end()) { - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths); + auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, build_info); Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); Checks::exit_success(VCPKG_LINE_INFO); } @@ -171,7 +44,7 @@ namespace vcpkg::Commands::Build const SourceParagraph& spgh = *maybe_spgh.get(); StatusParagraphs status_db = database_load_check(paths); - const auto result = build_package(spgh, spec, paths, paths.port_dir(spec), status_db); + const auto result = Build::build_package(spgh, spec, paths, paths.port_dir(spec), status_db); if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { System::println(System::Color::error, diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/commands_build_external.cpp index 97f5c8335..2712ba0cf 100644 --- a/toolsrc/src/commands_build_external.cpp +++ b/toolsrc/src/commands_build_external.cpp @@ -17,6 +17,6 @@ namespace vcpkg::Commands::BuildExternal const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({}); const fs::path port_dir = args.command_arguments.at(1); - Build::perform_and_exit(spec, port_dir, options, paths); + BuildCommand::perform_and_exit(spec, port_dir, options, paths); } } diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 91d1ff01a..398f6a5f4 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "Paragraphs.h" +#include "vcpkg_Build.h" #include "vcpkg_Chrono.h" #include "vcpkg_Commands.h" #include "vcpkg_Dependencies.h" @@ -71,7 +72,7 @@ namespace vcpkg::Commands::CI { System::println("Building package %s... ", display_name); auto&& source_paragraph = action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO); - const auto result_ex = Commands::Build::build_package( + const auto result_ex = Build::build_package( source_paragraph, action.spec, paths, paths.port_dir(action.spec), status_db); const auto result = result_ex.code; diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp index 33f1e6bc0..017d3c8f7 100644 --- a/toolsrc/src/commands_env.cpp +++ b/toolsrc/src/commands_env.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include "vcpkg_Build.h" #include "vcpkg_Commands.h" #include "vcpkg_System.h" diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index 20fdbcdf5..727bae666 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -2,6 +2,7 @@ #include "Paragraphs.h" #include "metrics.h" +#include "vcpkg_Build.h" #include "vcpkg_Commands.h" #include "vcpkg_Dependencies.h" #include "vcpkg_Files.h" @@ -324,12 +325,12 @@ namespace vcpkg::Commands::Install case InstallPlanType::BUILD_AND_INSTALL: { System::println("Building package %s... ", display_name); - const auto result = Commands::Build::build_package( - action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), - action.spec, - paths, - paths.port_dir(action.spec), - status_db); + const auto result = + Build::build_package(action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), + action.spec, + paths, + paths.port_dir(action.spec), + status_db); if (result.code != Build::BuildResult::SUCCEEDED) { System::println(System::Color::error, diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp new file mode 100644 index 000000000..ca731e759 --- /dev/null +++ b/toolsrc/src/vcpkg_Build.cpp @@ -0,0 +1,203 @@ +#include "pch.h" + +#include "Paragraphs.h" +#include "PostBuildLint.h" +#include "metrics.h" +#include "vcpkg_Build.h" +#include "vcpkg_Checks.h" +#include "vcpkg_Chrono.h" +#include "vcpkg_Commands.h" +#include "vcpkg_Enums.h" +#include "vcpkg_System.h" +#include "vcpkg_optional.h" +#include "vcpkglib.h" +#include "vcpkglib_helpers.h" + +using vcpkg::PostBuildLint::BuildPolicies; +namespace BuildPoliciesC = vcpkg::PostBuildLint::BuildPoliciesC; +using vcpkg::PostBuildLint::LinkageType; +namespace LinkageTypeC = vcpkg::PostBuildLint::LinkageTypeC; + +namespace vcpkg::Build +{ + namespace BuildInfoRequiredField + { + static const std::string CRT_LINKAGE = "CRTLinkage"; + static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; + } + + std::wstring make_build_env_cmd(const Triplet& triplet, const Toolset& toolset) + { + const wchar_t* tonull = L" >nul"; + if (g_debugging) + { + tonull = L""; + } + + return Strings::wformat( + LR"("%s" %s %s 2>&1)", toolset.vcvarsall.native(), Strings::utf8_to_utf16(triplet.architecture()), tonull); + } + + static void create_binary_control_file(const VcpkgPaths& paths, + const SourceParagraph& source_paragraph, + const Triplet& triplet) + { + const BinaryParagraph bpgh = BinaryParagraph(source_paragraph, triplet); + const fs::path binary_control_file = paths.packages / bpgh.dir() / "CONTROL"; + paths.get_filesystem().write_contents(binary_control_file, Strings::serialize(bpgh)); + } + + ExtendedBuildResult build_package(const SourceParagraph& source_paragraph, + const PackageSpec& spec, + const VcpkgPaths& paths, + const fs::path& port_dir, + const StatusParagraphs& status_db) + { + Checks::check_exit( + VCPKG_LINE_INFO, spec.name() == source_paragraph.name, "inconsistent arguments to build_package()"); + + const Triplet& triplet = spec.triplet(); + { + std::vector<PackageSpec> missing_specs; + for (auto&& dep : filter_dependencies(source_paragraph.depends, triplet)) + { + if (status_db.find_installed(dep, triplet) == status_db.end()) + { + missing_specs.push_back( + PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); + } + } + // Fail the build if any dependencies were missing + if (!missing_specs.empty()) + { + return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; + } + } + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path& git_exe_path = paths.get_git_exe(); + + const fs::path ports_cmake_script_path = paths.ports_cmake; + const Toolset& toolset = paths.get_toolset(); + const auto cmd_set_environment = make_build_env_cmd(triplet, toolset); + + const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, + ports_cmake_script_path, + {{L"CMD", L"BUILD"}, + {L"PORT", source_paragraph.name}, + {L"CURRENT_PORT_DIR", port_dir / "/."}, + {L"TARGET_TRIPLET", triplet.canonical_name()}, + {L"VCPKG_PLATFORM_TOOLSET", toolset.version}, + {L"GIT", git_exe_path}}); + + const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + + const ElapsedTime timer = ElapsedTime::create_started(); + + int return_code = System::cmd_execute_clean(command); + auto buildtimeus = timer.microseconds(); + Metrics::track_metric("buildtimeus-" + spec.to_string(), buildtimeus); + + if (return_code != 0) + { + Metrics::track_property("error", "build failed"); + Metrics::track_property("build_error", spec.to_string()); + return {BuildResult::BUILD_FAILED, {}}; + } + + auto build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, build_info); + + if (error_count != 0) + { + return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; + } + + create_binary_control_file(paths, source_paragraph, triplet); + + // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; + // delete_directory(port_buildtrees_dir); + + return {BuildResult::SUCCEEDED, {}}; + } + + const std::string& to_string(const BuildResult build_result) + { + static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); + static const std::string SUCCEEDED_STRING = "SUCCEEDED"; + static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; + static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; + static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; + + switch (build_result) + { + case BuildResult::NULLVALUE: return NULLVALUE_STRING; + case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; + case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; + case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) + { + return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); + } + + std::string create_user_troubleshooting_message(const PackageSpec& spec) + { + return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" + "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" + " Package: %s\n" + " Vcpkg version: %s\n" + "\n" + "Additionally, attach any relevant sections from the log files above.", + spec, + Commands::Version::version()); + } + + BuildInfo BuildInfo::create(std::unordered_map<std::string, std::string> pgh) + { + BuildInfo build_info; + const std::string crt_linkage_as_string = + details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE); + build_info.crt_linkage = LinkageType::value_of(crt_linkage_as_string); + Checks::check_exit(VCPKG_LINE_INFO, + build_info.crt_linkage != LinkageTypeC::NULLVALUE, + "Invalid crt linkage type: [%s]", + crt_linkage_as_string); + + const std::string library_linkage_as_string = + details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE); + build_info.library_linkage = LinkageType::value_of(library_linkage_as_string); + Checks::check_exit(VCPKG_LINE_INFO, + build_info.library_linkage != LinkageTypeC::NULLVALUE, + "Invalid library linkage type: [%s]", + library_linkage_as_string); + + // The remaining entries are policies + for (const std::unordered_map<std::string, std::string>::value_type& p : pgh) + { + const BuildPolicies policy = BuildPolicies::parse(p.first); + Checks::check_exit( + VCPKG_LINE_INFO, policy != BuildPoliciesC::NULLVALUE, "Unknown policy found: %s", p.first); + if (p.second == "enabled") + build_info.policies.emplace(policy, true); + else if (p.second == "disabled") + build_info.policies.emplace(policy, false); + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", p.first, p.second); + } + + return build_info; + } + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) + { + const Expected<std::unordered_map<std::string, std::string>> pghs = + Paragraphs::get_single_paragraph(fs, filepath); + Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); + return BuildInfo::create(*pghs.get()); + } +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 769ef5004..472f4d4e9 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -141,7 +141,7 @@ <ClInclude Include="..\include\lazy.h" /> <ClInclude Include="..\include\LineInfo.h" /> <ClInclude Include="..\include\ParagraphParseResult.h" /> - <ClInclude Include="..\include\PostBuildLint_BuildInfo.h" /> + <ClInclude Include="..\include\vcpkg_Build.h" /> <ClInclude Include="..\include\PostBuildLint_BuildPolicies.h" /> <ClInclude Include="..\include\coff_file_reader.h" /> <ClInclude Include="..\include\vcpkg_expected.h" /> @@ -188,7 +188,7 @@ <ClCompile Include="..\src\commands_export.cpp" /> <ClCompile Include="..\src\LineInfo.cpp" /> <ClCompile Include="..\src\ParagraphParseResult.cpp" /> - <ClCompile Include="..\src\PostBuildLint_BuildInfo.cpp" /> + <ClCompile Include="..\src\vcpkg_Build.cpp" /> <ClCompile Include="..\src\PostBuildLint_BuildPolicies.cpp" /> <ClCompile Include="..\src\coff_file_reader.cpp" /> <ClCompile Include="..\src\commands_available_commands.cpp" /> diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 26ad53af9..f8958b4a6 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -129,9 +129,6 @@ <ClCompile Include="..\src\PostBuildLint.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\src\PostBuildLint_BuildInfo.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\src\PostBuildLint_BuildPolicies.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -159,9 +156,6 @@ <ClCompile Include="..\src\commands_env.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\src\OptBool.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="..\src\PackageSpec.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -186,6 +180,9 @@ <ClCompile Include="..\src\VersionT.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\src\vcpkg_Build.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\include\SourceParagraph.h"> @@ -260,9 +257,6 @@ <ClInclude Include="..\include\PostBuildLint.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\PostBuildLint_BuildInfo.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\include\PostBuildLint_BuildPolicies.h"> <Filter>Header Files</Filter> </ClInclude> @@ -299,9 +293,6 @@ <ClInclude Include="..\include\CStringView.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\include\OptBool.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\include\PackageSpec.h"> <Filter>Header Files</Filter> </ClInclude> @@ -320,5 +311,8 @@ <ClInclude Include="..\include\VcpkgPaths.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\include\vcpkg_Build.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project>
\ No newline at end of file |
