aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-04-30 04:09:05 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-05-01 17:24:54 -0700
commit20657a29ca8cc2aec104caca7703fcd72bf5746e (patch)
tree800fc0675cf6e184303921c8adea8ea8fc297e56
parenta0d5b944953f14cb58121e76f7fe6140e8134ca3 (diff)
downloadvcpkg-20657a29ca8cc2aec104caca7703fcd72bf5746e.tar.gz
vcpkg-20657a29ca8cc2aec104caca7703fcd72bf5746e.zip
[vcpkg] Split vcpkg::Commands::Build -> vcpkg::Build, vcpkg::Commands::BuildCommand
-rw-r--r--toolsrc/include/PostBuildLint.h3
-rw-r--r--toolsrc/include/PostBuildLint_BuildInfo.h21
-rw-r--r--toolsrc/include/vcpkg_Build.h60
-rw-r--r--toolsrc/include/vcpkg_Commands.h35
-rw-r--r--toolsrc/src/PostBuildLint.cpp14
-rw-r--r--toolsrc/src/PostBuildLint_BuildInfo.cpp60
-rw-r--r--toolsrc/src/commands_available_commands.cpp2
-rw-r--r--toolsrc/src/commands_build.cpp139
-rw-r--r--toolsrc/src/commands_build_external.cpp2
-rw-r--r--toolsrc/src/commands_ci.cpp3
-rw-r--r--toolsrc/src/commands_env.cpp1
-rw-r--r--toolsrc/src/commands_install.cpp13
-rw-r--r--toolsrc/src/vcpkg_Build.cpp203
-rw-r--r--toolsrc/vcpkglib/vcpkglib.vcxproj4
-rw-r--r--toolsrc/vcpkglib/vcpkglib.vcxproj.filters18
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