From 35e985d3ccf60235bc4881df4d934610cd507090 Mon Sep 17 00:00:00 2001 From: Victor Romero Date: Thu, 27 Jun 2019 12:20:12 -0700 Subject: [PATCH] Triplets Overlay Implementation (#7053) * Triplets Overlay Implementation * Use cache for get_triplet_file_path() * Code cleanup --- scripts/ports.cmake | 2 +- toolsrc/include/vcpkg/vcpkgcmdarguments.h | 1 + toolsrc/include/vcpkg/vcpkgpaths.h | 11 +++- toolsrc/src/vcpkg.cpp | 4 +- toolsrc/src/vcpkg/build.cpp | 13 ++++- toolsrc/src/vcpkg/help.cpp | 2 + toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 30 ++++------ toolsrc/src/vcpkg/vcpkgpaths.cpp | 67 ++++++++++++++++++----- 8 files changed, 87 insertions(+), 43 deletions(-) diff --git a/scripts/ports.cmake b/scripts/ports.cmake index 118cc94813..860d08893f 100644 --- a/scripts/ports.cmake +++ b/scripts/ports.cmake @@ -32,7 +32,7 @@ endif() if(CMD MATCHES "^BUILD$") - set(CMAKE_TRIPLET_FILE ${VCPKG_ROOT_DIR}/triplets/${TARGET_TRIPLET}.cmake) + set(CMAKE_TRIPLET_FILE ${TARGET_TRIPLET_FILE}) if(NOT EXISTS ${CMAKE_TRIPLET_FILE}) message(FATAL_ERROR "Unsupported target triplet. Triplet file does not exist: ${CMAKE_TRIPLET_FILE}") endif() diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index cad013eb88..ff13ae6bf6 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -88,6 +88,7 @@ namespace vcpkg std::unique_ptr vcpkg_root_dir; std::unique_ptr triplet; std::unique_ptr> overlay_ports; + std::unique_ptr> overlay_triplets; Optional debug = nullopt; Optional sendmetrics = nullopt; Optional printmetrics = nullopt; diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h index b09169b027..a30e0c6534 100644 --- a/toolsrc/include/vcpkg/vcpkgpaths.h +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -47,14 +47,17 @@ namespace vcpkg struct VcpkgPaths { - static Expected create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path); + static Expected create(const fs::path& vcpkg_root_dir, + const std::string& default_vs_path, + const std::vector* triplets_dirs); fs::path package_dir(const PackageSpec& spec) const; fs::path build_info_file_path(const PackageSpec& spec) const; fs::path listfile_path(const BinaryParagraph& pgh) const; - - const std::vector& get_available_triplets() const; + bool is_valid_triplet(const Triplet& t) const; + const std::vector& get_available_triplets() const; + const fs::path get_triplet_file_path(const Triplet& triplet) const; fs::path root; fs::path packages; @@ -93,7 +96,9 @@ namespace vcpkg Lazy> toolsets_vs2013; fs::path default_vs_path; + std::vector triplets_dirs; mutable std::unique_ptr m_tool_cache; + mutable vcpkg::Cache m_triplets_cache; }; } diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index e02bdc71f1..5da97b136d 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -118,7 +118,9 @@ static void inner(const VcpkgCmdArguments& args) auto default_vs_path = System::get_environment_variable("VCPKG_VISUAL_STUDIO_PATH").value_or(""); - const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir, default_vs_path); + const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir, + default_vs_path, + args.overlay_triplets.get()); Checks::check_exit(VCPKG_LINE_INFO, !expected_paths.error(), "Error: Invalid vcpkg root directory %s: %s", diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 059a09432c..f826a48652 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -361,9 +361,15 @@ namespace vcpkg::Build { auto& fs = paths.get_filesystem(); const Triplet& triplet = spec.triplet(); + const auto& triplet_file_path = paths.get_triplet_file_path(spec.triplet()).u8string(); - if (!Strings::starts_with(Strings::ascii_to_lowercase(config.port_dir.u8string()), - Strings::ascii_to_lowercase(paths.ports.u8string()))) + if (!Strings::case_insensitive_ascii_starts_with(triplet_file_path, + paths.triplets.u8string())) + { + System::printf("-- Loading triplet configuration from: %s\n", triplet_file_path); + } + if (!Strings::case_insensitive_ascii_starts_with(config.port_dir.u8string(), + paths.ports.u8string())) { System::printf("-- Installing port from location: %s\n", config.port_dir.u8string()); } @@ -390,6 +396,7 @@ namespace vcpkg::Build {"PORT", config.scf.core_paragraph->name}, {"CURRENT_PORT_DIR", config.port_dir}, {"TARGET_TRIPLET", spec.triplet().canonical_name()}, + {"TARGET_TRIPLET_FILE", triplet_file_path}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, {"VCPKG_USE_HEAD_VERSION", Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, {"DOWNLOADS", paths.downloads}, @@ -890,7 +897,7 @@ namespace vcpkg::Build const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; - const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); + const fs::path triplet_file_path = paths.get_triplet_file_path(triplet); const auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, ports_cmake_script_path, diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 6ee573dfcc..896f62661f 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -117,6 +117,8 @@ namespace vcpkg::Help "\n" " --overlay-ports= Specify directories to be used when searching for ports\n" "\n" + " --overlay-triplets= Specify directories containing triplets files\n" + "\n" " --vcpkg-root Specify the vcpkg root " "directory\n" " (default: " ENVVAR(VCPKG_ROOT) // diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 21bf4d0285..3c1452d475 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -45,26 +45,6 @@ namespace vcpkg option_field = new_setting; } - static void parse_multivalue(const std::string* arg_begin, - const std::string* arg_end, - const std::string& option_name, - std::unique_ptr>& option_field) - { - if (arg_begin == arg_end) - { - System::print2(System::Color::error, "Error: expected value after ", option_name, '\n'); - Metrics::g_metrics.lock()->track_property("error", "error option name"); - Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (!option_field) - { - option_field = std::make_unique>(); - } - option_field->emplace_back(*arg_begin); - } - static void parse_cojoined_multivalue(std::string new_value, const std::string& option_name, std::unique_ptr>& option_field) @@ -163,6 +143,13 @@ namespace vcpkg args.overlay_ports); continue; } + if (Strings::starts_with(arg, "--overlay-triplets=")) + { + parse_cojoined_multivalue(arg.substr(sizeof("--overlay-triplets=") - 1), + "--overlay-triplets", + args.overlay_triplets); + continue; + } if (arg == "--debug") { parse_switch(true, "debug", args.debug); @@ -418,6 +405,9 @@ namespace vcpkg System::printf(" %-40s %s\n", "--overlay-ports=", "Specify directories to be used when searching for ports"); + System::printf(" %-40s %s\n", + "--overlay-triplets=", + "Specify directories containing triplets files"); System::printf(" %-40s %s\n", "--vcpkg-root ", "Specify the vcpkg directory to use instead of current directory or tool directory"); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 562a18c9ba..909fbeb448 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -13,7 +13,9 @@ namespace vcpkg { - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, + const std::string& default_vs_path, + const std::vector* triplets_dirs) { std::error_code ec; const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); @@ -76,6 +78,20 @@ namespace vcpkg paths.ports_cmake = paths.scripts / "ports.cmake"; + if (triplets_dirs) + { + for (auto&& triplets_dir : *triplets_dirs) + { + auto path = fs::u8path(triplets_dir); + Checks::check_exit(VCPKG_LINE_INFO, + paths.get_filesystem().exists(path), + "Error: Path does not exist '%s'", + triplets_dir); + paths.triplets_dirs.emplace_back(fs::stdfs::canonical(path)); + } + } + paths.triplets_dirs.emplace_back(fs::stdfs::canonical(paths.root / "triplets")); + return paths; } @@ -91,20 +107,6 @@ namespace vcpkg return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); } - const std::vector& VcpkgPaths::get_available_triplets() const - { - return this->available_triplets.get_lazy([this]() -> std::vector { - std::vector output; - for (auto&& path : this->get_filesystem().get_files_non_recursive(this->triplets)) - { - output.push_back(path.stem().filename().string()); - } - Util::sort(output); - - return output; - }); - } - bool VcpkgPaths::is_valid_triplet(const Triplet& t) const { const auto it = Util::find_if(this->get_available_triplets(), [&](auto&& available_triplet) { @@ -113,6 +115,41 @@ namespace vcpkg return it != this->get_available_triplets().cend(); } + const std::vector& VcpkgPaths::get_available_triplets() const + { + return this->available_triplets.get_lazy([this]() -> std::vector { + std::vector output; + for (auto&& triplets_dir : triplets_dirs) + { + for (auto&& path : this->get_filesystem().get_files_non_recursive(triplets_dir)) + { + output.push_back(path.stem().filename().string()); + } + } + Util::sort_unique_erase(output); + return output; + }); + } + + const fs::path VcpkgPaths::get_triplet_file_path(const Triplet& triplet) const + { + return m_triplets_cache.get_lazy(triplet, [&]()-> auto { + for (auto&& triplet_dir : triplets_dirs) + { + auto&& path = triplet_dir / (triplet.canonical_name() + ".cmake"); + if (this->get_filesystem().exists(path)) + { + return path; + } + } + + Checks::exit_with_message(VCPKG_LINE_INFO, + "Error: Triplet file %s.cmake not found", + triplet.canonical_name()); + }); + + } + const fs::path& VcpkgPaths::get_tool_exe(const std::string& tool) const { if (!m_tool_cache) m_tool_cache = get_tool_cache();