mirror of
https://github.com/microsoft/vcpkg.git
synced 2025-06-07 18:47:04 +08:00
[vcpkg] Split vcpkg::Commands::Build -> vcpkg::Build, vcpkg::Commands::BuildCommand
This commit is contained in:
parent
a0d5b94495
commit
20657a29ca
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
60
toolsrc/include/vcpkg_Build.h
Normal file
60
toolsrc/include/vcpkg_Build.h
Normal file
@ -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);
|
||||
}
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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},
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include "vcpkg_Build.h"
|
||||
#include "vcpkg_Commands.h"
|
||||
#include "vcpkg_System.h"
|
||||
|
||||
|
@ -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,
|
||||
|
203
toolsrc/src/vcpkg_Build.cpp
Normal file
203
toolsrc/src/vcpkg_Build.cpp
Normal file
@ -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());
|
||||
}
|
||||
}
|
@ -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" />
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user