[vcpkg] Track compiler information in ABI (#11654)

* [vcpkg] Refactor out abi_tags_from_pre_build_info()

* [vcpkg] Track Windows toolchain file in triplet hash

* [vcpkg] Improve error messages when constructing PreBuildInfo

* [vcpkg] Extract InstallPlanAction::BuildAbiInfo

* [vcpkg] Extract Build::EnvCache and private-impl VcpkgPaths

* [vcpkg] Enable compiler hash detection when binarycaching is enabled

* [vcpkg] Downgrade warning about missing ABI keys

When binarycaching is not enabled, this warning is spurious and provides no user value.

* [vcpkg] Cleanup

* [vcpkg] Refactor compiler tracking into triplet abi computation

Move several static global caches into VcpkgPaths/EnvCache.
Add feature flag 'compilertracking' to enable the new feature.

* [vcpkg] Refactor out PreBuildInfo::using_vcvars()

Move VcpkgTripletVar into build.cpp because it is not used outside that file.

* [vcpkg] Address some code analysis warnings

Co-authored-by: Robert Schumacher <roschuma@microsoft.com>
This commit is contained in:
ras0219 2020-06-22 14:14:36 -07:00 committed by GitHub
parent 2bf1f30deb
commit aef838536e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 657 additions and 402 deletions

View File

@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.10)
project(detect_compiler)
file(SHA1 "${CMAKE_CXX_COMPILER}" CXX_HASH)
file(SHA1 "${CMAKE_C_COMPILER}" C_HASH)
string(SHA1 COMPILER_HASH "${C_HASH}${CXX_HASH}")
message("#COMPILER_HASH#${COMPILER_HASH}")

View File

@ -0,0 +1,28 @@
set(LOGS
${CURRENT_BUILDTREES_DIR}/config-${TARGET_TRIPLET}-out.log
${CURRENT_BUILDTREES_DIR}/config-${TARGET_TRIPLET}-rel-out.log
${CURRENT_BUILDTREES_DIR}/config-${TARGET_TRIPLET}-dbg-out.log
)
foreach(LOG IN LISTS LOGS)
file(REMOVE ${LOG})
if(EXISTS ${LOG})
message(FATAL_ERROR "Could not remove ${LOG}")
endif()
endforeach()
set(VCPKG_BUILD_TYPE release)
vcpkg_configure_cmake(
SOURCE_PATH "${CMAKE_CURRENT_LIST_DIR}"
PREFER_NINJA
)
foreach(LOG IN LISTS LOGS)
if(EXISTS ${LOG})
file(READ "${LOG}" _contents)
message("${_contents}")
return()
endif()
endforeach()
message(FATAL_ERROR "Could read logs: ${LOGS}")

View File

@ -43,9 +43,6 @@ if(CMD MATCHES "^BUILD$")
if(NOT EXISTS ${CURRENT_PORT_DIR}/portfile.cmake) if(NOT EXISTS ${CURRENT_PORT_DIR}/portfile.cmake)
message(FATAL_ERROR "Port is missing portfile: ${CURRENT_PORT_DIR}/portfile.cmake") message(FATAL_ERROR "Port is missing portfile: ${CURRENT_PORT_DIR}/portfile.cmake")
endif() endif()
if(NOT EXISTS ${CURRENT_PORT_DIR}/CONTROL)
message(FATAL_ERROR "Port is missing control file: ${CURRENT_PORT_DIR}/CONTROL")
endif()
unset(PACKAGES_DIR) unset(PACKAGES_DIR)
unset(BUILDTREES_DIR) unset(BUILDTREES_DIR)
@ -74,7 +71,9 @@ if(CMD MATCHES "^BUILD$")
include(${SCRIPTS}/cmake/vcpkg_common_definitions.cmake) include(${SCRIPTS}/cmake/vcpkg_common_definitions.cmake)
include(${SCRIPTS}/cmake/vcpkg_common_functions.cmake) include(${SCRIPTS}/cmake/vcpkg_common_functions.cmake)
include(${CURRENT_PORT_DIR}/portfile.cmake) include(${CURRENT_PORT_DIR}/portfile.cmake)
include(${SCRIPTS}/build_info.cmake) if(DEFINED PORT)
include(${SCRIPTS}/build_info.cmake)
endif()
elseif(CMD MATCHES "^CREATE$") elseif(CMD MATCHES "^CREATE$")
file(TO_NATIVE_PATH ${VCPKG_ROOT_DIR} NATIVE_VCPKG_ROOT_DIR) file(TO_NATIVE_PATH ${VCPKG_ROOT_DIR} NATIVE_VCPKG_ROOT_DIR)
file(TO_NATIVE_PATH ${DOWNLOADS} NATIVE_DOWNLOADS) file(TO_NATIVE_PATH ${DOWNLOADS} NATIVE_DOWNLOADS)

View File

@ -10,7 +10,7 @@ namespace vcpkg
template<class Err> template<class Err>
struct ErrorHolder struct ErrorHolder
{ {
ErrorHolder() : m_is_error(false) {} ErrorHolder() : m_is_error(false), m_err{} {}
template<class U> template<class U>
ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err)) ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err))
{ {

View File

@ -19,8 +19,10 @@
#include <sal.h> #include <sal.h>
#endif #endif
#ifndef _Analysis_assume_ #if defined(_MSC_VER)
#define _Analysis_assume_(...) #define ASSUME(expr) __assume(expr)
#else
#define ASSUME(expr)
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -22,6 +22,11 @@ namespace vcpkg::Util
{ {
augend->insert(augend->end(), addend.begin(), addend.end()); augend->insert(augend->end(), addend.begin(), addend.end());
} }
template<class Vec, class Key>
bool contains(const Vec& container, const Key& item)
{
return std::find(container.begin(), container.end(), item) != container.end();
}
} }
namespace Sets namespace Sets

View File

@ -36,6 +36,8 @@ namespace vcpkg
bool purge_tombstones) = 0; bool purge_tombstones) = 0;
}; };
IBinaryProvider& null_binary_provider();
ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs(const VcpkgPaths& paths, ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs(const VcpkgPaths& paths,
View<std::string> args); View<std::string> args);
ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs_pure(const std::string& env_string, ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs_pure(const std::string& env_string,

View File

@ -10,6 +10,7 @@
#include <vcpkg/base/cstringview.h> #include <vcpkg/base/cstringview.h>
#include <vcpkg/base/files.h> #include <vcpkg/base/files.h>
#include <vcpkg/base/optional.h> #include <vcpkg/base/optional.h>
#include <vcpkg/base/system.process.h>
#include <array> #include <array>
#include <map> #include <map>
@ -27,6 +28,11 @@ namespace vcpkg::Dependencies
struct ActionPlan; struct ActionPlan;
} }
namespace vcpkg::System
{
struct Environment;
}
namespace vcpkg::Build namespace vcpkg::Build
{ {
namespace Command namespace Command
@ -34,7 +40,6 @@ namespace vcpkg::Build
void perform_and_exit_ex(const FullPackageSpec& full_spec, void perform_and_exit_ex(const FullPackageSpec& full_spec,
const SourceControlFileLocation& scfl, const SourceControlFileLocation& scfl,
const PortFileProvider::PathsPortFileProvider& provider, const PortFileProvider::PathsPortFileProvider& provider,
const bool binary_caching_enabled,
IBinaryProvider& binaryprovider, IBinaryProvider& binaryprovider,
const VcpkgPaths& paths); const VcpkgPaths& paths);
@ -90,12 +95,6 @@ namespace vcpkg::Build
}; };
const std::string& to_string(DownloadTool tool); const std::string& to_string(DownloadTool tool);
enum class BinaryCaching
{
NO = 0,
YES
};
enum class FailOnTombstone enum class FailOnTombstone
{ {
NO = 0, NO = 0,
@ -117,7 +116,6 @@ namespace vcpkg::Build
CleanPackages clean_packages; CleanPackages clean_packages;
CleanDownloads clean_downloads; CleanDownloads clean_downloads;
DownloadTool download_tool; DownloadTool download_tool;
BinaryCaching binary_caching;
FailOnTombstone fail_on_tombstone; FailOnTombstone fail_on_tombstone;
PurgeDecompressFailure purge_decompress_failure; PurgeDecompressFailure purge_decompress_failure;
}; };
@ -149,14 +147,14 @@ namespace vcpkg::Build
/// <summary> /// <summary>
/// Settings from the triplet file which impact the build environment and post-build checks /// Settings from the triplet file which impact the build environment and post-build checks
/// </summary> /// </summary>
struct PreBuildInfo struct PreBuildInfo : Util::ResourceBase
{ {
PreBuildInfo(const VcpkgPaths& paths, PreBuildInfo(const VcpkgPaths& paths,
Triplet triplet, Triplet triplet,
const std::unordered_map<std::string, std::string>& cmakevars); const std::unordered_map<std::string, std::string>& cmakevars);
bool load_vcvars_env; Triplet triplet;
std::string triplet_abi_tag; bool load_vcvars_env = false;
std::string target_architecture; std::string target_architecture;
std::string cmake_system_name; std::string cmake_system_name;
std::string cmake_system_version; std::string cmake_system_version;
@ -165,39 +163,17 @@ namespace vcpkg::Build
Optional<std::string> external_toolchain_file; Optional<std::string> external_toolchain_file;
Optional<ConfigurationType> build_type; Optional<ConfigurationType> build_type;
Optional<std::string> public_abi_override; Optional<std::string> public_abi_override;
Optional<const SourceControlFileLocation&> port;
std::vector<std::string> passthrough_env_vars; std::vector<std::string> passthrough_env_vars;
fs::path toolchain_file() const;
bool using_vcvars() const;
private:
const VcpkgPaths& m_paths;
}; };
std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset);
enum class VcpkgTripletVar
{
TARGET_ARCHITECTURE = 0,
CMAKE_SYSTEM_NAME,
CMAKE_SYSTEM_VERSION,
PLATFORM_TOOLSET,
VISUAL_STUDIO_PATH,
CHAINLOAD_TOOLCHAIN_FILE,
BUILD_TYPE,
ENV_PASSTHROUGH,
PUBLIC_ABI_OVERRIDE,
LOAD_VCVARS_ENV,
};
const std::unordered_map<std::string, VcpkgTripletVar> VCPKG_OPTIONS = {
{"VCPKG_TARGET_ARCHITECTURE", VcpkgTripletVar::TARGET_ARCHITECTURE},
{"VCPKG_CMAKE_SYSTEM_NAME", VcpkgTripletVar::CMAKE_SYSTEM_NAME},
{"VCPKG_CMAKE_SYSTEM_VERSION", VcpkgTripletVar::CMAKE_SYSTEM_VERSION},
{"VCPKG_PLATFORM_TOOLSET", VcpkgTripletVar::PLATFORM_TOOLSET},
{"VCPKG_VISUAL_STUDIO_PATH", VcpkgTripletVar::VISUAL_STUDIO_PATH},
{"VCPKG_CHAINLOAD_TOOLCHAIN_FILE", VcpkgTripletVar::CHAINLOAD_TOOLCHAIN_FILE},
{"VCPKG_BUILD_TYPE", VcpkgTripletVar::BUILD_TYPE},
{"VCPKG_ENV_PASSTHROUGH", VcpkgTripletVar::ENV_PASSTHROUGH},
{"VCPKG_PUBLIC_ABI_OVERRIDE", VcpkgTripletVar::PUBLIC_ABI_OVERRIDE},
{"VCPKG_LOAD_VCVARS_ENV", VcpkgTripletVar::LOAD_VCVARS_ENV},
};
struct ExtendedBuildResult struct ExtendedBuildResult
{ {
ExtendedBuildResult(BuildResult code); ExtendedBuildResult(BuildResult code);
@ -238,8 +214,7 @@ namespace vcpkg::Build
BuildPolicy::ALLOW_OBSOLETE_MSVCRT, BuildPolicy::ALLOW_OBSOLETE_MSVCRT,
BuildPolicy::ALLOW_RESTRICTED_HEADERS, BuildPolicy::ALLOW_RESTRICTED_HEADERS,
BuildPolicy::SKIP_DUMPBIN_CHECKS, BuildPolicy::SKIP_DUMPBIN_CHECKS,
BuildPolicy::SKIP_ARCHITECTURE_CHECK BuildPolicy::SKIP_ARCHITECTURE_CHECK};
};
const std::string& to_string(BuildPolicy policy); const std::string& to_string(BuildPolicy policy);
CStringView to_cmake_variable(BuildPolicy policy); CStringView to_cmake_variable(BuildPolicy policy);
@ -300,12 +275,45 @@ namespace vcpkg::Build
fs::path tag_file; fs::path tag_file;
}; };
struct AbiInfo
{
std::unique_ptr<PreBuildInfo> pre_build_info;
const Toolset* toolset;
std::string package_abi;
Optional<fs::path> abi_tag_file;
};
void compute_all_abis(const VcpkgPaths& paths, void compute_all_abis(const VcpkgPaths& paths,
Dependencies::ActionPlan& action_plan, Dependencies::ActionPlan& action_plan,
const CMakeVars::CMakeVarProvider& var_provider, const CMakeVars::CMakeVarProvider& var_provider,
const StatusParagraphs& status_db); const StatusParagraphs& status_db);
Optional<AbiTagAndFile> compute_abi_tag(const VcpkgPaths& paths, struct EnvCache
const Dependencies::InstallPlanAction& config, {
Span<const AbiEntry> dependency_abis); explicit EnvCache(bool compiler_tracking) : m_compiler_tracking(compiler_tracking) {}
const System::Environment& get_action_env(const VcpkgPaths& paths, const AbiInfo& abi_info);
const std::string& get_triplet_info(const VcpkgPaths& paths, const AbiInfo& abi_info);
private:
struct TripletMapEntry
{
std::string hash;
Cache<std::string, std::string> compiler_hashes;
};
Cache<fs::path, TripletMapEntry> m_triplet_cache;
Cache<fs::path, std::string> m_toolchain_cache;
#if defined(_WIN32)
struct EnvMapEntry
{
std::unordered_map<std::string, std::string> env_map;
Cache<std::string, System::Environment> cmd_cache;
};
Cache<std::vector<std::string>, EnvMapEntry> envs;
#endif
bool m_compiler_tracking;
};
} }

View File

@ -55,6 +55,7 @@ namespace vcpkg::Dependencies
std::string displayname() const; std::string displayname() const;
const std::string& public_abi() const; const std::string& public_abi() const;
const Build::PreBuildInfo& pre_build_info(LineInfo linfo) const;
PackageSpec spec; PackageSpec spec;
@ -69,9 +70,7 @@ namespace vcpkg::Dependencies
std::vector<PackageSpec> package_dependencies; std::vector<PackageSpec> package_dependencies;
std::vector<std::string> feature_list; std::vector<std::string> feature_list;
Optional<std::unique_ptr<Build::PreBuildInfo>> pre_build_info; Optional<Build::AbiInfo> abi_info;
Optional<std::string> package_abi;
Optional<fs::path> abi_tag_file;
}; };
enum class RemovePlanType enum class RemovePlanType

View File

@ -18,8 +18,8 @@ namespace vcpkg::Export::Prefab
Optional<std::string> maybe_version; Optional<std::string> maybe_version;
Optional<std::string> maybe_min_sdk; Optional<std::string> maybe_min_sdk;
Optional<std::string> maybe_target_sdk; Optional<std::string> maybe_target_sdk;
bool enable_maven; bool enable_maven = false;
bool enable_debug; bool enable_debug = false;
}; };
struct NdkVersion struct NdkVersion
{ {

View File

@ -130,7 +130,9 @@ namespace vcpkg
// feature flags // feature flags
Optional<bool> feature_packages = nullopt; Optional<bool> feature_packages = nullopt;
Optional<bool> binary_caching = nullopt; Optional<bool> binary_caching = nullopt;
Optional<bool> compiler_tracking = nullopt;
bool binary_caching_enabled() const { return binary_caching.value_or(false); } bool binary_caching_enabled() const { return binary_caching.value_or(false); }
bool compiler_tracking_enabled() const { return compiler_tracking.value_or(false); }
std::string command; std::string command;
std::vector<std::string> command_arguments; std::vector<std::string> command_arguments;

View File

@ -6,9 +6,10 @@
#include <vcpkg/vcpkgcmdarguments.h> #include <vcpkg/vcpkgcmdarguments.h>
#include <vcpkg/base/cache.h> #include <vcpkg/base/cache.h>
#include <vcpkg/base/expected.h>
#include <vcpkg/base/files.h> #include <vcpkg/base/files.h>
#include <vcpkg/base/lazy.h> #include <vcpkg/base/lazy.h>
#include <vcpkg/base/optional.h>
#include <vcpkg/base/util.h>
namespace vcpkg namespace vcpkg
{ {
@ -46,9 +47,20 @@ namespace vcpkg
namespace Build namespace Build
{ {
struct PreBuildInfo; struct PreBuildInfo;
struct AbiInfo;
} }
struct VcpkgPaths namespace System
{
struct Environment;
}
namespace details
{
struct VcpkgPathsImpl;
}
struct VcpkgPaths : Util::MoveOnlyBase
{ {
struct TripletFile struct TripletFile
{ {
@ -59,6 +71,7 @@ namespace vcpkg
}; };
VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args); VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args);
~VcpkgPaths() noexcept;
fs::path package_dir(const PackageSpec& spec) const; fs::path package_dir(const PackageSpec& spec) const;
fs::path build_info_file_path(const PackageSpec& spec) const; fs::path build_info_file_path(const PackageSpec& spec) const;
@ -105,17 +118,10 @@ namespace vcpkg
Files::Filesystem& get_filesystem() const; Files::Filesystem& get_filesystem() const;
const System::Environment& get_action_env(const Build::AbiInfo& abi_info) const;
const std::string& get_triplet_info(const Build::AbiInfo& abi_info) const;
private: private:
Lazy<std::vector<TripletFile>> available_triplets; std::unique_ptr<details::VcpkgPathsImpl> m_pimpl;
Lazy<std::vector<Toolset>> toolsets;
Lazy<std::vector<Toolset>> toolsets_vs2013;
fs::path default_vs_path;
std::vector<fs::path> triplets_dirs;
Files::Filesystem* fsPtr;
mutable std::unique_ptr<ToolCache> m_tool_cache;
mutable vcpkg::Cache<Triplet, fs::path> m_triplets_cache;
}; };
} }

View File

@ -33,7 +33,7 @@ namespace vcpkg::Downloads
url_path, url_path,
target_file_path, target_file_path,
std::to_string(err)); std::to_string(err));
_Analysis_assume_(f != nullptr); ASSUME(f != nullptr);
auto hSession = WinHttpOpen(L"vcpkg/1.0", auto hSession = WinHttpOpen(L"vcpkg/1.0",
IsWindows8Point1OrGreater() ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY IsWindows8Point1OrGreater() ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY

View File

@ -69,7 +69,7 @@ namespace
void prefetch() override {} void prefetch() override {}
RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override
{ {
const auto& abi_tag = action.package_abi.value_or_exit(VCPKG_LINE_INFO); const auto& abi_tag = action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi;
auto& spec = action.spec; auto& spec = action.spec;
auto& fs = paths.get_filesystem(); auto& fs = paths.get_filesystem();
std::error_code ec; std::error_code ec;
@ -134,7 +134,7 @@ namespace
void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override
{ {
if (m_write_dirs.empty()) return; if (m_write_dirs.empty()) return;
const auto& abi_tag = action.package_abi.value_or_exit(VCPKG_LINE_INFO); const auto& abi_tag = action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi;
auto& spec = action.spec; auto& spec = action.spec;
auto& fs = paths.get_filesystem(); auto& fs = paths.get_filesystem();
const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip");
@ -209,7 +209,7 @@ namespace
const Dependencies::InstallPlanAction& action, const Dependencies::InstallPlanAction& action,
bool purge_tombstones) override bool purge_tombstones) override
{ {
const auto& abi_tag = action.package_abi.value_or_exit(VCPKG_LINE_INFO); const auto& abi_tag = action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi;
auto& fs = paths.get_filesystem(); auto& fs = paths.get_filesystem();
std::error_code ec; std::error_code ec;
for (auto&& archives_root_dir : m_read_dirs) for (auto&& archives_root_dir : m_read_dirs)
@ -246,6 +246,27 @@ namespace
std::vector<fs::path> m_read_dirs, m_write_dirs; std::vector<fs::path> m_read_dirs, m_write_dirs;
}; };
struct NullBinaryProvider : IBinaryProvider
{
void prefetch() override {}
RestoreResult try_restore(const VcpkgPaths&, const Dependencies::InstallPlanAction&) override
{
return RestoreResult::missing;
}
void push_success(const VcpkgPaths&, const Dependencies::InstallPlanAction&) override {}
void push_failure(const VcpkgPaths&, const std::string&, const PackageSpec&) override {}
RestoreResult precheck(const VcpkgPaths&, const Dependencies::InstallPlanAction&, bool) override
{
return RestoreResult::missing;
}
};
}
IBinaryProvider& vcpkg::null_binary_provider()
{
static NullBinaryProvider p;
return p;
} }
ExpectedS<std::unique_ptr<IBinaryProvider>> vcpkg::create_binary_provider_from_configs(const VcpkgPaths& paths, ExpectedS<std::unique_ptr<IBinaryProvider>> vcpkg::create_binary_provider_from_configs(const VcpkgPaths& paths,

View File

@ -32,17 +32,16 @@ using vcpkg::Parse::ParseControlErrorInfo;
using vcpkg::Parse::ParseExpected; using vcpkg::Parse::ParseExpected;
using vcpkg::PortFileProvider::PathsPortFileProvider; using vcpkg::PortFileProvider::PathsPortFileProvider;
namespace vcpkg::Build::Command namespace vcpkg::Build
{ {
using Dependencies::InstallPlanAction; using Dependencies::InstallPlanAction;
using Dependencies::InstallPlanType; using Dependencies::InstallPlanType;
void perform_and_exit_ex(const FullPackageSpec& full_spec, void Command::perform_and_exit_ex(const FullPackageSpec& full_spec,
const SourceControlFileLocation& scfl, const SourceControlFileLocation& scfl,
const PathsPortFileProvider& provider, const PathsPortFileProvider& provider,
const bool binary_caching_enabled, IBinaryProvider& binaryprovider,
IBinaryProvider& binaryprovider, const VcpkgPaths& paths)
const VcpkgPaths& paths)
{ {
auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
auto& var_provider = *var_provider_storage; auto& var_provider = *var_provider_storage;
@ -71,7 +70,6 @@ namespace vcpkg::Build::Command
Build::CleanPackages::NO, Build::CleanPackages::NO,
Build::CleanDownloads::NO, Build::CleanDownloads::NO,
Build::DownloadTool::BUILT_IN, Build::DownloadTool::BUILT_IN,
binary_caching_enabled ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::NO, Build::FailOnTombstone::NO,
}; };
@ -92,8 +90,7 @@ namespace vcpkg::Build::Command
} }
Checks::check_exit(VCPKG_LINE_INFO, action != nullptr); Checks::check_exit(VCPKG_LINE_INFO, action != nullptr);
_Analysis_assume_(action != nullptr); ASSUME(action != nullptr);
action->build_options = build_package_options; action->build_options = build_package_options;
const auto build_timer = Chrono::ElapsedTimer::create_started(); const auto build_timer = Chrono::ElapsedTimer::create_started();
@ -133,7 +130,7 @@ namespace vcpkg::Build::Command
nullptr, nullptr,
}; };
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet) void Command::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
{ {
// Build only takes a single package and all dependencies must already be installed // Build only takes a single package and all dependencies must already be installed
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
@ -152,9 +149,10 @@ namespace vcpkg::Build::Command
const auto* scfl = provider.get_control_file(port_name).get(); const auto* scfl = provider.get_control_file(port_name).get();
Checks::check_exit(VCPKG_LINE_INFO, scfl != nullptr, "Error: Couldn't find port '%s'", port_name); Checks::check_exit(VCPKG_LINE_INFO, scfl != nullptr, "Error: Couldn't find port '%s'", port_name);
_Analysis_assume_(scfl != nullptr); ASSUME(scfl != nullptr);
perform_and_exit_ex(spec, *scfl, provider, args.binary_caching_enabled(), *binaryprovider, paths); perform_and_exit_ex(
spec, *scfl, provider, args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(), paths);
} }
} }
@ -263,14 +261,15 @@ namespace vcpkg::Build
})); }));
} }
#if defined(_WIN32) const System::Environment& EnvCache::get_action_env(const VcpkgPaths& paths, const AbiInfo& abi_info)
static const std::unordered_map<std::string, std::string>& make_env_passthrough(const PreBuildInfo& pre_build_info)
{ {
static Cache<std::vector<std::string>, std::unordered_map<std::string, std::string>> envs; #if defined(_WIN32)
return envs.get_lazy(pre_build_info.passthrough_env_vars, [&]() { std::string build_env_cmd = make_build_env_cmd(*abi_info.pre_build_info, *abi_info.toolset);
const auto& base_env = envs.get_lazy(abi_info.pre_build_info->passthrough_env_vars, [&]() -> EnvMapEntry {
std::unordered_map<std::string, std::string> env; std::unordered_map<std::string, std::string> env;
for (auto&& env_var : pre_build_info.passthrough_env_vars) for (auto&& env_var : abi_info.pre_build_info->passthrough_env_vars)
{ {
auto env_val = System::get_environment_variable(env_var); auto env_val = System::get_environment_variable(env_var);
@ -280,15 +279,61 @@ namespace vcpkg::Build
} }
} }
return env; return {env};
});
return base_env.cmd_cache.get_lazy(build_env_cmd, [&]() {
const fs::path& powershell_exe_path = paths.get_tool_exe("powershell-core");
auto& fs = paths.get_filesystem();
if (!fs.exists(powershell_exe_path.parent_path() / "powershell.exe"))
{
fs.copy(
powershell_exe_path, powershell_exe_path.parent_path() / "powershell.exe", fs::copy_options::none);
}
auto clean_env = System::get_modified_clean_environment(base_env.env_map,
powershell_exe_path.parent_path().u8string() + ";");
if (build_env_cmd.empty())
return clean_env;
else
return System::cmd_execute_modify_env(build_env_cmd, clean_env);
});
#else
return System::get_clean_environment();
#endif
}
static std::string load_compiler_hash(const VcpkgPaths& paths, const AbiInfo& abi_info);
const std::string& EnvCache::get_triplet_info(const VcpkgPaths& paths, const AbiInfo& abi_info)
{
const auto& fs = paths.get_filesystem();
const fs::path triplet_file_path = paths.get_triplet_file_path(abi_info.pre_build_info->triplet);
auto tcfile = abi_info.pre_build_info->toolchain_file();
auto&& toolchain_hash = m_toolchain_cache.get_lazy(
tcfile, [&]() { return Hash::get_file_hash(VCPKG_LINE_INFO, fs, tcfile, Hash::Algorithm::Sha1); });
auto&& triplet_entry = m_triplet_cache.get_lazy(triplet_file_path, [&]() -> TripletMapEntry {
return TripletMapEntry{Hash::get_file_hash(VCPKG_LINE_INFO, fs, triplet_file_path, Hash::Algorithm::Sha1)};
});
return triplet_entry.compiler_hashes.get_lazy(toolchain_hash, [&]() -> std::string {
if (m_compiler_tracking)
{
auto compiler_hash = load_compiler_hash(paths, abi_info);
return Strings::concat(triplet_entry.hash, '-', toolchain_hash, '-', compiler_hash);
}
else
{
return triplet_entry.hash + "-" + toolchain_hash;
}
}); });
} }
#endif
std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset)
{ {
if (pre_build_info.external_toolchain_file.has_value() && !pre_build_info.load_vcvars_env) return ""; if (!pre_build_info.using_vcvars()) return "";
if (!pre_build_info.cmake_system_name.empty() && pre_build_info.cmake_system_name != "WindowsStore") return "";
const char* tonull = " >nul"; const char* tonull = " >nul";
if (Debug::g_debugging) if (Debug::g_debugging)
@ -353,10 +398,84 @@ namespace vcpkg::Build
return concurrency; return concurrency;
} }
static std::vector<System::CMakeVariable> get_cmake_vars(const VcpkgPaths& paths, static void get_generic_cmake_build_args(const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& action, Triplet triplet,
Triplet triplet, const Toolset& toolset,
const Toolset& toolset) std::vector<System::CMakeVariable>& out_vars)
{
Util::Vectors::append(&out_vars,
std::initializer_list<System::CMakeVariable>{
{"CMD", "BUILD"},
{"TARGET_TRIPLET", triplet.canonical_name()},
{"TARGET_TRIPLET_FILE", paths.get_triplet_file_path(triplet).u8string()},
{"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()},
{"DOWNLOADS", paths.downloads},
{"VCPKG_CONCURRENCY", std::to_string(get_concurrency())},
});
if (!System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
{
const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT);
out_vars.push_back({"GIT", git_exe_path});
}
}
static std::string load_compiler_hash(const VcpkgPaths& paths, const AbiInfo& abi_info)
{
auto triplet = abi_info.pre_build_info->triplet;
System::print2("Detecting compiler hash for triplet ", triplet, "...\n");
auto buildpath = paths.buildtrees / "detect_compiler";
std::vector<System::CMakeVariable> cmake_args{
{"CURRENT_PORT_DIR", paths.scripts / "detect_compiler"},
{"CURRENT_BUILDTREES_DIR", buildpath},
{"CURRENT_PACKAGES_DIR", paths.packages / ("detect_compiler_" + triplet.canonical_name())},
};
get_generic_cmake_build_args(paths, triplet, *abi_info.toolset, cmake_args);
auto command = vcpkg::make_cmake_cmd(paths, paths.ports_cmake, std::move(cmake_args));
const auto& env = paths.get_action_env(abi_info);
auto& fs = paths.get_filesystem();
if (!fs.exists(buildpath))
{
std::error_code err;
fs.create_directory(buildpath, err);
Checks::check_exit(VCPKG_LINE_INFO,
!err.value(),
"Failed to create directory '%s', code: %d",
buildpath.u8string(),
err.value());
}
auto stdoutlog = buildpath / ("stdout-" + triplet.canonical_name() + ".log");
std::ofstream out_file(stdoutlog.native().c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
Checks::check_exit(VCPKG_LINE_INFO, out_file, "Failed to open '%s' for writing", stdoutlog.u8string());
std::string compiler_hash;
const int return_code = System::cmd_execute_and_stream_lines(
command,
[&](const std::string& s) {
static const StringLiteral s_marker = "#COMPILER_HASH#";
if (Strings::starts_with(s, s_marker))
{
compiler_hash = s.data() + s_marker.size();
}
Debug::print(s, '\n');
out_file.write(s.data(), s.size()).put('\n');
Checks::check_exit(
VCPKG_LINE_INFO, out_file, "Error occurred while writing '%s'", stdoutlog.u8string());
},
env);
out_file.close();
Checks::check_exit(
VCPKG_LINE_INFO, !compiler_hash.empty(), "Error occured while detecting compiler information");
Debug::print("Detecting compiler hash for triplet ", triplet, ": ", compiler_hash, "\n");
return compiler_hash;
}
static std::vector<System::CMakeVariable> get_cmake_build_args(const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& action,
Triplet triplet)
{ {
#if !defined(_WIN32) #if !defined(_WIN32)
// TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107. // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107.
@ -365,7 +484,6 @@ namespace vcpkg::Build
#endif #endif
auto& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO); auto& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
auto& scf = *scfl.source_control_file; auto& scf = *scfl.source_control_file;
const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT);
std::string all_features; std::string all_features;
for (auto& feature : scf.feature_paragraphs) for (auto& feature : scf.feature_paragraphs)
@ -374,30 +492,22 @@ namespace vcpkg::Build
} }
std::vector<System::CMakeVariable> variables{ std::vector<System::CMakeVariable> variables{
{"CMD", "BUILD"},
{"PORT", scf.core_paragraph->name}, {"PORT", scf.core_paragraph->name},
{"CURRENT_PORT_DIR", scfl.source_location}, {"CURRENT_PORT_DIR", scfl.source_location},
{"TARGET_TRIPLET", triplet.canonical_name()},
{"TARGET_TRIPLET_FILE", paths.get_triplet_file_path(triplet).u8string()},
{"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()},
{"VCPKG_USE_HEAD_VERSION", Util::Enum::to_bool(action.build_options.use_head_version) ? "1" : "0"}, {"VCPKG_USE_HEAD_VERSION", Util::Enum::to_bool(action.build_options.use_head_version) ? "1" : "0"},
{"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(action.build_options.allow_downloads) ? "1" : "0"}, {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(action.build_options.allow_downloads) ? "1" : "0"},
{"_VCPKG_DOWNLOAD_TOOL", to_string(action.build_options.download_tool)}, {"_VCPKG_DOWNLOAD_TOOL", to_string(action.build_options.download_tool)},
{"FEATURES", Strings::join(";", action.feature_list)}, {"FEATURES", Strings::join(";", action.feature_list)},
{"ALL_FEATURES", all_features}, {"ALL_FEATURES", all_features},
{"VCPKG_CONCURRENCY", std::to_string(get_concurrency())},
}; };
get_generic_cmake_build_args(
paths, triplet, *action.abi_info.value_or_exit(VCPKG_LINE_INFO).toolset, variables);
if (Util::Enum::to_bool(action.build_options.only_downloads)) if (Util::Enum::to_bool(action.build_options.only_downloads))
{ {
variables.push_back({"VCPKG_DOWNLOAD_MODE", "true"}); variables.push_back({"VCPKG_DOWNLOAD_MODE", "true"});
} }
if (!System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
{
variables.push_back({"GIT", git_exe_path});
}
const Files::Filesystem& fs = paths.get_filesystem(); const Files::Filesystem& fs = paths.get_filesystem();
std::vector<std::string> port_configs; std::vector<std::string> port_configs;
@ -421,78 +531,54 @@ namespace vcpkg::Build
return variables; return variables;
} }
static std::string get_triplet_abi(const VcpkgPaths& paths, const PreBuildInfo& pre_build_info, Triplet triplet) bool PreBuildInfo::using_vcvars() const
{ {
static std::map<fs::path, std::string> s_hash_cache; return (!external_toolchain_file.has_value() || load_vcvars_env) &&
(cmake_system_name.empty() || cmake_system_name == "WindowsStore");
}
const fs::path triplet_file_path = paths.get_triplet_file_path(triplet); fs::path PreBuildInfo::toolchain_file() const
const auto& fs = paths.get_filesystem(); {
if (auto p = external_toolchain_file.get())
std::string hash;
auto it_hash = s_hash_cache.find(triplet_file_path);
if (it_hash != s_hash_cache.end())
{ {
hash = it_hash->second; return fs::u8path(*p);
}
else if (cmake_system_name == "Linux")
{
return m_paths.scripts / fs::u8path("toolchains/linux.cmake");
}
else if (cmake_system_name == "Darwin")
{
return m_paths.scripts / fs::u8path("toolchains/osx.cmake");
}
else if (cmake_system_name == "FreeBSD")
{
return m_paths.scripts / fs::u8path("toolchains/freebsd.cmake");
}
else if (cmake_system_name == "Android")
{
return m_paths.scripts / fs::u8path("toolchains/android.cmake");
}
else if (cmake_system_name.empty() || cmake_system_name == "Windows" || cmake_system_name == "WindowsStore")
{
return m_paths.scripts / fs::u8path("toolchains/windows.cmake");
} }
else else
{ {
const auto algo = Hash::Algorithm::Sha1; Checks::exit_with_message(VCPKG_LINE_INFO,
// TODO: Use file path as part of hash. "Unable to determine toolchain to use for triplet %s with CMAKE_SYSTEM_NAME %s",
// REASON: Copying a triplet file without modifying it produces the same hash as the original. triplet,
hash = Hash::get_file_hash(VCPKG_LINE_INFO, fs, triplet_file_path, algo); cmake_system_name);
if (auto p = pre_build_info.external_toolchain_file.get())
{
hash += "-";
hash += Hash::get_file_hash(VCPKG_LINE_INFO, fs, *p, algo);
}
else if (pre_build_info.cmake_system_name == "Linux")
{
hash += "-";
hash += Hash::get_file_hash(
VCPKG_LINE_INFO, fs, paths.scripts / fs::u8path("toolchains/linux.cmake"), algo);
}
else if (pre_build_info.cmake_system_name == "Darwin")
{
hash += "-";
hash +=
Hash::get_file_hash(VCPKG_LINE_INFO, fs, paths.scripts / fs::u8path("toolchains/osx.cmake"), algo);
}
else if (pre_build_info.cmake_system_name == "FreeBSD")
{
hash += "-";
hash += Hash::get_file_hash(
VCPKG_LINE_INFO, fs, paths.scripts / fs::u8path("toolchains/freebsd.cmake"), algo);
}
else if (pre_build_info.cmake_system_name == "Android")
{
hash += "-";
hash += Hash::get_file_hash(
VCPKG_LINE_INFO, fs, paths.scripts / fs::u8path("toolchains/android.cmake"), algo);
}
s_hash_cache.emplace(triplet_file_path, hash);
} }
return hash;
} }
static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action)
{ {
const auto& pre_build_info = *action.pre_build_info.value_or_exit(VCPKG_LINE_INFO).get(); const auto& pre_build_info = action.pre_build_info(VCPKG_LINE_INFO);
auto& fs = paths.get_filesystem(); auto& fs = paths.get_filesystem();
auto&& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO); auto&& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
#if defined(_WIN32)
const fs::path& powershell_exe_path = paths.get_tool_exe("powershell-core");
if (!fs.exists(powershell_exe_path.parent_path() / "powershell.exe"))
{
fs.copy(powershell_exe_path, powershell_exe_path.parent_path() / "powershell.exe", fs::copy_options::none);
}
#endif
Triplet triplet = action.spec.triplet(); Triplet triplet = action.spec.triplet();
const auto& triplet_file_path = paths.get_triplet_file_path(triplet).u8string(); const auto& triplet_file_path = paths.get_triplet_file_path(triplet).u8string();
@ -516,26 +602,10 @@ namespace vcpkg::Build
const auto timer = Chrono::ElapsedTimer::create_started(); const auto timer = Chrono::ElapsedTimer::create_started();
auto command = vcpkg::make_cmake_cmd( auto command = vcpkg::make_cmake_cmd(paths, paths.ports_cmake, get_cmake_build_args(paths, action, triplet));
paths, paths.ports_cmake, get_cmake_vars(paths, action, triplet, paths.get_toolset(pre_build_info)));
#if defined(_WIN32)
std::string build_env_cmd = make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info));
const std::unordered_map<std::string, std::string>& base_env = make_env_passthrough(pre_build_info); const auto& env = paths.get_action_env(action.abi_info.value_or_exit(VCPKG_LINE_INFO));
static Cache<std::pair<const std::unordered_map<std::string, std::string>*, std::string>, System::Environment>
build_env_cache;
const auto& env = build_env_cache.get_lazy({&base_env, build_env_cmd}, [&]() {
auto clean_env =
System::get_modified_clean_environment(base_env, powershell_exe_path.parent_path().u8string() + ";");
if (build_env_cmd.empty())
return clean_env;
else
return System::cmd_execute_modify_env(build_env_cmd, clean_env);
});
#else
const auto& env = System::get_clean_environment();
#endif
auto buildpath = paths.buildtrees / action.spec.name(); auto buildpath = paths.buildtrees / action.spec.name();
if (!fs.exists(buildpath)) if (!fs.exists(buildpath))
{ {
@ -652,38 +722,58 @@ namespace vcpkg::Build
return result; return result;
} }
Optional<AbiTagAndFile> compute_abi_tag(const VcpkgPaths& paths, static void abi_entries_from_abi_info(const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& action, const AbiInfo& abi_info,
Span<const AbiEntry> dependency_abis) std::vector<AbiEntry>& abi_tag_entries)
{
abi_tag_entries.emplace_back("triplet", paths.get_triplet_info(abi_info));
const auto& pre_build_info = *abi_info.pre_build_info;
if (pre_build_info.public_abi_override)
{
abi_tag_entries.emplace_back(
"public_abi_override",
Hash::get_string_hash(pre_build_info.public_abi_override.value_or_exit(VCPKG_LINE_INFO),
Hash::Algorithm::Sha1));
}
for (const auto& env_var : pre_build_info.passthrough_env_vars)
{
abi_tag_entries.emplace_back(
"ENV:" + env_var,
Hash::get_string_hash(System::get_environment_variable(env_var).value_or(""), Hash::Algorithm::Sha1));
}
}
static Optional<AbiTagAndFile> compute_abi_tag(const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& action,
Span<const AbiEntry> dependency_abis)
{ {
auto& fs = paths.get_filesystem(); auto& fs = paths.get_filesystem();
Triplet triplet = action.spec.triplet(); Triplet triplet = action.spec.triplet();
const std::string& name = action.spec.name(); const std::string& name = action.spec.name();
const auto& pre_build_info = *action.pre_build_info.value_or_exit(VCPKG_LINE_INFO);
std::vector<AbiEntry> abi_tag_entries(dependency_abis.begin(), dependency_abis.end()); std::vector<AbiEntry> abi_tag_entries(dependency_abis.begin(), dependency_abis.end());
// Sorted here as the order of dependency_abis is the only abi_entries_from_abi_info(paths, action.abi_info.value_or_exit(VCPKG_LINE_INFO), abi_tag_entries);
// non-deterministically ordered set of AbiEntries
Util::sort(abi_tag_entries);
// If there is an unusually large number of files in the port then // If there is an unusually large number of files in the port then
// something suspicious is going on. Rather than hash all of them // something suspicious is going on. Rather than hash all of them
// just mark the port as no-hash // just mark the port as no-hash
const int max_port_file_count = 100; const int max_port_file_count = 100;
// the order of recursive_directory_iterator is undefined so save the names to sort
auto&& port_dir = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO).source_location; auto&& port_dir = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO).source_location;
std::vector<AbiEntry> port_files; size_t port_file_count = 0;
for (auto& port_file : fs::stdfs::recursive_directory_iterator(port_dir)) for (auto& port_file : fs::stdfs::recursive_directory_iterator(port_dir))
{ {
if (fs::is_regular_file(fs.status(VCPKG_LINE_INFO, port_file))) if (fs::is_regular_file(fs.status(VCPKG_LINE_INFO, port_file)))
{ {
port_files.emplace_back( abi_tag_entries.emplace_back(
port_file.path().filename().u8string(), port_file.path().filename().u8string(),
vcpkg::Hash::get_file_hash(VCPKG_LINE_INFO, fs, port_file, Hash::Algorithm::Sha1)); vcpkg::Hash::get_file_hash(VCPKG_LINE_INFO, fs, port_file, Hash::Algorithm::Sha1));
if (port_files.size() > max_port_file_count) ++port_file_count;
if (port_file_count > max_port_file_count)
{ {
abi_tag_entries.emplace_back("no_hash_max_portfile", ""); abi_tag_entries.emplace_back("no_hash_max_portfile", "");
break; break;
@ -691,15 +781,6 @@ namespace vcpkg::Build
} }
} }
if (port_files.size() <= max_port_file_count)
{
Util::sort(port_files, [](const AbiEntry& l, const AbiEntry& r) {
return l.value < r.value || (l.value == r.value && l.key < r.key);
});
std::move(port_files.begin(), port_files.end(), std::back_inserter(abi_tag_entries));
}
abi_tag_entries.emplace_back("cmake", paths.get_tool_version(Tools::CMAKE)); abi_tag_entries.emplace_back("cmake", paths.get_tool_version(Tools::CMAKE));
#if defined(_WIN32) #if defined(_WIN32)
@ -714,38 +795,23 @@ namespace vcpkg::Build
Hash::Algorithm::Sha1)); Hash::Algorithm::Sha1));
abi_tag_entries.emplace_back("post_build_checks", "2"); abi_tag_entries.emplace_back("post_build_checks", "2");
abi_tag_entries.emplace_back("triplet", pre_build_info.triplet_abi_tag);
std::vector<std::string> sorted_feature_list = action.feature_list; std::vector<std::string> sorted_feature_list = action.feature_list;
Util::sort(sorted_feature_list); Util::sort(sorted_feature_list);
abi_tag_entries.emplace_back("features", Strings::join(";", sorted_feature_list)); abi_tag_entries.emplace_back("features", Strings::join(";", sorted_feature_list));
if (pre_build_info.public_abi_override)
{
abi_tag_entries.emplace_back(
"public_abi_override",
Hash::get_string_hash(pre_build_info.public_abi_override.value_or_exit(VCPKG_LINE_INFO),
Hash::Algorithm::Sha1));
}
// No need to sort, the variables are stored in the same order they are written down in the abi-settings file
for (const auto& env_var : pre_build_info.passthrough_env_vars)
{
abi_tag_entries.emplace_back(
"ENV:" + env_var,
Hash::get_string_hash(System::get_environment_variable(env_var).value_or(""), Hash::Algorithm::Sha1));
}
if (action.build_options.use_head_version == UseHeadVersion::YES) abi_tag_entries.emplace_back("head", ""); if (action.build_options.use_head_version == UseHeadVersion::YES) abi_tag_entries.emplace_back("head", "");
Util::sort(abi_tag_entries);
const std::string full_abi_info = const std::string full_abi_info =
Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; });
if (Debug::g_debugging) if (Debug::g_debugging)
{ {
std::string message = "[DEBUG] <abientries>\n"; std::string message = Strings::concat("[DEBUG] <abientries for ", action.spec, ">\n");
for (auto&& entry : abi_tag_entries) for (auto&& entry : abi_tag_entries)
{ {
Strings::append(message, "[DEBUG] ", entry.key, "|", entry.value, "\n"); Strings::append(message, "[DEBUG] ", entry.key, "|", entry.value, "\n");
} }
Strings::append(message, "[DEBUG] </abientries>\n"); Strings::append(message, "[DEBUG] </abientries>\n");
System::print2(message); System::print2(message);
@ -765,7 +831,7 @@ namespace vcpkg::Build
abi_file_path}; abi_file_path};
} }
System::print2( Debug::print(
"Warning: abi keys are missing values:\n", "Warning: abi keys are missing values:\n",
Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; }), Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; }),
"\n"); "\n");
@ -812,17 +878,18 @@ namespace vcpkg::Build
} }
} }
action.pre_build_info = std::make_unique<PreBuildInfo>( action.abi_info = Build::AbiInfo();
auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO);
abi_info.pre_build_info = std::make_unique<PreBuildInfo>(
paths, action.spec.triplet(), var_provider.get_tag_vars(action.spec).value_or_exit(VCPKG_LINE_INFO)); paths, action.spec.triplet(), var_provider.get_tag_vars(action.spec).value_or_exit(VCPKG_LINE_INFO));
abi_info.toolset = &paths.get_toolset(*abi_info.pre_build_info);
auto maybe_abi_tag_and_file = compute_abi_tag(paths, action, dependency_abis); auto maybe_abi_tag_and_file = compute_abi_tag(paths, action, dependency_abis);
if (auto p = maybe_abi_tag_and_file.get()) if (auto p = maybe_abi_tag_and_file.get())
{ {
action.abi_tag_file = std::move(p->tag_file); abi_info.package_abi = std::move(p->tag);
action.package_abi = std::move(p->tag); abi_info.abi_tag_file = std::move(p->tag_file);
}
else
{
action.package_abi = "";
} }
} }
} }
@ -832,8 +899,6 @@ namespace vcpkg::Build
IBinaryProvider& binaries_provider, IBinaryProvider& binaries_provider,
const StatusParagraphs& status_db) const StatusParagraphs& status_db)
{ {
auto binary_caching_enabled = action.build_options.binary_caching == BinaryCaching::YES;
auto& fs = paths.get_filesystem(); auto& fs = paths.get_filesystem();
auto& spec = action.spec; auto& spec = action.spec;
const std::string& name = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO) const std::string& name = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO)
@ -869,31 +934,29 @@ namespace vcpkg::Build
AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi});
} }
if (!action.abi_tag_file) auto& abi_info = action.abi_info.value_or_exit(VCPKG_LINE_INFO);
if (!abi_info.abi_tag_file)
{ {
return do_build_package_and_clean_buildtrees(paths, action); return do_build_package_and_clean_buildtrees(paths, action);
} }
auto& abi_file = *action.abi_tag_file.get(); auto& abi_file = *abi_info.abi_tag_file.get();
std::error_code ec; std::error_code ec;
const fs::path abi_package_dir = paths.package_dir(spec) / "share" / spec.name(); const fs::path abi_package_dir = paths.package_dir(spec) / "share" / spec.name();
const fs::path abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; const fs::path abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt";
if (binary_caching_enabled) auto restore = binaries_provider.try_restore(paths, action);
if (restore == RestoreResult::build_failed)
return BuildResult::BUILD_FAILED;
else if (restore == RestoreResult::success)
{ {
auto restore = binaries_provider.try_restore(paths, action); auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec);
if (restore == RestoreResult::build_failed) auto bcf = std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO));
return BuildResult::BUILD_FAILED; return {BuildResult::SUCCEEDED, std::move(bcf)};
else if (restore == RestoreResult::success) }
{ else
auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); {
auto bcf = std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); // missing package, proceed to build.
return {BuildResult::SUCCEEDED, std::move(bcf)};
}
else
{
// missing package, proceed to build.
}
} }
ExtendedBuildResult result = do_build_package_and_clean_buildtrees(paths, action); ExtendedBuildResult result = do_build_package_and_clean_buildtrees(paths, action);
@ -902,14 +965,13 @@ namespace vcpkg::Build
fs.copy_file(abi_file, abi_file_in_package, fs::copy_options::none, ec); fs.copy_file(abi_file, abi_file_in_package, fs::copy_options::none, ec);
Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string()); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string());
if (binary_caching_enabled && result.code == BuildResult::SUCCEEDED) if (result.code == BuildResult::SUCCEEDED)
{ {
binaries_provider.push_success(paths, action); binaries_provider.push_success(paths, action);
} }
else if (binary_caching_enabled && else if ((result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED))
(result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED))
{ {
binaries_provider.push_failure(paths, action.package_abi.value_or_exit(VCPKG_LINE_INFO), spec); binaries_provider.push_failure(paths, abi_info.package_abi, spec);
} }
return result; return result;
@ -1023,16 +1085,49 @@ namespace vcpkg::Build
PreBuildInfo::PreBuildInfo(const VcpkgPaths& paths, PreBuildInfo::PreBuildInfo(const VcpkgPaths& paths,
Triplet triplet, Triplet triplet,
const std::unordered_map<std::string, std::string>& cmakevars) const std::unordered_map<std::string, std::string>& cmakevars)
: m_paths(paths), triplet(triplet)
{ {
enum class VcpkgTripletVar
{
TARGET_ARCHITECTURE = 0,
CMAKE_SYSTEM_NAME,
CMAKE_SYSTEM_VERSION,
PLATFORM_TOOLSET,
VISUAL_STUDIO_PATH,
CHAINLOAD_TOOLCHAIN_FILE,
BUILD_TYPE,
ENV_PASSTHROUGH,
PUBLIC_ABI_OVERRIDE,
LOAD_VCVARS_ENV,
};
static const std::vector<std::pair<std::string, VcpkgTripletVar>> VCPKG_OPTIONS = {
{"VCPKG_TARGET_ARCHITECTURE", VcpkgTripletVar::TARGET_ARCHITECTURE},
{"VCPKG_CMAKE_SYSTEM_NAME", VcpkgTripletVar::CMAKE_SYSTEM_NAME},
{"VCPKG_CMAKE_SYSTEM_VERSION", VcpkgTripletVar::CMAKE_SYSTEM_VERSION},
{"VCPKG_PLATFORM_TOOLSET", VcpkgTripletVar::PLATFORM_TOOLSET},
{"VCPKG_VISUAL_STUDIO_PATH", VcpkgTripletVar::VISUAL_STUDIO_PATH},
{"VCPKG_CHAINLOAD_TOOLCHAIN_FILE", VcpkgTripletVar::CHAINLOAD_TOOLCHAIN_FILE},
{"VCPKG_BUILD_TYPE", VcpkgTripletVar::BUILD_TYPE},
{"VCPKG_ENV_PASSTHROUGH", VcpkgTripletVar::ENV_PASSTHROUGH},
{"VCPKG_PUBLIC_ABI_OVERRIDE", VcpkgTripletVar::PUBLIC_ABI_OVERRIDE},
{"VCPKG_LOAD_VCVARS_ENV", VcpkgTripletVar::LOAD_VCVARS_ENV},
};
std::string empty;
for (auto&& kv : VCPKG_OPTIONS) for (auto&& kv : VCPKG_OPTIONS)
{ {
auto find_itr = cmakevars.find(kv.first); const std::string& variable_value = [&]() -> const std::string& {
if (find_itr == cmakevars.end()) auto find_itr = cmakevars.find(kv.first);
{ if (find_itr == cmakevars.end())
continue; {
} return empty;
}
const std::string& variable_value = find_itr->second; else
{
return find_itr->second;
}
}();
switch (kv.second) switch (kv.second)
{ {
@ -1057,7 +1152,9 @@ namespace vcpkg::Build
build_type = ConfigurationType::RELEASE; build_type = ConfigurationType::RELEASE;
else else
Checks::exit_with_message( Checks::exit_with_message(
VCPKG_LINE_INFO, "Unknown setting for VCPKG_BUILD_TYPE: %s", variable_value); VCPKG_LINE_INFO,
"Unknown setting for VCPKG_BUILD_TYPE: %s. Valid settings are '', 'debug' and 'release'.",
variable_value);
break; break;
case VcpkgTripletVar::ENV_PASSTHROUGH: case VcpkgTripletVar::ENV_PASSTHROUGH:
passthrough_env_vars = Strings::split(variable_value, ';'); passthrough_env_vars = Strings::split(variable_value, ';');
@ -1080,16 +1177,16 @@ namespace vcpkg::Build
Strings::case_insensitive_ascii_equals(variable_value, "false")) Strings::case_insensitive_ascii_equals(variable_value, "false"))
load_vcvars_env = false; load_vcvars_env = false;
else else
Checks::exit_with_message( Checks::exit_with_message(VCPKG_LINE_INFO,
VCPKG_LINE_INFO, "Unknown boolean setting for VCPKG_LOAD_VCVARS_ENV: %s", variable_value); "Unknown boolean setting for VCPKG_LOAD_VCVARS_ENV: %s. Valid "
"settings are '', '1', '0', 'ON', 'OFF', 'TRUE', and 'FALSE'.",
variable_value);
break; break;
} }
} }
triplet_abi_tag = get_triplet_abi(paths, *this, triplet);
} }
ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) { } ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) {}
ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf) ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr<BinaryControlFile>&& bcf)
: code(code), binary_control_file(std::move(bcf)) : code(code), binary_control_file(std::move(bcf))
{ {

View File

@ -115,8 +115,7 @@ namespace vcpkg::CMakeVars
fs::path path = paths.buildtrees / Strings::concat(tag_extract_id++, ".vcpkg_tags.cmake"); fs::path path = paths.buildtrees / Strings::concat(tag_extract_id++, ".vcpkg_tags.cmake");
std::error_code ec; fs.create_directories(paths.buildtrees, ignore_errors);
fs.create_directories(paths.buildtrees, ec);
fs.write_contents(path, extraction_file, VCPKG_LINE_INFO); fs.write_contents(path, extraction_file, VCPKG_LINE_INFO);
return path; return path;

View File

@ -40,8 +40,7 @@ namespace vcpkg::Commands::BuildExternal
Build::Command::perform_and_exit_ex(spec, Build::Command::perform_and_exit_ex(spec,
maybe_scfl.value_or_exit(VCPKG_LINE_INFO), maybe_scfl.value_or_exit(VCPKG_LINE_INFO),
provider, provider,
args.binary_caching_enabled(), args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
*binaryprovider,
paths); paths);
} }
} }

View File

@ -257,7 +257,6 @@ namespace vcpkg::Commands::CI
const CMakeVars::CMakeVarProvider& var_provider, const CMakeVars::CMakeVarProvider& var_provider,
const std::vector<FullPackageSpec>& specs, const std::vector<FullPackageSpec>& specs,
const bool purge_tombstones, const bool purge_tombstones,
const bool binary_caching_enabled,
IBinaryProvider& binaryprovider) IBinaryProvider& binaryprovider)
{ {
auto ret = std::make_unique<UnknownCIPortsResults>(); auto ret = std::make_unique<UnknownCIPortsResults>();
@ -272,7 +271,6 @@ namespace vcpkg::Commands::CI
Build::CleanPackages::YES, Build::CleanPackages::YES,
Build::CleanDownloads::NO, Build::CleanDownloads::NO,
Build::DownloadTool::BUILT_IN, Build::DownloadTool::BUILT_IN,
binary_caching_enabled ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::YES, Build::FailOnTombstone::YES,
}; };
@ -312,7 +310,7 @@ namespace vcpkg::Commands::CI
for (auto&& action : action_plan.install_actions) for (auto&& action : action_plan.install_actions)
{ {
auto p = &action; auto p = &action;
ret->abi_map.emplace(action.spec, action.package_abi.value_or_exit(VCPKG_LINE_INFO)); ret->abi_map.emplace(action.spec, action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi);
ret->features.emplace(action.spec, action.feature_list); ret->features.emplace(action.spec, action.feature_list);
if (auto scfl = p->source_control_file_location.get()) if (auto scfl = p->source_control_file_location.get())
{ {
@ -371,7 +369,7 @@ namespace vcpkg::Commands::CI
p->spec, p->spec,
(b_will_build ? "*" : " "), (b_will_build ? "*" : " "),
state, state,
action.package_abi.value_or_exit(VCPKG_LINE_INFO))); action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi));
if (stdout_buffer.size() > 2048) if (stdout_buffer.size() > 2048)
{ {
System::print2(stdout_buffer); System::print2(stdout_buffer);
@ -431,7 +429,6 @@ namespace vcpkg::Commands::CI
Build::CleanPackages::YES, Build::CleanPackages::YES,
Build::CleanDownloads::NO, Build::CleanDownloads::NO,
Build::DownloadTool::BUILT_IN, Build::DownloadTool::BUILT_IN,
args.binary_caching_enabled() ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::YES, Build::FailOnTombstone::YES,
Build::PurgeDecompressFailure::YES, Build::PurgeDecompressFailure::YES,
}; };
@ -461,14 +458,14 @@ namespace vcpkg::Commands::CI
return FullPackageSpec{spec, std::move(default_features)}; return FullPackageSpec{spec, std::move(default_features)};
}); });
auto split_specs = find_unknown_ports_for_ci(paths, auto split_specs =
exclusions_set, find_unknown_ports_for_ci(paths,
provider, exclusions_set,
var_provider, provider,
all_default_full_specs, var_provider,
purge_tombstones, all_default_full_specs,
args.binary_caching_enabled(), purge_tombstones,
*binaryprovider); args.binary_caching_enabled() ? *binaryprovider : null_binary_provider());
PortFileProvider::MapPortFileProvider new_default_provider(split_specs->default_feature_provider); PortFileProvider::MapPortFileProvider new_default_provider(split_specs->default_feature_provider);
Dependencies::CreateInstallPlanOptions serialize_options; Dependencies::CreateInstallPlanOptions serialize_options;
@ -558,7 +555,8 @@ namespace vcpkg::Commands::CI
auto it_xunit = options.settings.find(OPTION_XUNIT); auto it_xunit = options.settings.find(OPTION_XUNIT);
if (it_xunit != options.settings.end()) if (it_xunit != options.settings.end())
{ {
paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunitTestResults.build_xml(), VCPKG_LINE_INFO); paths.get_filesystem().write_contents(
fs::u8path(it_xunit->second), xunitTestResults.build_xml(), VCPKG_LINE_INFO);
} }
Checks::exit_success(VCPKG_LINE_INFO); Checks::exit_success(VCPKG_LINE_INFO);

View File

@ -47,7 +47,6 @@ namespace vcpkg::Commands::SetInstalled
Build::CleanPackages::YES, Build::CleanPackages::YES,
Build::CleanDownloads::YES, Build::CleanDownloads::YES,
Build::DownloadTool::BUILT_IN, Build::DownloadTool::BUILT_IN,
args.binary_caching_enabled() ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::NO, Build::FailOnTombstone::NO,
}; };
@ -71,7 +70,7 @@ namespace vcpkg::Commands::SetInstalled
for (const auto& action : action_plan.install_actions) for (const auto& action : action_plan.install_actions)
{ {
all_abis.insert(action.package_abi.value_or_exit(VCPKG_LINE_INFO)); all_abis.insert(action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi);
} }
// currently (or once) installed specifications // currently (or once) installed specifications
@ -105,8 +104,12 @@ namespace vcpkg::Commands::SetInstalled
Dependencies::print_plan(real_action_plan, true); Dependencies::print_plan(real_action_plan, true);
const auto summary = const auto summary = Install::perform(real_action_plan,
Install::perform(real_action_plan, Install::KeepGoing::NO, paths, status_db, *binaryprovider, *cmake_vars); Install::KeepGoing::NO,
paths,
status_db,
args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
*cmake_vars);
System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n"); System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");

View File

@ -165,7 +165,6 @@ namespace vcpkg::Commands::Upgrade
Build::CleanPackages::NO, Build::CleanPackages::NO,
Build::CleanDownloads::NO, Build::CleanDownloads::NO,
Build::DownloadTool::BUILT_IN, Build::DownloadTool::BUILT_IN,
args.binary_caching_enabled() ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::NO, Build::FailOnTombstone::NO,
}; };
@ -188,7 +187,12 @@ namespace vcpkg::Commands::Upgrade
var_provider.load_tag_vars(action_plan, provider); var_provider.load_tag_vars(action_plan, provider);
const Install::InstallSummary summary = const Install::InstallSummary summary =
Install::perform(action_plan, keep_going, paths, status_db, *binaryprovider, var_provider); Install::perform(action_plan,
keep_going,
paths,
status_db,
args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(),
var_provider);
System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n"); System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");

View File

@ -403,12 +403,24 @@ namespace vcpkg::Dependencies
} }
const std::string& InstallPlanAction::public_abi() const const std::string& InstallPlanAction::public_abi() const
{ {
if (auto p = pre_build_info.get()) switch (plan_type)
{ {
if (auto q = p->get()->public_abi_override.get()) return *q; case InstallPlanType::ALREADY_INSTALLED:
return installed_package.value_or_exit(VCPKG_LINE_INFO).core->package.abi;
case InstallPlanType::BUILD_AND_INSTALL:
{
auto&& i = abi_info.value_or_exit(VCPKG_LINE_INFO);
if (auto o = i.pre_build_info->public_abi_override.get())
return *o;
else
return i.package_abi;
}
default: Checks::unreachable(VCPKG_LINE_INFO);
} }
if (auto p = installed_package.get()) return p->core->package.abi; }
return package_abi.value_or_exit(VCPKG_LINE_INFO); const Build::PreBuildInfo& InstallPlanAction::pre_build_info(LineInfo linfo) const
{
return *abi_info.value_or_exit(linfo).pre_build_info.get();
} }
bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right)

View File

@ -84,7 +84,6 @@ namespace vcpkg::Export
Build::CleanPackages::NO, Build::CleanPackages::NO,
Build::CleanDownloads::NO, Build::CleanDownloads::NO,
Build::DownloadTool::BUILT_IN, Build::DownloadTool::BUILT_IN,
Build::BinaryCaching::NO,
Build::FailOnTombstone::NO, Build::FailOnTombstone::NO,
}; };

View File

@ -159,7 +159,7 @@ namespace vcpkg::Export::Prefab
if (std::regex_search(content, pkg_match, pkg_regex)) if (std::regex_search(content, pkg_match, pkg_regex))
{ {
for (const auto& p : pkg_match) for (const auto& p : pkg_match)
{ {
std::string delimiter = "="; std::string delimiter = "=";
std::string s = p.str(); std::string s = p.str();
@ -218,28 +218,25 @@ namespace vcpkg::Export::Prefab
static void maven_install(const fs::path& aar, const fs::path& pom, const Options& prefab_options) static void maven_install(const fs::path& aar, const fs::path& pom, const Options& prefab_options)
{ {
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
{
System::print2("\n[DEBUG] Installing POM and AAR file to ~/.m2\n\n"); System::print2("\n[DEBUG] Installing POM and AAR file to ~/.m2\n\n");
} }
const char* cmd_line_format = prefab_options.enable_debug ? R"("%s" "install:install-file" "-Dfile=%s" "-DpomFile=%s")" const char* cmd_line_format = prefab_options.enable_debug
: R"("%s" "-q" "install:install-file" "-Dfile=%s" "-DpomFile=%s")"; ? R"("%s" "install:install-file" "-Dfile=%s" "-DpomFile=%s")"
: R"("%s" "-q" "install:install-file" "-Dfile=%s" "-DpomFile=%s")";
const auto cmd_line = Strings::format(cmd_line_format, const auto cmd_line = Strings::format(cmd_line_format, Tools::MAVEN, aar.u8string(), pom.u8string());
Tools::MAVEN,
aar.u8string(),
pom.u8string());
const int exit_code = System::cmd_execute_clean(cmd_line); const int exit_code = System::cmd_execute_clean(cmd_line);
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: %s installing maven file", aar.generic_u8string()); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: %s installing maven file", aar.generic_u8string());
} }
static Build::PreBuildInfo build_info_from_triplet(const VcpkgPaths& paths, static std::unique_ptr<Build::PreBuildInfo> build_info_from_triplet(
const std::unique_ptr<CMakeVars::CMakeVarProvider>& provider, const VcpkgPaths& paths, const std::unique_ptr<CMakeVars::CMakeVarProvider>& provider, const Triplet& triplet)
const Triplet& triplet)
{ {
provider->load_generic_triplet_vars(triplet); provider->load_generic_triplet_vars(triplet);
const Build::PreBuildInfo pre_build_info( return std::make_unique<Build::PreBuildInfo>(
paths, triplet, provider->get_generic_triplet_vars(triplet).value_or_exit(VCPKG_LINE_INFO)); paths, triplet, provider->get_generic_triplet_vars(triplet).value_or_exit(VCPKG_LINE_INFO));
return pre_build_info;
} }
static bool is_supported(const Build::PreBuildInfo& info) static bool is_supported(const Build::PreBuildInfo& info)
@ -256,35 +253,38 @@ namespace vcpkg::Export::Prefab
{ {
auto build_info = build_info_from_triplet(paths, provider, default_triplet); auto build_info = build_info_from_triplet(paths, provider, default_triplet);
Checks::check_exit(VCPKG_LINE_INFO, is_supported(build_info), "Currenty supported on android triplets"); Checks::check_exit(VCPKG_LINE_INFO, is_supported(*build_info), "Currenty supported on android triplets");
} }
std::vector<VcpkgPaths::TripletFile> available_triplets = paths.get_available_triplets(); std::vector<VcpkgPaths::TripletFile> available_triplets = paths.get_available_triplets();
std::unordered_map<CPUArchitecture, std::string> required_archs = { std::unordered_map<CPUArchitecture, std::string> required_archs = {{CPUArchitecture::ARM, "armeabi-v7a"},
{CPUArchitecture::ARM, "armeabi-v7a"}, {CPUArchitecture::ARM64, "arm64-v8a"},
{CPUArchitecture::ARM64, "arm64-v8a"}, {CPUArchitecture::X86, "x86"},
{CPUArchitecture::X86, "x86"}, {CPUArchitecture::X64, "x86_64"}};
{CPUArchitecture::X64, "x86_64"}};
std::unordered_map<CPUArchitecture, int> cpu_architecture_api_map = {{CPUArchitecture::ARM64, 21}, std::unordered_map<CPUArchitecture, int> cpu_architecture_api_map = {{CPUArchitecture::ARM64, 21},
{CPUArchitecture::ARM, 16}, {CPUArchitecture::ARM, 16},
{CPUArchitecture::X64, 21}, {CPUArchitecture::X64, 21},
{CPUArchitecture::X86, 16}}; {CPUArchitecture::X86, 16}};
std::vector<Triplet> triplets; std::vector<Triplet> triplets;
std::unordered_map<Triplet, std::string> triplet_abi_map; std::unordered_map<Triplet, std::string> triplet_abi_map;
std::unordered_map<Triplet, int> triplet_api_map; std::unordered_map<Triplet, int> triplet_api_map;
for (auto& triplet_file : available_triplets){ for (auto& triplet_file : available_triplets)
if (triplet_file.name.size() > 0){ {
if (triplet_file.name.size() > 0)
{
Triplet triplet = Triplet::from_canonical_name(std::move(triplet_file.name)); Triplet triplet = Triplet::from_canonical_name(std::move(triplet_file.name));
auto triplet_build_info = build_info_from_triplet(paths, provider, triplet); auto triplet_build_info = build_info_from_triplet(paths, provider, triplet);
if (is_supported(triplet_build_info)){ if (is_supported(*triplet_build_info))
auto cpu_architecture = System::to_cpu_architecture(triplet_build_info.target_architecture).value_or_exit(VCPKG_LINE_INFO); {
auto cpu_architecture = System::to_cpu_architecture(triplet_build_info->target_architecture)
.value_or_exit(VCPKG_LINE_INFO);
auto required_arch = required_archs.find(cpu_architecture); auto required_arch = required_archs.find(cpu_architecture);
if (required_arch != required_archs.end()){ if (required_arch != required_archs.end())
{
triplets.push_back(triplet); triplets.push_back(triplet);
triplet_abi_map[triplet] = required_archs[cpu_architecture]; triplet_abi_map[triplet] = required_archs[cpu_architecture];
triplet_api_map[triplet] = cpu_architecture_api_map[cpu_architecture]; triplet_api_map[triplet] = cpu_architecture_api_map[cpu_architecture];
@ -294,9 +294,10 @@ namespace vcpkg::Export::Prefab
} }
} }
Checks::check_exit( Checks::check_exit(
VCPKG_LINE_INFO, required_archs.empty(), "Export requires the following architectures arm64-v8a, armeabi-v7a, x86_64, x86 to be present"); VCPKG_LINE_INFO,
required_archs.empty(),
"Export requires the following architectures arm64-v8a, armeabi-v7a, x86_64, x86 to be present");
Optional<std::string> android_ndk_home = System::get_environment_variable("ANDROID_NDK_HOME"); Optional<std::string> android_ndk_home = System::get_environment_variable("ANDROID_NDK_HOME");
@ -371,25 +372,28 @@ namespace vcpkg::Export::Prefab
for (const auto& action : export_plan) for (const auto& action : export_plan)
{ {
const std::string name = action.spec.name(); const std::string name = action.spec.name();
auto dependencies = action.dependencies(default_triplet); auto dependencies = action.dependencies(default_triplet);
const auto action_build_info = Build::read_build_info(utils, paths.build_info_file_path(action.spec)); const auto action_build_info = Build::read_build_info(utils, paths.build_info_file_path(action.spec));
const bool is_empty_package = action_build_info.policies.is_enabled(Build::BuildPolicy::EMPTY_PACKAGE); const bool is_empty_package = action_build_info.policies.is_enabled(Build::BuildPolicy::EMPTY_PACKAGE);
if (is_empty_package)
if(is_empty_package){ {
empty_package_dependencies[name] = std::set<PackageSpec>(); empty_package_dependencies[name] = std::set<PackageSpec>();
for(auto dependency : dependencies){ for (auto dependency : dependencies)
if(empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end()){ {
auto& child_deps = empty_package_dependencies[name]; if (empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end())
{
auto& child_deps = empty_package_dependencies[name];
auto& parent_deps = empty_package_dependencies[dependency.name()]; auto& parent_deps = empty_package_dependencies[dependency.name()];
for(auto parent_dep: parent_deps){ for (auto parent_dep : parent_deps)
child_deps.insert(parent_dep); {
child_deps.insert(parent_dep);
} }
} }
else { else
{
empty_package_dependencies[name].insert(dependency); empty_package_dependencies[name].insert(dependency);
} }
} }
@ -446,13 +450,17 @@ namespace vcpkg::Export::Prefab
std::set<PackageSpec> dependencies_minus_empty_packages; std::set<PackageSpec> dependencies_minus_empty_packages;
for(auto dependency: dependencies){ for (auto dependency : dependencies)
if(empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end()){ {
for(auto& empty_package_dep: empty_package_dependencies[dependency.name()]){ if (empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end())
{
for (auto& empty_package_dep : empty_package_dependencies[dependency.name()])
{
dependencies_minus_empty_packages.insert(empty_package_dep); dependencies_minus_empty_packages.insert(empty_package_dep);
} }
} }
else { else
{
dependencies_minus_empty_packages.insert(dependency); dependencies_minus_empty_packages.insert(dependency);
} }
} }
@ -485,22 +493,26 @@ namespace vcpkg::Export::Prefab
pom_dependencies.push_back("</dependencies>\n"); pom_dependencies.push_back("</dependencies>\n");
} }
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
System::print2(Strings::format( {
"[DEBUG]\n\tWriting manifest\n\tTo %s\n\tWriting prefab meta data\n\tTo %s\n\n", System::print2(
manifest_path.generic_u8string(), prefab_path.generic_u8string())); Strings::format("[DEBUG]\n\tWriting manifest\n\tTo %s\n\tWriting prefab meta data\n\tTo %s\n\n",
manifest_path.generic_u8string(),
prefab_path.generic_u8string()));
} }
utils.write_contents(manifest_path, manifest, VCPKG_LINE_INFO); utils.write_contents(manifest_path, manifest, VCPKG_LINE_INFO);
utils.write_contents(prefab_path, pm.to_json(), VCPKG_LINE_INFO); utils.write_contents(prefab_path, pm.to_json(), VCPKG_LINE_INFO);
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
std::vector<std::string> triplet_names; {
for(auto triplet: triplets){ std::vector<std::string> triplet_names;
for (auto triplet : triplets)
{
triplet_names.push_back(triplet.canonical_name()); triplet_names.push_back(triplet.canonical_name());
} }
System::print2(Strings::format("[DEBUG] Found %d triplets\n\t%s\n\n", triplets.size(), System::print2(Strings::format(
Strings::join("\n\t", triplet_names))); "[DEBUG] Found %d triplets\n\t%s\n\n", triplets.size(), Strings::join("\n\t", triplet_names)));
} }
for (const auto& triplet : triplets) for (const auto& triplet : triplets)
@ -557,12 +569,13 @@ namespace vcpkg::Export::Prefab
ABIMetadata ab; ABIMetadata ab;
ab.abi = triplet_abi_map[triplet]; ab.abi = triplet_abi_map[triplet];
ab.api = triplet_api_map[triplet]; ab.api = triplet_api_map[triplet];
ab.stl = Strings::contains(extension, "a") ?"c++_static": "c++_shared"; ab.stl = Strings::contains(extension, "a") ? "c++_static" : "c++_shared";
ab.ndk = version.major(); ab.ndk = version.major();
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
{
System::print2(Strings::format("[DEBUG] Found module %s:%s\n", module_name, ab.abi)); System::print2(Strings::format("[DEBUG] Found module %s:%s\n", module_name, ab.abi));
} }
@ -573,15 +586,15 @@ namespace vcpkg::Export::Prefab
module_name = module_name.substr(3); module_name = module_name.substr(3);
} }
fs::path module_dir = (modules_directory / module_name); fs::path module_dir = (modules_directory / module_name);
fs::path module_libs_dir = fs::path module_libs_dir = module_dir / "libs" / Strings::format("android.%s", ab.abi);
module_dir / "libs" / Strings::format("android.%s", ab.abi);
utils.create_directories(module_libs_dir, error_code); utils.create_directories(module_libs_dir, error_code);
fs::path abi_path = module_libs_dir / "abi.json"; fs::path abi_path = module_libs_dir / "abi.json";
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
System::print2(Strings::format("\tWriting abi metadata\n\tTo %s\n", {
abi_path.generic_u8string())); System::print2(
Strings::format("\tWriting abi metadata\n\tTo %s\n", abi_path.generic_u8string()));
} }
utils.write_contents(abi_path, ab.to_string(), VCPKG_LINE_INFO); utils.write_contents(abi_path, ab.to_string(), VCPKG_LINE_INFO);
@ -592,17 +605,20 @@ namespace vcpkg::Export::Prefab
exported_module_path, exported_module_path,
fs::copy_options::overwrite_existing, fs::copy_options::overwrite_existing,
error_code); error_code);
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
{
System::print2(Strings::format("\tCopying libs\n\tFrom %s\n\tTo %s\n", System::print2(Strings::format("\tCopying libs\n\tFrom %s\n\tTo %s\n",
installed_module_path.generic_u8string(), exported_module_path.generic_u8string())); installed_module_path.generic_u8string(),
exported_module_path.generic_u8string()));
} }
fs::path installed_headers_dir = installed_dir / "include"; fs::path installed_headers_dir = installed_dir / "include";
fs::path exported_headers_dir = module_libs_dir / "include"; fs::path exported_headers_dir = module_libs_dir / "include";
if (prefab_options.enable_debug)
if(prefab_options.enable_debug){ {
System::print2(Strings::format("\tCopying headers\n\tFrom %s\n\tTo %s\n", System::print2(Strings::format("\tCopying headers\n\tFrom %s\n\tTo %s\n",
installed_headers_dir.generic_u8string(), exported_headers_dir.generic_u8string())); installed_headers_dir.generic_u8string(),
exported_headers_dir.generic_u8string()));
} }
utils.copy(installed_headers_dir, exported_headers_dir, fs::copy_options::recursive); utils.copy(installed_headers_dir, exported_headers_dir, fs::copy_options::recursive);
@ -611,9 +627,10 @@ namespace vcpkg::Export::Prefab
fs::path module_meta_path = module_dir / "module.json"; fs::path module_meta_path = module_dir / "module.json";
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
{
System::print2(Strings::format("\tWriting module metadata\n\tTo %s\n\n", System::print2(Strings::format("\tWriting module metadata\n\tTo %s\n\n",
module_meta_path.generic_u8string())); module_meta_path.generic_u8string()));
} }
utils.write_contents(module_meta_path, meta.to_json(), VCPKG_LINE_INFO); utils.write_contents(module_meta_path, meta.to_json(), VCPKG_LINE_INFO);
@ -624,9 +641,11 @@ namespace vcpkg::Export::Prefab
fs::path exported_archive_path = per_package_dir_path / Strings::format("%s-%s.aar", name, norm_version); fs::path exported_archive_path = per_package_dir_path / Strings::format("%s-%s.aar", name, norm_version);
fs::path pom_path = per_package_dir_path / "pom.xml"; fs::path pom_path = per_package_dir_path / "pom.xml";
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
{
System::print2(Strings::format("[DEBUG] Exporting AAR And POM\n\tAAR Path %s\n\tPOM Path %s\n", System::print2(Strings::format("[DEBUG] Exporting AAR And POM\n\tAAR Path %s\n\tPOM Path %s\n",
exported_archive_path.generic_u8string(), pom_path.generic_u8string())); exported_archive_path.generic_u8string(),
pom_path.generic_u8string()));
} }
compress_directory(paths, package_directory, exported_archive_path); compress_directory(paths, package_directory, exported_archive_path);
@ -656,14 +675,16 @@ namespace vcpkg::Export::Prefab
if (prefab_options.enable_maven) if (prefab_options.enable_maven)
{ {
maven_install(exported_archive_path, pom_path, prefab_options); maven_install(exported_archive_path, pom_path, prefab_options);
if(prefab_options.enable_debug){ if (prefab_options.enable_debug)
System::print2( {
Strings::format("\n\n[DEBUG] Configuration properties in Android Studio\nIn app/build.gradle\n\n\t%s:%s:%s\n\n", System::print2(Strings::format(
group_id, artifact_id, norm_version)); "\n\n[DEBUG] Configuration properties in Android Studio\nIn app/build.gradle\n\n\t%s:%s:%s\n\n",
group_id,
artifact_id,
norm_version));
System::print2(R"(And cmake flags System::print2(R"(And cmake flags
externalNativeBuild { externalNativeBuild {
cmake { cmake {
@ -674,13 +695,14 @@ namespace vcpkg::Export::Prefab
)"); )");
System::print2(R"(In gradle.properties System::print2(R"(In gradle.properties
android.enablePrefab=true android.enablePrefab=true
android.enableParallelJsonGen=false android.enableParallelJsonGen=false
android.prefabVersion=${prefab.version} android.prefabVersion=${prefab.version}
)");} )");
}
} }
System::print2(System::Color::success, System::print2(System::Color::success,
Strings::format("Successfuly exported %s. Checkout %s \n", Strings::format("Successfuly exported %s. Checkout %s \n",

View File

@ -305,9 +305,9 @@ namespace vcpkg::Install
using Build::ExtendedBuildResult; using Build::ExtendedBuildResult;
static ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths, static ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths,
InstallPlanAction& action, InstallPlanAction& action,
StatusParagraphs& status_db, StatusParagraphs& status_db,
IBinaryProvider& binaries_provider) IBinaryProvider& binaries_provider)
{ {
const InstallPlanType& plan_type = action.plan_type; const InstallPlanType& plan_type = action.plan_type;
const std::string display_name = action.spec.to_string(); const std::string display_name = action.spec.to_string();
@ -685,7 +685,6 @@ namespace vcpkg::Install
clean_after_build ? Build::CleanPackages::YES : Build::CleanPackages::NO, clean_after_build ? Build::CleanPackages::YES : Build::CleanPackages::NO,
clean_after_build ? Build::CleanDownloads::YES : Build::CleanDownloads::NO, clean_after_build ? Build::CleanDownloads::YES : Build::CleanDownloads::NO,
download_tool, download_tool,
(args.binary_caching_enabled() && !only_downloads) ? Build::BinaryCaching::YES : Build::BinaryCaching::NO,
Build::FailOnTombstone::NO, Build::FailOnTombstone::NO,
}; };
@ -766,7 +765,12 @@ namespace vcpkg::Install
} }
const InstallSummary summary = const InstallSummary summary =
perform(action_plan, keep_going, paths, status_db, *binaryprovider, var_provider); perform(action_plan,
keep_going,
paths,
status_db,
args.binary_caching_enabled() && !only_downloads ? *binaryprovider : null_binary_provider(),
var_provider);
System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n"); System::print2("\nTotal elapsed time: ", summary.total_elapsed_time, "\n\n");

View File

@ -552,11 +552,14 @@ namespace vcpkg
if (const auto unpacked = vcpkg_feature_flags_env.get()) if (const auto unpacked = vcpkg_feature_flags_env.get())
{ {
auto flags = Strings::split(*unpacked, ','); auto flags = Strings::split(*unpacked, ',');
if (!binary_caching if (!binary_caching && Util::Vectors::contains(flags, "binarycaching"))
&& std::find(flags.begin(), flags.end(), "binarycaching") != flags.end())
{ {
binary_caching = true; binary_caching = true;
} }
if (Util::Vectors::contains(flags, "compilertracking"))
{
compiler_tracking = true;
}
} }
if (!triplet) if (!triplet)

View File

@ -2,7 +2,7 @@
#include <vcpkg/base/expected.h> #include <vcpkg/base/expected.h>
#include <vcpkg/base/files.h> #include <vcpkg/base/files.h>
#include <vcpkg/base/system.h> #include <vcpkg/base/system.process.h>
#include <vcpkg/base/util.h> #include <vcpkg/base/util.h>
#include <vcpkg/base/system.debug.h> #include <vcpkg/base/system.debug.h>
#include <vcpkg/base/system.process.h> #include <vcpkg/base/system.process.h>
@ -64,7 +64,33 @@ namespace
namespace vcpkg namespace vcpkg
{ {
VcpkgPaths::VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args) : fsPtr(&filesystem) namespace details
{
struct VcpkgPathsImpl
{
VcpkgPathsImpl(Files::Filesystem& fs, bool compiler_tracking)
: fs_ptr(&fs), m_tool_cache(get_tool_cache()), m_env_cache(compiler_tracking)
{
}
Lazy<std::vector<VcpkgPaths::TripletFile>> available_triplets;
Lazy<std::vector<Toolset>> toolsets;
Files::Filesystem* fs_ptr;
fs::path default_vs_path;
std::vector<fs::path> triplets_dirs;
std::unique_ptr<ToolCache> m_tool_cache;
Cache<Triplet, fs::path> m_triplets_cache;
Build::EnvCache m_env_cache;
};
}
VcpkgPaths::~VcpkgPaths() noexcept {}
VcpkgPaths::VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args)
: m_pimpl(std::make_unique<details::VcpkgPathsImpl>(filesystem, args.compiler_tracking_enabled()))
{ {
original_cwd = filesystem.current_path(VCPKG_LINE_INFO); original_cwd = filesystem.current_path(VCPKG_LINE_INFO);
if (args.vcpkg_root_dir) if (args.vcpkg_root_dir)
@ -109,7 +135,8 @@ namespace vcpkg
if (args.default_visual_studio_path) if (args.default_visual_studio_path)
{ {
default_vs_path = filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.default_visual_studio_path)); m_pimpl->default_vs_path =
filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(*args.default_visual_studio_path));
} }
triplets = filesystem.canonical(VCPKG_LINE_INFO, root / fs::u8path("triplets")); triplets = filesystem.canonical(VCPKG_LINE_INFO, root / fs::u8path("triplets"));
@ -132,11 +159,12 @@ namespace vcpkg
{ {
for (auto&& overlay_triplets_dir : *args.overlay_triplets) for (auto&& overlay_triplets_dir : *args.overlay_triplets)
{ {
triplets_dirs.emplace_back(filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir))); m_pimpl->triplets_dirs.emplace_back(
filesystem.canonical(VCPKG_LINE_INFO, fs::u8path(overlay_triplets_dir)));
} }
} }
triplets_dirs.emplace_back(triplets); m_pimpl->triplets_dirs.emplace_back(triplets);
triplets_dirs.emplace_back(community_triplets); m_pimpl->triplets_dirs.emplace_back(community_triplets);
} }
fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); }
@ -167,10 +195,10 @@ namespace vcpkg
const std::vector<VcpkgPaths::TripletFile>& VcpkgPaths::get_available_triplets() const const std::vector<VcpkgPaths::TripletFile>& VcpkgPaths::get_available_triplets() const
{ {
return this->available_triplets.get_lazy([this]() -> std::vector<TripletFile> { return m_pimpl->available_triplets.get_lazy([this]() -> std::vector<TripletFile> {
std::vector<TripletFile> output; std::vector<TripletFile> output;
Files::Filesystem& fs = this->get_filesystem(); Files::Filesystem& fs = this->get_filesystem();
for (auto&& triplets_dir : triplets_dirs) for (auto&& triplets_dir : m_pimpl->triplets_dirs)
{ {
for (auto&& path : fs.get_files_non_recursive(triplets_dir)) for (auto&& path : fs.get_files_non_recursive(triplets_dir))
{ {
@ -186,9 +214,9 @@ namespace vcpkg
const fs::path VcpkgPaths::get_triplet_file_path(Triplet triplet) const const fs::path VcpkgPaths::get_triplet_file_path(Triplet triplet) const
{ {
return m_triplets_cache.get_lazy( return m_pimpl->m_triplets_cache.get_lazy(
triplet, [&]() -> auto { triplet, [&]() -> auto {
for (const auto& triplet_dir : triplets_dirs) for (const auto& triplet_dir : m_pimpl->triplets_dirs)
{ {
auto path = triplet_dir / (triplet.canonical_name() + ".cmake"); auto path = triplet_dir / (triplet.canonical_name() + ".cmake");
if (this->get_filesystem().exists(path)) if (this->get_filesystem().exists(path))
@ -204,19 +232,16 @@ namespace vcpkg
const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const
{ {
if (!m_tool_cache) m_tool_cache = get_tool_cache(); return m_pimpl->m_tool_cache->get_tool_path(*this, tool);
return m_tool_cache->get_tool_path(*this, tool);
} }
const std::string& VcpkgPaths::get_tool_version(const std::string& tool) const const std::string& VcpkgPaths::get_tool_version(const std::string& tool) const
{ {
if (!m_tool_cache) m_tool_cache = get_tool_cache(); return m_pimpl->m_tool_cache->get_tool_version(*this, tool);
return m_tool_cache->get_tool_version(*this, tool);
} }
const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const
{ {
if ((prebuildinfo.external_toolchain_file && !prebuildinfo.load_vcvars_env) || if (!prebuildinfo.using_vcvars())
(!prebuildinfo.cmake_system_name.empty() && prebuildinfo.cmake_system_name != "WindowsStore"))
{ {
static Toolset external_toolset = []() -> Toolset { static Toolset external_toolset = []() -> Toolset {
Toolset ret; Toolset ret;
@ -235,15 +260,15 @@ namespace vcpkg
#if !defined(_WIN32) #if !defined(_WIN32)
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows."); Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows.");
#else #else
const std::vector<Toolset>& vs_toolsets = const std::vector<Toolset>& vs_toolsets = m_pimpl->toolsets.get_lazy(
this->toolsets.get_lazy([this]() { return VisualStudio::find_toolset_instances_preferred_first(*this); }); [this]() { return VisualStudio::find_toolset_instances_preferred_first(*this); });
std::vector<const Toolset*> candidates = Util::fmap(vs_toolsets, [](auto&& x) { return &x; }); std::vector<const Toolset*> candidates = Util::fmap(vs_toolsets, [](auto&& x) { return &x; });
const auto tsv = prebuildinfo.platform_toolset.get(); const auto tsv = prebuildinfo.platform_toolset.get();
auto vsp = prebuildinfo.visual_studio_path.get(); auto vsp = prebuildinfo.visual_studio_path.get();
if (!vsp && !default_vs_path.empty()) if (!vsp && !m_pimpl->default_vs_path.empty())
{ {
vsp = &default_vs_path; vsp = &m_pimpl->default_vs_path;
} }
if (tsv && vsp) if (tsv && vsp)
@ -284,5 +309,15 @@ namespace vcpkg
#endif #endif
} }
Files::Filesystem& VcpkgPaths::get_filesystem() const { return *fsPtr; } const System::Environment& VcpkgPaths::get_action_env(const Build::AbiInfo& abi_info) const
{
return m_pimpl->m_env_cache.get_action_env(*this, abi_info);
}
const std::string& VcpkgPaths::get_triplet_info(const Build::AbiInfo& abi_info) const
{
return m_pimpl->m_env_cache.get_triplet_info(*this, abi_info);
}
Files::Filesystem& VcpkgPaths::get_filesystem() const { return *m_pimpl->fs_ptr; }
} }