diff options
| author | Griffin Downs <35574547+grdowns@users.noreply.github.com> | 2019-07-01 13:14:53 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-07-01 13:14:53 -0700 |
| commit | 0b9cf040bafa0a8ed064e47459779d72fcf9b9c4 (patch) | |
| tree | 53036c9f0b7f051abe737376f7ddeeeccd9948d0 /toolsrc/src | |
| parent | 34d19da9ffd0571bf16190ec4a16a04bef265900 (diff) | |
| parent | 77cfd20b83e71a0c513658e7c4d049d4039905af (diff) | |
| download | vcpkg-0b9cf040bafa0a8ed064e47459779d72fcf9b9c4.tar.gz vcpkg-0b9cf040bafa0a8ed064e47459779d72fcf9b9c4.zip | |
Merge branch 'master' into openssl-unix-dynamic
Diffstat (limited to 'toolsrc/src')
34 files changed, 660 insertions, 204 deletions
diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp index 72bdbdb65..51ababd3d 100644 --- a/toolsrc/src/tests.arguments.cpp +++ b/toolsrc/src/tests.arguments.cpp @@ -1,7 +1,9 @@ #include "tests.pch.h"
+#if defined(_WIN32)
#pragma comment(lib, "version")
#pragma comment(lib, "winhttp")
+#endif
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@@ -61,4 +63,4 @@ namespace UnitTest1 Assert::AreEqual(size_t{0}, v.command_arguments.size());
}
};
-}
\ No newline at end of file +}
diff --git a/toolsrc/src/tests.dependencies.cpp b/toolsrc/src/tests.dependencies.cpp index f82fad4e4..7d8283ed6 100644 --- a/toolsrc/src/tests.dependencies.cpp +++ b/toolsrc/src/tests.dependencies.cpp @@ -1,7 +1,9 @@ #include "tests.pch.h" +#if defined(_WIN32) #pragma comment(lib, "version") #pragma comment(lib, "winhttp") +#endif using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/toolsrc/src/tests.packagespec.cpp b/toolsrc/src/tests.packagespec.cpp index 32ad81227..d3bc18c79 100644 --- a/toolsrc/src/tests.packagespec.cpp +++ b/toolsrc/src/tests.packagespec.cpp @@ -2,8 +2,10 @@ #include <tests.utils.h> +#if defined(_WIN32) #pragma comment(lib, "version") #pragma comment(lib, "winhttp") +#endif using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp index 9a56ad9ee..e99d07694 100644 --- a/toolsrc/src/tests.paragraph.cpp +++ b/toolsrc/src/tests.paragraph.cpp @@ -1,7 +1,9 @@ #include "tests.pch.h" +#if defined(_WIN32) #pragma comment(lib, "version") #pragma comment(lib, "winhttp") +#endif using namespace Microsoft::VisualStudio::CppUnitTestFramework; diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 238aa7032..ab24266b4 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -47,7 +47,8 @@ namespace UnitTest1 Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - Assert::AreEqual(pkg_name.c_str(), plan.source_control_file.get()->core_paragraph->name.c_str()); + auto* scfl = plan.source_control_file_location.get(); + Assert::AreEqual(pkg_name.c_str(), scfl->source_control_file->core_paragraph->name.c_str()); Assert::AreEqual(size_t(vec.size()), feature_list.size()); for (auto&& feature_name : vec) @@ -79,7 +80,7 @@ namespace UnitTest1 /// </summary> struct PackageSpecMap { - std::unordered_map<std::string, SourceControlFile> map; + std::unordered_map<std::string, SourceControlFileLocation> map; Triplet triplet; PackageSpecMap(const Triplet& t = Triplet::X86_WINDOWS) noexcept { triplet = t; } @@ -94,7 +95,8 @@ namespace UnitTest1 { auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); Assert::IsTrue(spec.has_value()); - map.emplace(scf.core_paragraph->name, std::move(scf)); + map.emplace(scf.core_paragraph->name, + SourceControlFileLocation{std::unique_ptr<SourceControlFile>(std::move(&scf)), ""}); return PackageSpec{*spec.get()}; } }; diff --git a/toolsrc/src/tests.update.cpp b/toolsrc/src/tests.update.cpp index b6e487c17..5e3f9f3e2 100644 --- a/toolsrc/src/tests.update.cpp +++ b/toolsrc/src/tests.update.cpp @@ -21,9 +21,9 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; + std::unordered_map<std::string, SourceControlFileLocation> map; auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); + map.emplace("a", SourceControlFileLocation { std::move(scf), "" }); Dependencies::MapPortFileProvider provider(map); auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), @@ -45,9 +45,9 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; + std::unordered_map<std::string, SourceControlFileLocation> map; auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); + map.emplace("a", SourceControlFileLocation { std::move(scf), "" }); Dependencies::MapPortFileProvider provider(map); auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), @@ -71,9 +71,9 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; + std::unordered_map<std::string, SourceControlFileLocation> map; auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "0"}}})); - map.emplace("a", std::move(*scf)); + map.emplace("a", SourceControlFileLocation{ std::move(scf), "" }); Dependencies::MapPortFileProvider provider(map); auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), @@ -92,9 +92,9 @@ namespace UnitTest1 StatusParagraphs status_db(std::move(status_paragraphs)); - std::unordered_map<std::string, SourceControlFile> map; + std::unordered_map<std::string, SourceControlFileLocation> map; auto scf = unwrap(SourceControlFile::parse_control_file(Pgh{{{"Source", "a"}, {"Version", "2"}}})); - map.emplace("a", std::move(*scf)); + map.emplace("a", SourceControlFileLocation{ std::move(scf), "" }); Dependencies::MapPortFileProvider provider(map); auto pkgs = SortedVector<OutdatedPackage>(Update::find_outdated_packages(provider, status_db), diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index ab7586eeb..5da97b136 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -40,8 +40,10 @@ #include <memory> #include <random> +#if defined(_WIN32) #pragma comment(lib, "ole32") #pragma comment(lib, "shell32") +#endif using namespace vcpkg; @@ -116,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<VcpkgPaths> expected_paths = VcpkgPaths::create(vcpkg_root_dir, default_vs_path); + const Expected<VcpkgPaths> 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/base/downloads.cpp b/toolsrc/src/vcpkg/base/downloads.cpp index 218ff86b3..4bb2178e5 100644 --- a/toolsrc/src/vcpkg/base/downloads.cpp +++ b/toolsrc/src/vcpkg/base/downloads.cpp @@ -105,7 +105,7 @@ namespace vcpkg::Downloads bResults = WinHttpQueryDataAvailable(hRequest, &dwSize); Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpQueryDataAvailable() failed: %d", GetLastError()); - if (buf.size() < dwSize) buf.resize(dwSize * 2); + if (buf.size() < dwSize) buf.resize(static_cast<size_t>(dwSize) * 2); bResults = WinHttpReadData(hRequest, (LPVOID)buf.data(), dwSize, &downloaded_size); Checks::check_exit(VCPKG_LINE_INFO, bResults, "WinHttpReadData() failed: %d", GetLastError()); @@ -157,9 +157,10 @@ namespace vcpkg::Downloads const std::string& sha512) { const std::string download_path_part = download_path.u8string() + ".part"; + auto download_path_part_path = fs::u8path(download_path_part); std::error_code ec; fs.remove(download_path, ec); - fs.remove(download_path_part, ec); + fs.remove(download_path_part_path, ec); #if defined(_WIN32) auto url_no_proto = url.substr(8); // drop https:// auto path_begin = Util::find(url_no_proto, '/'); @@ -173,14 +174,7 @@ namespace vcpkg::Downloads Checks::check_exit(VCPKG_LINE_INFO, code == 0, "Could not download %s", url); #endif - verify_downloaded_file_hash(fs, url, download_path_part, sha512); - fs.rename(download_path_part, download_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Failed to do post-download rename-in-place.\n" - "fs.rename(%s, %s, %s)", - download_path_part, - download_path.u8string(), - ec.message()); + verify_downloaded_file_hash(fs, url, download_path_part_path, sha512); + fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); } } diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 0396a2415..5099795e9 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -24,12 +24,43 @@ namespace vcpkg::Files { static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])"); - void Filesystem::write_contents(const fs::path& file_path, const std::string& data) + std::string Filesystem::read_contents(const fs::path& path, LineInfo linfo) const + { + auto maybe_contents = this->read_contents(path); + if (auto p = maybe_contents.get()) + return std::move(*p); + else + Checks::exit_with_message( + linfo, "error reading file: %s: %s", path.u8string(), maybe_contents.error().message()); + } + void Filesystem::write_contents(const fs::path& path, const std::string& data, LineInfo linfo) + { + std::error_code ec; + this->write_contents(path, data, ec); + if (ec) Checks::exit_with_message(linfo, "error writing file: %s: %s", path.u8string(), ec.message()); + } + void Filesystem::rename(const fs::path& oldpath, const fs::path& newpath, LineInfo linfo) + { + std::error_code ec; + this->rename(oldpath, newpath, ec); + if (ec) + Checks::exit_with_message( + linfo, "error renaming file: %s: %s: %s", oldpath.u8string(), newpath.u8string(), ec.message()); + } + + bool Filesystem::remove(const fs::path& path, LineInfo linfo) { std::error_code ec; - write_contents(file_path, data, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "error while writing file: %s: %s", file_path.u8string(), ec.message()); + auto r = this->remove(path, ec); + if (ec) Checks::exit_with_message(linfo, "error removing file: %s: %s", path.u8string(), ec.message()); + return r; + } + + void Filesystem::write_lines(const fs::path& path, const std::vector<std::string>& lines, LineInfo linfo) + { + std::error_code ec; + this->write_lines(path, lines, ec); + if (ec) Checks::exit_with_message(linfo, "error writing lines: %s: %s", path.u8string(), ec.message()); } struct RealFilesystem final : Filesystem @@ -147,30 +178,39 @@ namespace vcpkg::Files return ret; } - virtual void write_lines(const fs::path& file_path, const std::vector<std::string>& lines) override + virtual void write_lines(const fs::path& file_path, + const std::vector<std::string>& lines, + std::error_code& ec) override { std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); + if (!output) + { + ec.assign(errno, std::generic_category()); + return; + } for (const std::string& line : lines) { output << line << "\n"; + if (!output) + { + output.close(); + ec.assign(errno, std::generic_category()); + return; + } } output.close(); } - virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) override { fs::stdfs::rename(oldpath, newpath, ec); } - virtual void rename(const fs::path& oldpath, const fs::path& newpath) override - { - fs::stdfs::rename(oldpath, newpath); - } virtual void rename_or_copy(const fs::path& oldpath, const fs::path& newpath, StringLiteral temp_suffix, std::error_code& ec) override { this->rename(oldpath, newpath, ec); + Util::unused(temp_suffix); #if defined(__linux__) || defined(__APPLE__) if (ec) { @@ -213,7 +253,6 @@ namespace vcpkg::Files } #endif } - virtual bool remove(const fs::path& path) override { return fs::stdfs::remove(path); } virtual bool remove(const fs::path& path, std::error_code& ec) override { return fs::stdfs::remove(path, ec); } virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) override { diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index ce634a227..54a74a7a1 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -185,7 +185,7 @@ std::vector<std::string> Strings::split(const std::string& s, const std::string& return output; } -std::vector<std::string> Strings::split(const std::string& s, const std::string& delimiter, int max_count) +std::vector<std::string> Strings::split(const std::string& s, const std::string& delimiter, size_t max_count) { std::vector<std::string> output; diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 48a701bfa..c5ff050f0 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -16,7 +16,9 @@ #include <sys/sysctl.h> #endif +#if defined(_WIN32) #pragma comment(lib, "Advapi32") +#endif using namespace vcpkg::System; @@ -386,6 +388,7 @@ namespace vcpkg // Flush stdout before launching external process fflush(nullptr); + auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) // We are wrap the command line in quotes to cause cmd.exe to correctly process it auto actual_cmd_line = Strings::concat('"', cmd_line, '"'); @@ -393,11 +396,19 @@ namespace vcpkg g_ctrl_c_state.transition_to_spawn_process(); const int exit_code = _wsystem(Strings::to_utf16(actual_cmd_line).c_str()); g_ctrl_c_state.transition_from_spawn_process(); - Debug::print("_wsystem() returned ", exit_code, '\n'); + Debug::print("_wsystem() returned ", + exit_code, + " after ", + Strings::format("%8d", static_cast<int>(timer.microseconds())), + " us\n"); #else Debug::print("_system(", cmd_line, ")\n"); const int exit_code = system(cmd_line.c_str()); - Debug::print("_system() returned ", exit_code, '\n'); + Debug::print("_system() returned ", + exit_code, + " after ", + Strings::format("%8d", static_cast<int>(timer.microseconds())), + " us\n"); #endif return exit_code; } @@ -596,6 +607,11 @@ namespace vcpkg #else void System::register_console_ctrl_handler() {} #endif + + int System::get_num_logical_cores() + { + return std::thread::hardware_concurrency(); + } } namespace vcpkg::Debug diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7bd6f467b..1975d3aaf 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -23,6 +23,7 @@ #include <vcpkg/vcpkglib.h>
using vcpkg::Build::BuildResult;
+using vcpkg::Dependencies::PathsPortFileProvider;
using vcpkg::Parse::ParseControlErrorInfo;
using vcpkg::Parse::ParseExpected;
@@ -34,34 +35,26 @@ namespace vcpkg::Build::Command static constexpr StringLiteral OPTION_CHECKS_ONLY = "--checks-only";
void perform_and_exit_ex(const FullPackageSpec& full_spec,
- const fs::path& port_dir,
+ const SourceControlFileLocation& scfl,
const ParsedArguments& options,
const VcpkgPaths& paths)
{
const PackageSpec& spec = full_spec.package_spec;
+ const auto& scf = *scfl.source_control_file;
if (Util::Sets::contains(options.switches, OPTION_CHECKS_ONLY))
{
const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet());
const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec));
- const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info);
+ const size_t error_count =
+ PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info, scfl.source_location);
Checks::check_exit(VCPKG_LINE_INFO, error_count == 0);
Checks::exit_success(VCPKG_LINE_INFO);
}
- const ParseExpected<SourceControlFile> source_control_file =
- Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
-
- if (!source_control_file.has_value())
- {
- print_error_message(source_control_file.error());
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO);
Checks::check_exit(VCPKG_LINE_INFO,
- spec.name() == scf->core_paragraph->name,
+ spec.name() == scf.core_paragraph->name,
"The Source field inside the CONTROL file does not match the port directory: '%s' != '%s'",
- scf->core_paragraph->name,
+ scf.core_paragraph->name,
spec.name());
const StatusParagraphs status_db = database_load_check(paths);
@@ -80,7 +73,7 @@ namespace vcpkg::Build::Command features_as_set.emplace("core");
const Build::BuildPackageConfig build_config{
- *scf, spec.triplet(), fs::path{port_dir}, build_package_options, features_as_set};
+ scf, spec.triplet(), fs::path(scfl.source_location), build_package_options, features_as_set};
const auto build_timer = Chrono::ElapsedTimer::create_started();
const auto result = Build::build_package(paths, build_config, status_db);
@@ -128,10 +121,19 @@ namespace vcpkg::Build::Command // Build only takes a single package and all dependencies must already be installed
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
std::string first_arg = args.command_arguments.at(0);
+
const FullPackageSpec spec = Input::check_and_get_full_package_spec(
std::move(first_arg), default_triplet, COMMAND_STRUCTURE.example_text);
+
Input::check_triplet(spec.package_spec.triplet(), paths);
- perform_and_exit_ex(spec, paths.port_dir(spec.package_spec), options, paths);
+
+ PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ const auto port_name = spec.package_spec.name();
+ 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);
+
+ perform_and_exit_ex(spec, *scfl, options, paths);
}
}
@@ -280,7 +282,7 @@ namespace vcpkg::Build start += "\n" + Strings::serialize(feature);
}
const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL";
- paths.get_filesystem().write_contents(binary_control_file, start);
+ paths.get_filesystem().write_contents(binary_control_file, start, VCPKG_LINE_INFO);
}
static std::vector<FeatureSpec> compute_required_feature_specs(const BuildPackageConfig& config,
@@ -334,6 +336,23 @@ namespace vcpkg::Build return ret;
}
+ static int get_concurrency()
+ {
+ static int concurrency = [] {
+ auto user_defined_concurrency = System::get_environment_variable("VCPKG_MAX_CONCURRENCY");
+ if (user_defined_concurrency)
+ {
+ return std::stoi(user_defined_concurrency.value_or_exit(VCPKG_LINE_INFO));
+ }
+ else
+ {
+ return System::get_num_logical_cores() + 1;
+ }
+ }();
+
+ return concurrency;
+ }
+
static ExtendedBuildResult do_build_package(const VcpkgPaths& paths,
const PreBuildInfo& pre_build_info,
const PackageSpec& spec,
@@ -342,6 +361,18 @@ 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::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());
+ }
#if !defined(_WIN32)
// TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107.
@@ -365,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},
@@ -372,6 +404,7 @@ namespace vcpkg::Build {"_VCPKG_DOWNLOAD_TOOL", to_string(config.build_package_options.download_tool)},
{"FEATURES", Strings::join(";", config.feature_list)},
{"ALL_FEATURES", all_features},
+ {"VCPKG_CONCURRENCY", std::to_string(get_concurrency())},
};
if (!System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value())
@@ -410,7 +443,8 @@ namespace vcpkg::Build }
const BuildInfo build_info = read_build_info(fs, paths.build_info_file_path(spec));
- const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info);
+ const size_t error_count =
+ PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info, config.port_dir);
auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag);
@@ -547,7 +581,7 @@ namespace vcpkg::Build std::error_code ec;
fs.create_directories(paths.buildtrees / name, ec);
const auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt");
- fs.write_contents(abi_file_path, full_abi_info);
+ fs.write_contents(abi_file_path, full_abi_info, VCPKG_LINE_INFO);
return AbiTagAndFile{Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path};
}
@@ -560,7 +594,7 @@ namespace vcpkg::Build return nullopt;
}
- static void decompress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& archive_path)
+ static int decompress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& archive_path)
{
auto& fs = paths.get_filesystem();
@@ -574,12 +608,13 @@ namespace vcpkg::Build #if defined(_WIN32)
auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP);
- System::cmd_execute_clean(Strings::format(
+ int result = System::cmd_execute_clean(Strings::format(
R"("%s" x "%s" -o"%s" -y >nul)", seven_zip_exe.u8string(), archive_path.u8string(), pkg_path.u8string()));
#else
- System::cmd_execute_clean(
+ int result = System::cmd_execute_clean(
Strings::format(R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string()));
#endif
+ return result;
}
// Compress the source directory into the destination file.
@@ -665,11 +700,16 @@ namespace vcpkg::Build {
System::print2("Using cached binary package: ", archive_path.u8string(), "\n");
- decompress_archive(paths, spec, archive_path);
+ auto archive_result = decompress_archive(paths, spec, archive_path);
+
+ if (archive_result != 0)
+ {
+ System::print2("Failed to decompress archive package\n");
+ return BuildResult::BUILD_FAILED;
+ }
auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec);
- std::unique_ptr<BinaryControlFile> bcf =
- std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO));
+ auto bcf = std::make_unique<BinaryControlFile>(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO));
return {BuildResult::SUCCEEDED, std::move(bcf)};
}
@@ -687,7 +727,7 @@ namespace vcpkg::Build }
}
- System::print2("Could not locate cached archive: ", archive_path.u8string(), "\n");
+ System::printf("Could not locate cached archive: %s\n", archive_path.u8string());
ExtendedBuildResult result = do_build_package_and_clean_buildtrees(
paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config);
@@ -863,7 +903,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,
@@ -967,6 +1007,12 @@ namespace vcpkg::Build hash += "-";
hash += Hash::get_file_hash(fs, *p, "SHA1");
}
+ else if (pre_build_info.cmake_system_name.empty() ||
+ pre_build_info.cmake_system_name == "WindowsStore")
+ {
+ hash += "-";
+ hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "windows.cmake", "SHA1");
+ }
else if (pre_build_info.cmake_system_name == "Linux")
{
hash += "-";
diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index afef518eb..3cf4dd98f 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -90,7 +90,8 @@ namespace vcpkg::Commands::Autocomplete const auto port_name = match[2].str(); const auto triplet_prefix = match[3].str(); - auto maybe_port = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(port_name)); + // TODO: Support autocomplete for ports in --overlay-ports + auto maybe_port = Paragraphs::try_load_port(paths.get_filesystem(), paths.ports / port_name); if (maybe_port.error()) { Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp index 19b89c2f5..1c3c511c2 100644 --- a/toolsrc/src/vcpkg/commands.buildexternal.cpp +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -23,7 +23,12 @@ namespace vcpkg::Commands::BuildExternal std::string(args.command_arguments.at(0)), default_triplet, COMMAND_STRUCTURE.example_text); Input::check_triplet(spec.package_spec.triplet(), paths); - const fs::path port_dir = args.command_arguments.at(1); - Build::Command::perform_and_exit_ex(spec, port_dir, options, paths); + auto overlays = args.overlay_ports ? *args.overlay_ports : std::vector<std::string>(); + overlays.insert(overlays.begin(), args.command_arguments.at(1)); + Dependencies::PathsPortFileProvider provider(paths, &overlays); + auto maybe_scfl = provider.get_control_file(spec.package_spec.name()); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_scfl.has_value(), "could not load control file for %s", spec.package_spec.name()); + Build::Command::perform_and_exit_ex(spec, maybe_scfl.value_or_exit(VCPKG_LINE_INFO), options, paths); } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index ff7e7a134..c12c26ff7 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -232,12 +232,17 @@ namespace vcpkg::Commands::CI { // determine abi tag std::string abi; - if (auto scf = p->source_control_file.get()) + if (auto scfl = p->source_control_file_location.get()) { auto triplet = p->spec.triplet(); const Build::BuildPackageConfig build_config{ - *scf, triplet, paths.port_dir(p->spec), build_options, p->feature_list}; + *scfl->source_control_file, + triplet, + static_cast<fs::path>(scfl->source_location), + build_options, + p->feature_list + }; auto dependency_abis = Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry { @@ -351,7 +356,8 @@ namespace vcpkg::Commands::CI } StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFileProvider(paths); + + Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get()); const Build::BuildPackageOptions install_plan_options = { Build::UseHeadVersion::NO, @@ -369,7 +375,10 @@ namespace vcpkg::Commands::CI XunitTestResults xunitTestResults; - std::vector<std::string> all_ports = Install::get_all_port_names(paths); + std::vector<std::string> all_ports = + Util::fmap(provider.load_all_control_files(), [](auto&& scfl) -> std::string { + return scfl->source_control_file.get()->core_paragraph->name; + }); std::vector<TripletAndSummary> results; auto timer = Chrono::ElapsedTimer::create_started(); for (const Triplet& triplet : triplets) @@ -378,13 +387,13 @@ namespace vcpkg::Commands::CI xunitTestResults.push_collection(triplet.canonical_name()); - Dependencies::PackageGraph pgraph(paths_port_file, status_db); + Dependencies::PackageGraph pgraph(provider, status_db); std::vector<PackageSpec> specs = PackageSpec::to_package_specs(all_ports, triplet); // Install the default features for every package auto all_feature_specs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); auto split_specs = - find_unknown_ports_for_ci(paths, exclusions_set, paths_port_file, all_feature_specs, purge_tombstones); + find_unknown_ports_for_ci(paths, exclusions_set, provider, all_feature_specs, purge_tombstones); auto feature_specs = FullPackageSpec::to_feature_specs(split_specs->unknown); for (auto&& fspec : feature_specs) @@ -442,7 +451,7 @@ namespace vcpkg::Commands::CI if (is_dry_run) { - Dependencies::print_plan(action_plan); + Dependencies::print_plan(action_plan, true, paths.ports); } else { @@ -485,11 +494,11 @@ namespace vcpkg::Commands::CI System::print2("Total elapsed time: ", result.summary.total_elapsed_time, "\n"); result.summary.print(); } - + auto& fs = paths.get_filesystem(); 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()); + fs.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.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 48a289fa5..c0800a4b5 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -6,6 +6,9 @@ #include <vcpkg/commands.h>
#include <vcpkg/help.h>
#include <vcpkg/paragraphs.h>
+#include <vcpkg/dependencies.h>
+
+using vcpkg::Dependencies::PathsPortFileProvider;
namespace vcpkg::Commands::DependInfo
{
@@ -35,7 +38,7 @@ namespace vcpkg::Commands::DependInfo return output;
}
- std::string create_dot_as_string(const std::vector<std::unique_ptr<SourceControlFile>>& source_control_files)
+ std::string create_dot_as_string(const std::vector<const SourceControlFile*>& source_control_files)
{
int empty_node_count = 0;
@@ -64,7 +67,7 @@ namespace vcpkg::Commands::DependInfo return s;
}
- std::string create_dgml_as_string(const std::vector<std::unique_ptr<SourceControlFile>>& source_control_files)
+ std::string create_dgml_as_string(const std::vector<const SourceControlFile*>& source_control_files)
{
std::string s;
s.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
@@ -109,7 +112,7 @@ namespace vcpkg::Commands::DependInfo }
std::string create_graph_as_string(const std::unordered_set<std::string>& switches,
- const std::vector<std::unique_ptr<SourceControlFile>>& source_control_files)
+ const std::vector<const SourceControlFile*>& source_control_files)
{
if (Util::Sets::contains(switches, OPTION_DOT))
{
@@ -124,7 +127,7 @@ namespace vcpkg::Commands::DependInfo void build_dependencies_list(std::set<std::string>& packages_to_keep,
const std::string& requested_package,
- const std::vector<std::unique_ptr<SourceControlFile>>& source_control_files,
+ const std::vector<const SourceControlFile*>& source_control_files,
const std::unordered_set<std::string>& switches)
{
const auto source_control_file =
@@ -154,7 +157,11 @@ namespace vcpkg::Commands::DependInfo {
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
+ // TODO: Optimize implementation, current implementation needs to load all ports from disk which is too slow.
+ PathsPortFileProvider provider(paths, args.overlay_ports.get());
+ auto source_control_files = Util::fmap(provider.load_all_control_files(), [](auto&& scfl) -> const SourceControlFile * {
+ return scfl->source_control_file.get();
+ });
if (args.command_arguments.size() >= 1)
{
@@ -178,7 +185,7 @@ namespace vcpkg::Commands::DependInfo for (auto&& source_control_file : source_control_files)
{
- const SourceParagraph& source_paragraph = *source_control_file->core_paragraph;
+ const SourceParagraph& source_paragraph = *source_control_file->core_paragraph.get();
const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); });
System::print2(source_paragraph.name, ": ", s, "\n");
}
diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 98176b2b0..f2f0b1569 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -79,6 +79,7 @@ namespace vcpkg::Commands::Edit const auto& fs = paths.get_filesystem(); auto packages = fs.get_files_non_recursive(paths.packages); + // TODO: Support edit for --overlay-ports return Util::fmap(ports, [&](const std::string& port_name) -> std::string { const auto portpath = paths.ports / port_name; const auto portfile = portpath / "portfile.cmake"; diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index ba9e28233..f0946110c 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -106,7 +106,8 @@ namespace vcpkg::Export::IFW create_release_date(), action.spec.name(), action.spec.triplet().canonical_name(), - deps)); + deps), + VCPKG_LINE_INFO); // Return dir path for export package data return ifw_packages_dir_path / @@ -138,7 +139,8 @@ namespace vcpkg::Export::IFW <ReleaseDate>%s</ReleaseDate> </Package> )###", - create_release_date())); + create_release_date()), + VCPKG_LINE_INFO); for (const auto& unique_package : unique_packages) { @@ -167,7 +169,8 @@ namespace vcpkg::Export::IFW action.spec.name(), safe_rich_from_plain_text(binary_paragraph.description), binary_paragraph.version, - create_release_date())); + create_release_date()), + VCPKG_LINE_INFO); } } @@ -195,7 +198,8 @@ namespace vcpkg::Export::IFW <ReleaseDate>%s</ReleaseDate> </Package> )###", - create_release_date())); + create_release_date()), + VCPKG_LINE_INFO); for (const std::string& triplet : unique_triplets) { @@ -217,7 +221,8 @@ namespace vcpkg::Export::IFW </Package> )###", triplet, - create_release_date())); + create_release_date()), + VCPKG_LINE_INFO); } } @@ -243,7 +248,8 @@ namespace vcpkg::Export::IFW <ReleaseDate>%s</ReleaseDate> </Package> )###", - create_release_date())); + create_release_date()), + VCPKG_LINE_INFO); } void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) @@ -283,7 +289,8 @@ namespace vcpkg::Export::IFW <TargetDir>@RootDir@/src/vcpkg</TargetDir>%s </Installer> )###", - formatted_repo_url)); + formatted_repo_url), + VCPKG_LINE_INFO); } void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) @@ -325,7 +332,8 @@ namespace vcpkg::Export::IFW <ForcedInstallation>true</ForcedInstallation> </Package> )###", - create_release_date())); + create_release_date()), + VCPKG_LINE_INFO); const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp index f03140fbd..40f5a434c 100644 --- a/toolsrc/src/vcpkg/commands.import.cpp +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -89,7 +89,7 @@ namespace vcpkg::Commands::Import place_library_files_in(paths.get_filesystem(), include_directory, project_directory, library_destination_path); const fs::path control_file_path = library_destination_path / "CONTROL"; - fs.write_contents(control_file_path, Strings::serialize(control_file_data)); + fs.write_contents(control_file_path, Strings::serialize(control_file_data), VCPKG_LINE_INFO); } const CommandStructure COMMAND_STRUCTURE = { diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index ef555a844..fda9e2b11 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -209,7 +209,7 @@ namespace vcpkg::Commands::Integrate if (should_install_system) { const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets"; - fs.write_contents(sys_src_path, create_system_targets_shortcut()); + fs.write_contents(sys_src_path, create_system_targets_shortcut(), VCPKG_LINE_INFO); const std::string param = Strings::format(R"(/c mkdir "%s" & copy "%s" "%s" /Y > nul)", SYSTEM_WIDE_TARGETS_FILE.parent_path().string(), @@ -248,7 +248,8 @@ namespace vcpkg::Commands::Integrate const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; fs.write_contents(appdata_src_path, - create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.u8string())); + create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.u8string()), + VCPKG_LINE_INFO); auto appdata_dst_path = get_appdata_targets_path(); const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); @@ -268,12 +269,7 @@ namespace vcpkg::Commands::Integrate const auto pathtxt = get_path_txt_path(); std::error_code ec; - fs.write_contents(pathtxt, paths.root.generic_u8string(), ec); - if (ec) - { - System::print2(System::Color::error, "Error: Failed to write file: ", pathtxt.u8string(), "\n"); - Checks::exit_fail(VCPKG_LINE_INFO); - } + fs.write_contents(pathtxt, paths.root.generic_u8string(), VCPKG_LINE_INFO); System::print2(System::Color::success, "Applied user-wide integration for this vcpkg root.\n"); const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; @@ -344,9 +340,11 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s" const std::string nuget_id = get_nuget_id(paths.root); const std::string nupkg_version = "1.0.0"; - fs.write_contents(targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets)); - fs.write_contents(props_file_path, create_nuget_props_file_contents()); - fs.write_contents(nuspec_file_path, create_nuspec_file_contents(paths.root, nuget_id, nupkg_version)); + fs.write_contents( + targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets), VCPKG_LINE_INFO); + fs.write_contents(props_file_path, create_nuget_props_file_contents(), VCPKG_LINE_INFO); + fs.write_contents( + nuspec_file_path, create_nuspec_file_contents(paths.root, nuget_id, nupkg_version), VCPKG_LINE_INFO); // Using all forward slashes for the command line const std::string cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" > nul)", @@ -411,7 +409,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console Checks::exit_with_code(VCPKG_LINE_INFO, rc); } -#elif defined(__unix__) +#else static void integrate_bash(const VcpkgPaths& paths) { const auto home_path = System::get_environment_variable("HOME").value_or_exit(VCPKG_LINE_INFO); @@ -449,7 +447,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console System::printf("Adding vcpkg completion entry to %s\n", bashrc_path.u8string()); bashrc_content.push_back(Strings::format("source %s", completion_script_path.u8string())); - fs.write_contents(bashrc_path, Strings::join("\n", bashrc_content) + '\n'); + fs.write_contents(bashrc_path, Strings::join("\n", bashrc_content) + '\n', VCPKG_LINE_INFO); Checks::exit_success(VCPKG_LINE_INFO); } #endif @@ -460,11 +458,12 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console "first use\n" " vcpkg integrate remove Remove user-wide integration\n" " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n" - " vcpkg integrate powershell Enable PowerShell Tab-Completion\n"; + " vcpkg integrate powershell Enable PowerShell tab-completion\n"; #else const char* const INTEGRATE_COMMAND_HELPSTRING = " vcpkg integrate install Make installed packages available user-wide.\n" - " vcpkg integrate remove Remove user-wide integration\n"; + " vcpkg integrate remove Remove user-wide integration\n" + " vcpkg integrate bash Enable bash tab-completion\n"; #endif namespace Subcommand @@ -478,7 +477,15 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console static std::vector<std::string> valid_arguments(const VcpkgPaths&) { - return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT, Subcommand::POWERSHELL, Subcommand::BASH}; + return + { + Subcommand::INSTALL, Subcommand::REMOVE, +#if defined(_WIN32) + Subcommand::PROJECT, Subcommand::POWERSHELL, +#else + Subcommand::BASH, +#endif + }; } const CommandStructure COMMAND_STRUCTURE = { @@ -512,7 +519,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { return integrate_powershell(paths); } -#elif defined(__unix__) +#else if (args.command_arguments[0] == Subcommand::BASH) { return integrate_bash(paths); diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp index a0afd69e1..3d8387ee1 100644 --- a/toolsrc/src/vcpkg/commands.search.cpp +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -7,6 +7,9 @@ #include <vcpkg/paragraphs.h> #include <vcpkg/sourceparagraph.h> #include <vcpkg/vcpkglib.h> +#include <vcpkg/dependencies.h> + +using vcpkg::Dependencies::PathsPortFileProvider; namespace vcpkg::Commands::Search { @@ -63,7 +66,10 @@ namespace vcpkg::Commands::Search const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); const bool full_description = Util::Sets::contains(options.switches, OPTION_FULLDESC); - auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + PathsPortFileProvider provider(paths, args.overlay_ports.get()); + auto source_paragraphs = Util::fmap(provider.load_all_control_files(), [](auto&& port) -> const SourceControlFile * { + return port->source_control_file.get(); + }); if (args.command_arguments.empty()) { diff --git a/toolsrc/src/vcpkg/commands.upgrade.cpp b/toolsrc/src/vcpkg/commands.upgrade.cpp index 29815ca94..1e64b2eb6 100644 --- a/toolsrc/src/vcpkg/commands.upgrade.cpp +++ b/toolsrc/src/vcpkg/commands.upgrade.cpp @@ -43,7 +43,8 @@ namespace vcpkg::Commands::Upgrade StatusParagraphs status_db = database_load_check(paths); - Dependencies::PathsPortFileProvider provider(paths); + // Load ports from ports dirs + Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get()); Dependencies::PackageGraph graph(provider, status_db); // input sanitization @@ -85,12 +86,12 @@ namespace vcpkg::Commands::Upgrade not_installed.push_back(spec); } - auto maybe_scf = provider.get_control_file(spec.name()); - if (auto p_scf = maybe_scf.get()) + auto maybe_scfl = provider.get_control_file(spec.name()); + if (auto p_scfl = maybe_scfl.get()) { if (it != status_db.end()) { - if (p_scf->core_paragraph->version != (*it)->package.version) + if (p_scfl->source_control_file->core_paragraph->version != (*it)->package.version) { to_upgrade.push_back(spec); } @@ -170,7 +171,7 @@ namespace vcpkg::Commands::Upgrade } } - Dependencies::print_plan(plan, true); + Dependencies::print_plan(plan, true, paths.ports); if (!no_dry_run) { diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 8fde28929..b604c9acf 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -22,7 +22,7 @@ namespace vcpkg::Dependencies struct ClusterSource { - const SourceControlFile* scf = nullptr; + const SourceControlFileLocation* scfl = nullptr; std::unordered_map<std::string, std::vector<FeatureSpec>> build_edges; }; @@ -92,12 +92,12 @@ namespace vcpkg::Dependencies if (it == m_graph.end()) { // Load on-demand from m_provider - auto maybe_scf = m_provider.get_control_file(spec.name()); + auto maybe_scfl = m_provider.get_control_file(spec.name()); auto& clust = m_graph[spec]; clust.spec = spec; - if (auto p_scf = maybe_scf.get()) + if (auto p_scfl = maybe_scfl.get()) { - clust.source = cluster_from_scf(*p_scf, clust.spec.triplet()); + clust.source = cluster_from_scf(*p_scfl, clust.spec.triplet()); } return clust; } @@ -105,15 +105,17 @@ namespace vcpkg::Dependencies } private: - static ClusterSource cluster_from_scf(const SourceControlFile& scf, Triplet t) + static ClusterSource cluster_from_scf(const SourceControlFileLocation& scfl, Triplet t) { ClusterSource ret; - ret.build_edges.emplace("core", filter_dependencies_to_specs(scf.core_paragraph->depends, t)); + ret.build_edges.emplace("core", + filter_dependencies_to_specs(scfl.source_control_file->core_paragraph->depends, + t)); - for (const auto& feature : scf.feature_paragraphs) + for (const auto& feature : scfl.source_control_file->feature_paragraphs) ret.build_edges.emplace(feature->name, filter_dependencies_to_specs(feature->depends, t)); - ret.scf = &scf; + ret.scfl = &scfl; return ret; } @@ -121,6 +123,27 @@ namespace vcpkg::Dependencies const PortFileProvider& m_provider; }; + std::string to_output_string(RequestType request_type, + const CStringView s, + const Build::BuildPackageOptions& options, + const fs::path& install_port_path, + const fs::path& default_port_path) + { + if (!default_port_path.empty() + && !Strings::case_insensitive_ascii_starts_with(install_port_path.u8string(), + default_port_path.u8string())) + { + const char* const from_head = options.use_head_version == Build::UseHeadVersion::YES ? " (from HEAD)" : ""; + switch (request_type) + { + case RequestType::AUTO_SELECTED: return Strings::format(" * %s%s -- %s", s, from_head, install_port_path.u8string()); + case RequestType::USER_REQUESTED: return Strings::format(" %s%s -- %s", s, from_head, install_port_path.u8string()); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + return to_output_string(request_type, s, options); + } + std::string to_output_string(RequestType request_type, const CStringView s, const Build::BuildPackageOptions& options) @@ -129,7 +152,7 @@ namespace vcpkg::Dependencies switch (request_type) { - case RequestType::AUTO_SELECTED: return Strings::format(" * %s%s", s, from_head); + case RequestType::AUTO_SELECTED: return Strings::format(" * %s%s", s, from_head); case RequestType::USER_REQUESTED: return Strings::format(" %s%s", s, from_head); default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -139,7 +162,7 @@ namespace vcpkg::Dependencies { switch (request_type) { - case RequestType::AUTO_SELECTED: return Strings::format(" * %s", s); + case RequestType::AUTO_SELECTED: return Strings::format(" * %s", s); case RequestType::USER_REQUESTED: return Strings::format(" %s", s); default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -151,12 +174,12 @@ namespace vcpkg::Dependencies } InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& scf, + const SourceControlFileLocation& scfl, const std::set<std::string>& features, const RequestType& request_type, std::vector<PackageSpec>&& dependencies) : spec(spec) - , source_control_file(scf) + , source_control_file_location(scfl) , plan_type(InstallPlanType::BUILD_AND_INSTALL) , request_type(request_type) , build_options{} @@ -268,37 +291,145 @@ namespace vcpkg::Dependencies return left->spec.name() < right->spec.name(); } - MapPortFileProvider::MapPortFileProvider(const std::unordered_map<std::string, SourceControlFile>& map) : ports(map) - { - } + MapPortFileProvider::MapPortFileProvider(const std::unordered_map<std::string, SourceControlFileLocation>& map) + : ports(map) + {} - Optional<const SourceControlFile&> MapPortFileProvider::get_control_file(const std::string& spec) const + Optional<const SourceControlFileLocation&> MapPortFileProvider::get_control_file(const std::string& spec) const { auto scf = ports.find(spec); if (scf == ports.end()) return nullopt; return scf->second; } - PathsPortFileProvider::PathsPortFileProvider(const VcpkgPaths& paths) : ports(paths) {} + std::vector<const SourceControlFileLocation*> MapPortFileProvider::load_all_control_files() const + { + return Util::fmap(ports, [](auto&& kvpair) -> const SourceControlFileLocation * { return &kvpair.second; }); + } + + PathsPortFileProvider::PathsPortFileProvider(const vcpkg::VcpkgPaths& paths, + const std::vector<std::string>* ports_dirs_paths) + : filesystem(paths.get_filesystem()) + { + if (ports_dirs_paths) + { + for (auto&& overlay_path : *ports_dirs_paths) + { + if (!overlay_path.empty()) + { + auto overlay = fs::stdfs::canonical(fs::u8path(overlay_path)); + + Checks::check_exit(VCPKG_LINE_INFO, + filesystem.exists(overlay), + "Error: Path \"%s\" does not exist", + overlay.string()); + + Checks::check_exit(VCPKG_LINE_INFO, + fs::stdfs::is_directory(overlay), + "Error: Path \"%s\" must be a directory", + overlay.string()); + + ports_dirs.emplace_back(overlay); + } + } + } + ports_dirs.emplace_back(paths.ports); + } - Optional<const SourceControlFile&> PathsPortFileProvider::get_control_file(const std::string& spec) const + Optional<const SourceControlFileLocation&> PathsPortFileProvider::get_control_file(const std::string& spec) const { auto cache_it = cache.find(spec); if (cache_it != cache.end()) { return cache_it->second; } - Parse::ParseExpected<SourceControlFile> source_control_file = - Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); - if (auto scf = source_control_file.get()) + for (auto&& ports_dir : ports_dirs) { - auto it = cache.emplace(spec, std::move(*scf->get())); - return it.first->second; + // Try loading individual port + if (filesystem.exists(ports_dir / "CONTROL")) + { + auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir); + if (auto scf = maybe_scf.get()) + { + if (scf->get()->core_paragraph->name == spec) + { + SourceControlFileLocation scfl{ std::move(*scf), ports_dir }; + auto it = cache.emplace(spec, std::move(scfl)); + return it.first->second; + } + } + else + { + vcpkg::print_error_message(maybe_scf.error()); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Error: Failed to load port from %s", + spec, ports_dir.u8string()); + } + } + + auto found_scf = Paragraphs::try_load_port(filesystem, ports_dir / spec); + if (auto scf = found_scf.get()) + { + if (scf->get()->core_paragraph->name == spec) + { + SourceControlFileLocation scfl{ std::move(*scf), ports_dir / spec }; + auto it = cache.emplace(spec, std::move(scfl)); + return it.first->second; + } + } } + return nullopt; } + std::vector<const SourceControlFileLocation*> PathsPortFileProvider::load_all_control_files() const + { + // Reload cache with ports contained in all ports_dirs + cache.clear(); + std::vector<const SourceControlFileLocation*> ret; + for (auto&& ports_dir : ports_dirs) + { + // Try loading individual port + if (filesystem.exists(ports_dir / "CONTROL")) + { + auto maybe_scf = Paragraphs::try_load_port(filesystem, ports_dir); + if (auto scf = maybe_scf.get()) + { + auto port_name = scf->get()->core_paragraph->name; + if (cache.find(port_name) == cache.end()) + { + SourceControlFileLocation scfl{ std::move(*scf), ports_dir }; + auto it = cache.emplace(port_name, std::move(scfl)); + ret.emplace_back(&it.first->second); + } + } + else + { + vcpkg::print_error_message(maybe_scf.error()); + Checks::exit_with_message(VCPKG_LINE_INFO, + "Error: Failed to load port from %s", + ports_dir.u8string()); + } + continue; + } + + // Try loading all ports inside ports_dir + auto found_scf = Paragraphs::load_all_ports(filesystem, ports_dir); + for (auto&& scf : found_scf) + { + auto port_name = scf->core_paragraph->name; + if (cache.find(port_name) == cache.end()) + { + SourceControlFileLocation scfl{ std::move(scf), ports_dir / port_name }; + auto it = cache.emplace(port_name, std::move(scfl)); + ret.emplace_back(&it.first->second); + } + } + } + return ret; + } + std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db) { @@ -488,16 +619,18 @@ namespace vcpkg::Dependencies if (plus) return MarkPlusResult::SUCCESS; plus = true; - auto p_source = cluster.source.get(); - Checks::check_exit(VCPKG_LINE_INFO, - p_source != nullptr, - "Error: Cannot find definition for package `%s`.", - cluster.spec.name()); + const auto p_source = cluster.source.get(); + if (p_source == nullptr) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Cannot find definition for package `%s`.", cluster.spec.name()); + } + auto&& control_file = *p_source->scfl->source_control_file.get(); if (feature.empty()) { // Add default features for this package. This is an exact reference, so ignore prevent_default_features. - for (auto&& default_feature : p_source->scf->core_paragraph.get()->default_features) + for (auto&& default_feature : control_file.core_paragraph.get()->default_features) { auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); if (res != MarkPlusResult::SUCCESS) @@ -512,7 +645,7 @@ namespace vcpkg::Dependencies if (feature == "*") { - for (auto&& fpgh : p_source->scf->feature_paragraphs) + for (auto&& fpgh : control_file.feature_paragraphs) { auto res = mark_plus(fpgh->name, cluster, graph, graph_plan, prevent_default_features); @@ -589,7 +722,8 @@ namespace vcpkg::Dependencies // Check if any default features have been added auto& previous_df = p_installed->ipv.core->package.default_features; - for (auto&& default_feature : p_source->scf->core_paragraph->default_features) + auto&& control_file = *p_source->scfl->source_control_file.get(); + for (auto&& default_feature : control_file.core_paragraph->default_features) { if (std::find(previous_df.begin(), previous_df.end(), default_feature) == previous_df.end()) { @@ -634,7 +768,7 @@ namespace vcpkg::Dependencies /// <param name="map">Map of all source control files in the current environment.</param> /// <param name="specs">Feature specifications to resolve dependencies for.</param> /// <param name="status_db">Status of installed packages in the current environment.</param> - std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFile>& map, + std::vector<AnyAction> create_feature_install_plan(const std::unordered_map<std::string, SourceControlFileLocation>& map, const std::vector<FeatureSpec>& specs, const StatusParagraphs& status_db) { @@ -697,7 +831,11 @@ namespace vcpkg::Dependencies if (p_cluster->transient_uninstalled) { // If it will be transiently uninstalled, we need to issue a full installation command - auto pscf = p_cluster->source.value_or_exit(VCPKG_LINE_INFO).scf; + auto* pscfl = p_cluster->source.value_or_exit(VCPKG_LINE_INFO).scfl; + Checks::check_exit(VCPKG_LINE_INFO, + pscfl != nullptr, + "Error: Expected a SourceControlFileLocation to exist"); + auto&& scfl = *pscfl; auto dep_specs = Util::fmap(m_graph_plan->install_graph.adjacency_list(p_cluster), [](ClusterPtr const& p) { return p->spec; }); @@ -705,7 +843,7 @@ namespace vcpkg::Dependencies plan.emplace_back(InstallPlanAction{ p_cluster->spec, - *pscf, + scfl, p_cluster->to_install_features, p_cluster->request_type, std::move(dep_specs), @@ -776,7 +914,7 @@ namespace vcpkg::Dependencies PackageGraph::~PackageGraph() = default; - void print_plan(const std::vector<AnyAction>& action_plan, const bool is_recursive) + void print_plan(const std::vector<AnyAction>& action_plan, const bool is_recursive, const fs::path& default_ports_dir) { std::vector<const RemovePlanAction*> remove_plans; std::vector<const InstallPlanAction*> rebuilt_plans; @@ -831,8 +969,17 @@ namespace vcpkg::Dependencies std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); std::sort(excluded.begin(), excluded.end(), &InstallPlanAction::compare_by_name); - static auto actions_to_output_string = [](const std::vector<const InstallPlanAction*>& v) { - return Strings::join("\n", v, [](const InstallPlanAction* p) { + static auto actions_to_output_string = [&](const std::vector<const InstallPlanAction*>& v) { + return Strings::join("\n", v, [&](const InstallPlanAction* p) { + if (auto * pscfl = p->source_control_file_location.get()) + { + return to_output_string(p->request_type, + p->displayname(), + p->build_options, + pscfl->source_location, + default_ports_dir); + } + return to_output_string(p->request_type, p->displayname(), p->build_options); }); }; diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 433d7a1af..88c1526c5 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -141,12 +141,12 @@ namespace vcpkg::Export std::error_code ec; fs.create_directories(paths.buildsystems / "tmp", ec); - fs.write_contents(targets_redirect, targets_redirect_content); + fs.write_contents(targets_redirect, targets_redirect_content, VCPKG_LINE_INFO); const std::string nuspec_file_content = create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, nuget_version); const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec"; - fs.write_contents(nuspec_file_path, nuspec_file_content); + fs.write_contents(nuspec_file_path, nuspec_file_content, VCPKG_LINE_INFO); // -NoDefaultExcludes is needed for ".vcpkg-root" const auto cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", @@ -488,7 +488,10 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console // create the plan const StatusParagraphs status_db = database_load_check(paths); - Dependencies::PathsPortFileProvider provider(paths); + + // Load ports from ports dirs + Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get()); + std::vector<ExportPlanAction> export_plan = Dependencies::create_export_plan(opts.specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 84a054e0f..896f62661 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -111,10 +111,14 @@ namespace vcpkg::Help " vcpkg contact Display contact information to send feedback\n" "\n" "Options:\n" - " --triplet <t> Specify the target architecture triplet.\n" + " --triplet <t> Specify the target architecture triplet\n" " (default: " ENVVAR(VCPKG_DEFAULT_TRIPLET) // ", see 'vcpkg help triplet')\n" "\n" + " --overlay-ports=<path> Specify directories to be used when searching for ports\n" + "\n" + " --overlay-triplets=<path> Specify directories containing triplets files\n" + "\n" " --vcpkg-root <path> Specify the vcpkg root " "directory\n" " (default: " ENVVAR(VCPKG_ROOT) // @@ -137,7 +141,7 @@ namespace vcpkg::Help void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); if (args.command_arguments.empty()) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index adab4249f..de19c360a 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -138,7 +138,7 @@ namespace vcpkg::Install std::sort(output.begin(), output.end()); - fs.write_lines(listfile, output); + fs.write_lines(listfile, output, VCPKG_LINE_INFO); } static std::vector<file_pack> extract_files_in_triplet( @@ -330,9 +330,10 @@ namespace vcpkg::Install System::printf("Building package %s...\n", display_name_with_features); auto result = [&]() -> Build::ExtendedBuildResult { - const Build::BuildPackageConfig build_config{action.source_control_file.value_or_exit(VCPKG_LINE_INFO), + const auto& scfl = action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO); + const Build::BuildPackageConfig build_config{*scfl.source_control_file, action.spec.triplet(), - paths.port_dir(action.spec), + static_cast<fs::path>(scfl.source_location), action.build_options, action.feature_list}; return Build::build_package(paths, build_config, status_db); @@ -364,7 +365,12 @@ namespace vcpkg::Install const fs::path download_dir = paths.downloads; std::error_code ec; for (auto& p : fs.get_files_non_recursive(download_dir)) - if (!fs.is_directory(p)) fs.remove(p); + { + if (!fs.is_directory(p)) + { + fs.remove(p, VCPKG_LINE_INFO); + } + } } return {code, std::move(bcf)}; @@ -628,6 +634,8 @@ namespace vcpkg::Install const bool clean_after_build = Util::Sets::contains(options.switches, (OPTION_CLEAN_AFTER_BUILD)); const KeepGoing keep_going = to_keep_going(Util::Sets::contains(options.switches, OPTION_KEEP_GOING)); + auto& fs = paths.get_filesystem(); + // create the plan StatusParagraphs status_db = database_load_check(paths); @@ -645,13 +653,10 @@ namespace vcpkg::Install Build::FailOnTombstone::NO, }; - auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - std::unordered_map<std::string, SourceControlFile> scf_map; - for (auto&& port : all_ports) - scf_map[port->core_paragraph->name] = std::move(*port); - MapPortFileProvider provider(scf_map); + //// Load ports from ports dirs + PathsPortFileProvider provider(paths, args.overlay_ports.get()); - // Note: action_plan will hold raw pointers to SourceControlFiles from this map + // Note: action_plan will hold raw pointers to SourceControlFileLocations from this map std::vector<AnyAction> action_plan = create_feature_install_plan(provider, FullPackageSpec::to_feature_specs(specs), status_db); @@ -679,7 +684,7 @@ namespace vcpkg::Install Metrics::g_metrics.lock()->track_property("installplan", specs_string); - Dependencies::print_plan(action_plan, is_recursive); + Dependencies::print_plan(action_plan, is_recursive, paths.ports); if (dry_run) { @@ -703,7 +708,7 @@ namespace vcpkg::Install xunit_doc += summary.xunit_results(); xunit_doc += "</collection></assembly></assemblies>\n"; - paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunit_doc); + fs.write_contents(fs::u8path(it_xunit->second), xunit_doc, VCPKG_LINE_INFO); } for (auto&& result : summary.results) diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 5ca2b056a..9dd520ed6 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -9,8 +9,10 @@ #include <vcpkg/base/strings.h> #include <vcpkg/base/system.process.h> +#if defined(_WIN32) #pragma comment(lib, "version") #pragma comment(lib, "winhttp") +#endif namespace vcpkg::Metrics { diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index d6581c2b4..c760a034f 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -857,14 +857,15 @@ namespace vcpkg::PostBuildLint size_t perform_all_checks(const PackageSpec& spec, const VcpkgPaths& paths, const PreBuildInfo& pre_build_info, - const BuildInfo& build_info) + const BuildInfo& build_info, + const fs::path& port_dir) { System::print2("-- Performing post-build validation\n"); const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info); if (error_count != 0) { - const fs::path portfile = paths.ports / spec.name() / "portfile.cmake"; + const fs::path portfile = port_dir / "portfile.cmake"; System::print2(System::Color::error, "Found ", error_count, diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 685cdfdc3..a40b27bd7 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -111,7 +111,7 @@ namespace vcpkg::Remove } } - fs.remove(paths.listfile_path(ipv.core->package)); + fs.remove(paths.listfile_path(ipv.core->package), VCPKG_LINE_INFO); } for (auto&& spgh : spghs) @@ -229,7 +229,8 @@ namespace vcpkg::Remove Checks::exit_fail(VCPKG_LINE_INFO); } - Dependencies::PathsPortFileProvider provider(paths); + // Load ports from ports dirs + Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get()); specs = Util::fmap(Update::find_outdated_packages(provider, status_db), [](auto&& outdated) { return outdated.spec; }); diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index 2fdfbe0f2..4f4b23055 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -131,7 +131,10 @@ namespace vcpkg virtual const std::string& exe_stem() const = 0; virtual std::array<int, 3> default_min_version() const = 0; - virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const {} + virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const + { + Util::unused(out_candidate_paths); + } virtual Optional<std::string> get_version(const fs::path& path_to_exe) const = 0; }; @@ -406,6 +409,7 @@ git version 2.17.1.windows.2 virtual void add_special_paths(std::vector<fs::path>& out_candidate_paths) const override { + Util::unused(out_candidate_paths); // TODO: Uncomment later // const std::vector<fs::path> from_path = Files::find_from_PATH("installerbase"); // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp index 344192d59..6320bae5b 100644 --- a/toolsrc/src/vcpkg/update.cpp +++ b/toolsrc/src/vcpkg/update.cpp @@ -23,10 +23,10 @@ namespace vcpkg::Update for (auto&& ipv : installed_packages) { const auto& pgh = ipv.core; - auto maybe_scf = provider.get_control_file(pgh->package.spec.name()); - if (auto p_scf = maybe_scf.get()) + auto maybe_scfl = provider.get_control_file(pgh->package.spec.name()); + if (auto p_scfl = maybe_scfl.get()) { - auto&& port_version = p_scf->core_paragraph->version; + auto&& port_version = p_scfl->source_control_file->core_paragraph->version; auto&& installed_version = pgh->package.version; if (installed_version != port_version) { @@ -52,12 +52,12 @@ namespace vcpkg::Update void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); System::print2("Using local portfile versions. To update the local portfiles, use `git pull`.\n"); const StatusParagraphs status_db = database_load_check(paths); - Dependencies::PathsPortFileProvider provider(paths); + Dependencies::PathsPortFileProvider provider(paths, args.overlay_ports.get()); const auto outdated_packages = SortedVector<OutdatedPackage>(find_outdated_packages(provider, status_db), &OutdatedPackage::compare_by_name); diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp index 8565c28f9..3c1452d47 100644 --- a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -45,6 +45,25 @@ namespace vcpkg option_field = new_setting; } + static void parse_cojoined_multivalue(std::string new_value, + const std::string& option_name, + std::unique_ptr<std::vector<std::string>>& option_field) + { + if (new_value.empty()) + { + 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<std::vector<std::string>>(); + } + option_field->emplace_back(std::move(new_value)); + } + VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const CommandLineCharType* const* const argv) { @@ -117,6 +136,20 @@ namespace vcpkg parse_value(arg_begin, arg_end, "--triplet", args.triplet); continue; } + if (Strings::starts_with(arg, "--overlay-ports=")) + { + parse_cojoined_multivalue(arg.substr(sizeof("--overlay-ports=") - 1), + "--overlay-ports", + 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); @@ -166,7 +199,21 @@ namespace vcpkg const auto eq_pos = arg.find('='); if (eq_pos != std::string::npos) { - args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); + const auto& key = arg.substr(0, eq_pos); + const auto& value = arg.substr(eq_pos + 1); + + auto it = args.optional_command_arguments.find(key); + if (args.optional_command_arguments.end() == it) + { + args.optional_command_arguments.emplace(key, std::vector<std::string> { value }); + } + else + { + if (auto* maybe_values = it->second.get()) + { + maybe_values->emplace_back(value); + } + } } else { @@ -264,7 +311,51 @@ namespace vcpkg } else { - output.settings.emplace(option.name, it->second.value_or_exit(VCPKG_LINE_INFO)); + const auto& value = it->second.value_or_exit(VCPKG_LINE_INFO); + if (value.front().empty()) + { + // Fail when not given a value, e.g.: "vcpkg install sqlite3 --additional-ports=" + System::printf( + System::Color::error, "Error: The option '%s' must be passed an argument.\n", option.name); + failed = true; + } + else + { + output.settings.emplace(option.name, value.front()); + options_copy.erase(it); + } + } + } + } + + for (auto&& option : command_structure.options.multisettings) + { + const auto it = options_copy.find(option.name); + if (it != options_copy.end()) + { + if (!it->second.has_value()) + { + // Not having a string value indicates it was passed like '--a' + System::printf( + System::Color::error, "Error: The option '%s' must be passed an argument.\n", option.name); + failed = true; + } + else + { + const auto& value = it->second.value_or_exit(VCPKG_LINE_INFO); + for (auto&& v : value) + { + if (v.empty()) + { + System::printf( + System::Color::error, "Error: The option '%s' must be passed an argument.\n", option.name); + failed = true; + } + else + { + output.multisettings[option.name].emplace_back(v); + } + } options_copy.erase(it); } } @@ -306,7 +397,17 @@ namespace vcpkg { System::printf(" %-40s %s\n", (option.name + "=..."), option.short_help_text); } + for (auto&& option : command_structure.options.multisettings) + { + System::printf(" %-40s %s\n", (option.name + "=..."), option.short_help_text); + } System::printf(" %-40s %s\n", "--triplet <t>", "Set the default triplet for unqualified packages"); + System::printf(" %-40s %s\n", + "--overlay-ports=<path>", + "Specify directories to be used when searching for ports"); + System::printf(" %-40s %s\n", + "--overlay-triplets=<path>", + "Specify directories containing triplets files"); System::printf(" %-40s %s\n", "--vcpkg-root <path>", "Specify the vcpkg directory to use instead of current directory or tool directory"); diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp index c8e95dab1..2a52111a6 100644 --- a/toolsrc/src/vcpkg/vcpkglib.cpp +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -21,7 +21,7 @@ namespace vcpkg return StatusParagraphs(); } - fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file); + fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file, VCPKG_LINE_INFO); } auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO); @@ -72,15 +72,15 @@ namespace vcpkg } } - fs.write_contents(status_file_new, Strings::serialize(current_status_db)); + fs.write_contents(status_file_new, Strings::serialize(current_status_db), VCPKG_LINE_INFO); - fs.rename(status_file_new, status_file); + fs.rename(status_file_new, status_file, VCPKG_LINE_INFO); for (auto&& file : update_files) { if (!fs.is_regular_file(file)) continue; - fs.remove(file); + fs.remove(file, VCPKG_LINE_INFO); } return current_status_db; @@ -95,8 +95,8 @@ namespace vcpkg const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; const auto update_filename = paths.vcpkg_dir_updates / Strings::format("%010d", my_update_id); - fs.write_contents(tmp_update_filename, Strings::serialize(p)); - fs.rename(tmp_update_filename, update_filename); + fs.write_contents(tmp_update_filename, Strings::serialize(p), VCPKG_LINE_INFO); + fs.rename(tmp_update_filename, update_filename, VCPKG_LINE_INFO); } static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs, @@ -165,8 +165,8 @@ namespace vcpkg // Replace the listfile on disk const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated"; - fs.write_lines(updated_listfile_path, *lines); - fs.rename(updated_listfile_path, listfile_path); + fs.write_lines(updated_listfile_path, *lines, VCPKG_LINE_INFO); + fs.rename(updated_listfile_path, listfile_path, VCPKG_LINE_INFO); } std::vector<InstalledPackageView> get_installed_ports(const StatusParagraphs& status_db) diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 512bcfc35..909fbeb44 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -13,7 +13,9 @@ namespace vcpkg { - Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) + Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir, + const std::string& default_vs_path, + const std::vector<std::string>* triplets_dirs) { std::error_code ec; const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); @@ -76,14 +78,25 @@ 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; } fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } - fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } - fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } - fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const { return this->package_dir(spec) / "BUILD_INFO"; @@ -94,26 +107,47 @@ namespace vcpkg return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); } + bool VcpkgPaths::is_valid_triplet(const Triplet& t) const + { + const auto it = Util::find_if(this->get_available_triplets(), [&](auto&& available_triplet) { + return t.canonical_name() == available_triplet; + }); + return it != this->get_available_triplets().cend(); + } + const std::vector<std::string>& VcpkgPaths::get_available_triplets() const { return this->available_triplets.get_lazy([this]() -> std::vector<std::string> { std::vector<std::string> output; - for (auto&& path : this->get_filesystem().get_files_non_recursive(this->triplets)) + for (auto&& triplets_dir : triplets_dirs) { - output.push_back(path.stem().filename().string()); + for (auto&& path : this->get_filesystem().get_files_non_recursive(triplets_dir)) + { + output.push_back(path.stem().filename().string()); + } } - Util::sort(output); - + Util::sort_unique_erase(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) { - return t.canonical_name() == available_triplet; - }); - return it != this->get_available_triplets().cend(); + 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 |
