diff --git a/scripts/detect_compiler/CMakeLists.txt b/scripts/detect_compiler/CMakeLists.txt new file mode 100644 index 0000000000..5dc0889a6b --- /dev/null +++ b/scripts/detect_compiler/CMakeLists.txt @@ -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}") diff --git a/scripts/detect_compiler/portfile.cmake b/scripts/detect_compiler/portfile.cmake new file mode 100644 index 0000000000..16c760706a --- /dev/null +++ b/scripts/detect_compiler/portfile.cmake @@ -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}") diff --git a/scripts/ports.cmake b/scripts/ports.cmake index cd687026fb..8c7c71d34a 100644 --- a/scripts/ports.cmake +++ b/scripts/ports.cmake @@ -43,9 +43,6 @@ if(CMD MATCHES "^BUILD$") if(NOT EXISTS ${CURRENT_PORT_DIR}/portfile.cmake) message(FATAL_ERROR "Port is missing portfile: ${CURRENT_PORT_DIR}/portfile.cmake") 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(BUILDTREES_DIR) @@ -74,7 +71,9 @@ if(CMD MATCHES "^BUILD$") include(${SCRIPTS}/cmake/vcpkg_common_definitions.cmake) include(${SCRIPTS}/cmake/vcpkg_common_functions.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$") file(TO_NATIVE_PATH ${VCPKG_ROOT_DIR} NATIVE_VCPKG_ROOT_DIR) file(TO_NATIVE_PATH ${DOWNLOADS} NATIVE_DOWNLOADS) diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h index 88b09fdb2e..ff60149ac9 100644 --- a/toolsrc/include/vcpkg/base/expected.h +++ b/toolsrc/include/vcpkg/base/expected.h @@ -10,7 +10,7 @@ namespace vcpkg template struct ErrorHolder { - ErrorHolder() : m_is_error(false) {} + ErrorHolder() : m_is_error(false), m_err{} {} template ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) { diff --git a/toolsrc/include/vcpkg/base/pragmas.h b/toolsrc/include/vcpkg/base/pragmas.h index 97d01955ec..73f14c4b24 100644 --- a/toolsrc/include/vcpkg/base/pragmas.h +++ b/toolsrc/include/vcpkg/base/pragmas.h @@ -19,8 +19,10 @@ #include #endif -#ifndef _Analysis_assume_ -#define _Analysis_assume_(...) +#if defined(_MSC_VER) +#define ASSUME(expr) __assume(expr) +#else +#define ASSUME(expr) #endif #ifdef _MSC_VER diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 849781b95d..89f2c51d61 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -22,6 +22,11 @@ namespace vcpkg::Util { augend->insert(augend->end(), addend.begin(), addend.end()); } + template + bool contains(const Vec& container, const Key& item) + { + return std::find(container.begin(), container.end(), item) != container.end(); + } } namespace Sets diff --git a/toolsrc/include/vcpkg/binarycaching.h b/toolsrc/include/vcpkg/binarycaching.h index 69e3287d60..88f529c22e 100644 --- a/toolsrc/include/vcpkg/binarycaching.h +++ b/toolsrc/include/vcpkg/binarycaching.h @@ -36,6 +36,8 @@ namespace vcpkg bool purge_tombstones) = 0; }; + IBinaryProvider& null_binary_provider(); + ExpectedS> create_binary_provider_from_configs(const VcpkgPaths& paths, View args); ExpectedS> create_binary_provider_from_configs_pure(const std::string& env_string, diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h index 864317fb90..68cfd7d238 100644 --- a/toolsrc/include/vcpkg/build.h +++ b/toolsrc/include/vcpkg/build.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,11 @@ namespace vcpkg::Dependencies struct ActionPlan; } +namespace vcpkg::System +{ + struct Environment; +} + namespace vcpkg::Build { namespace Command @@ -34,7 +40,6 @@ namespace vcpkg::Build void perform_and_exit_ex(const FullPackageSpec& full_spec, const SourceControlFileLocation& scfl, const PortFileProvider::PathsPortFileProvider& provider, - const bool binary_caching_enabled, IBinaryProvider& binaryprovider, const VcpkgPaths& paths); @@ -90,12 +95,6 @@ namespace vcpkg::Build }; const std::string& to_string(DownloadTool tool); - enum class BinaryCaching - { - NO = 0, - YES - }; - enum class FailOnTombstone { NO = 0, @@ -117,7 +116,6 @@ namespace vcpkg::Build CleanPackages clean_packages; CleanDownloads clean_downloads; DownloadTool download_tool; - BinaryCaching binary_caching; FailOnTombstone fail_on_tombstone; PurgeDecompressFailure purge_decompress_failure; }; @@ -149,14 +147,14 @@ namespace vcpkg::Build /// /// Settings from the triplet file which impact the build environment and post-build checks /// - struct PreBuildInfo + struct PreBuildInfo : Util::ResourceBase { PreBuildInfo(const VcpkgPaths& paths, Triplet triplet, const std::unordered_map& cmakevars); - bool load_vcvars_env; - std::string triplet_abi_tag; + Triplet triplet; + bool load_vcvars_env = false; std::string target_architecture; std::string cmake_system_name; std::string cmake_system_version; @@ -165,39 +163,17 @@ namespace vcpkg::Build Optional external_toolchain_file; Optional build_type; Optional public_abi_override; - Optional port; std::vector 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); - 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 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 { ExtendedBuildResult(BuildResult code); @@ -238,8 +214,7 @@ namespace vcpkg::Build BuildPolicy::ALLOW_OBSOLETE_MSVCRT, BuildPolicy::ALLOW_RESTRICTED_HEADERS, BuildPolicy::SKIP_DUMPBIN_CHECKS, - BuildPolicy::SKIP_ARCHITECTURE_CHECK - }; + BuildPolicy::SKIP_ARCHITECTURE_CHECK}; const std::string& to_string(BuildPolicy policy); CStringView to_cmake_variable(BuildPolicy policy); @@ -300,12 +275,45 @@ namespace vcpkg::Build fs::path tag_file; }; + struct AbiInfo + { + std::unique_ptr pre_build_info; + const Toolset* toolset; + std::string package_abi; + Optional abi_tag_file; + }; + void compute_all_abis(const VcpkgPaths& paths, Dependencies::ActionPlan& action_plan, const CMakeVars::CMakeVarProvider& var_provider, const StatusParagraphs& status_db); - Optional compute_abi_tag(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& config, - Span dependency_abis); + struct EnvCache + { + 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 compiler_hashes; + }; + Cache m_triplet_cache; + Cache m_toolchain_cache; + +#if defined(_WIN32) + struct EnvMapEntry + { + std::unordered_map env_map; + Cache cmd_cache; + }; + + Cache, EnvMapEntry> envs; +#endif + + bool m_compiler_tracking; + }; } diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h index d2eca44087..7b1696dc34 100644 --- a/toolsrc/include/vcpkg/dependencies.h +++ b/toolsrc/include/vcpkg/dependencies.h @@ -55,6 +55,7 @@ namespace vcpkg::Dependencies std::string displayname() const; const std::string& public_abi() const; + const Build::PreBuildInfo& pre_build_info(LineInfo linfo) const; PackageSpec spec; @@ -69,9 +70,7 @@ namespace vcpkg::Dependencies std::vector package_dependencies; std::vector feature_list; - Optional> pre_build_info; - Optional package_abi; - Optional abi_tag_file; + Optional abi_info; }; enum class RemovePlanType diff --git a/toolsrc/include/vcpkg/export.prefab.h b/toolsrc/include/vcpkg/export.prefab.h index 56a5ba3719..cf9f940f92 100644 --- a/toolsrc/include/vcpkg/export.prefab.h +++ b/toolsrc/include/vcpkg/export.prefab.h @@ -18,8 +18,8 @@ namespace vcpkg::Export::Prefab Optional maybe_version; Optional maybe_min_sdk; Optional maybe_target_sdk; - bool enable_maven; - bool enable_debug; + bool enable_maven = false; + bool enable_debug = false; }; struct NdkVersion { diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index e4ed0471b6..378aa97030 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -130,7 +130,9 @@ namespace vcpkg // feature flags Optional feature_packages = nullopt; Optional binary_caching = nullopt; + Optional compiler_tracking = nullopt; 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::vector command_arguments; diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index 38a9d4e4d4..c4c420820c 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -6,9 +6,10 @@ #include #include -#include #include #include +#include +#include namespace vcpkg { @@ -46,9 +47,20 @@ namespace vcpkg namespace Build { struct PreBuildInfo; + struct AbiInfo; } - struct VcpkgPaths + namespace System + { + struct Environment; + } + + namespace details + { + struct VcpkgPathsImpl; + } + + struct VcpkgPaths : Util::MoveOnlyBase { struct TripletFile { @@ -59,6 +71,7 @@ namespace vcpkg }; VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args); + ~VcpkgPaths() noexcept; fs::path package_dir(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; + 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: - Lazy> available_triplets; - Lazy> toolsets; - Lazy> toolsets_vs2013; - - fs::path default_vs_path; - std::vector triplets_dirs; - - Files::Filesystem* fsPtr; - - mutable std::unique_ptr m_tool_cache; - mutable vcpkg::Cache m_triplets_cache; + std::unique_ptr m_pimpl; }; } diff --git a/toolsrc/src/vcpkg/base/downloads.cpp b/toolsrc/src/vcpkg/base/downloads.cpp index c46fe42883..051e8306fa 100644 --- a/toolsrc/src/vcpkg/base/downloads.cpp +++ b/toolsrc/src/vcpkg/base/downloads.cpp @@ -33,7 +33,7 @@ namespace vcpkg::Downloads url_path, target_file_path, std::to_string(err)); - _Analysis_assume_(f != nullptr); + ASSUME(f != nullptr); auto hSession = WinHttpOpen(L"vcpkg/1.0", IsWindows8Point1OrGreater() ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY diff --git a/toolsrc/src/vcpkg/binarycaching.cpp b/toolsrc/src/vcpkg/binarycaching.cpp index 408477307a..6fe775bdd1 100644 --- a/toolsrc/src/vcpkg/binarycaching.cpp +++ b/toolsrc/src/vcpkg/binarycaching.cpp @@ -69,7 +69,7 @@ namespace void prefetch() 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& fs = paths.get_filesystem(); std::error_code ec; @@ -134,7 +134,7 @@ namespace void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) override { 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& fs = paths.get_filesystem(); const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); @@ -209,7 +209,7 @@ namespace const Dependencies::InstallPlanAction& action, 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(); std::error_code ec; for (auto&& archives_root_dir : m_read_dirs) @@ -246,6 +246,27 @@ namespace std::vector 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> vcpkg::create_binary_provider_from_configs(const VcpkgPaths& paths, diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 2c79f71ce9..c61c6b77bc 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -32,17 +32,16 @@ using vcpkg::Parse::ParseControlErrorInfo; using vcpkg::Parse::ParseExpected; using vcpkg::PortFileProvider::PathsPortFileProvider; -namespace vcpkg::Build::Command +namespace vcpkg::Build { using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; - void perform_and_exit_ex(const FullPackageSpec& full_spec, - const SourceControlFileLocation& scfl, - const PathsPortFileProvider& provider, - const bool binary_caching_enabled, - IBinaryProvider& binaryprovider, - const VcpkgPaths& paths) + void Command::perform_and_exit_ex(const FullPackageSpec& full_spec, + const SourceControlFileLocation& scfl, + const PathsPortFileProvider& provider, + IBinaryProvider& binaryprovider, + const VcpkgPaths& paths) { auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; @@ -71,7 +70,6 @@ namespace vcpkg::Build::Command Build::CleanPackages::NO, Build::CleanDownloads::NO, Build::DownloadTool::BUILT_IN, - binary_caching_enabled ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, Build::FailOnTombstone::NO, }; @@ -92,8 +90,7 @@ namespace vcpkg::Build::Command } Checks::check_exit(VCPKG_LINE_INFO, action != nullptr); - _Analysis_assume_(action != nullptr); - + ASSUME(action != nullptr); action->build_options = build_package_options; const auto build_timer = Chrono::ElapsedTimer::create_started(); @@ -133,7 +130,7 @@ namespace vcpkg::Build::Command 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 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(); 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) - static const std::unordered_map& make_env_passthrough(const PreBuildInfo& pre_build_info) + const System::Environment& EnvCache::get_action_env(const VcpkgPaths& paths, const AbiInfo& abi_info) { - static Cache, std::unordered_map> envs; - return envs.get_lazy(pre_build_info.passthrough_env_vars, [&]() { +#if defined(_WIN32) + 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 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); @@ -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) { - if (pre_build_info.external_toolchain_file.has_value() && !pre_build_info.load_vcvars_env) return ""; - if (!pre_build_info.cmake_system_name.empty() && pre_build_info.cmake_system_name != "WindowsStore") return ""; + if (!pre_build_info.using_vcvars()) return ""; const char* tonull = " >nul"; if (Debug::g_debugging) @@ -353,10 +398,84 @@ namespace vcpkg::Build return concurrency; } - static std::vector get_cmake_vars(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - Triplet triplet, - const Toolset& toolset) + static void get_generic_cmake_build_args(const VcpkgPaths& paths, + Triplet triplet, + const Toolset& toolset, + std::vector& out_vars) + { + Util::Vectors::append(&out_vars, + std::initializer_list{ + {"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 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 get_cmake_build_args(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + Triplet triplet) { #if !defined(_WIN32) // 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 auto& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO); auto& scf = *scfl.source_control_file; - const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT); std::string all_features; for (auto& feature : scf.feature_paragraphs) @@ -374,30 +492,22 @@ namespace vcpkg::Build } std::vector variables{ - {"CMD", "BUILD"}, {"PORT", scf.core_paragraph->name}, {"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_NO_DOWNLOADS", !Util::Enum::to_bool(action.build_options.allow_downloads) ? "1" : "0"}, {"_VCPKG_DOWNLOAD_TOOL", to_string(action.build_options.download_tool)}, {"FEATURES", Strings::join(";", action.feature_list)}, {"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)) { 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(); std::vector port_configs; @@ -421,78 +531,54 @@ namespace vcpkg::Build 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 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); - const auto& fs = paths.get_filesystem(); - - std::string hash; - - auto it_hash = s_hash_cache.find(triplet_file_path); - if (it_hash != s_hash_cache.end()) + fs::path PreBuildInfo::toolchain_file() const + { + if (auto p = external_toolchain_file.get()) { - 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 { - const auto algo = Hash::Algorithm::Sha1; - // TODO: Use file path as part of hash. - // REASON: Copying a triplet file without modifying it produces the same hash as the original. - hash = Hash::get_file_hash(VCPKG_LINE_INFO, fs, triplet_file_path, algo); - - 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); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Unable to determine toolchain to use for triplet %s with CMAKE_SYSTEM_NAME %s", + triplet, + cmake_system_name); } - - return hash; } 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&& 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(); 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(); - auto command = vcpkg::make_cmake_cmd( - 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)); + auto command = vcpkg::make_cmake_cmd(paths, paths.ports_cmake, get_cmake_build_args(paths, action, triplet)); - const std::unordered_map& base_env = make_env_passthrough(pre_build_info); - static Cache*, std::string>, System::Environment> - build_env_cache; + const auto& env = paths.get_action_env(action.abi_info.value_or_exit(VCPKG_LINE_INFO)); - 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(); if (!fs.exists(buildpath)) { @@ -652,38 +722,58 @@ namespace vcpkg::Build return result; } - Optional compute_abi_tag(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - Span dependency_abis) + static void abi_entries_from_abi_info(const VcpkgPaths& paths, + const AbiInfo& abi_info, + std::vector& 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 compute_abi_tag(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + Span dependency_abis) { auto& fs = paths.get_filesystem(); Triplet triplet = action.spec.triplet(); const std::string& name = action.spec.name(); - const auto& pre_build_info = *action.pre_build_info.value_or_exit(VCPKG_LINE_INFO); std::vector abi_tag_entries(dependency_abis.begin(), dependency_abis.end()); - // Sorted here as the order of dependency_abis is the only - // non-deterministically ordered set of AbiEntries - Util::sort(abi_tag_entries); + abi_entries_from_abi_info(paths, action.abi_info.value_or_exit(VCPKG_LINE_INFO), abi_tag_entries); // If there is an unusually large number of files in the port then // something suspicious is going on. Rather than hash all of them // just mark the port as no-hash 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; - std::vector port_files; + size_t port_file_count = 0; for (auto& port_file : fs::stdfs::recursive_directory_iterator(port_dir)) { 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(), 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", ""); 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)); #if defined(_WIN32) @@ -714,38 +795,23 @@ namespace vcpkg::Build Hash::Algorithm::Sha1)); abi_tag_entries.emplace_back("post_build_checks", "2"); - abi_tag_entries.emplace_back("triplet", pre_build_info.triplet_abi_tag); std::vector sorted_feature_list = action.feature_list; Util::sort(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", ""); + Util::sort(abi_tag_entries); + const std::string full_abi_info = Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); if (Debug::g_debugging) { - std::string message = "[DEBUG] \n"; + std::string message = Strings::concat("[DEBUG] \n"); 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] \n"); System::print2(message); @@ -765,7 +831,7 @@ namespace vcpkg::Build abi_file_path}; } - System::print2( + Debug::print( "Warning: abi keys are missing values:\n", Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; }), "\n"); @@ -812,17 +878,18 @@ namespace vcpkg::Build } } - action.pre_build_info = std::make_unique( + 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( 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); if (auto p = maybe_abi_tag_and_file.get()) { - action.abi_tag_file = std::move(p->tag_file); - action.package_abi = std::move(p->tag); - } - else - { - action.package_abi = ""; + abi_info.package_abi = std::move(p->tag); + abi_info.abi_tag_file = std::move(p->tag_file); } } } @@ -832,8 +899,6 @@ namespace vcpkg::Build IBinaryProvider& binaries_provider, const StatusParagraphs& status_db) { - auto binary_caching_enabled = action.build_options.binary_caching == BinaryCaching::YES; - auto& fs = paths.get_filesystem(); auto& spec = action.spec; 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}); } - 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); } - auto& abi_file = *action.abi_tag_file.get(); + auto& abi_file = *abi_info.abi_tag_file.get(); std::error_code ec; 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"; - 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); - if (restore == RestoreResult::build_failed) - return BuildResult::BUILD_FAILED; - else if (restore == RestoreResult::success) - { - auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); - auto bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); - return {BuildResult::SUCCEEDED, std::move(bcf)}; - } - else - { - // missing package, proceed to build. - } + auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); + auto bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); + return {BuildResult::SUCCEEDED, std::move(bcf)}; + } + else + { + // missing package, proceed to build. } 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); 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); } - else if (binary_caching_enabled && - (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED)) + else if ((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; @@ -1023,16 +1085,49 @@ namespace vcpkg::Build PreBuildInfo::PreBuildInfo(const VcpkgPaths& paths, Triplet triplet, const std::unordered_map& 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> 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) { - auto find_itr = cmakevars.find(kv.first); - if (find_itr == cmakevars.end()) - { - continue; - } - - const std::string& variable_value = find_itr->second; + const std::string& variable_value = [&]() -> const std::string& { + auto find_itr = cmakevars.find(kv.first); + if (find_itr == cmakevars.end()) + { + return empty; + } + else + { + return find_itr->second; + } + }(); switch (kv.second) { @@ -1057,7 +1152,9 @@ namespace vcpkg::Build build_type = ConfigurationType::RELEASE; else 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; case VcpkgTripletVar::ENV_PASSTHROUGH: passthrough_env_vars = Strings::split(variable_value, ';'); @@ -1080,16 +1177,16 @@ namespace vcpkg::Build Strings::case_insensitive_ascii_equals(variable_value, "false")) load_vcvars_env = false; else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown boolean setting for VCPKG_LOAD_VCVARS_ENV: %s", variable_value); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Unknown boolean setting for VCPKG_LOAD_VCVARS_ENV: %s. Valid " + "settings are '', '1', '0', 'ON', 'OFF', 'TRUE', and 'FALSE'.", + variable_value); 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&& bcf) : code(code), binary_control_file(std::move(bcf)) { diff --git a/toolsrc/src/vcpkg/cmakevars.cpp b/toolsrc/src/vcpkg/cmakevars.cpp index c5e2d8822c..de3b0204be 100644 --- a/toolsrc/src/vcpkg/cmakevars.cpp +++ b/toolsrc/src/vcpkg/cmakevars.cpp @@ -115,8 +115,7 @@ namespace vcpkg::CMakeVars fs::path path = paths.buildtrees / Strings::concat(tag_extract_id++, ".vcpkg_tags.cmake"); - std::error_code ec; - fs.create_directories(paths.buildtrees, ec); + fs.create_directories(paths.buildtrees, ignore_errors); fs.write_contents(path, extraction_file, VCPKG_LINE_INFO); return path; diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp index 1b2623f2c4..b25b5e4bf2 100644 --- a/toolsrc/src/vcpkg/commands.buildexternal.cpp +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -40,8 +40,7 @@ namespace vcpkg::Commands::BuildExternal Build::Command::perform_and_exit_ex(spec, maybe_scfl.value_or_exit(VCPKG_LINE_INFO), provider, - args.binary_caching_enabled(), - *binaryprovider, + args.binary_caching_enabled() ? *binaryprovider : null_binary_provider(), paths); } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 1180cb35c1..76f8237953 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -257,7 +257,6 @@ namespace vcpkg::Commands::CI const CMakeVars::CMakeVarProvider& var_provider, const std::vector& specs, const bool purge_tombstones, - const bool binary_caching_enabled, IBinaryProvider& binaryprovider) { auto ret = std::make_unique(); @@ -272,7 +271,6 @@ namespace vcpkg::Commands::CI Build::CleanPackages::YES, Build::CleanDownloads::NO, Build::DownloadTool::BUILT_IN, - binary_caching_enabled ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, Build::FailOnTombstone::YES, }; @@ -312,7 +310,7 @@ namespace vcpkg::Commands::CI for (auto&& action : action_plan.install_actions) { 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); if (auto scfl = p->source_control_file_location.get()) { @@ -371,7 +369,7 @@ namespace vcpkg::Commands::CI p->spec, (b_will_build ? "*" : " "), 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) { System::print2(stdout_buffer); @@ -431,7 +429,6 @@ namespace vcpkg::Commands::CI Build::CleanPackages::YES, Build::CleanDownloads::NO, Build::DownloadTool::BUILT_IN, - args.binary_caching_enabled() ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, Build::FailOnTombstone::YES, Build::PurgeDecompressFailure::YES, }; @@ -461,14 +458,14 @@ namespace vcpkg::Commands::CI return FullPackageSpec{spec, std::move(default_features)}; }); - auto split_specs = find_unknown_ports_for_ci(paths, - exclusions_set, - provider, - var_provider, - all_default_full_specs, - purge_tombstones, - args.binary_caching_enabled(), - *binaryprovider); + auto split_specs = + find_unknown_ports_for_ci(paths, + exclusions_set, + provider, + var_provider, + all_default_full_specs, + purge_tombstones, + args.binary_caching_enabled() ? *binaryprovider : null_binary_provider()); PortFileProvider::MapPortFileProvider new_default_provider(split_specs->default_feature_provider); Dependencies::CreateInstallPlanOptions serialize_options; @@ -558,7 +555,8 @@ namespace vcpkg::Commands::CI auto it_xunit = options.settings.find(OPTION_XUNIT); 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); diff --git a/toolsrc/src/vcpkg/commands.setinstalled.cpp b/toolsrc/src/vcpkg/commands.setinstalled.cpp index 81fb346839..15a7803409 100644 --- a/toolsrc/src/vcpkg/commands.setinstalled.cpp +++ b/toolsrc/src/vcpkg/commands.setinstalled.cpp @@ -47,7 +47,6 @@ namespace vcpkg::Commands::SetInstalled Build::CleanPackages::YES, Build::CleanDownloads::YES, Build::DownloadTool::BUILT_IN, - args.binary_caching_enabled() ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, Build::FailOnTombstone::NO, }; @@ -71,7 +70,7 @@ namespace vcpkg::Commands::SetInstalled 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 @@ -105,8 +104,12 @@ namespace vcpkg::Commands::SetInstalled Dependencies::print_plan(real_action_plan, true); - const auto summary = - Install::perform(real_action_plan, Install::KeepGoing::NO, paths, status_db, *binaryprovider, *cmake_vars); + const auto summary = Install::perform(real_action_plan, + 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"); diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index 5884fd7305..919f07e918 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -165,7 +165,6 @@ namespace vcpkg::Commands::Upgrade Build::CleanPackages::NO, Build::CleanDownloads::NO, Build::DownloadTool::BUILT_IN, - args.binary_caching_enabled() ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, Build::FailOnTombstone::NO, }; @@ -188,7 +187,12 @@ namespace vcpkg::Commands::Upgrade var_provider.load_tag_vars(action_plan, provider); 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"); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index c57f44c0e0..26cb3109b2 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -403,12 +403,24 @@ namespace vcpkg::Dependencies } 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) diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 10f320bd82..205fcd31eb 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -84,7 +84,6 @@ namespace vcpkg::Export Build::CleanPackages::NO, Build::CleanDownloads::NO, Build::DownloadTool::BUILT_IN, - Build::BinaryCaching::NO, Build::FailOnTombstone::NO, }; diff --git a/toolsrc/src/vcpkg/export.prefab.cpp b/toolsrc/src/vcpkg/export.prefab.cpp index 9899f5d3c8..84a099edd8 100644 --- a/toolsrc/src/vcpkg/export.prefab.cpp +++ b/toolsrc/src/vcpkg/export.prefab.cpp @@ -159,7 +159,7 @@ namespace vcpkg::Export::Prefab 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 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) { - if(prefab_options.enable_debug){ + if (prefab_options.enable_debug) + { 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")" - : R"("%s" "-q" "install:install-file" "-Dfile=%s" "-DpomFile=%s")"; + const char* cmd_line_format = prefab_options.enable_debug + ? 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, - Tools::MAVEN, - aar.u8string(), - pom.u8string()); + const auto cmd_line = Strings::format(cmd_line_format, Tools::MAVEN, aar.u8string(), pom.u8string()); 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()); } - static Build::PreBuildInfo build_info_from_triplet(const VcpkgPaths& paths, - const std::unique_ptr& provider, - const Triplet& triplet) + static std::unique_ptr build_info_from_triplet( + const VcpkgPaths& paths, const std::unique_ptr& provider, const Triplet& triplet) { provider->load_generic_triplet_vars(triplet); - const Build::PreBuildInfo pre_build_info( + return std::make_unique( 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) @@ -256,35 +253,38 @@ namespace vcpkg::Export::Prefab { 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 available_triplets = paths.get_available_triplets(); - std::unordered_map required_archs = { - {CPUArchitecture::ARM, "armeabi-v7a"}, - {CPUArchitecture::ARM64, "arm64-v8a"}, - {CPUArchitecture::X86, "x86"}, - {CPUArchitecture::X64, "x86_64"}}; + std::unordered_map required_archs = {{CPUArchitecture::ARM, "armeabi-v7a"}, + {CPUArchitecture::ARM64, "arm64-v8a"}, + {CPUArchitecture::X86, "x86"}, + {CPUArchitecture::X64, "x86_64"}}; std::unordered_map cpu_architecture_api_map = {{CPUArchitecture::ARM64, 21}, - {CPUArchitecture::ARM, 16}, - {CPUArchitecture::X64, 21}, - {CPUArchitecture::X86, 16}}; - + {CPUArchitecture::ARM, 16}, + {CPUArchitecture::X64, 21}, + {CPUArchitecture::X86, 16}}; std::vector triplets; std::unordered_map triplet_abi_map; std::unordered_map triplet_api_map; - for (auto& triplet_file : available_triplets){ - if (triplet_file.name.size() > 0){ + for (auto& triplet_file : available_triplets) + { + if (triplet_file.name.size() > 0) + { Triplet triplet = Triplet::from_canonical_name(std::move(triplet_file.name)); auto triplet_build_info = build_info_from_triplet(paths, provider, triplet); - if (is_supported(triplet_build_info)){ - auto cpu_architecture = System::to_cpu_architecture(triplet_build_info.target_architecture).value_or_exit(VCPKG_LINE_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 required_arch = required_archs.find(cpu_architecture); - if (required_arch != required_archs.end()){ + if (required_arch != required_archs.end()) + { triplets.push_back(triplet); triplet_abi_map[triplet] = required_archs[cpu_architecture]; triplet_api_map[triplet] = cpu_architecture_api_map[cpu_architecture]; @@ -294,9 +294,10 @@ namespace vcpkg::Export::Prefab } } - 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 android_ndk_home = System::get_environment_variable("ANDROID_NDK_HOME"); @@ -371,25 +372,28 @@ namespace vcpkg::Export::Prefab for (const auto& action : export_plan) { - const std::string name = action.spec.name(); auto dependencies = action.dependencies(default_triplet); 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(); - for(auto dependency : dependencies){ - if(empty_package_dependencies.find(dependency.name()) != empty_package_dependencies.end()){ - auto& child_deps = empty_package_dependencies[name]; + for (auto dependency : dependencies) + { + 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()]; - for(auto parent_dep: parent_deps){ - child_deps.insert(parent_dep); + for (auto parent_dep : parent_deps) + { + child_deps.insert(parent_dep); } } - else { + else + { empty_package_dependencies[name].insert(dependency); } } @@ -446,13 +450,17 @@ namespace vcpkg::Export::Prefab std::set dependencies_minus_empty_packages; - 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()]){ + 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()]) + { dependencies_minus_empty_packages.insert(empty_package_dep); } } - else { + else + { dependencies_minus_empty_packages.insert(dependency); } } @@ -485,22 +493,26 @@ namespace vcpkg::Export::Prefab pom_dependencies.push_back("\n"); } - 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", - manifest_path.generic_u8string(), prefab_path.generic_u8string())); + 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", + manifest_path.generic_u8string(), + prefab_path.generic_u8string())); } utils.write_contents(manifest_path, manifest, VCPKG_LINE_INFO); utils.write_contents(prefab_path, pm.to_json(), VCPKG_LINE_INFO); - if(prefab_options.enable_debug){ - std::vector triplet_names; - for(auto triplet: triplets){ + if (prefab_options.enable_debug) + { + std::vector triplet_names; + for (auto triplet : triplets) + { triplet_names.push_back(triplet.canonical_name()); } - System::print2(Strings::format("[DEBUG] Found %d triplets\n\t%s\n\n", triplets.size(), - Strings::join("\n\t", triplet_names))); + System::print2(Strings::format( + "[DEBUG] Found %d triplets\n\t%s\n\n", triplets.size(), Strings::join("\n\t", triplet_names))); } for (const auto& triplet : triplets) @@ -557,12 +569,13 @@ namespace vcpkg::Export::Prefab ABIMetadata ab; 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(); - if(prefab_options.enable_debug){ + if (prefab_options.enable_debug) + { 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); } fs::path module_dir = (modules_directory / module_name); - fs::path module_libs_dir = - module_dir / "libs" / Strings::format("android.%s", ab.abi); + fs::path module_libs_dir = module_dir / "libs" / Strings::format("android.%s", ab.abi); utils.create_directories(module_libs_dir, error_code); fs::path abi_path = module_libs_dir / "abi.json"; - if(prefab_options.enable_debug){ - System::print2(Strings::format("\tWriting abi metadata\n\tTo %s\n", - abi_path.generic_u8string())); + if (prefab_options.enable_debug) + { + 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); @@ -592,17 +605,20 @@ namespace vcpkg::Export::Prefab exported_module_path, fs::copy_options::overwrite_existing, 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", - 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 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", - 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); @@ -611,9 +627,10 @@ namespace vcpkg::Export::Prefab 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", - module_meta_path.generic_u8string())); + module_meta_path.generic_u8string())); } 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 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", - 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); @@ -656,14 +675,16 @@ namespace vcpkg::Export::Prefab if (prefab_options.enable_maven) { - maven_install(exported_archive_path, pom_path, prefab_options); - 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", - group_id, artifact_id, norm_version)); + 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", + group_id, + artifact_id, + norm_version)); - System::print2(R"(And cmake flags + System::print2(R"(And cmake flags externalNativeBuild { 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.enableParallelJsonGen=false android.prefabVersion=${prefab.version} -)");} +)"); + } } System::print2(System::Color::success, Strings::format("Successfuly exported %s. Checkout %s \n", diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index d00a764fcd..940034c6cc 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -305,9 +305,9 @@ namespace vcpkg::Install using Build::ExtendedBuildResult; static ExtendedBuildResult perform_install_plan_action(const VcpkgPaths& paths, - InstallPlanAction& action, - StatusParagraphs& status_db, - IBinaryProvider& binaries_provider) + InstallPlanAction& action, + StatusParagraphs& status_db, + IBinaryProvider& binaries_provider) { const InstallPlanType& plan_type = action.plan_type; 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::CleanDownloads::YES : Build::CleanDownloads::NO, download_tool, - (args.binary_caching_enabled() && !only_downloads) ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, Build::FailOnTombstone::NO, }; @@ -766,7 +765,12 @@ namespace vcpkg::Install } 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"); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index f34f771ddd..0d69bf7dad 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -552,11 +552,14 @@ namespace vcpkg if (const auto unpacked = vcpkg_feature_flags_env.get()) { auto flags = Strings::split(*unpacked, ','); - if (!binary_caching - && std::find(flags.begin(), flags.end(), "binarycaching") != flags.end()) + if (!binary_caching && Util::Vectors::contains(flags, "binarycaching")) { binary_caching = true; } + if (Util::Vectors::contains(flags, "compilertracking")) + { + compiler_tracking = true; + } } if (!triplet) diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 0219627c4a..0099854a9d 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -64,7 +64,33 @@ namespace 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> available_triplets; + Lazy> toolsets; + + Files::Filesystem* fs_ptr; + + fs::path default_vs_path; + std::vector triplets_dirs; + + std::unique_ptr m_tool_cache; + Cache m_triplets_cache; + Build::EnvCache m_env_cache; + }; + } + + VcpkgPaths::~VcpkgPaths() noexcept {} + + VcpkgPaths::VcpkgPaths(Files::Filesystem& filesystem, const VcpkgCmdArguments& args) + : m_pimpl(std::make_unique(filesystem, args.compiler_tracking_enabled())) { original_cwd = filesystem.current_path(VCPKG_LINE_INFO); if (args.vcpkg_root_dir) @@ -109,7 +135,8 @@ namespace vcpkg 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")); @@ -132,11 +159,12 @@ namespace vcpkg { 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); - triplets_dirs.emplace_back(community_triplets); + m_pimpl->triplets_dirs.emplace_back(triplets); + m_pimpl->triplets_dirs.emplace_back(community_triplets); } fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } @@ -167,10 +195,10 @@ namespace vcpkg const std::vector& VcpkgPaths::get_available_triplets() const { - return this->available_triplets.get_lazy([this]() -> std::vector { + return m_pimpl->available_triplets.get_lazy([this]() -> std::vector { std::vector output; 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)) { @@ -186,9 +214,9 @@ namespace vcpkg 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 { - for (const auto& triplet_dir : triplets_dirs) + for (const auto& triplet_dir : m_pimpl->triplets_dirs) { auto path = triplet_dir / (triplet.canonical_name() + ".cmake"); if (this->get_filesystem().exists(path)) @@ -204,19 +232,16 @@ namespace vcpkg const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const { - if (!m_tool_cache) m_tool_cache = get_tool_cache(); - return m_tool_cache->get_tool_path(*this, tool); + return m_pimpl->m_tool_cache->get_tool_path(*this, tool); } const std::string& VcpkgPaths::get_tool_version(const std::string& tool) const { - if (!m_tool_cache) m_tool_cache = get_tool_cache(); - return m_tool_cache->get_tool_version(*this, tool); + return m_pimpl->m_tool_cache->get_tool_version(*this, tool); } const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const { - if ((prebuildinfo.external_toolchain_file && !prebuildinfo.load_vcvars_env) || - (!prebuildinfo.cmake_system_name.empty() && prebuildinfo.cmake_system_name != "WindowsStore")) + if (!prebuildinfo.using_vcvars()) { static Toolset external_toolset = []() -> Toolset { Toolset ret; @@ -235,15 +260,15 @@ namespace vcpkg #if !defined(_WIN32) Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot build windows triplets from non-windows."); #else - const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return VisualStudio::find_toolset_instances_preferred_first(*this); }); + const std::vector& vs_toolsets = m_pimpl->toolsets.get_lazy( + [this]() { return VisualStudio::find_toolset_instances_preferred_first(*this); }); std::vector candidates = Util::fmap(vs_toolsets, [](auto&& x) { return &x; }); const auto tsv = prebuildinfo.platform_toolset.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) @@ -284,5 +309,15 @@ namespace vcpkg #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; } }