From 9c62c6a37ac940abbb4f19237d9a891881421a1a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 11 Oct 2018 22:03:05 -0700 Subject: Upgrades 2018.10.11 --- toolsrc/src/vcpkg/build.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7569f340f..9b97701ef 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -468,18 +468,18 @@ namespace vcpkg::Build const Triplet& triplet = config.triplet; const std::string& name = config.scf.core_paragraph->name; - std::vector abi_tag_entries; + std::vector abi_tag_entries(dependency_abis.begin(), dependency_abis.end()); abi_tag_entries.emplace_back(AbiEntry {"cmake", paths.get_tool_version(Tools::CMAKE)}); - abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); - abi_tag_entries.emplace_back( AbiEntry {"portfile", vcpkg::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( AbiEntry {"control", vcpkg::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); - abi_tag_entries.emplace_back(AbiEntry {"triplet", pre_build_info.triplet_abi_tag}); + abi_tag_entries.emplace_back(AbiEntry{"vcpkg_fixup_cmake_targets", "1"}); + + abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); const std::string features = Strings::join(";", config.feature_list); abi_tag_entries.emplace_back(AbiEntry {"features", features}); -- cgit v1.2.3 From ac1dd2022a1de05ee0a813f00346b1a9546ce03a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 26 Oct 2018 21:31:59 -0700 Subject: [vcpkg-edit] Don't launch the editor in a clean environment --- toolsrc/src/vcpkg/base/system.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index d95752bba..6797111c2 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -117,10 +117,7 @@ namespace vcpkg::System } #if defined(_WIN32) - static void windows_create_clean_process(const CStringView cmd_line, - const std::unordered_map& extra_env, - PROCESS_INFORMATION& process_info, - DWORD dwCreationFlags) noexcept + static std::wstring compute_clean_environment(const std::unordered_map& extra_env) { static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; @@ -173,9 +170,6 @@ namespace vcpkg::System L"NVCUDASAMPLES_ROOT", }; - // Flush stdout before launching external process - fflush(nullptr); - std::wstring env_cstr; for (auto&& env_wstring : env_wstrings) @@ -206,10 +200,27 @@ namespace vcpkg::System env_cstr.push_back(L'\0'); } + return env_cstr; + } +#endif + +#if defined(_WIN32) + /// If non-null, an environment block to use for the new process. If null, the new + /// process will inherit the current environment. + static void windows_create_process(const CStringView cmd_line, + const wchar_t* maybe_environment, + DWORD dwCreationFlags, + PROCESS_INFORMATION* process_info) noexcept + { + Checks::check_exit(VCPKG_LINE_INFO, process_info != nullptr); + STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); startup_info.cb = sizeof(STARTUPINFOW); + // Flush stdout before launching external process + fflush(nullptr); + // Wrapping the command in a single set of quotes causes cmd.exe to correctly execute const std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); Debug::println("CreateProcessW(%s)", actual_cmd_line); @@ -219,10 +230,10 @@ namespace vcpkg::System nullptr, FALSE, IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | dwCreationFlags, - env_cstr.data(), + (void*)maybe_environment, nullptr, &startup_info, - &process_info); + process_info); Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); } @@ -236,7 +247,7 @@ namespace vcpkg::System PROCESS_INFORMATION process_info; memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); - windows_create_clean_process(cmd_line, {}, process_info, DETACHED_PROCESS); + windows_create_process(cmd_line, nullptr, DETACHED_PROCESS, &process_info); CloseHandle(process_info.hThread); CloseHandle(process_info.hProcess); @@ -255,7 +266,8 @@ namespace vcpkg::System memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); GlobalState::g_ctrl_c_state.transition_to_spawn_process(); - windows_create_clean_process(cmd_line, extra_env, process_info, NULL); + auto clean_env = compute_clean_environment(extra_env); + windows_create_process(cmd_line, clean_env.c_str(), NULL, &process_info); CloseHandle(process_info.hThread); -- cgit v1.2.3 From 7136958e6a4d5100393bdc13ec09af0bacda481b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 28 Oct 2018 03:38:46 -0700 Subject: [vcpkg hash] Also try sha512sum --- toolsrc/src/vcpkg/base/hash.cpp | 53 +++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 10 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/hash.cpp b/toolsrc/src/vcpkg/base/hash.cpp index 31bd8d05e..276f15eb9 100644 --- a/toolsrc/src/vcpkg/base/hash.cpp +++ b/toolsrc/src/vcpkg/base/hash.cpp @@ -174,21 +174,25 @@ namespace vcpkg::Hash return hash_type.substr(3, hash_type.length() - 3); } - static std::string run_shasum_and_post_process(const std::string& cmd_line) + static Optional run_shasum(const std::string& cmd_line) { const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Failed to run:\n" - " %s", - cmd_line); + if (ec_data.exit_code == 0) + { + return ec_data.output; + } - std::vector split = Strings::split(ec_data.output, " "); + return nullopt; + } + + static std::string parse_shasum_output(const std::string& shasum_output) + { + std::vector split = Strings::split(shasum_output, " "); Checks::check_exit(VCPKG_LINE_INFO, split.size() == 3, "Expected output of the form [hash filename\n] (3 tokens), but got\n" "[%s] (%s tokens)", - ec_data.output, + shasum_output, std::to_string(split.size())); return split[0]; @@ -198,8 +202,23 @@ namespace vcpkg::Hash { const std::string digest_size = get_digest_size(hash_type); Checks::check_exit(VCPKG_LINE_INFO, fs.exists(path), "File %s does not exist", path.u8string()); + + if (digest_size == "512") + { + const std::string cmd_line = Strings::format(R"(sha512sum "%s")", path.u8string()); + const auto shasum_output = run_shasum(cmd_line); + if (auto s = shasum_output.get()) + { + return parse_shasum_output(*s); + } + } + const std::string cmd_line = Strings::format(R"(shasum -a %s "%s")", digest_size, path.u8string()); - return run_shasum_and_post_process(cmd_line); + const auto shasum_output = run_shasum(cmd_line); + if (auto s = shasum_output.get()) + { + return parse_shasum_output(*s); + } } std::string get_string_hash(const std::string& s, const std::string& hash_type) @@ -207,8 +226,22 @@ namespace vcpkg::Hash const std::string digest_size = get_digest_size(hash_type); verify_has_only_allowed_chars(s); + if (digest_size == "512") + { + const std::string cmd_line = Strings::format(R"(echo -n "%s" | sha512sum)", s); + const auto shasum_output = run_shasum(cmd_line); + if (auto s = shasum_output.get()) + { + return parse_shasum_output(*s); + } + } + const std::string cmd_line = Strings::format(R"(echo -n "%s" | shasum -a %s)", s, digest_size); - return run_shasum_and_post_process(cmd_line); + const auto shasum_output = run_shasum(cmd_line); + if (auto s = shasum_output.get()) + { + return parse_shasum_output(*s); + } } #endif } -- cgit v1.2.3 From 60eca2d4cd9aa7fe8412455899669b7155d66d26 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 29 Oct 2018 22:00:13 -0700 Subject: [vcpkg hash] Try all shaXXXsum tools --- toolsrc/src/vcpkg/base/hash.cpp | 57 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/hash.cpp b/toolsrc/src/vcpkg/base/hash.cpp index 276f15eb9..7a74371db 100644 --- a/toolsrc/src/vcpkg/base/hash.cpp +++ b/toolsrc/src/vcpkg/base/hash.cpp @@ -174,17 +174,6 @@ namespace vcpkg::Hash return hash_type.substr(3, hash_type.length() - 3); } - static Optional run_shasum(const std::string& cmd_line) - { - const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - if (ec_data.exit_code == 0) - { - return ec_data.output; - } - - return nullopt; - } - static std::string parse_shasum_output(const std::string& shasum_output) { std::vector split = Strings::split(shasum_output, " "); @@ -203,22 +192,27 @@ namespace vcpkg::Hash const std::string digest_size = get_digest_size(hash_type); Checks::check_exit(VCPKG_LINE_INFO, fs.exists(path), "File %s does not exist", path.u8string()); - if (digest_size == "512") + // Try hash-specific tools, like sha512sum { - const std::string cmd_line = Strings::format(R"(sha512sum "%s")", path.u8string()); - const auto shasum_output = run_shasum(cmd_line); - if (auto s = shasum_output.get()) + const auto ec_data = System::cmd_execute_and_capture_output( + Strings::format(R"(sha%ssum "%s")", digest_size, path.u8string())); + if (ec_data.exit_code == 0) { - return parse_shasum_output(*s); + return parse_shasum_output(ec_data.output); } } - const std::string cmd_line = Strings::format(R"(shasum -a %s "%s")", digest_size, path.u8string()); - const auto shasum_output = run_shasum(cmd_line); - if (auto s = shasum_output.get()) + // Try shasum { - return parse_shasum_output(*s); + const auto ec_data = System::cmd_execute_and_capture_output( + Strings::format(R"(shasum -a %s "%s")", digest_size, path.u8string())); + if (ec_data.exit_code == 0) + { + return parse_shasum_output(ec_data.output); + } } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not hash file %s with %s", path.u8string(), hash_type); } std::string get_string_hash(const std::string& s, const std::string& hash_type) @@ -226,22 +220,27 @@ namespace vcpkg::Hash const std::string digest_size = get_digest_size(hash_type); verify_has_only_allowed_chars(s); - if (digest_size == "512") + // Try hash-specific tools, like sha512sum { - const std::string cmd_line = Strings::format(R"(echo -n "%s" | sha512sum)", s); - const auto shasum_output = run_shasum(cmd_line); - if (auto s = shasum_output.get()) + const auto ec_data = + System::cmd_execute_and_capture_output(Strings::format(R"(echo -n "%s" | sha%ssum)", s, digest_size)); + if (ec_data.exit_code == 0) { - return parse_shasum_output(*s); + return parse_shasum_output(ec_data.output); } } - const std::string cmd_line = Strings::format(R"(echo -n "%s" | shasum -a %s)", s, digest_size); - const auto shasum_output = run_shasum(cmd_line); - if (auto s = shasum_output.get()) + // Try shasum { - return parse_shasum_output(*s); + const auto ec_data = System::cmd_execute_and_capture_output( + Strings::format(R"(echo -n "%s" | shasum -a %s)", s, digest_size)); + if (ec_data.exit_code == 0) + { + return parse_shasum_output(ec_data.output); + } } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not hash input string with %s", hash_type); } #endif } -- cgit v1.2.3 From 1c2c69529e0ca44bd2fa4da68507d07aa3f310a4 Mon Sep 17 00:00:00 2001 From: Mark Salisbury Date: Fri, 2 Nov 2018 17:20:02 -0600 Subject: When downloading a tool, print URL and filepath (#4640) I'm seeing the error below: Building package zlib[core]:x86-windows... A suitable version of git was not found (required v2.17.1). Downloading portable git v2.17.1... Downloading git... WinHttpSendRequest() failed: 12002 I suspect the WinHttpSendRequest error is due to being behind a proxy - most download issues seem to be this. Or perhaps because a sys admin somewhere has disabled WinInet, somehow. I don't know. I don't know how to debug WinHttpSendRequest(); a quick google search didn't help. By printing the URL that vcpkg is trying to download, and where it's trying to download to, I can pop the URL in my browser, save it at the location specified, and move on with my life. --- toolsrc/src/vcpkg/tools.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index 313b5997b..e28291428 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -191,6 +191,7 @@ namespace vcpkg if (!fs.exists(tool_data.download_path)) { System::println("Downloading %s...", tool_name); + System::println(" %s -> %s", tool_data.url, tool_data.download_path.string()); Downloads::download_file(fs, tool_data.url, tool_data.download_path, tool_data.sha512); System::println("Downloading %s... done.", tool_name); } -- cgit v1.2.3 From 315ef424f8a2e98e0c601360683d2d831e70918d Mon Sep 17 00:00:00 2001 From: crackedmind Date: Sun, 4 Nov 2018 02:15:07 +0300 Subject: [autocomplete] Add autocompletion for `vcpkg upgrade` --- toolsrc/src/vcpkg/commands.autocomplete.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 564404421..bded1ee39 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -56,6 +56,7 @@ namespace vcpkg::Commands::Autocomplete "cache", "version", "contact", + "upgrade" }; Util::unstable_keep_if(public_commands, [&](const std::string& s) { @@ -124,6 +125,7 @@ namespace vcpkg::Commands::Autocomplete CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, CommandEntry{"integrate", R"###(^integrate(\s+)(\S*)$)###", Integrate::COMMAND_STRUCTURE}, + CommandEntry{"upgrade", R"###(^upgrade(\s+)(\S*)$)###", Upgrade::COMMAND_STRUCTURE}, }; for (auto&& command : COMMANDS) -- cgit v1.2.3 From f194e98593ac5638a15cb4b9675f52e63d2ffaf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Rodr=C3=ADguez?= Date: Tue, 6 Nov 2018 22:48:34 -0300 Subject: added vscode autodetection in macOS (#4589) --- toolsrc/src/vcpkg/commands.edit.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index b9d9d8c1a..044ae1c47 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -107,9 +107,6 @@ namespace vcpkg::Commands::Edit void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; - static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; - auto& fs = paths.get_filesystem(); const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); @@ -129,6 +126,10 @@ namespace vcpkg::Commands::Edit candidate_paths.emplace_back(*editor_path); } +#ifdef _WIN32 + static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; + const auto& program_files = System::get_program_files_platform_bitness(); if (const fs::path* pf = program_files.get()) { @@ -153,6 +154,10 @@ namespace vcpkg::Commands::Edit const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); +#elif defined(__APPLE__) + candidate_paths.push_back(fs::path{"/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code"}); + candidate_paths.push_back(fs::path{"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"}); +#endif const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); if (it == candidate_paths.cend()) -- cgit v1.2.3 From 273b8ce3d0d3533f3b959a7ecf4b0aa1eef22cab Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 7 Nov 2018 17:10:51 -0800 Subject: [vcpkg-fetch] Switch back to 18.1.0; add hack in vcpkg.exe to map the hashes together. --- toolsrc/src/vcpkg/base/downloads.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/downloads.cpp b/toolsrc/src/vcpkg/base/downloads.cpp index 1d7b3527d..fad3ff119 100644 --- a/toolsrc/src/vcpkg/base/downloads.cpp +++ b/toolsrc/src/vcpkg/base/downloads.cpp @@ -102,7 +102,17 @@ namespace vcpkg::Downloads const fs::path& path, const std::string& sha512) { - const std::string actual_hash = vcpkg::Hash::get_file_hash(fs, path, "SHA512"); + std::string actual_hash = vcpkg::Hash::get_file_hash(fs, path, "SHA512"); + + // + // This is the NEW hash for 7zip + if (actual_hash == "a9dfaaafd15d98a2ac83682867ec5766720acf6e99d40d1a00d480692752603bf3f3742623f0ea85647a92374df" + "405f331afd6021c5cf36af43ee8db198129c0") + // This is the OLD hash for 7zip + actual_hash = "8c75314102e68d2b2347d592f8e3eb05812e1ebb525decbac472231633753f1d4ca31c8e6881a36144a8da26b257" + "1305b3ae3f4e2b85fc4a290aeda63d1a13b8"; + // + Checks::check_exit(VCPKG_LINE_INFO, sha512 == actual_hash, "File does not have the expected hash:\n" -- cgit v1.2.3 From f1eb3aa4b95540a8fb4a8e8d341e4c08136bd756 Mon Sep 17 00:00:00 2001 From: Mark Ian Holland Date: Wed, 14 Nov 2018 23:25:50 +0000 Subject: Vulkan port (#4664) * [Vulkan] Add a vulkan port based on the cuda port * Add VULKAN_SDK env variable to whitelist * * Added some additional diagnostic information * Corrected if NOT exists statement --- toolsrc/src/vcpkg/base/system.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 6797111c2..9c72f8401 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -168,6 +168,8 @@ namespace vcpkg::System L"CUDA_PATH", // Environmental variable generated automatically by CUDA after installation L"NVCUDASAMPLES_ROOT", + // Enables find_package(Vulkan) in CMake. Environmental variable generated by Vulkan SDK installer + L"VULKAN_SDK", }; std::wstring env_cstr; -- cgit v1.2.3 From 02839ae4a83d505bae17d5856ce851af29c89c65 Mon Sep 17 00:00:00 2001 From: "Billy O'Neal (VC LIBS)" Date: Thu, 15 Nov 2018 11:24:24 -0800 Subject: vcpkg was going out of its way to use partition before calling the container erase function which is slower than just using remove_if. remove_if is already stable, so separate stable and unstable versions are unnecessary. https://iterator.wordpress.com/2016/01/31/algorithms_0/ Unstable remove_if algorithms are possible that might win, as indicated in that article; but plain remove_if provides the most consistent behavior. --- toolsrc/src/vcpkg/build.cpp | 36 ++++++++++---------- toolsrc/src/vcpkg/commands.autocomplete.cpp | 52 ++++++++++++++--------------- toolsrc/src/vcpkg/postbuildlint.cpp | 33 +++++++++--------- toolsrc/src/vcpkg/statusparagraph.cpp | 2 +- toolsrc/src/vcpkg/vcpkgpaths.cpp | 10 +++--- toolsrc/src/vcpkg/visualstudio.cpp | 30 ++++++++--------- 6 files changed, 82 insertions(+), 81 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 9b97701ef..0e60fd50e 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -63,7 +63,7 @@ namespace vcpkg::Build::Command spec.name()); const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options { + const Build::BuildPackageOptions build_package_options{ Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO, @@ -76,8 +76,8 @@ namespace vcpkg::Build::Command std::set features_as_set(full_spec.features.begin(), full_spec.features.end()); features_as_set.emplace("core"); - const Build::BuildPackageConfig build_config { - *scf, spec.triplet(), fs::path {port_dir}, build_package_options, features_as_set}; + const Build::BuildPackageConfig build_config{ + *scf, spec.triplet(), fs::path{port_dir}, 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); @@ -470,22 +470,22 @@ namespace vcpkg::Build std::vector abi_tag_entries(dependency_abis.begin(), dependency_abis.end()); - abi_tag_entries.emplace_back(AbiEntry {"cmake", paths.get_tool_version(Tools::CMAKE)}); + abi_tag_entries.emplace_back(AbiEntry{"cmake", paths.get_tool_version(Tools::CMAKE)}); abi_tag_entries.emplace_back( - AbiEntry {"portfile", vcpkg::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); + AbiEntry{"portfile", vcpkg::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( - AbiEntry {"control", vcpkg::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); + AbiEntry{"control", vcpkg::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); abi_tag_entries.emplace_back(AbiEntry{"vcpkg_fixup_cmake_targets", "1"}); abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); const std::string features = Strings::join(";", config.feature_list); - abi_tag_entries.emplace_back(AbiEntry {"features", features}); + abi_tag_entries.emplace_back(AbiEntry{"features", features}); if (config.build_package_options.use_head_version == UseHeadVersion::YES) - abi_tag_entries.emplace_back(AbiEntry {"head", ""}); + abi_tag_entries.emplace_back(AbiEntry{"head", ""}); Util::sort(abi_tag_entries); @@ -503,7 +503,7 @@ namespace vcpkg::Build } auto abi_tag_entries_missing = abi_tag_entries; - Util::stable_keep_if(abi_tag_entries_missing, [](const AbiEntry& p) { return p.value.empty(); }); + Util::erase_remove_if(abi_tag_entries_missing, [](const AbiEntry& p) { return !p.value.empty(); }); if (abi_tag_entries_missing.empty()) { @@ -512,7 +512,7 @@ namespace vcpkg::Build const auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); - return AbiTagAndFile {Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; + return AbiTagAndFile{Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; } System::println( @@ -581,8 +581,8 @@ namespace vcpkg::Build Util::sort_unique_erase(dep_pspecs); // Find all features that aren't installed. This mutates required_fspecs. - Util::unstable_keep_if(required_fspecs, [&](FeatureSpec const& fspec) { - return !status_db.is_installed(fspec) && fspec.name() != name; + Util::erase_remove_if(required_fspecs, [&](FeatureSpec const& fspec) { + return status_db.is_installed(fspec) || fspec.name() == name; }); if (!required_fspecs.empty()) @@ -602,7 +602,7 @@ namespace vcpkg::Build const auto status_it = status_db.find_installed(pspec); Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); dependency_abis.emplace_back( - AbiEntry {status_it->get()->package.spec.name(), status_it->get()->package.abi}); + AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); } const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); @@ -648,7 +648,7 @@ namespace vcpkg::Build System::println("Could not locate cached archive: %s", 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); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); std::error_code ec; fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); @@ -685,7 +685,7 @@ namespace vcpkg::Build } return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile {}).tag, config); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); } const std::string& to_string(const BuildResult build_result) @@ -850,21 +850,21 @@ namespace vcpkg::Build if (variable_name == "VCPKG_PLATFORM_TOOLSET") { pre_build_info.platform_toolset = - variable_value.empty() ? nullopt : Optional {variable_value}; + variable_value.empty() ? nullopt : Optional{variable_value}; continue; } if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") { pre_build_info.visual_studio_path = - variable_value.empty() ? nullopt : Optional {variable_value}; + variable_value.empty() ? nullopt : Optional{variable_value}; continue; } if (variable_name == "VCPKG_CHAINLOAD_TOOLCHAIN_FILE") { pre_build_info.external_toolchain_file = - variable_value.empty() ? nullopt : Optional {variable_value}; + variable_value.empty() ? nullopt : Optional{variable_value}; continue; } diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index bded1ee39..3b353feec 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -40,27 +40,25 @@ namespace vcpkg::Commands::Autocomplete const std::string requested_command = match[1].str(); // First try public commands - std::vector public_commands = { - "install", - "search", - "remove", - "list", - "update", - "hash", - "help", - "integrate", - "export", - "edit", - "create", - "owns", - "cache", - "version", - "contact", - "upgrade" - }; - - Util::unstable_keep_if(public_commands, [&](const std::string& s) { - return Strings::case_insensitive_ascii_starts_with(s, requested_command); + std::vector public_commands = {"install", + "search", + "remove", + "list", + "update", + "hash", + "help", + "integrate", + "export", + "edit", + "create", + "owns", + "cache", + "version", + "contact", + "upgrade"}; + + Util::erase_remove_if(public_commands, [&](const std::string& s) { + return !Strings::case_insensitive_ascii_starts_with(s, requested_command); }); if (!public_commands.empty()) @@ -79,8 +77,8 @@ namespace vcpkg::Commands::Autocomplete "portsdiff", }; - Util::unstable_keep_if(private_commands, [&](const std::string& s) { - return Strings::case_insensitive_ascii_starts_with(s, requested_command); + Util::erase_remove_if(private_commands, [&](const std::string& s) { + return !Strings::case_insensitive_ascii_starts_with(s, requested_command); }); output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(private_commands)); @@ -99,8 +97,8 @@ namespace vcpkg::Commands::Autocomplete } std::vector triplets = paths.get_available_triplets(); - Util::unstable_keep_if(triplets, [&](const std::string& s) { - return Strings::case_insensitive_ascii_starts_with(s, triplet_prefix); + Util::erase_remove_if(triplets, [&](const std::string& s) { + return !Strings::case_insensitive_ascii_starts_with(s, triplet_prefix); }); auto result = combine_port_with_triplets(port_name, triplets); @@ -152,8 +150,8 @@ namespace vcpkg::Commands::Autocomplete } } - Util::unstable_keep_if(results, [&](const std::string& s) { - return Strings::case_insensitive_ascii_starts_with(s, prefix); + Util::erase_remove_if(results, [&](const std::string& s) { + return !Strings::case_insensitive_ascii_starts_with(s, prefix); }); if (command.name == "install" && results.size() == 1 && !is_option) diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 90dcb7d64..650b6e3c9 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -16,9 +16,9 @@ using vcpkg::Build::PreBuildInfo; namespace vcpkg::PostBuildLint { - static auto has_extension_pred(const Files::Filesystem& fs, const std::string& ext) + static auto not_extension_pred(const Files::Filesystem& fs, const std::string& ext) { - return [&fs, ext](const fs::path& path) { return !fs.is_directory(path) && path.extension() == ext; }; + return [&fs, ext](const fs::path& path) { return fs.is_directory(path) || path.extension() != ext; }; } enum class LintStatus @@ -104,8 +104,8 @@ namespace vcpkg::PostBuildLint std::vector files_found = fs.get_files_recursive(debug_include_dir); - Util::unstable_keep_if( - files_found, [&fs](const fs::path& path) { return !fs.is_directory(path) && path.extension() != ".ifc"; }); + Util::erase_remove_if( + files_found, [&fs](const fs::path& path) { return fs.is_directory(path) || path.extension() == ".ifc"; }); if (!files_found.empty()) { @@ -206,7 +206,7 @@ namespace vcpkg::PostBuildLint static LintStatus check_for_dlls_in_lib_dir(const Files::Filesystem& fs, const fs::path& package_dir) { std::vector dlls = fs.get_files_recursive(package_dir / "lib"); - Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); + Util::erase_remove_if(dlls, not_extension_pred(fs, ".dll")); if (!dlls.empty()) { @@ -280,7 +280,7 @@ namespace vcpkg::PostBuildLint static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir) { std::vector exes = fs.get_files_recursive(package_dir / "bin"); - Util::unstable_keep_if(exes, has_extension_pred(fs, ".exe")); + Util::erase_remove_if(exes, not_extension_pred(fs, ".exe")); if (!exes.empty()) { @@ -572,8 +572,8 @@ namespace vcpkg::PostBuildLint { std::vector empty_directories = fs.get_files_recursive(dir); - Util::unstable_keep_if(empty_directories, [&fs](const fs::path& current) { - return fs.is_directory(current) && fs.is_empty(current); + Util::erase_remove_if(empty_directories, [&fs](const fs::path& current) { + return !fs.is_directory(current) || !fs.is_empty(current); }); if (!empty_directories.empty()) @@ -707,12 +707,15 @@ namespace vcpkg::PostBuildLint static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir) { std::vector misplaced_files = fs.get_files_non_recursive(dir); - Util::unstable_keep_if(misplaced_files, [&fs](const fs::path& path) { + Util::erase_remove_if(misplaced_files, [&fs](const fs::path& path) { const std::string filename = path.filename().generic_string(); if (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") || Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO")) - return false; - return !fs.is_directory(path); + { + return true; + } + + return fs.is_directory(path); }); if (!misplaced_files.empty()) @@ -764,9 +767,9 @@ namespace vcpkg::PostBuildLint const fs::path release_bin_dir = package_dir / "bin"; std::vector debug_libs = fs.get_files_recursive(debug_lib_dir); - Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib")); + Util::erase_remove_if(debug_libs, not_extension_pred(fs, ".lib")); std::vector release_libs = fs.get_files_recursive(release_lib_dir); - Util::unstable_keep_if(release_libs, has_extension_pred(fs, ".lib")); + Util::erase_remove_if(release_libs, not_extension_pred(fs, ".lib")); if (!pre_build_info.build_type) error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs); @@ -780,9 +783,9 @@ namespace vcpkg::PostBuildLint } std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); - Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); + Util::erase_remove_if(debug_dlls, not_extension_pred(fs, ".dll")); std::vector release_dlls = fs.get_files_recursive(release_bin_dir); - Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); + Util::erase_remove_if(release_dlls, not_extension_pred(fs, ".dll")); switch (build_info.library_linkage) { diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp index 462d8d8ed..86946a31a 100644 --- a/toolsrc/src/vcpkg/statusparagraph.cpp +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -105,7 +105,7 @@ namespace vcpkg { dep.erase(std::find(dep.begin(), dep.end(), '['), dep.end()); } - Util::unstable_keep_if(deps, [&](auto&& e) { return e != l_spec.name(); }); + Util::erase_remove_if(deps, [&](auto&& e) { return e == l_spec.name(); }); // Util::sort_unique_erase(deps); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 748fd20e0..9a51818e8 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -137,8 +137,8 @@ namespace vcpkg if (tsv && vsp) { - Util::stable_keep_if( - candidates, [&](const Toolset* t) { return *tsv == t->version && *vsp == t->visual_studio_root_path; }); + Util::erase_remove_if( + candidates, [&](const Toolset* t) { return *tsv != t->version || *vsp != t->visual_studio_root_path; }); Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instance at %s with %s toolset.", @@ -151,7 +151,7 @@ namespace vcpkg if (tsv) { - Util::stable_keep_if(candidates, [&](const Toolset* t) { return *tsv == t->version; }); + Util::erase_remove_if(candidates, [&](const Toolset* t) { return *tsv != t->version; }); Checks::check_exit( VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instance with %s toolset.", *tsv); } @@ -159,8 +159,8 @@ namespace vcpkg if (vsp) { const fs::path vs_root_path = *vsp; - Util::stable_keep_if(candidates, - [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); + Util::erase_remove_if(candidates, + [&](const Toolset* t) { return vs_root_path != t->visual_studio_root_path; }); Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instance at %s.", diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index e3656a7d2..51e6c22d1 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -130,9 +130,9 @@ namespace vcpkg::VisualStudio { // We want lexically_normal(), but it is not available // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash. Try both. - auto common7_tools = fs::path {*path_as_string}; - append_if_has_cl(fs::path {*path_as_string}.parent_path().parent_path()); - append_if_has_cl(fs::path {*path_as_string}.parent_path().parent_path().parent_path()); + auto common7_tools = fs::path{*path_as_string}; + append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path()); + append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path().parent_path()); } // VS2015 instance from Program Files @@ -143,7 +143,7 @@ namespace vcpkg::VisualStudio std::vector get_visual_studio_instances(const VcpkgPaths& paths) { - std::vector sorted {get_visual_studio_instances_internal(paths)}; + std::vector sorted{get_visual_studio_instances_internal(paths)}; std::sort(sorted.begin(), sorted.end(), VisualStudioInstance::preferred_first_comparator); return Util::fmap(sorted, [](const VisualStudioInstance& instance) { return instance.to_string(); }); } @@ -160,8 +160,8 @@ namespace vcpkg::VisualStudio std::vector found_toolsets; std::vector excluded_toolsets; - const SortedVector sorted {get_visual_studio_instances_internal(paths), - VisualStudioInstance::preferred_first_comparator}; + const SortedVector sorted{get_visual_studio_instances_internal(paths), + VisualStudioInstance::preferred_first_comparator}; const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; @@ -202,8 +202,8 @@ namespace vcpkg::VisualStudio // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; std::vector msvc_subdirectories = fs.get_files_non_recursive(msvc_path); - Util::unstable_keep_if(msvc_subdirectories, - [&fs](const fs::path& path) { return fs.is_directory(path); }); + Util::erase_remove_if(msvc_subdirectories, + [&fs](const fs::path& path) { return !fs.is_directory(path); }); // Sort them so that latest comes first std::sort( @@ -217,7 +217,7 @@ namespace vcpkg::VisualStudio paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - const Toolset v141_toolset { + const Toolset v141_toolset{ vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; const auto english_language_pack = dumpbin_path.parent_path() / "1033"; @@ -232,12 +232,12 @@ namespace vcpkg::VisualStudio if (v140_is_available) { - const Toolset v140_toolset {vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}; + const Toolset v140_toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}; found_toolsets.push_back(v140_toolset); } -- cgit v1.2.3 From 5f4af89cff6f32b8f754a6bf920632a898bc868c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 19 Nov 2018 17:16:29 -0800 Subject: [vcpkg] Improve error messages while installing --- toolsrc/src/vcpkg/dependencies.cpp | 60 +++++++++++++++++--------------------- toolsrc/src/vcpkg/tools.cpp | 2 -- 2 files changed, 27 insertions(+), 35 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 8fb35b0da..8f2b4eaef 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -488,26 +488,24 @@ namespace vcpkg::Dependencies if (plus) return MarkPlusResult::SUCCESS; plus = true; + auto p_source = cluster.source.get(); + if (!p_source) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Error: Cannot find definition for package `%s`.", cluster.spec.name()); + } + if (feature.empty()) { // Add default features for this package. This is an exact reference, so ignore prevent_default_features. - if (auto p_source = cluster.source.get()) + for (auto&& default_feature : p_source->scf->core_paragraph.get()->default_features) { - for (auto&& default_feature : p_source->scf->core_paragraph.get()->default_features) + auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); + if (res != MarkPlusResult::SUCCESS) { - auto res = mark_plus(default_feature, cluster, graph, graph_plan, prevent_default_features); - if (res != MarkPlusResult::SUCCESS) - { - return res; - } + return res; } } - else - { - Checks::exit_with_message(VCPKG_LINE_INFO, - "Error: Unable to install default features because can't find CONTROL for %s", - cluster.spec); - } // "core" is always required. return mark_plus("core", cluster, graph, graph_plan, prevent_default_features); @@ -515,28 +513,20 @@ namespace vcpkg::Dependencies if (feature == "*") { - if (auto p_source = cluster.source.get()) + for (auto&& fpgh : p_source->scf->feature_paragraphs) { - for (auto&& fpgh : p_source->scf->feature_paragraphs) - { - auto res = mark_plus(fpgh->name, cluster, graph, graph_plan, prevent_default_features); + auto res = mark_plus(fpgh->name, cluster, graph, graph_plan, prevent_default_features); - Checks::check_exit(VCPKG_LINE_INFO, - res == MarkPlusResult::SUCCESS, - "Error: Unable to locate feature %s in %s", - fpgh->name, - cluster.spec); - } + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Internal error while installing feature %s in %s", + fpgh->name, + cluster.spec); + } - auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); + auto res = mark_plus("core", cluster, graph, graph_plan, prevent_default_features); - Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); - } - else - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Unable to handle '*' because can't find CONTROL for %s", cluster.spec); - } + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); return MarkPlusResult::SUCCESS; } @@ -643,7 +633,7 @@ namespace vcpkg::Dependencies } /// Figure out which actions are required to install features specifications in `specs`. - /// Map of all source files in the current environment. + /// Map of all source control files in the current environment. /// Feature specifications to resolve dependencies for. /// Status of installed packages in the current environment. std::vector create_feature_install_plan(const std::unordered_map& map, @@ -666,7 +656,11 @@ namespace vcpkg::Dependencies auto res = mark_plus(spec.feature(), spec_cluster, *m_graph, *m_graph_plan, prevent_default_features); - Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: `%s` is not a feature of package `%s`", + spec.feature(), + spec.name()); m_graph_plan->install_graph.add_vertex(ClusterPtr{&spec_cluster}); } diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index e28291428..f4ee2d653 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -193,7 +193,6 @@ namespace vcpkg System::println("Downloading %s...", tool_name); System::println(" %s -> %s", tool_data.url, tool_data.download_path.string()); Downloads::download_file(fs, tool_data.url, tool_data.download_path, tool_data.sha512); - System::println("Downloading %s... done.", tool_name); } else { @@ -204,7 +203,6 @@ namespace vcpkg { System::println("Extracting %s...", tool_name); Archives::extract_archive(paths, tool_data.download_path, tool_data.tool_dir_path); - System::println("Extracting %s... done.", tool_name); } else { -- cgit v1.2.3 From 7a931c922fea21264596c3b790b21913933954fb Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 20 Nov 2018 19:11:50 -0800 Subject: Use Checks::check_exit() --- toolsrc/src/vcpkg/dependencies.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 8f2b4eaef..60c43e4a8 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -489,11 +489,10 @@ namespace vcpkg::Dependencies plus = true; auto p_source = cluster.source.get(); - if (!p_source) - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Error: Cannot find definition for package `%s`.", cluster.spec.name()); - } + Checks::check_exit(VCPKG_LINE_INFO, + p_source != nullptr, + "Error: Cannot find definition for package `%s`.", + cluster.spec.name()); if (feature.empty()) { -- cgit v1.2.3 From 105622619dcb11dc91c3fdf3a8cb9d4b4c87bbf9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Nov 2018 14:17:58 -0800 Subject: [vcpkg] Enable major version greater than 15 --- toolsrc/src/vcpkg/visualstudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index 51e6c22d1..83a530a10 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -170,7 +170,7 @@ namespace vcpkg::VisualStudio for (const VisualStudioInstance& vs_instance : sorted) { const std::string major_version = vs_instance.major_version(); - if (major_version == "15") + if (major_version >= "15") { const fs::path vc_dir = vs_instance.root_path / "VC"; -- cgit v1.2.3 From f3b5ed1d24c79966158d20a03b019c4976a0215c Mon Sep 17 00:00:00 2001 From: Raynor Vliegendhart Date: Thu, 29 Nov 2018 03:22:05 +0100 Subject: Add IE Proxy fallback for Win7 (#4838) --- toolsrc/src/vcpkg/base/downloads.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/downloads.cpp b/toolsrc/src/vcpkg/base/downloads.cpp index fad3ff119..571562244 100644 --- a/toolsrc/src/vcpkg/base/downloads.cpp +++ b/toolsrc/src/vcpkg/base/downloads.cpp @@ -42,6 +42,28 @@ namespace vcpkg::Downloads 0); Checks::check_exit(VCPKG_LINE_INFO, hSession, "WinHttpOpen() failed: %d", GetLastError()); + // Win7 IE Proxy fallback + if (IsWindows7OrGreater() && !IsWindows8Point1OrGreater()) { + // First check if any proxy has been found automatically + WINHTTP_PROXY_INFO proxyInfo; + DWORD proxyInfoSize = sizeof(WINHTTP_PROXY_INFO); + auto noProxyFound = + !WinHttpQueryOption(hSession, WINHTTP_OPTION_PROXY, &proxyInfo, &proxyInfoSize) + || proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY; + + // If no proxy was found automatically, use IE's proxy settings, if any + if (noProxyFound) { + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; + if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) { + WINHTTP_PROXY_INFO proxy; + proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; + proxy.lpszProxy = ieProxy.lpszProxy; + proxy.lpszProxyBypass = ieProxy.lpszProxyBypass; + WinHttpSetOption(hSession, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); + } + } + } + // Use Windows 10 defaults on Windows 7 DWORD secure_protocols(WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2); -- cgit v1.2.3 From 5ff5ab7ae29313e95eab07172721800c5fa84c0c Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Fri, 7 Dec 2018 17:34:13 -0800 Subject: Remove constructor for type that was using aggregate initialization; in C++20 any user declared constructor means a type is no longer an aggregate. (#4906) --- toolsrc/src/vcpkg/postbuildlint.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 650b6e3c9..a62d4ece5 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -657,8 +657,6 @@ namespace vcpkg::PostBuildLint { fs::path file; OutdatedDynamicCrt outdated_crt; - - OutdatedDynamicCrtAndFile() = delete; }; static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, -- cgit v1.2.3 From cf7e2f3906f78dcb89f320a642428b54c00e4e0b Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Tue, 11 Dec 2018 11:48:41 -0800 Subject: Allow redirection of the downloads folder with an environment variable. (#4883) * Add detection for VCPKG_DOWNLOADS environment variable in vcpkgpaths.cpp. * Pass the downloads directory from VcpkgPaths to cmake. * Also fixup bootstrap on *nix. * Make error message a little prettier. * Make that bash script actually work :) * [vcpkg] Alter Optional<> usage style * [vcpkg-docs] Add section on Environment Variables to the docs --- toolsrc/src/vcpkg/build.cpp | 3 ++- toolsrc/src/vcpkg/vcpkgpaths.cpp | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 0e60fd50e..67d9b63ed 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -372,7 +372,8 @@ namespace vcpkg::Build {"TARGET_TRIPLET", spec.triplet().canonical_name()}, {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, {"VCPKG_USE_HEAD_VERSION", - Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + Util::Enum::to_bool(config.build_package_options.use_head_version) ? "1" : "0"}, + {"DOWNLOADS", paths.downloads}, {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, {"_VCPKG_DOWNLOAD_TOOL", to_string(config.build_package_options.download_tool)}, {"GIT", git_exe_path}, diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 9a51818e8..a92a5673e 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -34,7 +34,32 @@ namespace vcpkg paths.packages = paths.root / "packages"; paths.buildtrees = paths.root / "buildtrees"; - paths.downloads = paths.root / "downloads"; + + const auto overriddenDownloadsPath = System::get_environment_variable("VCPKG_DOWNLOADS"); + if (auto odp = overriddenDownloadsPath.get()) + { + auto asPath = fs::u8path(*odp); + if (!fs::stdfs::is_directory(asPath)) + { + Metrics::g_metrics.lock()->track_property("error", "Invalid VCPKG_DOWNLOADS override directory."); + Checks::exit_with_message( + VCPKG_LINE_INFO, + "Invalid downloads override directory: %s; " + "create that directory or unset VCPKG_DOWNLOADS to use the default downloads location.", + asPath.u8string()); + } + + paths.downloads = fs::stdfs::canonical(std::move(asPath), ec); + if (ec) + { + return ec; + } + } + else + { + paths.downloads = paths.root / "downloads"; + } + paths.ports = paths.root / "ports"; paths.installed = paths.root / "installed"; paths.triplets = paths.root / "triplets"; -- cgit v1.2.3 From 828cedb755d1ef1616e4e134bf1c6ef1ee2ae389 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 11 Dec 2018 10:15:44 -0800 Subject: [vcpkg] Add support for muslc, static crt linkage, and forcing the system binaries for cmake and ninja --- toolsrc/src/vcpkg.cpp | 4 +++- toolsrc/src/vcpkg/tools.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 3589881a7..fc7283599 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -171,8 +171,10 @@ static void inner(const VcpkgCmdArguments& args) default_triplet = Triplet::from_canonical_name("x64-osx"); #elif defined(__FreeBSD__) default_triplet = Triplet::from_canonical_name("x64-freebsd"); -#else +#elif defined(__GLIBC__) default_triplet = Triplet::from_canonical_name("x64-linux"); +#else + default_triplet = Triplet::from_canonical_name("x64-linux-musl"); #endif } } diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index f4ee2d653..c623d816d 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -253,6 +253,11 @@ namespace vcpkg static PathAndVersion get_path(const VcpkgPaths& paths) { + if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) + { + return {"cmake", "0"}; + } + std::vector candidate_paths; #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); @@ -317,6 +322,11 @@ namespace vcpkg static PathAndVersion get_path(const VcpkgPaths& paths) { + if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) + { + return {"ninja", "0"}; + } + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "ninja"); std::vector candidate_paths; -- cgit v1.2.3 From fed9a245268df9591a4150fb1f916df0894ca9d3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 13 Dec 2018 13:49:24 -0800 Subject: [autocomplete] Add tab-completion support for bash --- toolsrc/src/vcpkg/commands.integrate.cpp | 52 ++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 82172e363..c1d3a8c8d 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include +#include #include #include #include @@ -122,7 +123,7 @@ namespace vcpkg::Commands::Integrate static ElevationPromptChoice elevated_cmd_execute(const std::string& param) { - SHELLEXECUTEINFOW sh_ex_info{}; + SHELLEXECUTEINFOW sh_ex_info {}; sh_ex_info.cbSize = sizeof(sh_ex_info); sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; sh_ex_info.hwnd = nullptr; @@ -404,6 +405,47 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console Checks::exit_with_code(VCPKG_LINE_INFO, rc); } +#elif defined(__unix__) + static void integrate_bash(const VcpkgPaths& paths) + { + const auto home_path = System::get_environment_variable("HOME").value_or_exit(VCPKG_LINE_INFO); + const fs::path bashrc_path = fs::path {home_path} / ".bashrc"; + + auto& fs = paths.get_filesystem(); + const fs::path completion_script_path = paths.scripts / "vcpkg_completion.bash"; + + Expected> maybe_bashrc_content = fs.read_lines(bashrc_path); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_bashrc_content.has_value(), "Unable to read %s", bashrc_path.u8string()); + + std::vector bashrc_content = maybe_bashrc_content.value_or_exit(VCPKG_LINE_INFO); + + std::vector matches; + for (auto&& line : bashrc_content) + { + std::smatch match; + if (std::regex_match(line, match, std::regex {R"###(^source.*scripts/vcpkg_completion.bash$)###"})) + { + matches.push_back(line); + } + } + + if (!matches.empty()) + { + System::print("vcpkg bash completion is already imported to your %s file.\n" + "The following entries were found:\n" + " %s\n" + "Please make sure you have started a new bash shell for the changes to take effect.\n", + bashrc_path.u8string(), + Strings::join("\n ", matches)); + Checks::exit_success(VCPKG_LINE_INFO); + } + + System::print("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)); + Checks::exit_success(VCPKG_LINE_INFO); + } #endif #if defined(_WIN32) @@ -425,11 +467,12 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console static const std::string REMOVE = "remove"; static const std::string PROJECT = "project"; static const std::string POWERSHELL = "powershell"; + static const std::string BASH = "bash"; } static std::vector valid_arguments(const VcpkgPaths&) { - return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT, Subcommand::POWERSHELL}; + return {Subcommand::INSTALL, Subcommand::REMOVE, Subcommand::PROJECT, Subcommand::POWERSHELL, Subcommand::BASH}; } const CommandStructure COMMAND_STRUCTURE = { @@ -463,6 +506,11 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { return integrate_powershell(paths); } +#elif defined(__unix__) + if (args.command_arguments[0] == Subcommand::BASH) + { + return integrate_bash(paths); + } #endif Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); -- cgit v1.2.3 From 9cbdb33caf9975e5bd8b76da80df04d7cbfaa9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mendakiewicz?= Date: Mon, 17 Dec 2018 16:15:15 -0800 Subject: get_versions should return all versions so the best match can be found (#4945) * get_versions should return all versions so the best match can be found * [vcpkg] Consider more than one path when searching for system binaries --- toolsrc/src/vcpkg/archives.cpp | 6 +- toolsrc/src/vcpkg/tools.cpp | 483 +++++++++++++++++++---------------------- 2 files changed, 226 insertions(+), 263 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/archives.cpp b/toolsrc/src/vcpkg/archives.cpp index 8943893d6..38efedf87 100644 --- a/toolsrc/src/vcpkg/archives.cpp +++ b/toolsrc/src/vcpkg/archives.cpp @@ -8,7 +8,11 @@ namespace vcpkg::Archives void extract_archive(const VcpkgPaths& paths, const fs::path& archive, const fs::path& to_path) { Files::Filesystem& fs = paths.get_filesystem(); - const fs::path to_path_partial = to_path.u8string() + ".partial"; + const fs::path to_path_partial = to_path.u8string() + ".partial" +#if defined(_WIN32) + + "." + std::to_string(GetCurrentProcessId()) +#endif + ; std::error_code ec; fs.remove_all(to_path, ec); diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index c623d816d..365271872 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -44,7 +44,7 @@ namespace vcpkg return result; } - static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) + static ExpectedT parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) { #if defined(_WIN32) static constexpr StringLiteral OS_STRING = "windows"; @@ -53,13 +53,13 @@ namespace vcpkg #elif defined(__linux__) static constexpr StringLiteral OS_STRING = "linux"; #else - return ToolData{}; + return std::string("operating system is unknown"); #endif #if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; - static const std::regex XML_VERSION_REGEX{R"###()###"}; + static const std::regex XML_VERSION_REGEX {R"###()###"}; static const std::string XML = paths.get_filesystem().read_contents(XML_PATH).value_or_exit(VCPKG_LINE_INFO); std::smatch match_xml_version; const bool has_xml_version = std::regex_search(XML.cbegin(), XML.cend(), match_xml_version, XML_VERSION_REGEX); @@ -67,22 +67,22 @@ namespace vcpkg has_xml_version, R"(Could not find in %s)", XML_VERSION, - XML_PATH.generic_string()); + XML_PATH.u8string()); Checks::check_exit(VCPKG_LINE_INFO, XML_VERSION == match_xml_version[1], "Expected %s version: [%s], but was [%s]. Please re-run bootstrap-vcpkg.", - XML_PATH.generic_string(), + XML_PATH.u8string(), XML_VERSION, match_xml_version[1]); - const std::regex tool_regex{Strings::format(R"###()###", tool, OS_STRING)}; + const std::regex tool_regex {Strings::format(R"###()###", tool, OS_STRING)}; std::smatch match_tool_entry; const bool has_tool_entry = std::regex_search(XML.cbegin(), XML.cend(), match_tool_entry, tool_regex); - Checks::check_exit(VCPKG_LINE_INFO, - has_tool_entry, - "Could not find entry for tool [%s] in %s", - tool, - XML_PATH.generic_string()); + if (!has_tool_entry) + { + return Strings::format( + "Could not find entry for tool %s in %s for os=%s", tool, XML_PATH.u8string(), OS_STRING); + } const std::string tool_data = StringRange::find_exactly_one_enclosed(XML, match_tool_entry[0], "").to_string(); @@ -106,13 +106,13 @@ namespace vcpkg const fs::path tool_dir_path = paths.tools / tool_dir_name; const fs::path exe_path = tool_dir_path / exe_relative_path; - return ToolData{*version.get(), - exe_path, - url, - paths.downloads / archive_name.value_or(exe_relative_path).to_string(), - archive_name.has_value(), - tool_dir_path, - sha512}; + return ToolData {*version.get(), + exe_path, + url, + paths.downloads / archive_name.value_or(exe_relative_path).to_string(), + archive_name.has_value(), + tool_dir_path, + sha512}; #endif } @@ -122,55 +122,43 @@ namespace vcpkg std::string version; }; - static Optional find_first_with_sufficient_version(const std::vector& candidates, - const std::array& expected_version) + struct ToolProvider { - const auto it = Util::find_if(candidates, [&](const PathAndVersion& candidate) { - const auto parsed_version = parse_version_string(candidate.version); - if (!parsed_version.has_value()) - { - return false; - } + virtual const std::string& tool_data_name() const = 0; + virtual const std::string& exe_stem() const = 0; + virtual std::array default_min_version() const = 0; - const std::array actual_version = *parsed_version.get(); - return actual_version[0] > expected_version[0] || - (actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) || - (actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] && - actual_version[2] >= expected_version[2]); - }); + virtual void add_special_paths(std::vector& out_candidate_paths) const {} + virtual Optional get_version(const fs::path& path_to_exe) const = 0; + }; - if (it == candidates.cend()) + static Optional find_first_with_sufficient_version(const Files::Filesystem& fs, + const ToolProvider& tool_provider, + const std::vector& candidates, + const std::array& expected_version) + { + for (auto&& candidate : candidates) { - return nullopt; + if (!fs.exists(candidate)) continue; + auto maybe_version = tool_provider.get_version(candidate); + const auto version = maybe_version.get(); + if (!version) continue; + const auto parsed_version = parse_version_string(*version); + if (!parsed_version) continue; + auto& actual_version = *parsed_version.get(); + const auto version_acceptable = + actual_version[0] > expected_version[0] || + (actual_version[0] == expected_version[0] && actual_version[1] > expected_version[1]) || + (actual_version[0] == expected_version[0] && actual_version[1] == expected_version[1] && + actual_version[2] >= expected_version[2]); + if (!version_acceptable) continue; + + return PathAndVersion {candidate, *version}; } - return *it; + return nullopt; } - struct VersionProvider - { - virtual Optional get_version(const fs::path& path_to_exe) const = 0; - - std::vector get_versions(const std::vector& candidate_paths) const - { - auto&& fs = Files::get_real_filesystem(); - - std::vector output; - for (auto&& p : candidate_paths) - { - if (!fs.exists(p)) continue; - auto maybe_version = this->get_version(p); - if (const auto version = maybe_version.get()) - { - output.emplace_back(PathAndVersion{p, *version}); - return output; - } - } - - return output; - } - }; - static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { const std::array& version = tool_data.version; @@ -220,76 +208,90 @@ namespace vcpkg } static PathAndVersion fetch_tool(const VcpkgPaths& paths, - const std::string& tool_name, - const ToolData& tool_data, - const VersionProvider& version_provider) + const ToolProvider& tool_provider, + const ToolData& tool_data) { - const auto downloaded_path = fetch_tool(paths, tool_name, tool_data); - const auto downloaded_version = version_provider.get_version(downloaded_path).value_or_exit(VCPKG_LINE_INFO); + const auto downloaded_path = fetch_tool(paths, tool_provider.tool_data_name(), tool_data); + const auto downloaded_version = tool_provider.get_version(downloaded_path).value_or_exit(VCPKG_LINE_INFO); return {downloaded_path, downloaded_version}; } - namespace CMake + static PathAndVersion get_path(const VcpkgPaths& paths, const ToolProvider& tool) { - struct CmakeVersionProvider : VersionProvider + auto& fs = paths.get_filesystem(); + + std::array min_version = tool.default_min_version(); + + std::vector candidate_paths; + auto maybe_tool_data = parse_tool_data_from_xml(paths, tool.tool_data_name()); + if (auto tool_data = maybe_tool_data.get()) { - Optional get_version(const fs::path& path_to_exe) const override - { - const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string()); - const auto rc = System::cmd_execute_and_capture_output(cmd); - if (rc.exit_code != 0) - { - return nullopt; - } + candidate_paths.push_back(tool_data->exe_path); + min_version = tool_data->version; + } - /* Sample output: - cmake version 3.10.2 + auto& exe_stem = tool.exe_stem(); + if (!exe_stem.empty()) + { + auto paths_from_path = fs.find_from_PATH(exe_stem); + candidate_paths.insert(candidate_paths.end(), paths_from_path.cbegin(), paths_from_path.cend()); + } - CMake suite maintained and supported by Kitware (kitware.com/cmake). - */ - return StringRange::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(); - } - }; + tool.add_special_paths(candidate_paths); - static PathAndVersion get_path(const VcpkgPaths& paths) + const auto maybe_path = find_first_with_sufficient_version(fs, tool, candidate_paths, min_version); + if (const auto p = maybe_path.get()) { - if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) - { - return {"cmake", "0"}; - } + return *p; + } + if (auto tool_data = maybe_tool_data.get()) + { + return fetch_tool(paths, tool, *tool_data); + } - std::vector candidate_paths; -#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "cmake"); - candidate_paths.push_back(TOOL_DATA.exe_path); -#else - static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; -#endif - const std::vector from_path = paths.get_filesystem().find_from_PATH("cmake"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + Checks::exit_with_message(VCPKG_LINE_INFO, maybe_tool_data.error()); + } + + struct CMakeProvider : ToolProvider + { + std::string m_exe = "cmake"; + + virtual const std::string& tool_data_name() const override { return m_exe; } + virtual const std::string& exe_stem() const override { return m_exe; } + virtual std::array default_min_version() const override { return {3, 5, 1}; } + virtual void add_special_paths(std::vector& out_candidate_paths) const override + { +#if defined(_WIN32) const auto& program_files = System::get_program_files_platform_bitness(); - if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); + if (const auto pf = program_files.get()) out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); const auto& program_files_32_bit = System::get_program_files_32_bit(); if (const auto pf = program_files_32_bit.get()) - candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); - - const CmakeVersionProvider version_provider{}; - const std::vector candidates_with_versions = version_provider.get_versions(candidate_paths); - const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version); - if (const auto p = maybe_path.get()) + out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); +#endif + } + virtual Optional get_version(const fs::path& path_to_exe) const override + { + const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string()); + const auto rc = System::cmd_execute_and_capture_output(cmd); + if (rc.exit_code != 0) { - return *p; + return nullopt; } - return fetch_tool(paths, Tools::CMAKE, TOOL_DATA, version_provider); + /* Sample output: +cmake version 3.10.2 + +CMake suite maintained and supported by Kitware (kitware.com/cmake). + */ + return StringRange::find_exactly_one_enclosed(rc.output, "cmake version ", "\n").to_string(); } - } + }; static fs::path get_7za_path(const VcpkgPaths& paths) { #if defined(_WIN32) - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); + static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip").value_or_exit(VCPKG_LINE_INFO); if (!paths.get_filesystem().exists(TOOL_DATA.exe_path)) { return fetch_tool(paths, "7zip", TOOL_DATA); @@ -300,195 +302,131 @@ namespace vcpkg #endif } - namespace Ninja + struct NinjaProvider : ToolProvider { - struct NinjaVersionProvider : VersionProvider - { - Optional get_version(const fs::path& path_to_exe) const override - { - const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string()); - const auto rc = System::cmd_execute_and_capture_output(cmd); - if (rc.exit_code != 0) - { - return nullopt; - } + std::string m_exe = "ninja"; - /* Sample output: - 1.8.2 - */ - return rc.output; - } - }; + virtual const std::string& tool_data_name() const override { return m_exe; } + virtual const std::string& exe_stem() const override { return m_exe; } + virtual std::array default_min_version() const override { return {3, 5, 1}; } - static PathAndVersion get_path(const VcpkgPaths& paths) + virtual Optional get_version(const fs::path& path_to_exe) const override { - if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) - { - return {"ninja", "0"}; - } - - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "ninja"); - - std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.exe_path); - const std::vector from_path = paths.get_filesystem().find_from_PATH("ninja"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - const NinjaVersionProvider version_provider{}; - const std::vector candidates_with_versions = version_provider.get_versions(candidate_paths); - const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version); - if (const auto p = maybe_path.get()) + const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string()); + const auto rc = System::cmd_execute_and_capture_output(cmd); + if (rc.exit_code != 0) { - return *p; + return nullopt; } - return fetch_tool(paths, Tools::NINJA, TOOL_DATA, version_provider); + /* Sample output: +1.8.2 + */ + return rc.output; } - } + }; - namespace Nuget + struct NuGetProvider : ToolProvider { - struct NugetVersionProvider : VersionProvider - { - Optional get_version(const fs::path& path_to_exe) const override - { - const std::string cmd = Strings::format(R"("%s")", path_to_exe.u8string()); - const auto rc = System::cmd_execute_and_capture_output(cmd); - if (rc.exit_code != 0) - { - return nullopt; - } + std::string m_exe = "nuget"; - /* Sample output: - NuGet Version: 4.6.2.5055 - usage: NuGet [args] [options] - Type 'NuGet help ' for help on a specific command. - - [[[List of available commands follows]]] - */ - return StringRange::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(); - } - }; + virtual const std::string& tool_data_name() const override { return m_exe; } + virtual const std::string& exe_stem() const override { return m_exe; } + virtual std::array default_min_version() const override { return {4, 6, 2}; } - static PathAndVersion get_path(const VcpkgPaths& paths) + virtual Optional get_version(const fs::path& path_to_exe) const override { - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "nuget"); - - std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.exe_path); - const std::vector from_path = paths.get_filesystem().find_from_PATH("nuget"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - const NugetVersionProvider version_provider{}; - const std::vector candidates_with_versions = version_provider.get_versions(candidate_paths); - const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version); - if (const auto p = maybe_path.get()) + const std::string cmd = Strings::format(R"("%s")", path_to_exe.u8string()); + const auto rc = System::cmd_execute_and_capture_output(cmd); + if (rc.exit_code != 0) { - return *p; + return nullopt; } - return fetch_tool(paths, Tools::NUGET, TOOL_DATA, version_provider); + /* Sample output: +NuGet Version: 4.6.2.5055 +usage: NuGet [args] [options] +Type 'NuGet help ' for help on a specific command. + +[[[List of available commands follows]]] + */ + return StringRange::find_exactly_one_enclosed(rc.output, "NuGet Version: ", "\n").to_string(); } - } + }; - namespace Git + struct GitProvider : ToolProvider { - struct GitVersionProvider : VersionProvider - { - Optional get_version(const fs::path& path_to_exe) const override - { - const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string()); - const auto rc = System::cmd_execute_and_capture_output(cmd); - if (rc.exit_code != 0) - { - return nullopt; - } + std::string m_exe = "git"; - /* Sample output: - git version 2.17.1.windows.2 - */ - const auto idx = rc.output.find("git version "); - Checks::check_exit(VCPKG_LINE_INFO, - idx != std::string::npos, - "Unexpected format of git version string: %s", - rc.output); - return rc.output.substr(idx); - } - }; + virtual const std::string& tool_data_name() const override { return m_exe; } + virtual const std::string& exe_stem() const override { return m_exe; } + virtual std::array default_min_version() const override { return {2, 7, 4}; } - static PathAndVersion get_path(const VcpkgPaths& paths) + virtual void add_special_paths(std::vector& out_candidate_paths) const { - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "git"); - - std::vector candidate_paths; #if defined(_WIN32) - candidate_paths.push_back(TOOL_DATA.exe_path); -#endif - const std::vector from_path = paths.get_filesystem().find_from_PATH("git"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - const auto& program_files = System::get_program_files_platform_bitness(); - if (const auto pf = program_files.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); + if (const auto pf = program_files.get()) out_candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); const auto& program_files_32_bit = System::get_program_files_32_bit(); - if (const auto pf = program_files_32_bit.get()) candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); + if (const auto pf = program_files_32_bit.get()) + out_candidate_paths.push_back(*pf / "git" / "cmd" / "git.exe"); +#endif + } - const GitVersionProvider version_provider{}; - const std::vector candidates_with_versions = version_provider.get_versions(candidate_paths); - const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version); - if (const auto p = maybe_path.get()) + virtual Optional get_version(const fs::path& path_to_exe) const override + { + const std::string cmd = Strings::format(R"("%s" --version)", path_to_exe.u8string()); + const auto rc = System::cmd_execute_and_capture_output(cmd); + if (rc.exit_code != 0) { - return *p; + return nullopt; } - return fetch_tool(paths, Tools::GIT, TOOL_DATA, version_provider); + /* Sample output: +git version 2.17.1.windows.2 + */ + const auto idx = rc.output.find("git version "); + Checks::check_exit( + VCPKG_LINE_INFO, idx != std::string::npos, "Unexpected format of git version string: %s", rc.output); + return rc.output.substr(idx); } - } + }; - namespace IfwInstallerBase + struct IfwInstallerBaseProvider : ToolProvider { - struct IfwInstallerBaseVersionProvider : VersionProvider - { - Optional get_version(const fs::path& path_to_exe) const override - { - const std::string cmd = Strings::format(R"("%s" --framework-version)", path_to_exe.u8string()); - const auto rc = System::cmd_execute_and_capture_output(cmd); - if (rc.exit_code != 0) - { - return nullopt; - } + std::string m_exe = ""; + std::string m_toolname = "installerbase"; - /* Sample output: - 3.1.81 - */ - return rc.output; - } - }; + virtual const std::string& tool_data_name() const override { return m_toolname; } + virtual const std::string& exe_stem() const override { return m_exe; } + virtual std::array default_min_version() const override { return {0, 0, 0}; } - static PathAndVersion get_path(const VcpkgPaths& paths) + virtual void add_special_paths(std::vector& out_candidate_paths) const { - static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "installerbase"); - - std::vector candidate_paths; - candidate_paths.push_back(TOOL_DATA.exe_path); // TODO: Uncomment later // const std::vector from_path = Files::find_from_PATH("installerbase"); // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / - // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" / - // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); - - const IfwInstallerBaseVersionProvider version_provider{}; - const std::vector candidates_with_versions = version_provider.get_versions(candidate_paths); - const auto maybe_path = find_first_with_sufficient_version(candidates_with_versions, TOOL_DATA.version); - if (const auto p = maybe_path.get()) + // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / + // "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / + // "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + } + + virtual Optional get_version(const fs::path& path_to_exe) const override + { + const std::string cmd = Strings::format(R"("%s" --framework-version)", path_to_exe.u8string()); + const auto rc = System::cmd_execute_and_capture_output(cmd); + if (rc.exit_code != 0) { - return *p; + return nullopt; } - return fetch_tool(paths, Tools::IFW_INSTALLER_BASE, TOOL_DATA, version_provider); + /* Sample output: +3.1.81 + */ + return rc.output; } - } + }; struct ToolCacheImpl final : ToolCache { @@ -506,12 +444,12 @@ namespace vcpkg tool == Tools::IFW_INSTALLER_BASE) return get_tool_pathversion(paths, tool).path; if (tool == Tools::IFW_BINARYCREATOR) - return IfwInstallerBase::get_path(paths).path.parent_path() / "binarycreator.exe"; + return get_tool_path(paths, Tools::IFW_INSTALLER_BASE).parent_path() / "binarycreator.exe"; if (tool == Tools::IFW_REPOGEN) - return IfwInstallerBase::get_path(paths).path.parent_path() / "repogen.exe"; + return get_tool_path(paths, Tools::IFW_INSTALLER_BASE).parent_path() / "repogen.exe"; // For other tools, we simply always auto-download them. - const ToolData tool_data = parse_tool_data_from_xml(paths, tool); + const ToolData tool_data = parse_tool_data_from_xml(paths, tool).value_or_exit(VCPKG_LINE_INFO); if (paths.get_filesystem().exists(tool_data.exe_path)) { return tool_data.exe_path; @@ -522,12 +460,33 @@ namespace vcpkg const PathAndVersion& get_tool_pathversion(const VcpkgPaths& paths, const std::string& tool) const { - return path_version_cache.get_lazy(tool, [&]() { - if (tool == Tools::CMAKE) return CMake::get_path(paths); - if (tool == Tools::GIT) return Git::get_path(paths); - if (tool == Tools::NINJA) return Ninja::get_path(paths); - if (tool == Tools::NUGET) return Nuget::get_path(paths); - if (tool == Tools::IFW_INSTALLER_BASE) return IfwInstallerBase::get_path(paths); + return path_version_cache.get_lazy(tool, [&]() -> PathAndVersion { + if (tool == Tools::CMAKE) + { + if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) + { + return {"cmake", "0"}; + } + return get_path(paths, CMakeProvider()); + } + if (tool == Tools::GIT) + { + if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) + { + return {"git", "0"}; + } + return get_path(paths, GitProvider()); + } + if (tool == Tools::NINJA) + { + if (System::get_environment_variable("VCPKG_FORCE_SYSTEM_BINARIES").has_value()) + { + return {"ninja", "0"}; + } + return get_path(paths, NinjaProvider()); + } + if (tool == Tools::NUGET) return get_path(paths, NuGetProvider()); + if (tool == Tools::IFW_INSTALLER_BASE) return get_path(paths, IfwInstallerBaseProvider()); Checks::exit_with_message(VCPKG_LINE_INFO, "Finding version for %s is not implemented yet.", tool); }); -- cgit v1.2.3 From b2996e1fd48842446a64443d057c576f819bda00 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Mon, 17 Dec 2018 16:45:09 -0800 Subject: Support custom Android NDK, better ABI specification (#4986) --- toolsrc/src/vcpkg/base/system.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 9c72f8401..8aa1db53c 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -170,6 +170,8 @@ namespace vcpkg::System L"NVCUDASAMPLES_ROOT", // Enables find_package(Vulkan) in CMake. Environmental variable generated by Vulkan SDK installer L"VULKAN_SDK", + // Enable targeted Android NDK + L"ANDROID_NDK_HOME", }; std::wstring env_cstr; -- cgit v1.2.3 From 2d63525a154cf6aba8db2014792eec62087fe1e6 Mon Sep 17 00:00:00 2001 From: ivysnow Date: Tue, 8 Jan 2019 08:03:35 +0800 Subject: [vcpkg] add support for FreeBSD (#4917) * [vcpkg] add support for FreeBSD * [x64-freebsd] Remove triplet because it is not currently in the set of supported triplets --- toolsrc/src/vcpkg/metrics.cpp | 2 ++ toolsrc/src/vcpkg/tools.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 2a73dba89..c34f30974 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -220,6 +220,8 @@ namespace vcpkg::Metrics "OSX", #elif defined(__linux__) "Linux", +#elif defined(__FreeBSD__) + "FreeBSD", #elif defined(__unix__) "Unix", #else diff --git a/toolsrc/src/vcpkg/tools.cpp b/toolsrc/src/vcpkg/tools.cpp index 365271872..b713b2752 100644 --- a/toolsrc/src/vcpkg/tools.cpp +++ b/toolsrc/src/vcpkg/tools.cpp @@ -52,11 +52,13 @@ namespace vcpkg static constexpr StringLiteral OS_STRING = "osx"; #elif defined(__linux__) static constexpr StringLiteral OS_STRING = "linux"; +#elif defined(__FreeBSD__) + static constexpr StringLiteral OS_STRING = "freebsd"; #else return std::string("operating system is unknown"); #endif -#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) +#if defined(_WIN32) || defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) static const std::string XML_VERSION = "2"; static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; static const std::regex XML_VERSION_REGEX {R"###()###"}; -- cgit v1.2.3 From 39b7876db496d2cae6ec8c2736a45db6319ad46f Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 18 Jan 2019 19:03:37 -0800 Subject: [vcpkg] Randomize topological sort in CI plans to allow concurrent builds to more efficiently interact --- toolsrc/src/vcpkg/commands.ci.cpp | 36 +++++++++++++++++++++++++++++++----- toolsrc/src/vcpkg/dependencies.cpp | 21 ++++++++++----------- 2 files changed, 41 insertions(+), 16 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 551eee27b..5ca962744 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -30,14 +31,16 @@ namespace vcpkg::Commands::CI static constexpr StringLiteral OPTION_EXCLUDE = "--exclude"; static constexpr StringLiteral OPTION_PURGE_TOMBSTONES = "--purge-tombstones"; static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; + static constexpr StringLiteral OPTION_RANDOMIZE = "--x-randomize"; static constexpr std::array CI_SETTINGS = {{ {OPTION_EXCLUDE, "Comma separated list of ports to skip"}, {OPTION_XUNIT, "File to output results in XUnit format (internal)"}, }}; - static constexpr std::array CI_SWITCHES = {{ + static constexpr std::array CI_SWITCHES = {{ {OPTION_DRY_RUN, "Print out plan without execution"}, + {OPTION_RANDOMIZE, "Randomize the install order"}, {OPTION_PURGE_TOMBSTONES, "Purge failure tombstones and retry building the ports"}, }}; @@ -69,7 +72,7 @@ namespace vcpkg::Commands::CI std::map abi_tag_map; std::set will_fail; - const Build::BuildPackageOptions install_plan_options = { + const Build::BuildPackageOptions build_options = { Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::YES, @@ -81,7 +84,9 @@ namespace vcpkg::Commands::CI vcpkg::Cache pre_build_info_cache; - auto action_plan = Dependencies::create_feature_install_plan(provider, fspecs, StatusParagraphs {}); + auto action_plan = Dependencies::create_feature_install_plan(provider, fspecs, {}, {}); + + auto timer = Chrono::ElapsedTimer::create_started(); for (auto&& action : action_plan) { @@ -94,7 +99,7 @@ namespace vcpkg::Commands::CI auto triplet = p->spec.triplet(); const Build::BuildPackageConfig build_config { - *scf, triplet, paths.port_dir(p->spec), install_plan_options, p->feature_list}; + *scf, triplet, paths.port_dir(p->spec), build_options, p->feature_list}; auto dependency_abis = Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry { @@ -174,6 +179,8 @@ namespace vcpkg::Commands::CI } } + System::print("Time to determine pass/fail: %s\n", timer.elapsed().to_string()); + return ret; } @@ -241,12 +248,31 @@ namespace vcpkg::Commands::CI for (auto&& fspec : fspecs) pgraph.install(fspec); + Dependencies::CreateInstallPlanOptions serialize_options; + + struct RandomizerInstance : Graphs::Randomizer + { + virtual int random(int i) override + { + if (i <= 1) return 0; + std::uniform_int_distribution d(0, i - 1); + return d(e); + } + + std::random_device e; + } randomizer_instance; + + if (Util::Sets::contains(options.switches, OPTION_RANDOMIZE)) + { + serialize_options.randomizer = &randomizer_instance; + } + auto action_plan = [&]() { int iterations = 0; do { bool inconsistent = false; - auto action_plan = pgraph.serialize(); + auto action_plan = pgraph.serialize(serialize_options); for (auto&& action : action_plan) { diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 60c43e4a8..19d8e7ae8 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -354,7 +354,7 @@ namespace vcpkg::Dependencies auto installed_ports = get_installed_ports(status_db); const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); + return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}, {}); } std::vector create_export_plan(const std::vector& specs, @@ -396,7 +396,7 @@ namespace vcpkg::Dependencies const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector toposort = - Graphs::topological_sort(specs, ExportAdjacencyProvider{status_db, specs_as_set}); + Graphs::topological_sort(specs, ExportAdjacencyProvider{status_db, specs_as_set}, {}); return toposort; } @@ -605,13 +605,10 @@ namespace vcpkg::Dependencies } } - /// Figure out which actions are required to install features specifications in `specs`. - /// Contains the ports of the current environment. - /// Feature specifications to resolve dependencies for. - /// Status of installed packages in the current environment. std::vector create_feature_install_plan(const PortFileProvider& provider, const std::vector& specs, - const StatusParagraphs& status_db) + const StatusParagraphs& status_db, + const CreateInstallPlanOptions& options) { std::unordered_set prevent_default_features; for (auto&& spec : specs) @@ -628,7 +625,7 @@ namespace vcpkg::Dependencies pgraph.install(spec, prevent_default_features); } - return pgraph.serialize(); + return pgraph.serialize(options); } /// Figure out which actions are required to install features specifications in `specs`. @@ -672,13 +669,15 @@ namespace vcpkg::Dependencies mark_minus(spec_cluster, *m_graph, *m_graph_plan, {}); } - std::vector PackageGraph::serialize() const + std::vector PackageGraph::serialize(const CreateInstallPlanOptions& options) const { auto remove_vertex_list = m_graph_plan->remove_graph.vertex_list(); - auto remove_toposort = Graphs::topological_sort(remove_vertex_list, m_graph_plan->remove_graph); + auto remove_toposort = + Graphs::topological_sort(remove_vertex_list, m_graph_plan->remove_graph, options.randomizer); auto insert_vertex_list = m_graph_plan->install_graph.vertex_list(); - auto insert_toposort = Graphs::topological_sort(insert_vertex_list, m_graph_plan->install_graph); + auto insert_toposort = + Graphs::topological_sort(insert_vertex_list, m_graph_plan->install_graph, options.randomizer); std::vector plan; -- cgit v1.2.3 From cde34211a506a2efc7483c41d937b31dc8e24666 Mon Sep 17 00:00:00 2001 From: Wim Leflere Date: Tue, 29 Jan 2019 22:40:47 +0100 Subject: Generate dependeny tree graph (#5185) * use dashed link for optional dependency * output full dependency tree * add warning if requested package does not exist * [vcpkg] Formatting * [vcpkg] Fix issue when parsing qualified dependencies Before this change, "harfbuzz[glib] (!x86)" would parse as "harfbuzz[glib]||!x86" instead of the desired "harfbuzz|glib|!x86" * [vcpkg] Improve depend-info handling of features and qualified dependencies. --- toolsrc/src/vcpkg/commands.dependinfo.cpp | 96 ++++++++++++++++++------------- toolsrc/src/vcpkg/sourceparagraph.cpp | 7 +-- 2 files changed, 59 insertions(+), 44 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp index 5f72e965b..455f3b7c5 100644 --- a/toolsrc/src/vcpkg/commands.dependinfo.cpp +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -12,16 +12,16 @@ namespace vcpkg::Commands::DependInfo constexpr StringLiteral OPTION_DOT = "--dot"; constexpr StringLiteral OPTION_DGML = "--dgml"; - constexpr std::array DEPEND_SWITCHES = { { - { OPTION_DOT, "Creates graph on basis of dot" }, - { OPTION_DGML, "Creates graph on basis of dgml" }, - } }; + constexpr std::array DEPEND_SWITCHES = {{ + {OPTION_DOT, "Creates graph on basis of dot"}, + {OPTION_DGML, "Creates graph on basis of dgml"}, + }}; const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string(R"###(depend-info [pat])###"), 0, - 1, - { DEPEND_SWITCHES,{} }, + SIZE_MAX, + {DEPEND_SWITCHES, {}}, nullptr, }; @@ -32,8 +32,7 @@ namespace vcpkg::Commands::DependInfo return output; } - std::string create_dot_as_string( - const std::vector>& source_control_files) + std::string create_dot_as_string(const std::vector>& source_control_files) { int empty_node_count = 0; @@ -53,7 +52,7 @@ namespace vcpkg::Commands::DependInfo s.append(Strings::format("%s;", name)); for (const Dependency& d : source_paragraph.depends) { - const std::string dependency_name = replace_dashes_with_underscore(d.name()); + const std::string dependency_name = replace_dashes_with_underscore(d.depend.name); s.append(Strings::format("%s -> %s;", name, dependency_name)); } } @@ -62,8 +61,7 @@ namespace vcpkg::Commands::DependInfo return s; } - std::string create_dgml_as_string( - const std::vector>& source_control_files) + std::string create_dgml_as_string(const std::vector>& source_control_files) { std::string s; s.append(""); @@ -79,16 +77,22 @@ namespace vcpkg::Commands::DependInfo // Iterate over dependencies. for (const Dependency& d : source_paragraph.depends) { - links.append(Strings::format("", name, d.name())); + if (d.qualifier.empty()) + links.append(Strings::format("", name, d.depend.name)); + else + links.append(Strings::format( + "", name, d.depend.name)); } // Iterate over feature dependencies. - const std::vector>& feature_paragraphs = source_control_file->feature_paragraphs; + const std::vector>& feature_paragraphs = + source_control_file->feature_paragraphs; for (const auto& feature_paragraph : feature_paragraphs) { for (const Dependency& d : feature_paragraph->depends) { - links.append(Strings::format("", name, d.name())); + links.append(Strings::format( + "", name, d.depend.name)); } } } @@ -101,9 +105,8 @@ namespace vcpkg::Commands::DependInfo return s; } - std::string create_graph_as_string( - const std::unordered_set& switches, - const std::vector>& source_control_files) + std::string create_graph_as_string(const std::unordered_set& switches, + const std::vector>& source_control_files) { if (Util::Sets::contains(switches, OPTION_DOT)) { @@ -116,35 +119,50 @@ namespace vcpkg::Commands::DependInfo return ""; } + void build_dependencies_list(std::set& packages_to_keep, + const std::string& requested_package, + const std::vector>& source_control_files) + { + const auto source_control_file = + Util::find_if(source_control_files, [&requested_package](const auto& source_control_file) { + return source_control_file->core_paragraph->name == requested_package; + }); + + if (source_control_file != source_control_files.end()) + { + const auto new_package = packages_to_keep.insert(requested_package).second; + + if (new_package) + { + for (const auto& dependency : (*source_control_file)->core_paragraph->depends) + { + build_dependencies_list(packages_to_keep, dependency.depend.name, source_control_files); + } + } + } + else + { + System::println(System::Color::warning, "package '%s' does not exist", requested_package); + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); auto source_control_files = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - if (args.command_arguments.size() == 1) + if (args.command_arguments.size() >= 1) { - const std::string filter = args.command_arguments.at(0); - - Util::erase_remove_if(source_control_files, - [&](const std::unique_ptr& source_control_file) { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - - if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) - { - return false; - } - - for (const Dependency& dependency : source_paragraph.depends) - { - if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) - { - return false; - } - } - - return true; - }); + std::set packages_to_keep; + for (const auto& requested_package : args.command_arguments) + { + build_dependencies_list(packages_to_keep, requested_package, source_control_files); + } + + Util::erase_remove_if(source_control_files, [&packages_to_keep](const auto& source_control_file) { + return !Util::Sets::contains(packages_to_keep, source_control_file->core_paragraph->name); + }); } if (!options.switches.empty()) diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index ed61cb42a..baa8b070b 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -194,16 +194,13 @@ namespace vcpkg auto pos = depend_string.find(' '); if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, ""); // expect of the form "\w+ \[\w+\]" - Dependency dep; - - dep.depend.name = depend_string.substr(0, pos); if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') { // Error, but for now just slurp the entire string. return Dependency::parse_dependency(depend_string, ""); } - dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); - return dep; + return Dependency::parse_dependency(depend_string.substr(0, pos), + depend_string.substr(pos + 2, depend_string.size() - pos - 3)); }); } -- cgit v1.2.3 From 660745956a59f58bc95b1802b2d08ddaeff37eb7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 25 Jan 2019 18:11:08 -0800 Subject: [boost][python3] Fix building with VS 2019 --- toolsrc/src/vcpkg/visualstudio.cpp | 54 +++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index 83a530a10..d2fccc716 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -12,6 +12,7 @@ namespace vcpkg::VisualStudio static constexpr CStringView V_120 = "v120"; static constexpr CStringView V_140 = "v140"; static constexpr CStringView V_141 = "v141"; + static constexpr CStringView V_142 = "v142"; struct VisualStudioInstance { @@ -213,35 +214,62 @@ namespace vcpkg::VisualStudio for (const fs::path& subdir : msvc_subdirectories) { + auto toolset_version_full = subdir.filename().u8string(); + auto toolset_version_prefix = toolset_version_full.substr(0, 4); + CStringView toolset_version; + std::string vcvars_option; + if (toolset_version_prefix.size() != 4) + { + // unknown toolset + continue; + } + else if (toolset_version_prefix[3] == '1') + { + toolset_version = V_141; + vcvars_option = "-vcvars_ver=14.1"; + } + else if (toolset_version_prefix[3] == '2') + { + toolset_version = V_142; + vcvars_option = "-vcvars_ver=14.2"; + } + else + { + // unknown toolset minor version + continue; + } const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - const Toolset v141_toolset{ - vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; + Toolset toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {vcvars_option}, + toolset_version, + supported_architectures}; const auto english_language_pack = dumpbin_path.parent_path() / "1033"; if (!fs.exists(english_language_pack)) { - excluded_toolsets.push_back(v141_toolset); - break; + excluded_toolsets.push_back(std::move(toolset)); + continue; } - found_toolsets.push_back(v141_toolset); + found_toolsets.push_back(std::move(toolset)); if (v140_is_available) { - const Toolset v140_toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}; - found_toolsets.push_back(v140_toolset); + found_toolsets.push_back({vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); } - break; + continue; } } -- cgit v1.2.3 From 74e0c1a7849a898ddd5bd6863bf191dc2a60ddef Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 29 Jan 2019 13:49:45 -0800 Subject: [vcpkg] Add additional checks for 32-bit hosted and targetting windows store when using VS2019 --- toolsrc/src/vcpkg/vcpkgpaths.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index a92a5673e..47994660c 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -192,6 +192,26 @@ namespace vcpkg vs_root_path.generic_string()); } + if (prebuildinfo.cmake_system_name == "WindowsStore") + { + // For now, cmake does not support VS 2019 when using the MSBuild generator. + Util::erase_remove_if(candidates, [&](const Toolset* t) { return t->version == "v142"; }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "With the current CMake version, UWP binaries can only be built with toolset version " + "v141 or below. Please install the v141 toolset in VS 2019."); + } + + if (System::get_host_processor() == System::CPUArchitecture::X86) + { + // For now, cmake does not support VS 2019 when using the MSBuild generator. + Util::erase_remove_if(candidates, [&](const Toolset* t) { return t->version == "v142"; }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "With the current CMake version, 32-bit machines can build with toolset version " + "v141 or below. Please install the v141 toolset in VS 2019."); + } + Checks::check_exit(VCPKG_LINE_INFO, !candidates.empty(), "No suitable Visual Studio instances were found"); return *candidates.front(); -- cgit v1.2.3 From 92bd67970d33ecdc1767c1dd042d73b7d1d998b0 Mon Sep 17 00:00:00 2001 From: Yang Shen Date: Fri, 1 Feb 2019 04:06:58 +0800 Subject: Adding #elif macros for ARM and ARM64 (#5232) --- toolsrc/src/vcpkg/base/system.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 8aa1db53c..b25412f7a 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -74,6 +74,10 @@ namespace vcpkg::System return CPUArchitecture::X64; #elif defined(__x86__) || defined(_M_X86) return CPUArchitecture::X86; +#elif defined(__arm__) || defined(_M_ARM) + return CPUArchitecture::ARM; +#elif defined(__aarch64__) || defined(_M_ARM64) + return CPUArchitecture::ARM64; #else #error "Unknown host architecture" #endif -- cgit v1.2.3 From 61e2cac730cc8b16c9373c6c463a335a21a1496a Mon Sep 17 00:00:00 2001 From: Phil Christensen Date: Fri, 1 Feb 2019 23:38:44 -0800 Subject: [vcpkg] improve port depend hash used in CI build also fixed a few unstable ports that somtimes fail in CI tests --- toolsrc/src/vcpkg/build.cpp | 1916 ++++++++++++++++++++++--------------------- 1 file changed, 975 insertions(+), 941 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 67d9b63ed..f39707065 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -1,941 +1,975 @@ -#include "pch.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using vcpkg::Build::BuildResult; -using vcpkg::Parse::ParseControlErrorInfo; -using vcpkg::Parse::ParseExpected; - -namespace vcpkg::Build::Command -{ - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - - static constexpr StringLiteral OPTION_CHECKS_ONLY = "--checks-only"; - - void perform_and_exit_ex(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const ParsedArguments& options, - const VcpkgPaths& paths) - { - const PackageSpec& spec = full_spec.package_spec; - 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); - Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); - Checks::exit_success(VCPKG_LINE_INFO); - } - - const ParseExpected 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, - "The Source field inside the CONTROL file does not match the port directory: '%s' != '%s'", - scf->core_paragraph->name, - spec.name()); - - const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{ - Build::UseHeadVersion::NO, - Build::AllowDownloads::YES, - Build::CleanBuildtrees::NO, - Build::CleanPackages::NO, - Build::DownloadTool::BUILT_IN, - GlobalState::g_binary_caching ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, - Build::FailOnTombstone::NO, - }; - - std::set features_as_set(full_spec.features.begin(), full_spec.features.end()); - features_as_set.emplace("core"); - - const Build::BuildPackageConfig build_config{ - *scf, spec.triplet(), fs::path{port_dir}, 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); - System::println("Elapsed time for package %s: %s", spec.to_string(), build_timer.to_string()); - - if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) - { - System::println(System::Color::error, - "The build command requires all dependencies to be already installed."); - System::println("The following dependencies are missing:"); - System::println(); - for (const auto& p : result.unmet_dependencies) - { - System::println(" %s", p); - } - System::println(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - Checks::check_exit(VCPKG_LINE_INFO, result.code != BuildResult::EXCLUDED); - - if (result.code != BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result.code, spec)); - System::println(Build::create_user_troubleshooting_message(spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - static constexpr std::array BUILD_SWITCHES = {{ - {OPTION_CHECKS_ONLY, "Only run checks, do not rebuild package"}, - }}; - - const CommandStructure COMMAND_STRUCTURE = { - Help::create_example_string("build zlib:x64-windows"), - 1, - 1, - {BUILD_SWITCHES, {}}, - nullptr, - }; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - // Build only takes a single package and all dependencies must already be installed - const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - const std::string command_argument = args.command_arguments.at(0); - const FullPackageSpec spec = - Input::check_and_get_full_package_spec(command_argument, default_triplet, COMMAND_STRUCTURE.example_text); - Input::check_triplet(spec.package_spec.triplet(), paths); - if (!spec.features.empty() && !GlobalState::feature_packages) - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); - } - perform_and_exit_ex(spec, paths.port_dir(spec.package_spec), options, paths); - } -} - -namespace vcpkg::Build -{ - static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; - static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; - static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; - static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; - static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; - - const std::string& to_string(BuildPolicy policy) - { - switch (policy) - { - case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; - case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; - case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; - case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; - case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - CStringView to_cmake_variable(BuildPolicy policy) - { - switch (policy) - { - case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; - case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; - case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; - case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; - case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - static const std::string NAME_BUILD_IN_DOWNLOAD = "BUILT_IN"; - static const std::string NAME_ARIA2_DOWNLOAD = "ARIA2"; - - const std::string& to_string(DownloadTool tool) - { - switch (tool) - { - case DownloadTool::BUILT_IN: return NAME_BUILD_IN_DOWNLOAD; - case DownloadTool::ARIA2: return NAME_ARIA2_DOWNLOAD; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - Optional to_linkage_type(const std::string& str) - { - if (str == "dynamic") return LinkageType::DYNAMIC; - if (str == "static") return LinkageType::STATIC; - return nullopt; - } - - namespace BuildInfoRequiredField - { - static const std::string CRT_LINKAGE = "CRTLinkage"; - static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; - } - - CStringView to_vcvarsall_target(const std::string& cmake_system_name) - { - if (cmake_system_name.empty()) return ""; - if (cmake_system_name == "Windows") return ""; - if (cmake_system_name == "WindowsStore") return "store"; - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); - } - - CStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) - { - auto maybe_target_arch = System::to_cpu_architecture(target_architecture); - Checks::check_exit( - VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); - auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); - auto host_architectures = System::get_supported_host_architectures(); - - for (auto&& host : host_architectures) - { - const auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { - return host == opt.host_arch && target_arch == opt.target_arch; - }); - if (it != toolset.supported_architectures.end()) return it->name; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, - "Unsupported toolchain combination. Target was: %s but supported ones were:\n%s", - target_architecture, - Strings::join(",", toolset.supported_architectures, [](const ToolsetArchOption& t) { - return t.name.c_str(); - })); - } - - std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) - { - if (pre_build_info.external_toolchain_file.has_value()) return ""; - if (!pre_build_info.cmake_system_name.empty() && pre_build_info.cmake_system_name != "WindowsStore") return ""; - - const char* tonull = " >nul"; - if (GlobalState::debugging) - { - tonull = ""; - } - - const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); - const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); - - return Strings::format(R"("%s" %s %s %s %s 2>&1 create_binary_control_file(const SourceParagraph& source_paragraph, - const Triplet& triplet, - const BuildInfo& build_info, - const std::string& abi_tag) - { - auto bcf = std::make_unique(); - BinaryParagraph bpgh(source_paragraph, triplet, abi_tag); - if (const auto p_ver = build_info.version.get()) - { - bpgh.version = *p_ver; - } - bcf->core_paragraph = std::move(bpgh); - return bcf; - } - - static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) - { - std::string start = Strings::serialize(bcf.core_paragraph); - for (auto&& feature : bcf.features) - { - 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); - } - - static std::vector compute_required_feature_specs(const BuildPackageConfig& config, - const StatusParagraphs& status_db) - { - const Triplet& triplet = config.triplet; - - const std::vector dep_strings = - Util::fmap_flatten(config.feature_list, [&](std::string const& feature) -> std::vector { - if (feature == "core") - { - return filter_dependencies(config.scf.core_paragraph->depends, triplet); - } - - auto maybe_feature = config.scf.find_feature(feature); - Checks::check_exit(VCPKG_LINE_INFO, maybe_feature.has_value()); - - return filter_dependencies(maybe_feature.get()->depends, triplet); - }); - - auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet); - Util::sort_unique_erase(dep_fspecs); - - // expand defaults - std::vector ret; - for (auto&& fspec : dep_fspecs) - { - if (fspec.feature().empty()) - { - // reference to default features - const auto it = status_db.find_installed(fspec.spec()); - if (it == status_db.end()) - { - // not currently installed, so just leave the default reference so it will fail later - ret.push_back(fspec); - } - else - { - ret.emplace_back(fspec.spec(), "core"); - for (auto&& default_feature : it->get()->package.default_features) - ret.emplace_back(fspec.spec(), default_feature); - } - } - else - { - ret.push_back(fspec); - } - } - Util::sort_unique_erase(ret); - - return ret; - } - - static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, - const PreBuildInfo& pre_build_info, - const PackageSpec& spec, - const std::string& abi_tag, - const BuildPackageConfig& config) - { - auto& fs = paths.get_filesystem(); - const Triplet& triplet = spec.triplet(); - -#if !defined(_WIN32) - // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107. - // bootstrap should have already downloaded ninja, but making sure it is present in case it was deleted. - vcpkg::Util::unused(paths.get_tool_exe(Tools::NINJA)); -#endif - - const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); - const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT); - - std::string all_features; - for (auto& feature : config.scf.feature_paragraphs) - { - all_features.append(feature->name + ";"); - } - - const Toolset& toolset = paths.get_toolset(pre_build_info); - const std::string cmd_launch_cmake = System::make_cmake_cmd( - cmake_exe_path, - paths.ports_cmake, - { - {"CMD", "BUILD"}, - {"PORT", config.scf.core_paragraph->name}, - {"CURRENT_PORT_DIR", config.port_dir}, - {"TARGET_TRIPLET", spec.triplet().canonical_name()}, - {"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}, - {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, - {"_VCPKG_DOWNLOAD_TOOL", to_string(config.build_package_options.download_tool)}, - {"GIT", git_exe_path}, - {"FEATURES", Strings::join(";", config.feature_list)}, - {"ALL_FEATURES", all_features}, - }); - - auto command = make_build_env_cmd(pre_build_info, toolset); - if (!command.empty()) - { -#ifdef _WIN32 - command.append(" & "); -#else - command.append(" && "); -#endif - } - command.append(cmd_launch_cmake); - const auto timer = Chrono::ElapsedTimer::create_started(); - - const int return_code = System::cmd_execute_clean(command); - const auto buildtimeus = timer.microseconds(); - const auto spec_string = spec.to_string(); - - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", - buildtimeus); - if (return_code != 0) - { - locked_metrics->track_property("error", "build failed"); - locked_metrics->track_property("build_error", spec_string); - return BuildResult::BUILD_FAILED; - } - } - - 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); - - auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag); - - if (error_count != 0) - { - return BuildResult::POST_BUILD_CHECKS_FAILED; - } - for (auto&& feature : config.feature_list) - { - for (auto&& f_pgh : config.scf.feature_paragraphs) - { - if (f_pgh->name == feature) - bcf->features.push_back( - create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); - } - } - - write_binary_control_file(paths, *bcf); - return {BuildResult::SUCCEEDED, std::move(bcf)}; - } - - static ExtendedBuildResult do_build_package_and_clean_buildtrees(const VcpkgPaths& paths, - const PreBuildInfo& pre_build_info, - const PackageSpec& spec, - const std::string& abi_tag, - const BuildPackageConfig& config) - { - auto result = do_build_package(paths, pre_build_info, spec, abi_tag, config); - - if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) - { - auto& fs = paths.get_filesystem(); - const fs::path buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; - auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); - for (auto&& file : buildtree_files) - { - if (fs.is_directory(file)) // Will only keep the logs - { - std::error_code ec; - fs.remove_all(file, ec); - } - } - } - - return result; - } - - Optional compute_abi_tag(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const PreBuildInfo& pre_build_info, - Span dependency_abis) - { - if (config.build_package_options.binary_caching == BinaryCaching::NO) return nullopt; - - auto& fs = paths.get_filesystem(); - const Triplet& triplet = config.triplet; - const std::string& name = config.scf.core_paragraph->name; - - std::vector abi_tag_entries(dependency_abis.begin(), dependency_abis.end()); - - abi_tag_entries.emplace_back(AbiEntry{"cmake", paths.get_tool_version(Tools::CMAKE)}); - - abi_tag_entries.emplace_back( - AbiEntry{"portfile", vcpkg::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); - abi_tag_entries.emplace_back( - AbiEntry{"control", vcpkg::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); - - abi_tag_entries.emplace_back(AbiEntry{"vcpkg_fixup_cmake_targets", "1"}); - - abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); - - const std::string features = Strings::join(";", config.feature_list); - abi_tag_entries.emplace_back(AbiEntry{"features", features}); - - if (config.build_package_options.use_head_version == UseHeadVersion::YES) - abi_tag_entries.emplace_back(AbiEntry{"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 (GlobalState::debugging) - { - System::println("[DEBUG] "); - for (auto&& entry : abi_tag_entries) - { - System::println("[DEBUG] %s|%s", entry.key, entry.value); - } - System::println("[DEBUG] "); - } - - auto abi_tag_entries_missing = abi_tag_entries; - Util::erase_remove_if(abi_tag_entries_missing, [](const AbiEntry& p) { return !p.value.empty(); }); - - if (abi_tag_entries_missing.empty()) - { - 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); - - return AbiTagAndFile{Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; - } - - System::println( - "Warning: binary caching disabled because abi keys are missing values:\n%s", - Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; })); - - return nullopt; - } - - static void decompress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& archive_path) - { - auto& fs = paths.get_filesystem(); - - auto pkg_path = paths.package_dir(spec); - std::error_code ec; - fs.remove_all(pkg_path, ec); - fs.create_directories(pkg_path, ec); - auto files = fs.get_files_non_recursive(pkg_path); - Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); - -#if defined(_WIN32) - auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); - - 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( - Strings::format(R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); -#endif - } - - static void compress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& tmp_archive_path) - { - auto& fs = paths.get_filesystem(); - - std::error_code ec; - - fs.remove(tmp_archive_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); -#if defined(_WIN32) - auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); - - System::cmd_execute_clean(Strings::format(R"("%s" a "%s" "%s\*" >nul)", - seven_zip_exe.u8string(), - tmp_archive_path.u8string(), - paths.package_dir(spec).u8string())); -#else - System::cmd_execute_clean(Strings::format( - R"(cd '%s' && zip --quiet -r '%s' *)", paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); -#endif - } - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) - { - auto& fs = paths.get_filesystem(); - const Triplet& triplet = config.triplet; - const std::string& name = config.scf.core_paragraph->name; - - std::vector required_fspecs = compute_required_feature_specs(config, status_db); - - // extract out the actual package ids - auto dep_pspecs = Util::fmap(required_fspecs, [](FeatureSpec const& fspec) { return fspec.spec(); }); - Util::sort_unique_erase(dep_pspecs); - - // Find all features that aren't installed. This mutates required_fspecs. - Util::erase_remove_if(required_fspecs, [&](FeatureSpec const& fspec) { - return status_db.is_installed(fspec) || fspec.name() == name; - }); - - if (!required_fspecs.empty()) - { - return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)}; - } - - const PackageSpec spec = - PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); - - std::vector dependency_abis; - - // dep_pspecs was not destroyed - for (auto&& pspec : dep_pspecs) - { - if (pspec == spec) continue; - const auto status_it = status_db.find_installed(pspec); - Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); - dependency_abis.emplace_back( - AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); - } - - const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - - auto maybe_abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); - - const auto abi_tag_and_file = maybe_abi_tag_and_file.get(); - - if (config.build_package_options.binary_caching == BinaryCaching::YES && abi_tag_and_file) - { - const fs::path archives_root_dir = paths.root / "archives"; - const std::string archive_name = abi_tag_and_file->tag + ".zip"; - const fs::path archive_subpath = fs::u8path(abi_tag_and_file->tag.substr(0, 2)) / archive_name; - const fs::path archive_path = archives_root_dir / archive_subpath; - const fs::path archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; - - if (fs.exists(archive_path)) - { - System::println("Using cached binary package: %s", archive_path.u8string()); - - decompress_archive(paths, spec, archive_path); - - auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); - std::unique_ptr bcf = - std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); - return {BuildResult::SUCCEEDED, std::move(bcf)}; - } - - if (fs.exists(archive_tombstone_path)) - { - if (config.build_package_options.fail_on_tombstone == FailOnTombstone::YES) - { - System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); - return BuildResult::BUILD_FAILED; - } - else - { - System::println( - System::Color::warning, "Found failure tombstone: %s", archive_tombstone_path.u8string()); - } - } - - System::println("Could not locate cached archive: %s", 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); - - std::error_code ec; - fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); - auto abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; - fs.copy_file(abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string()); - - if (result.code == BuildResult::SUCCEEDED) - { - const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); - - compress_archive(paths, spec, tmp_archive_path); - - fs.create_directories(archive_path.parent_path(), ec); - fs.rename_or_copy(tmp_archive_path, archive_path, ".tmp", ec); - if (ec) - { - System::println(System::Color::warning, - "Failed to store binary cache %s: %s", - archive_path.u8string(), - ec.message()); - } - else - System::println("Stored binary cache: %s", archive_path.u8string()); - } - else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) - { - // Build failed, so store tombstone archive - fs.create_directories(archive_tombstone_path.parent_path(), ec); - fs.write_contents(archive_tombstone_path, "", ec); - } - - return result; - } - - return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); - } - - const std::string& to_string(const BuildResult build_result) - { - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); - static const std::string SUCCEEDED_STRING = "SUCCEEDED"; - static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; - static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; - static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; - static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; - static const std::string EXCLUDED_STRING = "EXCLUDED"; - - switch (build_result) - { - case BuildResult::NULLVALUE: return NULLVALUE_STRING; - case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; - case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; - case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; - case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; - case BuildResult::EXCLUDED: return EXCLUDED_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) - { - return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); - } - - std::string create_user_troubleshooting_message(const PackageSpec& spec) - { - return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" - "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" - " Package: %s\n" - " Vcpkg version: %s\n" - "\n" - "Additionally, attach any relevant sections from the log files above.", - spec, - Commands::Version::version()); - } - - static BuildInfo inner_create_buildinfo(std::unordered_map pgh) - { - Parse::ParagraphParser parser(std::move(pgh)); - - BuildInfo build_info; - - { - std::string crt_linkage_as_string; - parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); - - auto crtlinkage = to_linkage_type(crt_linkage_as_string); - if (const auto p = crtlinkage.get()) - build_info.crt_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); - } - - { - std::string library_linkage_as_string; - parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); - auto liblinkage = to_linkage_type(library_linkage_as_string); - if (const auto p = liblinkage.get()) - build_info.library_linkage = *p; - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); - } - std::string version = parser.optional_field("Version"); - if (!version.empty()) build_info.version = std::move(version); - - std::map policies; - for (auto policy : G_ALL_POLICIES) - { - const auto setting = parser.optional_field(to_string(policy)); - if (setting.empty()) continue; - if (setting == "enabled") - policies.emplace(policy, true); - else if (setting == "disabled") - policies.emplace(policy, false); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); - } - - if (const auto err = parser.error_info("PostBuildInformation")) - { - print_error_message(err); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - build_info.policies = BuildPolicies(std::move(policies)); - - return build_info; - } - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) - { - const Expected> pghs = - Paragraphs::get_single_paragraph(fs, filepath); - Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); - return inner_create_buildinfo(*pghs.get()); - } - - PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) - { - static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; - - 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 auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - { - {"CMAKE_TRIPLET_FILE", triplet_file_path}, - }); - const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output); - - const std::vector lines = Strings::split(ec_data.output, "\n"); - - PreBuildInfo pre_build_info; - - const auto e = lines.cend(); - auto cur = std::find(lines.cbegin(), e, FLAG_GUID); - if (cur != e) ++cur; - - for (; cur != e; ++cur) - { - auto&& line = *cur; - - const std::vector s = Strings::split(line, "="); - Checks::check_exit(VCPKG_LINE_INFO, - s.size() == 1 || s.size() == 2, - "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]", - line); - - const bool variable_with_no_value = s.size() == 1; - const std::string variable_name = s.at(0); - const std::string variable_value = variable_with_no_value ? "" : s.at(1); - - if (variable_name == "VCPKG_TARGET_ARCHITECTURE") - { - pre_build_info.target_architecture = variable_value; - continue; - } - - if (variable_name == "VCPKG_CMAKE_SYSTEM_NAME") - { - pre_build_info.cmake_system_name = variable_value; - continue; - } - - if (variable_name == "VCPKG_CMAKE_SYSTEM_VERSION") - { - pre_build_info.cmake_system_version = variable_value; - continue; - } - - if (variable_name == "VCPKG_PLATFORM_TOOLSET") - { - pre_build_info.platform_toolset = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") - { - pre_build_info.visual_studio_path = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - if (variable_name == "VCPKG_CHAINLOAD_TOOLCHAIN_FILE") - { - pre_build_info.external_toolchain_file = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - if (variable_name == "VCPKG_BUILD_TYPE") - { - if (variable_value.empty()) - pre_build_info.build_type = nullopt; - else if (Strings::case_insensitive_ascii_equals(variable_value, "debug")) - pre_build_info.build_type = ConfigurationType::DEBUG; - else if (Strings::case_insensitive_ascii_equals(variable_value, "release")) - pre_build_info.build_type = ConfigurationType::RELEASE; - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown setting for VCPKG_BUILD_TYPE: %s", variable_value); - continue; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); - } - - pre_build_info.triplet_abi_tag = [&]() { - const auto& fs = paths.get_filesystem(); - static std::map s_hash_cache; - - auto it_hash = s_hash_cache.find(triplet_file_path); - if (it_hash != s_hash_cache.end()) - { - return it_hash->second; - } - auto hash = Hash::get_file_hash(fs, triplet_file_path, "SHA1"); - - if (auto p = pre_build_info.external_toolchain_file.get()) - { - hash += "-"; - hash += Hash::get_file_hash(fs, *p, "SHA1"); - } - else if (pre_build_info.cmake_system_name == "Linux") - { - hash += "-"; - hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "linux.cmake", "SHA1"); - } - else if (pre_build_info.cmake_system_name == "Darwin") - { - hash += "-"; - hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "osx.cmake", "SHA1"); - } - else if (pre_build_info.cmake_system_name == "FreeBSD") - { - hash += "-"; - hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "freebsd.cmake", "SHA1"); - } - else if (pre_build_info.cmake_system_name == "Android") - { - hash += "-"; - hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "android.cmake", "SHA1"); - } - - s_hash_cache.emplace(triplet_file_path, hash); - return hash; - }(); - - return pre_build_info; - } - ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) {} - ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr&& bcf) - : code(code), binary_control_file(std::move(bcf)) - { - } - ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps) - : code(code), unmet_dependencies(std::move(unmet_deps)) - { - } -} +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using vcpkg::Build::BuildResult; +using vcpkg::Parse::ParseControlErrorInfo; +using vcpkg::Parse::ParseExpected; + +namespace vcpkg::Build::Command +{ + using Dependencies::InstallPlanAction; + using Dependencies::InstallPlanType; + + static constexpr StringLiteral OPTION_CHECKS_ONLY = "--checks-only"; + + void perform_and_exit_ex(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const ParsedArguments& options, + const VcpkgPaths& paths) + { + const PackageSpec& spec = full_spec.package_spec; + 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); + Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); + Checks::exit_success(VCPKG_LINE_INFO); + } + + const ParseExpected 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, + "The Source field inside the CONTROL file does not match the port directory: '%s' != '%s'", + scf->core_paragraph->name, + spec.name()); + + const StatusParagraphs status_db = database_load_check(paths); + const Build::BuildPackageOptions build_package_options{ + Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::NO, + Build::CleanPackages::NO, + Build::DownloadTool::BUILT_IN, + GlobalState::g_binary_caching ? Build::BinaryCaching::YES : Build::BinaryCaching::NO, + Build::FailOnTombstone::NO, + }; + + std::set features_as_set(full_spec.features.begin(), full_spec.features.end()); + features_as_set.emplace("core"); + + const Build::BuildPackageConfig build_config{ + *scf, spec.triplet(), fs::path{port_dir}, 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); + System::println("Elapsed time for package %s: %s", spec.to_string(), build_timer.to_string()); + + if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) + { + System::println(System::Color::error, + "The build command requires all dependencies to be already installed."); + System::println("The following dependencies are missing:"); + System::println(); + for (const auto& p : result.unmet_dependencies) + { + System::println(" %s", p); + } + System::println(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + Checks::check_exit(VCPKG_LINE_INFO, result.code != BuildResult::EXCLUDED); + + if (result.code != BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, spec)); + System::println(Build::create_user_troubleshooting_message(spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + static constexpr std::array BUILD_SWITCHES = {{ + {OPTION_CHECKS_ONLY, "Only run checks, do not rebuild package"}, + }}; + + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("build zlib:x64-windows"), + 1, + 1, + {BUILD_SWITCHES, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + // Build only takes a single package and all dependencies must already be installed + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); + const std::string command_argument = args.command_arguments.at(0); + const FullPackageSpec spec = + Input::check_and_get_full_package_spec(command_argument, default_triplet, COMMAND_STRUCTURE.example_text); + Input::check_triplet(spec.package_spec.triplet(), paths); + if (!spec.features.empty() && !GlobalState::feature_packages) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); + } + perform_and_exit_ex(spec, paths.port_dir(spec.package_spec), options, paths); + } +} + +namespace vcpkg::Build +{ + static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; + static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; + static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; + static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; + static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; + + const std::string& to_string(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; + case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; + case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + CStringView to_cmake_variable(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; + case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; + case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + static const std::string NAME_BUILD_IN_DOWNLOAD = "BUILT_IN"; + static const std::string NAME_ARIA2_DOWNLOAD = "ARIA2"; + + const std::string& to_string(DownloadTool tool) + { + switch (tool) + { + case DownloadTool::BUILT_IN: return NAME_BUILD_IN_DOWNLOAD; + case DownloadTool::ARIA2: return NAME_ARIA2_DOWNLOAD; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + Optional to_linkage_type(const std::string& str) + { + if (str == "dynamic") return LinkageType::DYNAMIC; + if (str == "static") return LinkageType::STATIC; + return nullopt; + } + + namespace BuildInfoRequiredField + { + static const std::string CRT_LINKAGE = "CRTLinkage"; + static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; + } + + CStringView to_vcvarsall_target(const std::string& cmake_system_name) + { + if (cmake_system_name.empty()) return ""; + if (cmake_system_name == "Windows") return ""; + if (cmake_system_name == "WindowsStore") return "store"; + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); + } + + CStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) + { + auto maybe_target_arch = System::to_cpu_architecture(target_architecture); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); + auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); + auto host_architectures = System::get_supported_host_architectures(); + + for (auto&& host : host_architectures) + { + const auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + return host == opt.host_arch && target_arch == opt.target_arch; + }); + if (it != toolset.supported_architectures.end()) return it->name; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, + "Unsupported toolchain combination. Target was: %s but supported ones were:\n%s", + target_architecture, + Strings::join(",", toolset.supported_architectures, [](const ToolsetArchOption& t) { + return t.name.c_str(); + })); + } + + std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) + { + if (pre_build_info.external_toolchain_file.has_value()) return ""; + if (!pre_build_info.cmake_system_name.empty() && pre_build_info.cmake_system_name != "WindowsStore") return ""; + + const char* tonull = " >nul"; + if (GlobalState::debugging) + { + tonull = ""; + } + + const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); + const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); + + return Strings::format(R"("%s" %s %s %s %s 2>&1 create_binary_control_file(const SourceParagraph& source_paragraph, + const Triplet& triplet, + const BuildInfo& build_info, + const std::string& abi_tag) + { + auto bcf = std::make_unique(); + BinaryParagraph bpgh(source_paragraph, triplet, abi_tag); + if (const auto p_ver = build_info.version.get()) + { + bpgh.version = *p_ver; + } + bcf->core_paragraph = std::move(bpgh); + return bcf; + } + + static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) + { + std::string start = Strings::serialize(bcf.core_paragraph); + for (auto&& feature : bcf.features) + { + 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); + } + + static std::vector compute_required_feature_specs(const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + const Triplet& triplet = config.triplet; + + const std::vector dep_strings = + Util::fmap_flatten(config.feature_list, [&](std::string const& feature) -> std::vector { + if (feature == "core") + { + return filter_dependencies(config.scf.core_paragraph->depends, triplet); + } + + auto maybe_feature = config.scf.find_feature(feature); + Checks::check_exit(VCPKG_LINE_INFO, maybe_feature.has_value()); + + return filter_dependencies(maybe_feature.get()->depends, triplet); + }); + + auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet); + Util::sort_unique_erase(dep_fspecs); + + // expand defaults + std::vector ret; + for (auto&& fspec : dep_fspecs) + { + if (fspec.feature().empty()) + { + // reference to default features + const auto it = status_db.find_installed(fspec.spec()); + if (it == status_db.end()) + { + // not currently installed, so just leave the default reference so it will fail later + ret.push_back(fspec); + } + else + { + ret.emplace_back(fspec.spec(), "core"); + for (auto&& default_feature : it->get()->package.default_features) + ret.emplace_back(fspec.spec(), default_feature); + } + } + else + { + ret.push_back(fspec); + } + } + Util::sort_unique_erase(ret); + + return ret; + } + + static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const PackageSpec& spec, + const std::string& abi_tag, + const BuildPackageConfig& config) + { + auto& fs = paths.get_filesystem(); + const Triplet& triplet = spec.triplet(); + +#if !defined(_WIN32) + // TODO: remove when vcpkg.exe is in charge for acquiring tools. Change introduced in vcpkg v0.0.107. + // bootstrap should have already downloaded ninja, but making sure it is present in case it was deleted. + vcpkg::Util::unused(paths.get_tool_exe(Tools::NINJA)); +#endif + + const fs::path& cmake_exe_path = paths.get_tool_exe(Tools::CMAKE); + const fs::path& git_exe_path = paths.get_tool_exe(Tools::GIT); + + std::string all_features; + for (auto& feature : config.scf.feature_paragraphs) + { + all_features.append(feature->name + ";"); + } + + const Toolset& toolset = paths.get_toolset(pre_build_info); + const std::string cmd_launch_cmake = System::make_cmake_cmd( + cmake_exe_path, + paths.ports_cmake, + { + {"CMD", "BUILD"}, + {"PORT", config.scf.core_paragraph->name}, + {"CURRENT_PORT_DIR", config.port_dir}, + {"TARGET_TRIPLET", spec.triplet().canonical_name()}, + {"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}, + {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"_VCPKG_DOWNLOAD_TOOL", to_string(config.build_package_options.download_tool)}, + {"GIT", git_exe_path}, + {"FEATURES", Strings::join(";", config.feature_list)}, + {"ALL_FEATURES", all_features}, + }); + + auto command = make_build_env_cmd(pre_build_info, toolset); + if (!command.empty()) + { +#ifdef _WIN32 + command.append(" & "); +#else + command.append(" && "); +#endif + } + command.append(cmd_launch_cmake); + const auto timer = Chrono::ElapsedTimer::create_started(); + + const int return_code = System::cmd_execute_clean(command); + const auto buildtimeus = timer.microseconds(); + const auto spec_string = spec.to_string(); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_buildtime(spec.to_string() + ":[" + Strings::join(",", config.feature_list) + "]", + buildtimeus); + if (return_code != 0) + { + locked_metrics->track_property("error", "build failed"); + locked_metrics->track_property("build_error", spec_string); + return BuildResult::BUILD_FAILED; + } + } + + 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); + + auto bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag); + + if (error_count != 0) + { + return BuildResult::POST_BUILD_CHECKS_FAILED; + } + for (auto&& feature : config.feature_list) + { + for (auto&& f_pgh : config.scf.feature_paragraphs) + { + if (f_pgh->name == feature) + bcf->features.push_back( + create_binary_feature_control_file(*config.scf.core_paragraph, *f_pgh, triplet)); + } + } + + write_binary_control_file(paths, *bcf); + return {BuildResult::SUCCEEDED, std::move(bcf)}; + } + + static ExtendedBuildResult do_build_package_and_clean_buildtrees(const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const PackageSpec& spec, + const std::string& abi_tag, + const BuildPackageConfig& config) + { + auto result = do_build_package(paths, pre_build_info, spec, abi_tag, config); + + if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) + { + auto& fs = paths.get_filesystem(); + const fs::path buildtrees_dir = paths.buildtrees / config.scf.core_paragraph->name; + auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); + for (auto&& file : buildtree_files) + { + if (fs.is_directory(file)) // Will only keep the logs + { + std::error_code ec; + fs.remove_all(file, ec); + } + } + } + + return result; + } + + Optional compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span dependency_abis) + { + if (config.build_package_options.binary_caching == BinaryCaching::NO) return nullopt; + + auto& fs = paths.get_filesystem(); + const Triplet& triplet = config.triplet; + const std::string& name = config.scf.core_paragraph->name; + + std::vector abi_tag_entries(dependency_abis.begin(), dependency_abis.end()); + + abi_tag_entries.emplace_back(AbiEntry{"cmake", paths.get_tool_version(Tools::CMAKE)}); + + // 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 + std::vector port_files; + for (auto &port_file : fs::stdfs::recursive_directory_iterator(config.port_dir)) + { + if (fs::is_regular_file(status(port_file))) + { + port_files.push_back(port_file); + if (port_files.size() > max_port_file_count) + { + abi_tag_entries.emplace_back(AbiEntry{ "no_hash_max_portfile", "" }); + break; + } + } + } + + if (port_files.size() <= max_port_file_count) + { + std::sort(port_files.begin(), port_files.end()); + + int counter = 0; + for (auto & port_file : port_files) + { + // When vcpkg takes a dependency on C++17 it can use fs::relative, + // which will give a stable ordering and better names in the key entry. + // this is not available in the filesystem TS so instead number the files for the key. + std::string key = Strings::format("file_%03d", counter++); + if (GlobalState::debugging) + { + System::println("[DEBUG] mapping %s from %s", key, port_file.string()); + } + abi_tag_entries.emplace_back(AbiEntry{ key, vcpkg::Hash::get_file_hash(fs, port_file, "SHA1") }); + } + } + + abi_tag_entries.emplace_back(AbiEntry{"vcpkg_fixup_cmake_targets", "1"}); + + abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); + + const std::string features = Strings::join(";", config.feature_list); + abi_tag_entries.emplace_back(AbiEntry{"features", features}); + + if (config.build_package_options.use_head_version == UseHeadVersion::YES) + abi_tag_entries.emplace_back(AbiEntry{"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 (GlobalState::debugging) + { + System::println("[DEBUG] "); + for (auto&& entry : abi_tag_entries) + { + System::println("[DEBUG] %s|%s", entry.key, entry.value); + } + System::println("[DEBUG] "); + } + + auto abi_tag_entries_missing = abi_tag_entries; + Util::erase_remove_if(abi_tag_entries_missing, [](const AbiEntry& p) { return !p.value.empty(); }); + + if (abi_tag_entries_missing.empty()) + { + 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); + + return AbiTagAndFile{Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; + } + + System::println( + "Warning: binary caching disabled because abi keys are missing values:\n%s", + Strings::join("", abi_tag_entries_missing, [](const AbiEntry& e) { return " " + e.key + "\n"; })); + + return nullopt; + } + + static void decompress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& archive_path) + { + auto& fs = paths.get_filesystem(); + + auto pkg_path = paths.package_dir(spec); + std::error_code ec; + fs.remove_all(pkg_path, ec); + fs.create_directories(pkg_path, ec); + auto files = fs.get_files_non_recursive(pkg_path); + Checks::check_exit(VCPKG_LINE_INFO, files.empty(), "unable to clear path: %s", pkg_path.u8string()); + +#if defined(_WIN32) + auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); + + 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( + Strings::format(R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); +#endif + } + + static void compress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& tmp_archive_path) + { + auto& fs = paths.get_filesystem(); + + std::error_code ec; + + fs.remove(tmp_archive_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); +#if defined(_WIN32) + auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); + + System::cmd_execute_clean(Strings::format(R"("%s" a "%s" "%s\*" >nul)", + seven_zip_exe.u8string(), + tmp_archive_path.u8string(), + paths.package_dir(spec).u8string())); +#else + System::cmd_execute_clean(Strings::format( + R"(cd '%s' && zip --quiet -r '%s' *)", paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); +#endif + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + const Triplet& triplet = config.triplet; + const std::string& name = config.scf.core_paragraph->name; + + std::vector required_fspecs = compute_required_feature_specs(config, status_db); + + // extract out the actual package ids + auto dep_pspecs = Util::fmap(required_fspecs, [](FeatureSpec const& fspec) { return fspec.spec(); }); + Util::sort_unique_erase(dep_pspecs); + + // Find all features that aren't installed. This mutates required_fspecs. + Util::erase_remove_if(required_fspecs, [&](FeatureSpec const& fspec) { + return status_db.is_installed(fspec) || fspec.name() == name; + }); + + if (!required_fspecs.empty()) + { + return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(required_fspecs)}; + } + + const PackageSpec spec = + PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); + + std::vector dependency_abis; + + // dep_pspecs was not destroyed + for (auto&& pspec : dep_pspecs) + { + if (pspec == spec) continue; + const auto status_it = status_db.find_installed(pspec); + Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); + dependency_abis.emplace_back( + AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); + } + + const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); + + auto maybe_abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); + + const auto abi_tag_and_file = maybe_abi_tag_and_file.get(); + + if (config.build_package_options.binary_caching == BinaryCaching::YES && abi_tag_and_file) + { + const fs::path archives_root_dir = paths.root / "archives"; + const std::string archive_name = abi_tag_and_file->tag + ".zip"; + const fs::path archive_subpath = fs::u8path(abi_tag_and_file->tag.substr(0, 2)) / archive_name; + const fs::path archive_path = archives_root_dir / archive_subpath; + const fs::path archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + + if (fs.exists(archive_path)) + { + System::println("Using cached binary package: %s", archive_path.u8string()); + + decompress_archive(paths, spec, archive_path); + + auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); + std::unique_ptr bcf = + std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); + return {BuildResult::SUCCEEDED, std::move(bcf)}; + } + + if (fs.exists(archive_tombstone_path)) + { + if (config.build_package_options.fail_on_tombstone == FailOnTombstone::YES) + { + System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); + return BuildResult::BUILD_FAILED; + } + else + { + System::println( + System::Color::warning, "Found failure tombstone: %s", archive_tombstone_path.u8string()); + } + } + + System::println("Could not locate cached archive: %s", 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); + + std::error_code ec; + fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); + auto abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; + fs.copy_file(abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not copy into file: %s", abi_file_in_package.u8string()); + + if (result.code == BuildResult::SUCCEEDED) + { + const auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); + + compress_archive(paths, spec, tmp_archive_path); + + fs.create_directories(archive_path.parent_path(), ec); + fs.rename_or_copy(tmp_archive_path, archive_path, ".tmp", ec); + if (ec) + { + System::println(System::Color::warning, + "Failed to store binary cache %s: %s", + archive_path.u8string(), + ec.message()); + } + else + System::println("Stored binary cache: %s", archive_path.u8string()); + } + else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) + { + // Build failed, so store tombstone archive + fs.create_directories(archive_tombstone_path.parent_path(), ec); + fs.write_contents(archive_tombstone_path, "", ec); + } + + return result; + } + + return do_build_package_and_clean_buildtrees( + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); + } + + const std::string& to_string(const BuildResult build_result) + { + static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); + static const std::string SUCCEEDED_STRING = "SUCCEEDED"; + static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; + static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; + static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; + static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; + static const std::string EXCLUDED_STRING = "EXCLUDED"; + + switch (build_result) + { + case BuildResult::NULLVALUE: return NULLVALUE_STRING; + case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; + case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; + case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; + case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; + case BuildResult::EXCLUDED: return EXCLUDED_STRING; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) + { + return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); + } + + std::string create_user_troubleshooting_message(const PackageSpec& spec) + { + return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" + "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" + " Package: %s\n" + " Vcpkg version: %s\n" + "\n" + "Additionally, attach any relevant sections from the log files above.", + spec, + Commands::Version::version()); + } + + static BuildInfo inner_create_buildinfo(std::unordered_map pgh) + { + Parse::ParagraphParser parser(std::move(pgh)); + + BuildInfo build_info; + + { + std::string crt_linkage_as_string; + parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); + + auto crtlinkage = to_linkage_type(crt_linkage_as_string); + if (const auto p = crtlinkage.get()) + build_info.crt_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); + } + + { + std::string library_linkage_as_string; + parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); + auto liblinkage = to_linkage_type(library_linkage_as_string); + if (const auto p = liblinkage.get()) + build_info.library_linkage = *p; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); + } + std::string version = parser.optional_field("Version"); + if (!version.empty()) build_info.version = std::move(version); + + std::map policies; + for (auto policy : G_ALL_POLICIES) + { + const auto setting = parser.optional_field(to_string(policy)); + if (setting.empty()) continue; + if (setting == "enabled") + policies.emplace(policy, true); + else if (setting == "disabled") + policies.emplace(policy, false); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); + } + + if (const auto err = parser.error_info("PostBuildInformation")) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + build_info.policies = BuildPolicies(std::move(policies)); + + return build_info; + } + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) + { + const Expected> pghs = + Paragraphs::get_single_paragraph(fs, filepath); + Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); + return inner_create_buildinfo(*pghs.get()); + } + + PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) + { + static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; + + 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 auto cmd_launch_cmake = System::make_cmake_cmd(cmake_exe_path, + ports_cmake_script_path, + { + {"CMAKE_TRIPLET_FILE", triplet_file_path}, + }); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, ec_data.output); + + const std::vector lines = Strings::split(ec_data.output, "\n"); + + PreBuildInfo pre_build_info; + + const auto e = lines.cend(); + auto cur = std::find(lines.cbegin(), e, FLAG_GUID); + if (cur != e) ++cur; + + for (; cur != e; ++cur) + { + auto&& line = *cur; + + const std::vector s = Strings::split(line, "="); + Checks::check_exit(VCPKG_LINE_INFO, + s.size() == 1 || s.size() == 2, + "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]", + line); + + const bool variable_with_no_value = s.size() == 1; + const std::string variable_name = s.at(0); + const std::string variable_value = variable_with_no_value ? "" : s.at(1); + + if (variable_name == "VCPKG_TARGET_ARCHITECTURE") + { + pre_build_info.target_architecture = variable_value; + continue; + } + + if (variable_name == "VCPKG_CMAKE_SYSTEM_NAME") + { + pre_build_info.cmake_system_name = variable_value; + continue; + } + + if (variable_name == "VCPKG_CMAKE_SYSTEM_VERSION") + { + pre_build_info.cmake_system_version = variable_value; + continue; + } + + if (variable_name == "VCPKG_PLATFORM_TOOLSET") + { + pre_build_info.platform_toolset = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") + { + pre_build_info.visual_studio_path = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_CHAINLOAD_TOOLCHAIN_FILE") + { + pre_build_info.external_toolchain_file = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_BUILD_TYPE") + { + if (variable_value.empty()) + pre_build_info.build_type = nullopt; + else if (Strings::case_insensitive_ascii_equals(variable_value, "debug")) + pre_build_info.build_type = ConfigurationType::DEBUG; + else if (Strings::case_insensitive_ascii_equals(variable_value, "release")) + pre_build_info.build_type = ConfigurationType::RELEASE; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for VCPKG_BUILD_TYPE: %s", variable_value); + continue; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); + } + + pre_build_info.triplet_abi_tag = [&]() { + const auto& fs = paths.get_filesystem(); + static std::map s_hash_cache; + + auto it_hash = s_hash_cache.find(triplet_file_path); + if (it_hash != s_hash_cache.end()) + { + return it_hash->second; + } + auto hash = Hash::get_file_hash(fs, triplet_file_path, "SHA1"); + + if (auto p = pre_build_info.external_toolchain_file.get()) + { + hash += "-"; + hash += Hash::get_file_hash(fs, *p, "SHA1"); + } + else if (pre_build_info.cmake_system_name == "Linux") + { + hash += "-"; + hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "linux.cmake", "SHA1"); + } + else if (pre_build_info.cmake_system_name == "Darwin") + { + hash += "-"; + hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "osx.cmake", "SHA1"); + } + else if (pre_build_info.cmake_system_name == "FreeBSD") + { + hash += "-"; + hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "freebsd.cmake", "SHA1"); + } + else if (pre_build_info.cmake_system_name == "Android") + { + hash += "-"; + hash += Hash::get_file_hash(fs, paths.scripts / "toolchains" / "android.cmake", "SHA1"); + } + + s_hash_cache.emplace(triplet_file_path, hash); + return hash; + }(); + + return pre_build_info; + } + ExtendedBuildResult::ExtendedBuildResult(BuildResult code) : code(code) {} + ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::unique_ptr&& bcf) + : code(code), binary_control_file(std::move(bcf)) + { + } + ExtendedBuildResult::ExtendedBuildResult(BuildResult code, std::vector&& unmet_deps) + : code(code), unmet_dependencies(std::move(unmet_deps)) + { + } +} -- cgit v1.2.3 From 52f165ef3b162a4910b3e873d547ca994435e751 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 5 Feb 2019 14:46:17 -0800 Subject: [vcpkg] Respect the documented VS environment variable %VCPKG_VISUAL_STUDIO_PATH% --- toolsrc/src/vcpkg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index fc7283599..97565bf41 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -102,7 +102,7 @@ static void inner(const VcpkgCmdArguments& args) Debug::println("Using vcpkg-root: %s", vcpkg_root_dir.u8string()); - auto default_vs_path = System::get_environment_variable("VCPKG_DEFAULT_VS_PATH").value_or(""); + 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); Checks::check_exit(VCPKG_LINE_INFO, -- cgit v1.2.3 From d82f37b4bfc1422d4601fbb63cbd553c925f7014 Mon Sep 17 00:00:00 2001 From: Marco Craveiro Date: Sat, 9 Feb 2019 02:06:08 +0000 Subject: [vcpkg] Fix warning on Apple (#5333) Return type of _NSGetExecutablePath is int rather than bool [1], causing a warning on Apple. [1] https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dyld.3.html --- toolsrc/src/vcpkg/base/system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index b25412f7a..90b9c34b3 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -30,7 +30,7 @@ namespace vcpkg::System static constexpr const uint32_t buff_size = 1024 * 32; uint32_t size = buff_size; char buf[buff_size] = {}; - bool result = _NSGetExecutablePath(buf, &size); + int result = _NSGetExecutablePath(buf, &size); Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); std::unique_ptr canonicalPath(realpath(buf, NULL)); Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); -- cgit v1.2.3 From 92f57e460a1bd3c054b20970baab19ca358bdd4b Mon Sep 17 00:00:00 2001 From: Phil Christensen Date: Sun, 17 Feb 2019 00:46:16 -0800 Subject: [vcpkg] Save failure logs in tombstone in CI tests --- toolsrc/src/vcpkg/build.cpp | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f39707065..c0afd7772 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -579,28 +579,34 @@ namespace vcpkg::Build #endif } - static void compress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& tmp_archive_path) + // Compress the source directory into the destination file. + static void compress_directory(const VcpkgPaths& paths, const fs::path& source, const fs::path& destination) { auto& fs = paths.get_filesystem(); std::error_code ec; - fs.remove(tmp_archive_path, ec); + fs.remove(destination, ec); Checks::check_exit( - VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); + VCPKG_LINE_INFO, !fs.exists(destination), "Could not remove file: %s", destination.u8string()); #if defined(_WIN32) auto&& seven_zip_exe = paths.get_tool_exe(Tools::SEVEN_ZIP); System::cmd_execute_clean(Strings::format(R"("%s" a "%s" "%s\*" >nul)", seven_zip_exe.u8string(), - tmp_archive_path.u8string(), - paths.package_dir(spec).u8string())); + destination.u8string(), + source.u8string())); #else System::cmd_execute_clean(Strings::format( - R"(cd '%s' && zip --quiet -r '%s' *)", paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); + R"(cd '%s' && zip --quiet -r '%s' *)", source.u8string(), destination.u8string())); #endif } + static void compress_archive(const VcpkgPaths& paths, const PackageSpec& spec, const fs::path& destination) + { + compress_directory(paths, paths.package_dir(spec), destination); + } + ExtendedBuildResult build_package(const VcpkgPaths& paths, const BuildPackageConfig& config, const StatusParagraphs& status_db) @@ -711,9 +717,30 @@ namespace vcpkg::Build } else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) { - // Build failed, so store tombstone archive - fs.create_directories(archive_tombstone_path.parent_path(), ec); - fs.write_contents(archive_tombstone_path, "", ec); + if (!fs.exists(archive_tombstone_path)) + { + // Build failed, store all failure logs in the tombstone. + const auto tmp_log_path = paths.buildtrees / spec.name() / "tmp_failure_logs"; + const auto tmp_log_path_destination = tmp_log_path / spec.name(); + const auto tmp_failure_zip = paths.buildtrees / spec.name() / "failure_logs.zip"; + fs.create_directories(tmp_log_path_destination, ec); + + for (auto &log_file : fs::stdfs::directory_iterator(paths.buildtrees / spec.name())) + { + if (log_file.path().extension() == ".log") + { + fs.copy_file(log_file.path(), tmp_log_path_destination / log_file.path().filename(), fs::stdfs::copy_options::none, ec); + } + } + + compress_directory(paths, tmp_log_path, paths.buildtrees / spec.name() / "failure_logs.zip"); + + fs.create_directories(archive_tombstone_path.parent_path(), ec); + fs.rename_or_copy(tmp_failure_zip, archive_tombstone_path, ".tmp", ec); + + // clean up temporary directory + fs.remove_all(tmp_log_path, ec); + } } return result; -- cgit v1.2.3 From 8fd34506c3f2d06af8abd8cfbb543ad16e79c6a3 Mon Sep 17 00:00:00 2001 From: Phil Christensen Date: Thu, 21 Feb 2019 22:24:20 -0800 Subject: [vcpkg] improve xunit xml output used in CI tests --- toolsrc/src/vcpkg/commands.ci.cpp | 235 ++++++++++++++++++++++++++++++++------ toolsrc/src/vcpkg/install.cpp | 10 +- 2 files changed, 204 insertions(+), 41 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index 5ca962744..4ff503e1c 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -52,24 +52,176 @@ namespace vcpkg::Commands::CI nullptr, }; + struct XunitTestResults + { + public: + + XunitTestResults() + { + m_assembly_run_datetime = Chrono::CTime::get_current_date_time(); + } + + void add_test_results(const std::string& spec, const Build::BuildResult& build_result, const Chrono::ElapsedTime& elapsed_time, const std::string& abi_tag) + { + m_collections.back().tests.push_back({ spec, build_result, elapsed_time, abi_tag }); + } + + // Starting a new test collection + void push_collection( const std::string& name) + { + m_collections.push_back({name}); + } + + void collection_time(const vcpkg::Chrono::ElapsedTime& time) + { + m_collections.back().time = time; + } + + const std::string& build_xml() + { + m_xml.clear(); + xml_start_assembly(); + + for (const auto& collection : m_collections) + { + xml_start_collection(collection); + for (const auto& test : collection.tests) + { + xml_test(test); + } + xml_finish_collection(); + } + + xml_finish_assembly(); + return m_xml; + } + + void assembly_time(const vcpkg::Chrono::ElapsedTime& assembly_time) + { + m_assembly_time = assembly_time; + } + + private: + + struct XunitTest + { + std::string name; + vcpkg::Build::BuildResult result; + vcpkg::Chrono::ElapsedTime time; + std::string abi_tag; + }; + + struct XunitCollection + { + std::string name; + vcpkg::Chrono::ElapsedTime time; + std::vector tests; + }; + + void xml_start_assembly() + { + std::string datetime; + if (m_assembly_run_datetime) + { + auto rawDateTime = m_assembly_run_datetime.get()->to_string(); + // The expected format is "yyyy-mm-ddThh:mm:ss.0Z" + // 0123456789012345678901 + datetime = Strings::format(R"(run-date="%s" run-time="%s")", + rawDateTime.substr(0, 10), rawDateTime.substr(11, 8)); + } + + std::string time = Strings::format(R"(time="%lld")", m_assembly_time.as().count()); + + m_xml += Strings::format( + R"()" "\n" + R"( )" "\n" + , datetime, time); + } + void xml_finish_assembly() + { + m_xml += " \n" + "\n"; + } + + void xml_start_collection(const XunitCollection& collection) + { + m_xml += Strings::format(R"( )" + "\n", + collection.name, + collection.time.as().count()); + } + void xml_finish_collection() + { + m_xml += " \n"; + } + + void xml_test(const XunitTest& test) + { + std::string message_block; + const char* result_string = ""; + switch (test.result) + { + case BuildResult::POST_BUILD_CHECKS_FAILED: + case BuildResult::FILE_CONFLICTS: + case BuildResult::BUILD_FAILED: + result_string = "Fail"; + message_block = Strings::format("", to_string(test.result)); + break; + case BuildResult::EXCLUDED: + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: + result_string = "Skip"; + message_block = Strings::format("", to_string(test.result)); + break; + case BuildResult::SUCCEEDED: + result_string = "Pass"; + break; + default: + Checks::exit_fail(VCPKG_LINE_INFO); + break; + } + + std::string traits_block; + if (test.abi_tag != "") // only adding if there is a known abi tag + { + traits_block = Strings::format(R"()", test.abi_tag); + } + + m_xml += Strings::format(R"( %s%s)" + "\n", + test.name, + test.name, + test.time.as().count(), + result_string, + traits_block, + message_block); + } + + Optional m_assembly_run_datetime; + vcpkg::Chrono::ElapsedTime m_assembly_time; + std::vector m_collections; + + std::string m_xml; + }; + + struct UnknownCIPortsResults { std::vector unknown; std::map known; std::map> features; + std::map abi_tag_map; }; - static UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths, + static std::unique_ptr find_unknown_ports_for_ci(const VcpkgPaths& paths, const std::set& exclusions, const Dependencies::PortFileProvider& provider, const std::vector& fspecs, const bool purge_tombstones) { - UnknownCIPortsResults ret; + auto ret = std::make_unique(); auto& fs = paths.get_filesystem(); - std::map abi_tag_map; std::set will_fail; const Build::BuildPackageOptions build_options = { @@ -103,9 +255,9 @@ namespace vcpkg::Commands::CI auto dependency_abis = Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry { - auto it = abi_tag_map.find(spec); + auto it = ret->abi_tag_map.find(spec); - if (it == abi_tag_map.end()) + if (it == ret->abi_tag_map.end()) return {spec.name(), ""}; else return {spec.name(), it->second}; @@ -118,13 +270,13 @@ namespace vcpkg::Commands::CI if (auto tag_and_file = maybe_tag_and_file.get()) { abi = tag_and_file->tag; - abi_tag_map.emplace(p->spec, abi); + ret->abi_tag_map.emplace(p->spec, abi); } } else if (auto ipv = p->installed_package.get()) { abi = ipv->core->package.abi; - if (!abi.empty()) abi_tag_map.emplace(p->spec, abi); + if (!abi.empty()) ret->abi_tag_map.emplace(p->spec, abi); } std::string state; @@ -143,35 +295,35 @@ namespace vcpkg::Commands::CI bool b_will_build = false; - ret.features.emplace(p->spec, + ret->features.emplace(p->spec, std::vector {p->feature_list.begin(), p->feature_list.end()}); if (Util::Sets::contains(exclusions, p->spec.name())) { - ret.known.emplace(p->spec, BuildResult::EXCLUDED); + ret->known.emplace(p->spec, BuildResult::EXCLUDED); will_fail.emplace(p->spec); } else if (std::any_of(p->computed_dependencies.begin(), p->computed_dependencies.end(), [&](const PackageSpec& spec) { return Util::Sets::contains(will_fail, spec); })) { - ret.known.emplace(p->spec, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES); + ret->known.emplace(p->spec, BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES); will_fail.emplace(p->spec); } else if (fs.exists(archive_path)) { state += "pass"; - ret.known.emplace(p->spec, BuildResult::SUCCEEDED); + ret->known.emplace(p->spec, BuildResult::SUCCEEDED); } else if (fs.exists(archive_tombstone_path)) { state += "fail"; - ret.known.emplace(p->spec, BuildResult::BUILD_FAILED); + ret->known.emplace(p->spec, BuildResult::BUILD_FAILED); will_fail.emplace(p->spec); } else { - ret.unknown.push_back({p->spec, {p->feature_list.begin(), p->feature_list.end()}}); + ret->unknown.push_back({p->spec, {p->feature_list.begin(), p->feature_list.end()}}); b_will_build = true; } @@ -229,23 +381,29 @@ namespace vcpkg::Commands::CI }; std::vector> all_known_results; + std::map abi_tag_map; + + XunitTestResults xunitTestResults; std::vector all_ports = Install::get_all_port_names(paths); std::vector results; + auto timer = Chrono::ElapsedTimer::create_started(); for (const Triplet& triplet : triplets) { Input::check_triplet(triplet, paths); + xunitTestResults.push_collection(triplet.canonical_name()); + Dependencies::PackageGraph pgraph(paths_port_file, status_db); std::vector specs = PackageSpec::to_package_specs(all_ports, triplet); // Install the default features for every package - auto all_fspecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + 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_fspecs, purge_tombstones); - auto fspecs = FullPackageSpec::to_feature_specs(split_specs.unknown); + find_unknown_ports_for_ci(paths, exclusions_set, paths_port_file, all_feature_specs, purge_tombstones); + auto feature_specs = FullPackageSpec::to_feature_specs(split_specs->unknown); - for (auto&& fspec : fspecs) + for (auto&& fspec : feature_specs) pgraph.install(fspec); Dependencies::CreateInstallPlanOptions serialize_options; @@ -284,7 +442,7 @@ namespace vcpkg::Commands::CI p->plan_type = InstallPlanType::EXCLUDED; } - for (auto&& feature : split_specs.features[p->spec]) + for (auto&& feature : split_specs->features[p->spec]) if (p->feature_list.find(feature) == p->feature_list.end()) { pgraph.install({p->spec, feature}); @@ -304,13 +462,32 @@ namespace vcpkg::Commands::CI } else { + auto collection_timer = Chrono::ElapsedTimer::create_started(); auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); + auto collection_time_elapsed = collection_timer.elapsed(); + + // Adding results for ports that were built or pulled from an archive for (auto&& result : summary.results) - split_specs.known.erase(result.spec); - results.push_back({triplet, std::move(summary)}); - all_known_results.emplace_back(std::move(split_specs.known)); + { + split_specs->known.erase(result.spec); + xunitTestResults.add_test_results(result.spec.to_string(), result.build_result.code, result.timing, split_specs->abi_tag_map.at(result.spec)); + } + + // Adding results for ports that were not built because they have known states + for (auto&& port : split_specs->known) + { + xunitTestResults.add_test_results(port.first.to_string(), port.second, Chrono::ElapsedTime{}, split_specs->abi_tag_map.at(port.first)); + } + + all_known_results.emplace_back(std::move(split_specs->known)); + abi_tag_map.insert(split_specs->abi_tag_map.begin(), split_specs->abi_tag_map.end()); + + results.push_back({ triplet, std::move(summary)}); + + xunitTestResults.collection_time( collection_time_elapsed ); } } + xunitTestResults.assembly_time(timer.elapsed()); for (auto&& result : results) { @@ -322,21 +499,7 @@ namespace vcpkg::Commands::CI auto it_xunit = options.settings.find(OPTION_XUNIT); if (it_xunit != options.settings.end()) { - std::string xunit_doc = "\n"; - - for (auto&& result : results) - xunit_doc += result.summary.xunit_results(); - for (auto&& known_result : all_known_results) - { - for (auto&& result : known_result) - { - xunit_doc += - Install::InstallSummary::xunit_result(result.first, Chrono::ElapsedTime {}, result.second); - } - } - - xunit_doc += "\n"; - paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunit_doc); + paths.get_filesystem().write_contents(fs::u8path(it_xunit->second), xunitTestResults.build_xml()); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 1cfa2bf71..434876871 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -719,9 +719,9 @@ namespace vcpkg::Install return nullptr; } - std::string InstallSummary::xunit_result(const PackageSpec& spec, Chrono::ElapsedTime time, BuildResult code) + static std::string xunit_result(const PackageSpec& spec, Chrono::ElapsedTime time, BuildResult code) { - std::string inner_block; + std::string message_block; const char* result_string = ""; switch (code) { @@ -729,12 +729,12 @@ namespace vcpkg::Install case BuildResult::FILE_CONFLICTS: case BuildResult::BUILD_FAILED: result_string = "Fail"; - inner_block = Strings::format("", to_string(code)); + message_block = Strings::format("", to_string(code)); break; case BuildResult::EXCLUDED: case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: result_string = "Skip"; - inner_block = Strings::format("", to_string(code)); + message_block = Strings::format("", to_string(code)); break; case BuildResult::SUCCEEDED: result_string = "Pass"; break; default: Checks::exit_fail(VCPKG_LINE_INFO); @@ -746,7 +746,7 @@ namespace vcpkg::Install spec, time.as().count(), result_string, - inner_block); + message_block); } std::string InstallSummary::xunit_results() const -- cgit v1.2.3 From 233c4c358a6156913ef635be7717ca83c1c34b3e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 22 Feb 2019 11:31:35 -0800 Subject: [vcpkg edit] Check for VS Code onlinux (#5391) --- toolsrc/src/vcpkg/commands.edit.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 044ae1c47..c9d52c572 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -157,6 +157,9 @@ namespace vcpkg::Commands::Edit #elif defined(__APPLE__) candidate_paths.push_back(fs::path{"/Applications/Visual Studio Code - Insiders.app/Contents/Resources/app/bin/code"}); candidate_paths.push_back(fs::path{"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code"}); +#elif defined(__linux__) + candidate_paths.push_back(fs::path{"/usr/share/code/bin/code"}); + candidate_paths.push_back(fs::path{"/usr/bin/code"}); #endif const auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); -- cgit v1.2.3