From 63e1e1f7117df20c9fe445ed9db8a808fc611ea4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 9 Mar 2018 21:53:29 -0800 Subject: [vcpkg] Fix issue in upgrade dependency resolution where self-referencing features cause cycles --- toolsrc/src/tests.plan.cpp | 30 +++++++++++++++++++++++++++++- toolsrc/src/vcpkg/dependencies.cpp | 2 +- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 08d3c1dab..95056810c 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -996,6 +996,34 @@ namespace UnitTest1 features_check(&plan[1], "a", {"core", "a1"}); } + + TEST_METHOD(basic_upgrade_scheme_with_self_features) + { + std::vector> pghs; + pghs.push_back(make_status_pgh("a")); + pghs.push_back(make_status_feature_pgh("a", "a1", "")); + pghs.push_back(make_status_feature_pgh("a", "a2", "a[a1]")); + StatusParagraphs status_db(std::move(pghs)); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "", {{"a1", ""}, {"a2", "a[a1]"}}); + + Dependencies::MapPortFileProvider provider(spec_map.map); + Dependencies::PackageGraph graph(provider, status_db); + + graph.upgrade(spec_a); + + auto plan = graph.serialize(); + + Assert::AreEqual(size_t(2), plan.size()); + + Assert::AreEqual("a", plan[0].spec().name().c_str()); + Assert::IsTrue(plan[0].remove_action.has_value()); + + Assert::AreEqual("a", plan[1].spec().name().c_str()); + Assert::IsTrue(plan[1].install_action.has_value()); + Assert::IsTrue(plan[1].install_action.get()->feature_list == std::set{"core", "a1", "a2"}); + } }; class ExportPlanTests : public TestClass @@ -1069,7 +1097,7 @@ namespace UnitTest1 Assert::IsTrue(plan[0].plan_type == Dependencies::ExportPlanType::NOT_BUILT); } - TEST_METHOD(basic_upgrade_scheme_with_features) + TEST_METHOD(basic_export_scheme_with_features) { std::vector> pghs; pghs.push_back(make_status_pgh("b")); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 1f853014b..1d017a8d3 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -530,7 +530,7 @@ namespace vcpkg::Dependencies for (auto&& depend : remove_edges_edges) { auto& depend_cluster = graph.get(depend.spec()); - graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); + if (&depend_cluster != &cluster) graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); mark_minus(depend_cluster, graph, graph_plan); } } -- cgit v1.2.3 From 6670b87c18c544bbc9fa167f583b27dc52bce3d9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 10 Mar 2018 14:19:07 -0800 Subject: [vcpkg] Add VCPKG_DEFAULT_VS_PATH environment variable --- toolsrc/src/vcpkg.cpp | 4 +++- toolsrc/src/vcpkg/vcpkgpaths.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index ef68e6f72..d9b915367 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -94,7 +94,9 @@ static void inner(const VcpkgCmdArguments& args) Checks::check_exit(VCPKG_LINE_INFO, !vcpkg_root_dir.empty(), "Error: Could not detect vcpkg-root."); - const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir); + auto default_vs_path = System::get_environment_variable("VCPKG_DEFAULT_VS_PATH").value_or(""); + + const Expected expected_paths = VcpkgPaths::create(vcpkg_root_dir, default_vs_path); Checks::check_exit(VCPKG_LINE_INFO, !expected_paths.error(), "Error: Invalid vcpkg root directory %s: %s", diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index e62ef8662..02bc5f041 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -293,7 +293,7 @@ namespace vcpkg return fetch_tool(paths.scripts, "installerbase", TOOL_DATA); } - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) { std::error_code ec; const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); @@ -304,6 +304,7 @@ namespace vcpkg VcpkgPaths paths; paths.root = canonical_vcpkg_root_dir; + paths.default_vs_path = default_vs_path; if (paths.root.empty()) { @@ -643,7 +644,11 @@ namespace vcpkg std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = prebuildinfo.platform_toolset.get(); - const auto vsp = prebuildinfo.visual_studio_path.get(); + auto vsp = prebuildinfo.visual_studio_path.get(); + if (!vsp && !default_vs_path.empty()) + { + vsp = &default_vs_path; + } if (tsv && vsp) { -- cgit v1.2.3 From ad7fa55bb004571bc7d2aad337dda978fe4d2bac Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 6 Mar 2018 09:57:37 -0800 Subject: [vcpkg] Improve handling of external toolchains. Extract MSVC settings to a separate toolchain file. --- toolsrc/src/vcpkg/build.cpp | 1 + toolsrc/src/vcpkg/vcpkgpaths.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 5870bd187..aa84b6cf5 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -209,6 +209,7 @@ namespace vcpkg::Build 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) diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 02bc5f041..46e80c4a9 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -622,7 +622,8 @@ namespace vcpkg const Toolset& VcpkgPaths::get_toolset(const Build::PreBuildInfo& prebuildinfo) const { - if (prebuildinfo.external_toolchain_file) + if (prebuildinfo.external_toolchain_file || + (!prebuildinfo.cmake_system_name.empty() && prebuildinfo.cmake_system_name != "WindowsStore")) { static Toolset external_toolset = []() -> Toolset { Toolset ret; -- cgit v1.2.3 From 81b58d1868a0f7edf324b2f366426e2973ac80b7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 9 Mar 2018 03:51:19 -0800 Subject: [vcpkg] Use unzip/zip on non-windows --- toolsrc/src/vcpkg/build.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index aa84b6cf5..408dde798 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -438,10 +438,15 @@ namespace vcpkg::Build 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&& _7za = paths.get_7za_exe(); System::cmd_execute_clean(Strings::format( R"("%s" x "%s" -o"%s" -y >nul)", _7za.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 auto maybe_bcf = Paragraphs::try_load_cached_control_package(paths, spec); bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); @@ -538,6 +543,7 @@ namespace vcpkg::Build !fs.exists(tmp_archive_path), "Could not remove file: %s", tmp_archive_path.u8string()); +#if defined(_WIN32) auto&& _7za = paths.get_7za_exe(); System::cmd_execute_clean(Strings::format( @@ -545,7 +551,12 @@ namespace vcpkg::Build _7za.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 fs.create_directories(archives_dir, ec); fs.rename(tmp_archive_path, archive_path); -- cgit v1.2.3 From 81b9ab1291bd322b5de8ad0cec2f21ce4d828a28 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 04:26:00 -0700 Subject: [vcpkg] Refactor do_build_package and add archive tombstoning --- toolsrc/src/vcpkg/build.cpp | 238 +++++++++++++++++++++------------------ toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/paragraphs.cpp | 2 +- 3 files changed, 131 insertions(+), 111 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 408dde798..7abd5ae0a 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -315,8 +315,90 @@ namespace vcpkg::Build } static ExtendedBuildResult do_build_package(const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const PackageSpec& spec, + const std::string& abi_tag, const BuildPackageConfig& config, const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + const Triplet& triplet = spec.triplet(); + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path& git_exe_path = paths.get_git_exe(); + + 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"}, + {"_VCPKG_NO_DOWNLOADS", !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, + {"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()) command.append(" && "); + 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)}; + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) { auto& fs = paths.get_filesystem(); const Triplet& triplet = config.triplet; @@ -359,9 +441,6 @@ namespace vcpkg::Build } const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path& git_exe_path = paths.get_git_exe(); - - const fs::path ports_cmake_script_path = paths.ports_cmake; if (GlobalState::g_binary_caching) { @@ -420,124 +499,66 @@ namespace vcpkg::Build std::unique_ptr bcf; - auto archives_dir = paths.root / "archives"; - if (!abi_tag.empty()) - { - archives_dir /= abi_tag.substr(0, 2); - } - auto archive_path = archives_dir / (abi_tag + ".zip"); + auto archives_root_dir = paths.root / "archives"; + auto archive_name = abi_tag + ".zip"; + auto archive_subpath = abi_tag.empty() ? fs::path() : fs::u8path(abi_tag.substr(0, 2)) / archive_name; + auto archive_path = archives_root_dir / archive_subpath; + auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; - if (GlobalState::g_binary_caching && !abi_tag.empty() && fs.exists(archive_path)) + auto found_archive = false; + + if (GlobalState::g_binary_caching && !abi_tag.empty()) { - System::println("Using cached binary package: %s", archive_path.u8string()); + if (fs.exists(archive_path)) + { + System::println("Using cached binary package: %s", archive_path.u8string()); - 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()); + 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&& _7za = paths.get_7za_exe(); + auto&& _7za = paths.get_7za_exe(); - System::cmd_execute_clean(Strings::format( - R"("%s" x "%s" -o"%s" -y >nul)", _7za.u8string(), archive_path.u8string(), pkg_path.u8string())); + System::cmd_execute_clean(Strings::format( + R"("%s" x "%s" -o"%s" -y >nul)", _7za.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())); + System::cmd_execute_clean(Strings::format( + R"(unzip -qq "%s" "-d%s")", archive_path.u8string(), pkg_path.u8string())); #endif - auto maybe_bcf = Paragraphs::try_load_cached_control_package(paths, spec); - bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); - } - else - { - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { - System::println("Could not locate cached archive: %s", archive_path.u8string()); + auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); + bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); + found_archive = true; + return {BuildResult::SUCCEEDED, std::move(bcf)}; } - - std::string all_features; - for (auto& feature : config.scf.feature_paragraphs) + else if (fs.exists(archive_tombstone_path)) { - 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, - ports_cmake_script_path, - { - {"CMD", "BUILD"}, - {"PORT", config.scf.core_paragraph->name}, - {"CURRENT_PORT_DIR", config.port_dir / "/."}, - {"TARGET_TRIPLET", 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"}, - {"_VCPKG_NO_DOWNLOADS", - !Util::Enum::to_bool(config.build_package_options.allow_downloads) ? "1" : "0"}, - {"GIT", git_exe_path}, - {"FEATURES", features}, - {"ALL_FEATURES", all_features}, - }); - - auto command = make_build_env_cmd(pre_build_info, toolset); - if (!command.empty()) command.append(" && "); - 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; - } + System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); + 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); + if (GlobalState::g_binary_caching && !abi_tag.empty()) + { + System::println("Could not locate cached archive: %s", archive_path.u8string()); + } - bcf = create_binary_control_file(*config.scf.core_paragraph, triplet, build_info, abi_tag); + ExtendedBuildResult result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); - if (error_count != 0) - { - return BuildResult::POST_BUILD_CHECKS_FAILED; - } - for (auto&& feature : config.feature_list) + if (GlobalState::g_binary_caching && !abi_tag.empty()) + { + if (result.code == BuildResult::SUCCEEDED) { - 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)); - } - } + auto tmp_archive_path = paths.buildtrees / spec.name() / (triplet.to_string() + ".zip"); - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { std::error_code ec; fs.write_contents( paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt", full_abi_info, ec); - } - - write_binary_control_file(paths, *bcf); - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { - auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); - - std::error_code ec; fs.remove(tmp_archive_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !fs.exists(tmp_archive_path), @@ -557,21 +578,20 @@ namespace vcpkg::Build paths.package_dir(spec).u8string(), tmp_archive_path.u8string())); #endif - fs.create_directories(archives_dir, ec); + fs.create_directories(archive_path.parent_path(), ec); fs.rename(tmp_archive_path, archive_path); 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 failure archive + std::error_code ec; + fs.create_directories(archive_tombstone_path.parent_path(), ec); + fs.write_contents(archive_tombstone_path, "", ec); + } } - return {BuildResult::SUCCEEDED, std::move(bcf)}; - } - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) - { - ExtendedBuildResult result = do_build_package(paths, config, status_db); if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) { diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 46c7c53b8..7d36fba82 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -306,7 +306,7 @@ namespace vcpkg::Install System::println("Building package %s... done", display_name_with_features); auto bcf = std::make_unique( - Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); + Paragraphs::try_load_cached_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO)); auto code = aux_install(display_name_with_features, *bcf); if (action.build_options.clean_packages == Build::CleanPackages::YES) diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp index b66d53994..d0b0c0abf 100644 --- a/toolsrc/src/vcpkg/paragraphs.cpp +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -228,7 +228,7 @@ namespace vcpkg::Paragraphs return error_info; } - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) + Expected try_load_cached_package(const VcpkgPaths& paths, const PackageSpec& spec) { Expected>> pghs = get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); -- cgit v1.2.3 From f72b46690a89a7e19563f93f0eaa5f8a21184254 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 06:25:59 -0700 Subject: [vcpkg] Silence warnings on recent clang --- toolsrc/src/vcpkg/metrics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index d49cadbe2..9e17b237d 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -92,7 +92,7 @@ namespace vcpkg::Metrics { encoded.append("\\\""); } - else if (ch < 0x20 || ch >= 0x80) + else if (ch < 0x20 || static_cast(ch) >= 0x80) { // Note: this treats incoming Strings as Latin-1 static constexpr const char HEX[16] = { -- cgit v1.2.3 From 50a93f01970e499f35edbb57ce0328baeb465635 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 07:32:51 -0700 Subject: [vcpkg] Fix get_executable_path on BSD --- toolsrc/src/vcpkg/base/system.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index e55db9461..e24098f97 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -8,7 +8,11 @@ #include #if defined(__APPLE__) -# include +#include +#endif + +#if defined(__FreeBSD__) +#include #endif #pragma comment(lib, "Advapi32") @@ -35,14 +39,22 @@ namespace vcpkg::System const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); if (bytes == 0) std::abort(); return fs::path(buf, buf + bytes); -#elif __APPLE__ +#elif defined(__APPLE__) uint32_t size = 1024 * 32; char buf[size] = {}; bool 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)); + std::unique_ptr canonicalPath(realpath(buf, NULL)); Checks::check_exit(VCPKG_LINE_INFO, result != -1, "Could not determine current executable path."); return fs::path(std::string(canonicalPath.get())); +#elif defined(__FreeBSD__) + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + char exePath[2048]; + size_t len = sizeof(exePath); + auto rcode = sysctl(mib, 4, exePath, &len, NULL, 0); + Checks::check_exit(VCPKG_LINE_INFO, rcode == 0, "Could not determine current executable path."); + Checks::check_exit(VCPKG_LINE_INFO, len > 0, "Could not determine current executable path."); + return fs::path(exePath, exePath + len - 1); #else /* LINUX */ std::array buf; auto written = readlink("/proc/self/exe", buf.data(), buf.size()); -- cgit v1.2.3 From 3c7997215bc2e44125912fb7aae672f1b63944a8 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 13 Mar 2018 11:06:22 -0700 Subject: [vcpkg] Improve default triplets for non-windows --- toolsrc/src/vcpkg.cpp | 8 ++++++++ toolsrc/src/vcpkg/base/strings.cpp | 7 +++---- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index d9b915367..a65045aa8 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -157,7 +157,15 @@ static void inner(const VcpkgCmdArguments& args) } else { +#if defined(_WIN32) default_triplet = Triplet::X86_WINDOWS; +#elif defined(__APPLE__) + default_triplet = Triplet::from_canonical_name("x64-osx"); +#elif defined(__FreeBSD__) + default_triplet = Triplet::from_canonical_name("x64-freebsd"); +#else + default_triplet = Triplet::from_canonical_name("x64-linux"); +#endif } } diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index d912734e3..a08512c9f 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -108,11 +108,10 @@ namespace vcpkg::Strings #endif } - std::string ascii_to_lowercase(const std::string& input) + std::string ascii_to_lowercase(std::string s) { - std::string output(input); - std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char); - return output; + std::transform(s.begin(), s.end(), s.begin(), &details::tolower_char); + return s; } bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) -- cgit v1.2.3 From 90c4b8dbb7a69584a4a36c67e4982cf086b7c578 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Mar 2018 04:33:14 -0700 Subject: [vcpkg] Further refactoring inside `build_package()` --- toolsrc/src/vcpkg/build.cpp | 320 ++++++++++++++++++++---------------- toolsrc/src/vcpkg/commands.ci.cpp | 21 ++- toolsrc/src/vcpkg/commands.hash.cpp | 8 +- 3 files changed, 201 insertions(+), 148 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 7abd5ae0a..99ae5d2a3 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -396,23 +396,160 @@ namespace vcpkg::Build return {BuildResult::SUCCEEDED, std::move(bcf)}; } - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) + 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, + const StatusParagraphs& status_db) { + auto result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); + + 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) && file.filename() != "src") + { + std::error_code ec; + fs.remove_all(file, ec); + } + } + } + + return result; + } + + struct AbiEntry + { + std::string key; + std::string value; + }; + + struct AbiTagAndFile + { + std::string tag; + fs::path tag_file; + }; + + static Optional compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span dependency_abis) + { + if (!GlobalState::g_binary_caching) 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; + + abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); + + abi_tag_entries.emplace_back( + AbiEntry{"portfile", Commands::Hash::get_file_hash(paths, config.port_dir / "portfile.cmake", "SHA1")}); + abi_tag_entries.emplace_back( + AbiEntry{"control", Commands::Hash::get_file_hash(paths, config.port_dir / "CONTROL", "SHA1")}); + + abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); + + std::string features = Strings::join(";", config.feature_list); + abi_tag_entries.emplace_back(AbiEntry{"features", features}); - struct AbiEntry + if (config.build_package_options.use_head_version == UseHeadVersion::YES) + abi_tag_entries.emplace_back(AbiEntry{"head", ""}); + + std::string full_abi_info = + Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); + + if (GlobalState::debugging) { - std::string key; - std::string value; - }; + System::println("[DEBUG] "); + for (auto&& entry : abi_tag_entries) + { + System::println("[DEBUG] %s|%s", entry.key, entry.value); + } + System::println("[DEBUG] "); + } - std::vector abi_tag_entries; + auto abi_tag_entries_missing = abi_tag_entries; + Util::stable_keep_if(abi_tag_entries_missing, [](const AbiEntry& p) { return p.value.empty(); }); - const PackageSpec spec = - PackageSpec::from_name_and_triplet(config.scf.core_paragraph->name, triplet).value_or_exit(VCPKG_LINE_INFO); + if (abi_tag_entries_missing.empty()) + { + std::error_code ec; + fs.create_directories(paths.buildtrees / name, ec); + 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{Commands::Hash::get_file_hash(paths, abi_file_path, "SHA1"), abi_file_path}; + } + else + { + 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&& _7za = paths.get_7za_exe(); + + System::cmd_execute_clean(Strings::format( + R"("%s" x "%s" -o"%s" -y >nul)", _7za.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&& _7za = paths.get_7za_exe(); + + System::cmd_execute_clean(Strings::format( + R"("%s" a "%s" "%s\*" >nul)", + _7za.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); @@ -422,7 +559,7 @@ namespace vcpkg::Build // Find all features that aren't installed. This destroys required_fspecs. Util::unstable_keep_if(required_fspecs, [&](FeatureSpec const& fspec) { - return !status_db.is_installed(fspec) && fspec.name() != spec.name(); + return !status_db.is_installed(fspec) && fspec.name() != name; }); if (!required_fspecs.empty()) @@ -430,109 +567,45 @@ namespace vcpkg::Build 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; auto status_it = status_db.find_installed(pspec); Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); - abi_tag_entries.emplace_back( + dependency_abis.emplace_back( AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); } - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - - if (GlobalState::g_binary_caching) - { - abi_tag_entries.emplace_back(AbiEntry{ - "portfile", Commands::Hash::get_file_hash(cmake_exe_path, config.port_dir / "portfile.cmake", "SHA1")}); - abi_tag_entries.emplace_back(AbiEntry{ - "control", Commands::Hash::get_file_hash(cmake_exe_path, config.port_dir / "CONTROL", "SHA1")}); - } - const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); - 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", ""}); - - std::string full_abi_info = - Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); - - std::string abi_tag; - - if (GlobalState::g_binary_caching) - { - 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::stable_keep_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 / spec.name(), ec); - auto abi_file_path = paths.buildtrees / spec.name() / "vcpkg_abi_info"; - fs.write_contents(abi_file_path, full_abi_info); - - abi_tag = Commands::Hash::get_file_hash(paths.get_cmake_exe(), abi_file_path, "SHA1"); - } - else - { - 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"; - })); - } - } + auto abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); std::unique_ptr bcf; - auto archives_root_dir = paths.root / "archives"; - auto archive_name = abi_tag + ".zip"; - auto archive_subpath = abi_tag.empty() ? fs::path() : fs::u8path(abi_tag.substr(0, 2)) / archive_name; - auto archive_path = archives_root_dir / archive_subpath; - auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + auto maybe_abi_tag_and_file = abi_tag_and_file.get(); - auto found_archive = false; - - if (GlobalState::g_binary_caching && !abi_tag.empty()) + if (GlobalState::g_binary_caching && maybe_abi_tag_and_file) { + auto archives_root_dir = paths.root / "archives"; + auto archive_name = maybe_abi_tag_and_file->tag + ".zip"; + auto archive_subpath = fs::u8path(maybe_abi_tag_and_file->tag.substr(0, 2)) / archive_name; + auto archive_path = archives_root_dir / archive_subpath; + auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + if (fs.exists(archive_path)) { System::println("Using cached binary package: %s", archive_path.u8string()); - 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&& _7za = paths.get_7za_exe(); - - System::cmd_execute_clean(Strings::format( - R"("%s" x "%s" -o"%s" -y >nul)", _7za.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 + decompress_archive(paths, spec, archive_path); auto maybe_bcf = Paragraphs::try_load_cached_package(paths, spec); bcf = std::make_unique(std::move(maybe_bcf).value_or_exit(VCPKG_LINE_INFO)); - found_archive = true; return {BuildResult::SUCCEEDED, std::move(bcf)}; } else if (fs.exists(archive_tombstone_path)) @@ -540,75 +613,42 @@ namespace vcpkg::Build System::println("Found failure tombstone: %s", archive_tombstone_path.u8string()); return BuildResult::BUILD_FAILED; } - } - if (GlobalState::g_binary_caching && !abi_tag.empty()) - { System::println("Could not locate cached archive: %s", archive_path.u8string()); - } - ExtendedBuildResult result = do_build_package(paths, pre_build_info, spec, abi_tag, config, status_db); + ExtendedBuildResult result = do_build_package_and_clean_buildtrees( + paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + + std::error_code ec; + auto abi_file_in_package = paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt"; + fs.copy_file(maybe_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 (GlobalState::g_binary_caching && !abi_tag.empty()) - { if (result.code == BuildResult::SUCCEEDED) { - auto tmp_archive_path = paths.buildtrees / spec.name() / (triplet.to_string() + ".zip"); + auto tmp_archive_path = paths.buildtrees / spec.name() / (spec.triplet().to_string() + ".zip"); - std::error_code ec; - fs.write_contents( - paths.package_dir(spec) / "share" / spec.name() / "vcpkg_abi_info.txt", full_abi_info, 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&& _7za = paths.get_7za_exe(); + compress_archive(paths, spec, tmp_archive_path); - System::cmd_execute_clean(Strings::format( - R"("%s" a "%s" "%s\*" >nul)", - _7za.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 fs.create_directories(archive_path.parent_path(), ec); - fs.rename(tmp_archive_path, archive_path); 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 failure archive - std::error_code ec; + // Build failed, so store tombstone archive fs.create_directories(archive_tombstone_path.parent_path(), ec); fs.write_contents(archive_tombstone_path, "", ec); } - } - if (config.build_package_options.clean_buildtrees == CleanBuildtrees::YES) + return result; + } + else { - 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) && file.filename() != "src") - { - std::error_code ec; - fs.remove_all(file, ec); - } - } + return do_build_package_and_clean_buildtrees( + paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); } - - return result; } const std::string& to_string(const BuildResult build_result) @@ -732,7 +772,7 @@ namespace vcpkg::Build { return it_hash->second; } - auto hash = Commands::Hash::get_file_hash(paths.get_cmake_exe(), triplet_file_path, "SHA1"); + auto hash = Commands::Hash::get_file_hash(paths, triplet_file_path, "SHA1"); s_hash_cache.emplace(triplet_file_path, hash); return hash; } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index c43f25b40..e01072a0a 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -24,6 +24,7 @@ namespace vcpkg::Commands::CI Install::InstallSummary summary; }; + static constexpr StringLiteral OPTION_DRY_RUN = "--dry-run"; static constexpr StringLiteral OPTION_EXCLUDE = "--exclude"; static constexpr StringLiteral OPTION_XUNIT = "--x-xunit"; @@ -32,11 +33,14 @@ namespace vcpkg::Commands::CI {OPTION_XUNIT, "File to output results in XUnit format (internal)"}, }}; + static constexpr std::array CI_SWITCHES = { + {{OPTION_DRY_RUN, "Print out plan without execution"}}}; + const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("ci x64-windows"), - 0, + 1, SIZE_MAX, - {{}, CI_SETTINGS}, + {CI_SWITCHES, CI_SETTINGS}, nullptr, }; @@ -52,6 +56,8 @@ namespace vcpkg::Commands::CI exclusions_set.insert(exclusions.begin(), exclusions.end()); } + auto is_dry_run = Util::Sets::contains(options.switches, OPTION_DRY_RUN); + std::vector triplets; for (const std::string& triplet : args.command_arguments) { @@ -94,8 +100,15 @@ namespace vcpkg::Commands::CI } } - auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); - results.push_back({triplet, std::move(summary)}); + if (is_dry_run) + { + Dependencies::print_plan(action_plan); + } + else + { + auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); + results.push_back({triplet, std::move(summary)}); + } } for (auto&& result : results) diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index bbbbed036..cb0a8cc51 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -7,11 +7,11 @@ namespace vcpkg::Commands::Hash { - std::string get_file_hash(fs::path const& cmake_exe_path, fs::path const& path, std::string const& hash_type) + std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type) { const std::string cmd_line = Strings::format( R"("%s" -E %ssum "%s")", - cmake_exe_path.u8string(), + paths.get_cmake_exe().u8string(), Strings::ascii_to_lowercase(hash_type), path.u8string()); @@ -48,12 +48,12 @@ namespace vcpkg::Commands::Hash if (args.command_arguments.size() == 1) { - auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], "SHA512"); + auto hash = get_file_hash(paths, args.command_arguments[0], "SHA512"); System::println(hash); } if (args.command_arguments.size() == 2) { - auto hash = get_file_hash(paths.get_cmake_exe(), args.command_arguments[0], args.command_arguments[1]); + auto hash = get_file_hash(paths, args.command_arguments[0], args.command_arguments[1]); System::println(hash); } -- cgit v1.2.3 From 3a056235b85f34573903a7dc325d45e66549b6ff Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Mar 2018 16:56:33 -0700 Subject: [vcpkg] Create minimal package structure even on failure --- toolsrc/src/vcpkg/build.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 99ae5d2a3..b71bdbf25 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -620,6 +620,7 @@ namespace vcpkg::Build paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); 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(maybe_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()); -- cgit v1.2.3 From d253123055e6bdfb181c6a8a14a63e2d6fc68cad Mon Sep 17 00:00:00 2001 From: Jacob Zhong Date: Sun, 18 Mar 2018 20:24:19 +0800 Subject: Add options and documentation for env command (#3007) * [vcpkg] Add options and documentation for env command * [vcpkg-env] Cleanup. Add tools/*. --- toolsrc/src/vcpkg/base/system.cpp | 15 +++++++++-- toolsrc/src/vcpkg/commands.env.cpp | 54 +++++++++++++++++++++++++++++++++----- toolsrc/src/vcpkg/help.cpp | 6 +---- 3 files changed, 62 insertions(+), 13 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index e24098f97..f339afa51 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -153,12 +153,12 @@ namespace vcpkg::System R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args); } - int cmd_execute_clean(const CStringView cmd_line) + int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) { #if defined(_WIN32) 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)"; - static const std::string NEW_PATH = Strings::format( + std::string NEW_PATH = Strings::format( R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); std::vector env_wstrings = { @@ -224,11 +224,22 @@ namespace vcpkg::System env_cstr.push_back(L'\0'); } + if (extra_env.find("PATH") != extra_env.end()) + NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); env_cstr.append(L"VSLANG=1033"); env_cstr.push_back(L'\0'); + for (auto item : extra_env) + { + if (item.first == "PATH") continue; + env_cstr.append(Strings::to_utf16(item.first)); + env_cstr.push_back(L'='); + env_cstr.append(Strings::to_utf16(item.second)); + env_cstr.push_back(L'\0'); + } + STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); startup_info.cb = sizeof(STARTUPINFOW); diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index f3beef6cd..d078baedb 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -7,25 +8,66 @@ namespace vcpkg::Commands::Env { + static constexpr StringLiteral OPTION_BIN = "--bin"; + static constexpr StringLiteral OPTION_INCLUDE = "--include"; + static constexpr StringLiteral OPTION_DEBUG_BIN = "--debug-bin"; + static constexpr StringLiteral OPTION_TOOLS = "--tools"; + static constexpr StringLiteral OPTION_PYTHON = "--python"; + + static constexpr std::array SWITCHES = {{ + {OPTION_BIN, "Add installed bin/ to PATH"}, + {OPTION_INCLUDE, "Add installed include/ to INCLUDE"}, + {OPTION_DEBUG_BIN, "Add installed debug/bin/ to PATH"}, + {OPTION_TOOLS, "Add installed tools/*/ to PATH"}, + {OPTION_PYTHON, "Add installed python/ to PYTHONPATH"}, + }}; + const CommandStructure COMMAND_STRUCTURE = { Help::create_example_string("env --triplet x64-windows"), 0, 0, - {}, + {SWITCHES, {}}, nullptr, }; - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& triplet) { - args.parse_arguments(COMMAND_STRUCTURE); + const auto& fs = paths.get_filesystem(); + + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); - const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, triplet); const Toolset& toolset = paths.get_toolset(pre_build_info); auto env_cmd = Build::make_build_env_cmd(pre_build_info, toolset); + + std::unordered_map extra_env = {}; + const bool add_bin = Util::Sets::contains(options.switches, OPTION_BIN); + const bool add_include = Util::Sets::contains(options.switches, OPTION_INCLUDE); + const bool add_debug_bin = Util::Sets::contains(options.switches, OPTION_DEBUG_BIN); + const bool add_tools = Util::Sets::contains(options.switches, OPTION_TOOLS); + const bool add_python = Util::Sets::contains(options.switches, OPTION_PYTHON); + + std::vector path_vars; + if (add_bin) path_vars.push_back((paths.installed / triplet.to_string() / "bin").u8string()); + if (add_debug_bin) path_vars.push_back((paths.installed / triplet.to_string() / "debug" / "bin").u8string()); + if (add_include) extra_env.emplace("INCLUDE", (paths.installed / triplet.to_string() / "include").u8string()); + if (add_tools) + { + auto tools_dir = paths.installed / triplet.to_string() / "tools"; + auto tool_files = fs.get_files_non_recursive(tools_dir); + path_vars.push_back(tools_dir.u8string()); + for (auto&& tool_dir : tool_files) + { + if (fs.is_directory(tool_dir)) path_vars.push_back(tool_dir.u8string()); + } + } + if (add_python) extra_env.emplace("PYTHONPATH", (paths.installed / triplet.to_string() / "python").u8string()); + if (path_vars.size() > 0) extra_env.emplace("PATH", Strings::join(";", path_vars)); + if (env_cmd.empty()) - System::cmd_execute_clean("cmd"); + System::cmd_execute_clean("cmd", extra_env); else - System::cmd_execute_clean(env_cmd + " && cmd"); + System::cmd_execute_clean(env_cmd + " && cmd", extra_env); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index b7d355742..743619937 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -98,14 +98,10 @@ namespace vcpkg::Help " vcpkg create \n" " [archivename] Create a new package\n" " vcpkg owns Search for files in installed packages\n" - " vcpkg cache List cached compiled packages\n" + " vcpkg env Creates a clean shell environment for development or compiling.\n" " vcpkg version Display version information\n" " vcpkg contact Display contact information to send feedback\n" "\n" - //"internal commands:\n" - //" --check-build-deps \n" - //" --create-binary-control \n" - //"\n" "Options:\n" " --triplet Specify the target architecture triplet.\n" " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" -- cgit v1.2.3 From eab1d5c531695c2a644276832578e5550dd9abf6 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 14 Mar 2018 10:30:27 -0700 Subject: [vcpkg-ci] Do not rebuild libraries that were previously successful or failed --- toolsrc/src/tests.plan.cpp | 84 ++++++++++++++++++++- toolsrc/src/vcpkg/base/system.cpp | 10 ++- toolsrc/src/vcpkg/build.cpp | 44 ++++------- toolsrc/src/vcpkg/commands.ci.cpp | 138 +++++++++++++++++++++++++++++++++- toolsrc/src/vcpkg/dependencies.cpp | 11 ++- toolsrc/src/vcpkg/install.cpp | 59 ++++++++------- toolsrc/src/vcpkg/sourceparagraph.cpp | 10 +++ 7 files changed, 289 insertions(+), 67 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/tests.plan.cpp b/toolsrc/src/tests.plan.cpp index 95056810c..a99f1abb9 100644 --- a/toolsrc/src/tests.plan.cpp +++ b/toolsrc/src/tests.plan.cpp @@ -593,6 +593,87 @@ namespace UnitTest1 features_check(&install_plan[0], "a", {"core"}, Triplet::X64_WINDOWS); } + TEST_METHOD(install_plan_action_dependencies) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_c = spec_map.emplace("c"); + auto spec_b = spec_map.emplace("b", "c"); + spec_map.emplace("a", "b"); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"core"}, Triplet::X64_WINDOWS); + + features_check(&install_plan[1], "b", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[1].install_action.get()->computed_dependencies == + std::vector{spec_c}); + + features_check(&install_plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[2].install_action.get()->computed_dependencies == + std::vector{spec_b}); + } + + TEST_METHOD(install_plan_action_dependencies_2) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_c = spec_map.emplace("c"); + auto spec_b = spec_map.emplace("b", "c"); + spec_map.emplace("a", "c, b"); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 3); + features_check(&install_plan[0], "c", {"core"}, Triplet::X64_WINDOWS); + + features_check(&install_plan[1], "b", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[1].install_action.get()->computed_dependencies == + std::vector{spec_c}); + + features_check(&install_plan[2], "a", {"core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[2].install_action.get()->computed_dependencies == + std::vector{spec_b, spec_c}); + } + + TEST_METHOD(install_plan_action_dependencies_3) + { + std::vector> status_paragraphs; + + // Add a port "a" which depends on the core of "b", which was already + // installed explicitly + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + spec_map.emplace("a", "", {{"0", ""}, {"1", "a[0]"}}, {"1"}); + + // Install "a" (without explicit feature specification) + auto install_specs = FullPackageSpec::from_string("a", Triplet::X64_WINDOWS); + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({install_specs.value_or_exit(VCPKG_LINE_INFO)}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::IsTrue(install_plan.size() == 1); + features_check(&install_plan[0], "a", {"1", "0", "core"}, Triplet::X64_WINDOWS); + Assert::IsTrue(install_plan[0].install_action.get()->computed_dependencies == std::vector{}); + } + TEST_METHOD(upgrade_with_default_features_1) { std::vector> pghs; @@ -619,7 +700,6 @@ namespace UnitTest1 Assert::IsTrue(plan[0].remove_action.has_value()); Assert::AreEqual("a", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); features_check(&plan[1], "a", {"core", "0"}, Triplet::X86_WINDOWS); } @@ -651,11 +731,9 @@ namespace UnitTest1 Assert::IsTrue(plan[0].remove_action.has_value()); Assert::AreEqual("b", plan[1].spec().name().c_str()); - Assert::IsTrue(plan[1].install_action.has_value()); features_check(&plan[1], "b", {"b0", "core"}, Triplet::X64_WINDOWS); Assert::AreEqual("a", plan[2].spec().name().c_str()); - Assert::IsTrue(plan[2].install_action.has_value()); features_check(&plan[2], "a", {"core"}, Triplet::X64_WINDOWS); } diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index f339afa51..a315c7880 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -314,6 +314,8 @@ namespace vcpkg::System // Flush stdout before launching external process fflush(stdout); + auto timer = Chrono::ElapsedTimer::create_started(); + #if defined(_WIN32) const auto actual_cmd_line = Strings::format(R"###("%s 2>&1")###", cmd_line); @@ -335,8 +337,10 @@ namespace vcpkg::System } const auto ec = _pclose(pipe); - Debug::println("_pclose() returned %d", ec); remove_byte_order_marks(&output); + + Debug::println("_pclose() returned %d after %8d us", ec, (int)timer.microseconds()); + return {ec, Strings::to_utf8(output)}; #else const auto actual_cmd_line = Strings::format(R"###(%s 2>&1)###", cmd_line); @@ -359,7 +363,9 @@ namespace vcpkg::System } const auto ec = pclose(pipe); - Debug::println("pclose() returned %d", ec); + + Debug::println("_pclose() returned %d after %8d us", ec, (int)timer.microseconds()); + return {ec, output}; #endif } diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index b71bdbf25..bc9eca3ba 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -273,12 +273,10 @@ namespace vcpkg::Build return filter_dependencies(config.scf.core_paragraph->depends, triplet); } - auto it = - Util::find_if(config.scf.feature_paragraphs, - [&](std::unique_ptr const& fpgh) { return fpgh->name == feature; }); - Checks::check_exit(VCPKG_LINE_INFO, it != config.scf.feature_paragraphs.end()); + auto maybe_feature = config.scf.find_feature(feature); + Checks::check_exit(VCPKG_LINE_INFO, maybe_feature.has_value()); - return filter_dependencies(it->get()->depends, triplet); + return filter_dependencies(maybe_feature.get()->depends, triplet); }); auto dep_fspecs = FeatureSpec::from_strings_and_triplet(dep_strings, triplet); @@ -423,22 +421,10 @@ namespace vcpkg::Build return result; } - struct AbiEntry - { - std::string key; - std::string value; - }; - - struct AbiTagAndFile - { - std::string tag; - fs::path tag_file; - }; - - static Optional compute_abi_tag(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const PreBuildInfo& pre_build_info, - Span dependency_abis) + Optional compute_abi_tag(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const PreBuildInfo& pre_build_info, + Span dependency_abis) { if (!GlobalState::g_binary_caching) return nullopt; @@ -584,17 +570,17 @@ namespace vcpkg::Build const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - auto abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); + auto maybe_abi_tag_and_file = compute_abi_tag(paths, config, pre_build_info, dependency_abis); std::unique_ptr bcf; - auto maybe_abi_tag_and_file = abi_tag_and_file.get(); + auto abi_tag_and_file = maybe_abi_tag_and_file.get(); - if (GlobalState::g_binary_caching && maybe_abi_tag_and_file) + if (GlobalState::g_binary_caching && abi_tag_and_file) { auto archives_root_dir = paths.root / "archives"; - auto archive_name = maybe_abi_tag_and_file->tag + ".zip"; - auto archive_subpath = fs::u8path(maybe_abi_tag_and_file->tag.substr(0, 2)) / archive_name; + auto archive_name = abi_tag_and_file->tag + ".zip"; + auto archive_subpath = fs::u8path(abi_tag_and_file->tag.substr(0, 2)) / archive_name; auto archive_path = archives_root_dir / archive_subpath; auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; @@ -617,12 +603,12 @@ 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, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); 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(maybe_abi_tag_and_file->tag_file, abi_file_in_package, fs::stdfs::copy_options::none, ec); + 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) @@ -648,7 +634,7 @@ namespace vcpkg::Build else { return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config, status_db); } } diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp index e01072a0a..45eb1c83e 100644 --- a/toolsrc/src/vcpkg/commands.ci.cpp +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -1,5 +1,6 @@ #include "pch.h" +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -44,8 +46,120 @@ namespace vcpkg::Commands::CI nullptr, }; + UnknownCIPortsResults find_unknown_ports_for_ci(const VcpkgPaths& paths, + const std::set& exclusions, + const Dependencies::PortFileProvider& provider, + const std::vector& fspecs) + { + UnknownCIPortsResults ret; + + auto& fs = paths.get_filesystem(); + + std::map abi_tag_map; + std::set will_fail; + + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, + Build::AllowDownloads::YES, + Build::CleanBuildtrees::YES, + Build::CleanPackages::YES}; + + vcpkg::Cache pre_build_info_cache; + + auto action_plan = Dependencies::create_feature_install_plan(provider, fspecs, StatusParagraphs{}); + + for (auto&& action : action_plan) + { + if (auto p = action.install_action.get()) + { + // determine abi tag + std::string abi; + if (auto scf = p->source_control_file.get()) + { + auto triplet = p->spec.triplet(); + + const Build::BuildPackageConfig build_config{p->source_control_file.value_or_exit(VCPKG_LINE_INFO), + triplet, + paths.port_dir(p->spec), + install_plan_options, + p->feature_list}; + + auto dependency_abis = + Util::fmap(p->computed_dependencies, [&](const PackageSpec& spec) -> Build::AbiEntry { + auto it = abi_tag_map.find(spec); + + if (it == abi_tag_map.end()) + return {spec.name(), ""}; + else + return {spec.name(), it->second}; + }); + const auto& pre_build_info = pre_build_info_cache.get_lazy( + triplet, [&]() { return Build::PreBuildInfo::from_triplet_file(paths, triplet); }); + + auto maybe_tag_and_file = + Build::compute_abi_tag(paths, build_config, pre_build_info, dependency_abis); + if (auto tag_and_file = maybe_tag_and_file.get()) + { + abi = tag_and_file->tag; + 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); + } + + std::string state; + + auto archives_root_dir = paths.root / "archives"; + auto archive_name = abi + ".zip"; + auto archive_subpath = fs::u8path(abi.substr(0, 2)) / archive_name; + auto archive_path = archives_root_dir / archive_subpath; + auto archive_tombstone_path = archives_root_dir / "fail" / archive_subpath; + + bool b_will_build = false; + + if (Util::Sets::contains(exclusions, p->spec.name())) + { + 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); + will_fail.emplace(p->spec); + } + else if (fs.exists(archive_path)) + { + state += "pass"; + ret.known.emplace(p->spec, BuildResult::SUCCEEDED); + } + else if (fs.exists(archive_tombstone_path)) + { + state += "fail"; + ret.known.emplace(p->spec, BuildResult::BUILD_FAILED); + will_fail.emplace(p->spec); + } + else + { + ret.unknown.push_back(p->spec); + b_will_build = true; + } + + System::println("%40s: %1s %8s: %s", p->spec, (b_will_build ? "*" : " "), state, abi); + } + } + + return ret; + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { + Checks::check_exit( + VCPKG_LINE_INFO, GlobalState::g_binary_caching, "The ci command requires binary caching to be enabled."); + const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE); std::set exclusions_set; @@ -77,16 +191,21 @@ namespace vcpkg::Commands::CI Build::CleanBuildtrees::YES, Build::CleanPackages::YES}; - std::vector ports = Install::get_all_port_names(paths); + std::vector> all_known_results; + + std::vector all_ports = Install::get_all_port_names(paths); std::vector results; for (const Triplet& triplet : triplets) { Input::check_triplet(triplet, paths); - std::vector specs = PackageSpec::to_package_specs(ports, triplet); + + std::vector specs = PackageSpec::to_package_specs(all_ports, triplet); // Install the default features for every package - const auto featurespecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + auto all_fspecs = Util::fmap(specs, [](auto& spec) { return FeatureSpec(spec, ""); }); + auto split_specs = find_unknown_ports_for_ci(paths, exclusions_set, paths_port_file, all_fspecs); + auto fspecs = Util::fmap(split_specs.unknown, [](auto& spec) { return FeatureSpec(spec, ""); }); - auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, featurespecs, status_db); + auto action_plan = Dependencies::create_feature_install_plan(paths_port_file, fspecs, status_db); for (auto&& action : action_plan) { @@ -107,7 +226,10 @@ namespace vcpkg::Commands::CI else { auto summary = Install::perform(action_plan, Install::KeepGoing::YES, paths, status_db); + 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)); } } @@ -125,6 +247,14 @@ namespace vcpkg::Commands::CI 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); diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp index 1d017a8d3..f6d81c973 100644 --- a/toolsrc/src/vcpkg/dependencies.cpp +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -144,12 +144,14 @@ namespace vcpkg::Dependencies InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const SourceControlFile& scf, const std::set& features, - const RequestType& request_type) + const RequestType& request_type, + std::vector&& dependencies) : spec(spec) , source_control_file(scf) , plan_type(InstallPlanType::BUILD_AND_INSTALL) , request_type(request_type) , feature_list(features) + , computed_dependencies(std::move(dependencies)) { } @@ -162,6 +164,7 @@ namespace vcpkg::Dependencies , plan_type(InstallPlanType::ALREADY_INSTALLED) , request_type(request_type) , feature_list(features) + , computed_dependencies(installed_package.get()->dependencies()) { } @@ -683,11 +686,17 @@ namespace vcpkg::Dependencies // If it will be transiently uninstalled, we need to issue a full installation command auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); + + auto dep_specs = Util::fmap(m_graph_plan->install_graph.adjacency_list(p_cluster), + [](ClusterPtr const& p) { return p->spec; }); + Util::sort_unique_erase(dep_specs); + plan.emplace_back(InstallPlanAction{ p_cluster->spec, *pscf, p_cluster->to_install_features, p_cluster->request_type, + std::move(dep_specs), }); } else diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 7d36fba82..e30a34c18 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -668,39 +668,42 @@ namespace vcpkg::Install return nullptr; } + std::string InstallSummary::xunit_result(const PackageSpec& spec, Chrono::ElapsedTime time, BuildResult code) + { + std::string inner_block; + const char* result_string = ""; + switch (code) + { + case BuildResult::POST_BUILD_CHECKS_FAILED: + case BuildResult::FILE_CONFLICTS: + case BuildResult::BUILD_FAILED: + result_string = "Fail"; + inner_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)); + break; + case BuildResult::SUCCEEDED: result_string = "Pass"; break; + default: Checks::exit_fail(VCPKG_LINE_INFO); + } + + return Strings::format(R"(%s)" + "\n", + spec, + spec, + time.as().count(), + result_string, + inner_block); + } + std::string InstallSummary::xunit_results() const { std::string xunit_doc; for (auto&& result : results) { - std::string inner_block; - const char* result_string = ""; - switch (result.build_result.code) - { - case BuildResult::POST_BUILD_CHECKS_FAILED: - case BuildResult::FILE_CONFLICTS: - case BuildResult::BUILD_FAILED: - result_string = "Fail"; - inner_block = Strings::format("", - to_string(result.build_result.code)); - break; - case BuildResult::EXCLUDED: - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: - result_string = "Skip"; - inner_block = - Strings::format("", to_string(result.build_result.code)); - break; - case BuildResult::SUCCEEDED: result_string = "Pass"; break; - default: Checks::exit_fail(VCPKG_LINE_INFO); - } - - xunit_doc += Strings::format(R"(%s)" - "\n", - result.spec, - result.spec, - result.timing.as().count(), - result_string, - inner_block); + xunit_doc += xunit_result(result.spec, result.timing, result.build_result.code); } return xunit_doc; } diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp index 0b4baf189..ed61cb42a 100644 --- a/toolsrc/src/vcpkg/sourceparagraph.cpp +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -158,6 +158,16 @@ namespace vcpkg return std::move(control_file); } + Optional SourceControlFile::find_feature(const std::string& featurename) const + { + auto it = Util::find_if(feature_paragraphs, + [&](const std::unique_ptr& p) { return p->name == featurename; }); + if (it != feature_paragraphs.end()) + return **it; + else + return nullopt; + } + Dependency Dependency::parse_dependency(std::string name, std::string qualifier) { Dependency dep; -- cgit v1.2.3 From ab7985a34b8a4de59dc9a6e6c4c40fbb564797b8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 16 Mar 2018 16:53:48 -0700 Subject: [vcpkg-hash] Use BCrypt on Windows --- toolsrc/src/vcpkg/base/strings.cpp | 13 +++- toolsrc/src/vcpkg/commands.hash.cpp | 124 ++++++++++++++++++++++++++++++++---- 2 files changed, 121 insertions(+), 16 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp index a08512c9f..5fedf3e1f 100644 --- a/toolsrc/src/vcpkg/base/strings.cpp +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -7,10 +7,11 @@ namespace vcpkg::Strings::details { // To disambiguate between two overloads - static const auto isspace = [](const char c) { return std::isspace(c); }; + static bool IS_SPACE(const char c) { return std::isspace(c) != 0; }; // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() static char tolower_char(const char c) { return static_cast(std::tolower(c)); } + static char toupper_char(const char c) { return static_cast(std::toupper(c)); } #if defined(_WIN32) static _locale_t& c_locale() @@ -114,6 +115,12 @@ namespace vcpkg::Strings return s; } + std::string ascii_to_uppercase(std::string s) + { + std::transform(s.begin(), s.end(), s.begin(), &details::toupper_char); + return s; + } + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) { #if defined(_WIN32) @@ -136,8 +143,8 @@ namespace vcpkg::Strings std::string trim(std::string&& s) { - s.erase(std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(), s.end()); - s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::isspace)); + s.erase(std::find_if_not(s.rbegin(), s.rend(), details::IS_SPACE).base(), s.end()); + s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), details::IS_SPACE)); return std::move(s); } diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp index cb0a8cc51..9e1b54390 100644 --- a/toolsrc/src/vcpkg/commands.hash.cpp +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -1,13 +1,114 @@ #include "pch.h" +#include +#include #include #include #include #include +#if defined(_WIN32) +#include + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + namespace vcpkg::Commands::Hash { - std::string get_file_hash(const VcpkgPaths& paths, fs::path const& path, std::string const& hash_type) + namespace + { + static std::string to_hex(const unsigned char* string, const size_t bytes) + { + static constexpr char HEX_MAP[] = "0123456789abcdef"; + + std::string output; + output.resize(2 * bytes); + + size_t current_char = 0; + for (size_t i = 0; i < bytes; i++) + { + // high + output[current_char] = HEX_MAP[(string[i] & 0xF0) >> 4]; + ++current_char; + // low + output[current_char] = HEX_MAP[(string[i] & 0x0F)]; + ++current_char; + } + + return output; + } + + struct BCryptAlgorithmHandle : Util::ResourceBase + { + BCRYPT_ALG_HANDLE handle = nullptr; + + ~BCryptAlgorithmHandle() + { + if (handle) BCryptCloseAlgorithmProvider(handle, 0); + } + }; + + struct BCryptHashHandle : Util::ResourceBase + { + BCRYPT_HASH_HANDLE handle = nullptr; + + ~BCryptHashHandle() + { + if (handle) BCryptDestroyHash(handle); + } + }; + } + + std::string get_file_hash(const VcpkgPaths&, const fs::path& path, const std::string& hash_type) + { + BCryptAlgorithmHandle algorithm_handle; + + NTSTATUS error_code = BCryptOpenAlgorithmProvider( + &algorithm_handle.handle, Strings::to_utf16(Strings::ascii_to_uppercase(hash_type)).c_str(), nullptr, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to open the algorithm provider"); + + DWORD hash_buffer_bytes; + DWORD cb_data; + error_code = BCryptGetProperty(algorithm_handle.handle, + BCRYPT_HASH_LENGTH, + reinterpret_cast(&hash_buffer_bytes), + sizeof(DWORD), + &cb_data, + 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to get hash length"); + const ULONG length_in_bytes = hash_buffer_bytes; + + BCryptHashHandle hash_handle; + + error_code = BCryptCreateHash(algorithm_handle.handle, &hash_handle.handle, nullptr, 0, nullptr, 0, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to initialize the hasher"); + + FILE* file = nullptr; + const auto ec = _wfopen_s(&file, path.c_str(), L"rb"); + Checks::check_exit(VCPKG_LINE_INFO, ec == 0, "Failed to open file: %s", path.u8string()); + unsigned char buffer[4096]; + while (const auto actual_size = fread(buffer, 1, sizeof(buffer), file)) + { + error_code = BCryptHashData(hash_handle.handle, buffer, static_cast(actual_size), 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to hash data"); + } + + fclose(file); + + std::unique_ptr hash_buffer = std::make_unique(length_in_bytes); + + error_code = BCryptFinishHash(hash_handle.handle, hash_buffer.get(), length_in_bytes, 0); + Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); + + return to_hex(hash_buffer.get(), length_in_bytes); + } +} + +#else +namespace vcpkg::Commands::Hash +{ + std::string get_file_hash(const VcpkgPaths& paths, const fs::path& path, const std::string& hash_type) { const std::string cmd_line = Strings::format( R"("%s" -E %ssum "%s")", @@ -32,7 +133,11 @@ namespace vcpkg::Commands::Hash Util::erase_remove_if(hash, isspace); return hash; } +} +#endif +namespace vcpkg::Commands::Hash +{ const CommandStructure COMMAND_STRUCTURE = { Strings::format("The argument should be a file path\n%s", Help::create_example_string("hash boost_1_62_0.tar.bz2")), @@ -44,19 +149,12 @@ namespace vcpkg::Commands::Hash void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - args.parse_arguments(COMMAND_STRUCTURE); - - if (args.command_arguments.size() == 1) - { - auto hash = get_file_hash(paths, args.command_arguments[0], "SHA512"); - System::println(hash); - } - if (args.command_arguments.size() == 2) - { - auto hash = get_file_hash(paths, args.command_arguments[0], args.command_arguments[1]); - System::println(hash); - } + Util::unused(args.parse_arguments(COMMAND_STRUCTURE)); + const fs::path file_to_hash = args.command_arguments[0]; + const std::string algorithm = args.command_arguments.size() == 2 ? args.command_arguments[1] : "SHA512"; + const std::string hash = get_file_hash(paths, file_to_hash, algorithm); + System::println(hash); Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From d80dd5cbc777ce765c2d6b78d7c485fdf05f284b Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Mon, 19 Mar 2018 15:45:35 -0700 Subject: [vcpkg] Handle failure to store archive --- toolsrc/src/vcpkg/base/files.cpp | 4 ++++ toolsrc/src/vcpkg/build.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index b59104a59..4e61666b7 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -108,6 +108,10 @@ namespace vcpkg::Files output.close(); } + virtual void rename(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) override + { + fs::stdfs::rename(oldpath, newpath, ec); + } virtual void rename(const fs::path& oldpath, const fs::path& newpath) override { fs::stdfs::rename(oldpath, newpath); diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index bc9eca3ba..ebded2736 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -618,9 +618,12 @@ namespace vcpkg::Build compress_archive(paths, spec, tmp_archive_path); fs.create_directories(archive_path.parent_path(), ec); - fs.rename(tmp_archive_path, archive_path); - - System::println("Stored binary cache: %s", archive_path.u8string()); + fs.rename(tmp_archive_path, archive_path, ec); + if (ec) + System::println( + System::Color::warning, "Failed to store binary cache: %s", archive_path.u8string()); + else + System::println("Stored binary cache: %s", archive_path.u8string()); } else if (result.code == BuildResult::BUILD_FAILED || result.code == BuildResult::POST_BUILD_CHECKS_FAILED) { -- cgit v1.2.3 From 1baa7f16420a359328761b330cdaf58b82b6656c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Mar 2018 16:19:06 -0700 Subject: Improve error message when PROGRAMFILES is not found --- toolsrc/src/vcpkg/base/system.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index a315c7880..60067759a 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -533,7 +533,15 @@ namespace vcpkg::System static const fs::path& get_program_files() { - static const fs::path PATH = System::get_environment_variable("PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + static const fs::path PATH = []() -> fs::path { + auto value = System::get_environment_variable("PROGRAMFILES"); + if (auto v = value.get()) + { + return *v; + } + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find PROGRAMFILES environment variable"); + }(); + return PATH; } @@ -543,7 +551,7 @@ namespace vcpkg::System auto value = System::get_environment_variable("ProgramFiles(x86)"); if (auto v = value.get()) { - return std::move(*v); + return *v; } return get_program_files(); }(); @@ -556,7 +564,7 @@ namespace vcpkg::System auto value = System::get_environment_variable("ProgramW6432"); if (auto v = value.get()) { - return std::move(*v); + return *v; } return get_program_files(); }(); -- cgit v1.2.3 From d45954a96b625ba1856ac97b429163a1919a3299 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 21 Mar 2018 18:21:30 -0700 Subject: System::get_program_files() now returns Optional --- toolsrc/src/vcpkg/base/system.cpp | 35 ++++++++++++++++---------------- toolsrc/src/vcpkg/commands.edit.cpp | 20 +++++++++++++----- toolsrc/src/vcpkg/commands.integrate.cpp | 6 +++--- toolsrc/src/vcpkg/vcpkgpaths.cpp | 18 ++++++++-------- 4 files changed, 46 insertions(+), 33 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 60067759a..1094777af 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -224,21 +224,21 @@ namespace vcpkg::System env_cstr.push_back(L'\0'); } - if (extra_env.find("PATH") != extra_env.end()) - NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); + if (extra_env.find("PATH") != extra_env.end()) + NEW_PATH += Strings::format(";%s", extra_env.find("PATH")->second); env_cstr.append(Strings::to_utf16(NEW_PATH)); env_cstr.push_back(L'\0'); env_cstr.append(L"VSLANG=1033"); env_cstr.push_back(L'\0'); - for (auto item : extra_env) - { - if (item.first == "PATH") continue; - env_cstr.append(Strings::to_utf16(item.first)); - env_cstr.push_back(L'='); - env_cstr.append(Strings::to_utf16(item.second)); - env_cstr.push_back(L'\0'); - } + for (auto item : extra_env) + { + if (item.first == "PATH") continue; + env_cstr.append(Strings::to_utf16(item.first)); + env_cstr.push_back(L'='); + env_cstr.append(Strings::to_utf16(item.second)); + env_cstr.push_back(L'\0'); + } STARTUPINFOW startup_info; memset(&startup_info, 0, sizeof(STARTUPINFOW)); @@ -531,23 +531,24 @@ namespace vcpkg::System } #endif - static const fs::path& get_program_files() + static const Optional& get_program_files() { - static const fs::path PATH = []() -> fs::path { + static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("PROGRAMFILES"); if (auto v = value.get()) { return *v; } - Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find PROGRAMFILES environment variable"); + + return nullopt; }(); return PATH; } - const fs::path& get_program_files_32_bit() + const Optional& get_program_files_32_bit() { - static const fs::path PATH = []() -> fs::path { + static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("ProgramFiles(x86)"); if (auto v = value.get()) { @@ -558,9 +559,9 @@ namespace vcpkg::System return PATH; } - const fs::path& get_program_files_platform_bitness() + const Optional& get_program_files_platform_bitness() { - static const fs::path PATH = []() -> fs::path { + static const auto PATH = []() -> Optional { auto value = System::get_environment_variable("ProgramW6432"); if (auto v = value.get()) { diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 41f261a53..ac34a6720 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -69,14 +69,24 @@ namespace vcpkg::Commands::Edit std::vector candidate_paths; auto maybe_editor_path = System::get_environment_variable("EDITOR"); - if (auto editor_path = maybe_editor_path.get()) + if (const std::string* editor_path = maybe_editor_path.get()) { candidate_paths.emplace_back(*editor_path); } - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); + + const auto& program_files = System::get_program_files_platform_bitness(); + if (const fs::path* pf = program_files.get()) + { + candidate_paths.push_back(*pf / VS_CODE_INSIDERS); + candidate_paths.push_back(*pf / VS_CODE); + } + + const auto& program_files_32_bit = System::get_program_files_32_bit(); + if (const fs::path* pf = program_files_32_bit.get()) + { + candidate_paths.push_back(*pf / VS_CODE_INSIDERS); + candidate_paths.push_back(*pf / VS_CODE); + } const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 460e99b88..36e4e56e7 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -148,12 +148,12 @@ namespace vcpkg::Commands::Integrate static void integrate_install(const VcpkgPaths& paths) { static const std::array OLD_SYSTEM_TARGET_FILES = { - System::get_program_files_32_bit() / + System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", - System::get_program_files_32_bit() / + System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; static const fs::path SYSTEM_WIDE_TARGETS_FILE = - System::get_program_files_32_bit() / + System::get_program_files_32_bit().value_or_exit(VCPKG_LINE_INFO) / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; auto& fs = paths.get_filesystem(); diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 46e80c4a9..63a484a86 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -190,10 +190,11 @@ namespace vcpkg #endif const std::vector from_path = Files::find_from_PATH("cmake"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); -#if defined(_WIN32) - candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); -#endif + + 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"); + 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 Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); @@ -252,10 +253,11 @@ namespace vcpkg #endif const std::vector from_path = Files::find_from_PATH("git"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); -#if defined(_WIN32) - candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); -#endif + + 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"); + 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"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, TOOL_DATA.required_version); -- cgit v1.2.3 From c3fb0b169751ec0f25ac3752a7e83e21173073a4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Mar 2018 03:08:25 -0700 Subject: [vcpkg] Download cmake on osx and linux --- toolsrc/src/vcpkg/base/system.cpp | 6 ++-- toolsrc/src/vcpkg/vcpkgpaths.cpp | 73 ++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 16 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 1094777af..171dd2bbf 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -285,14 +285,14 @@ namespace vcpkg::System fflush(nullptr); // Basically we are wrapping it in quotes - const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); #if defined(_WIN32) + const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); Debug::println("_wsystem(%s)", actual_cmd_line); const int exit_code = _wsystem(Strings::to_utf16(actual_cmd_line).c_str()); Debug::println("_wsystem() returned %d", exit_code); #else - Debug::println("_system(%s)", actual_cmd_line); - const int exit_code = system(actual_cmd_line.c_str()); + Debug::println("_system(%s)", cmd_line); + const int exit_code = system(cmd_line.c_str()); Debug::println("_system() returned %d", exit_code); #endif return exit_code; diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp index 63a484a86..c36def15d 100644 --- a/toolsrc/src/vcpkg/vcpkgpaths.cpp +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -19,6 +19,8 @@ namespace vcpkg { std::array required_version; fs::path downloaded_exe_path; + std::string url; + fs::path downloaded_path; }; static Optional> parse_version_string(const std::string& version_as_string) @@ -41,8 +43,24 @@ namespace vcpkg static ToolData parse_tool_data_from_xml(const VcpkgPaths& paths, const std::string& tool) { +#if defined(_WIN32) + static constexpr StringLiteral OS_STRING = ""; +#elif defined(__APPLE__) + static constexpr StringLiteral OS_STRING = " os=\"osx\""; +#else // assume linux + static constexpr StringLiteral OS_STRING = " os=\"linux\""; +#endif + static const fs::path XML_PATH = paths.scripts / "vcpkgTools.xml"; + const auto maybe_get_string_inside_tags = [](const std::string& input, + const std::regex& regex) -> Optional { + std::smatch match; + const bool has_match = std::regex_search(input.cbegin(), input.cend(), match, regex); + if (!has_match) return nullopt; + return match[1]; + }; + const auto get_string_inside_tags = [](const std::string& input, const std::regex& regex, const std::string& tag_name) -> std::string { std::smatch match; @@ -57,7 +75,10 @@ namespace vcpkg static const std::regex VERSION_REGEX{ Strings::format(R"###(([\s\S]*?))###", tool)}; static const std::regex EXE_RELATIVE_PATH_REGEX{ - Strings::format(R"###(([\s\S]*?))###", tool)}; + Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; + static const std::regex ARCHIVE_RELATIVE_PATH_REGEX{ + Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; + static const std::regex URL_REGEX{Strings::format(R"###(([\s\S]*?))###", OS_STRING)}; const std::regex tool_regex{Strings::format(R"###(([\s\S]*?))###", tool)}; @@ -74,9 +95,13 @@ namespace vcpkg const std::string required_version_as_string = get_string_inside_tags(tool_data_as_string, VERSION_REGEX, "requiredVersion"); + const std::string url = get_string_inside_tags(tool_data_as_string, URL_REGEX, "url"); + const std::string exe_relative_path = get_string_inside_tags(tool_data_as_string, EXE_RELATIVE_PATH_REGEX, "exeRelativePath"); + auto archive_relative_path = maybe_get_string_inside_tags(tool_data_as_string, ARCHIVE_RELATIVE_PATH_REGEX); + const Optional> required_version = parse_version_string(required_version_as_string); Checks::check_exit(VCPKG_LINE_INFO, required_version.has_value(), @@ -85,7 +110,10 @@ namespace vcpkg required_version_as_string); const fs::path exe_path = paths.downloads / exe_relative_path; - return ToolData{*required_version.get(), exe_path}; + return ToolData{*required_version.get(), + exe_path, + url, + paths.downloads / archive_relative_path.value_or(exe_relative_path)}; } static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd, @@ -144,8 +172,10 @@ namespace vcpkg return data_lines; } - static fs::path fetch_tool(const fs::path& scripts_folder, const std::string& tool_name, const ToolData& tool_data) + static fs::path fetch_tool(const VcpkgPaths& paths, const std::string& tool_name, const ToolData& tool_data) { + const auto& fs = paths.get_filesystem(); + const fs::path& scripts_folder = paths.scripts; const std::array& version = tool_data.required_version; const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); @@ -154,6 +184,7 @@ namespace vcpkg version_as_string, tool_name, version_as_string); +#if defined(_WIN32) const fs::path script = scripts_folder / "fetchtool.ps1"; const std::string title = Strings::format( "Fetching %s version %s (No sufficient installed version was found)", tool_name, version_as_string); @@ -173,21 +204,37 @@ namespace vcpkg expected_downloaded_path.u8string(), actual_downloaded_path.u8string()); return actual_downloaded_path; +#else + if (!fs.exists(tool_data.downloaded_path)) + { + auto code = System::cmd_execute( + Strings::format(R"(curl '%s' --create-dirs --output '%s')", tool_data.url, tool_data.downloaded_path)); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "curl failed while downloading %s", tool_data.url); + } + auto code = System::cmd_execute( + Strings::format(R"(cd '%s' && tar xzf '%s')", paths.downloads, tool_data.downloaded_path)); + Checks::check_exit(VCPKG_LINE_INFO, code == 0, "tar failed while extracting %s", tool_data.downloaded_path); + + Checks::check_exit(VCPKG_LINE_INFO, + fs.exists(tool_data.downloaded_exe_path), + "Expected %s to exist after extracting", + tool_data.downloaded_exe_path); + + return tool_data.downloaded_exe_path; +#endif } static fs::path get_cmake_path(const VcpkgPaths& paths) { -#if defined(_WIN32) + 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.downloaded_exe_path); #else static const ToolData TOOL_DATA = ToolData{{3, 5, 1}, ""}; #endif static const std::string VERSION_CHECK_ARGUMENTS = "--version"; - std::vector candidate_paths; -#if defined(_WIN32) - candidate_paths.push_back(TOOL_DATA.downloaded_exe_path); -#endif const std::vector from_path = Files::find_from_PATH("cmake"); candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); @@ -203,7 +250,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "cmake", TOOL_DATA); + return fetch_tool(paths, "cmake", TOOL_DATA); } static fs::path get_7za_path(const VcpkgPaths& paths) @@ -212,7 +259,7 @@ namespace vcpkg static const ToolData TOOL_DATA = parse_tool_data_from_xml(paths, "7zip"); if (!paths.get_filesystem().exists(TOOL_DATA.downloaded_exe_path)) { - return fetch_tool(paths.scripts, "7zip", TOOL_DATA); + return fetch_tool(paths, "7zip", TOOL_DATA); } return TOOL_DATA.downloaded_exe_path; #else @@ -235,7 +282,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "nuget", TOOL_DATA); + return fetch_tool(paths, "nuget", TOOL_DATA); } static fs::path get_git_path(const VcpkgPaths& paths) @@ -266,7 +313,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "git", TOOL_DATA); + return fetch_tool(paths, "git", TOOL_DATA); } static fs::path get_ifw_installerbase_path(const VcpkgPaths& paths) @@ -292,7 +339,7 @@ namespace vcpkg return *p; } - return fetch_tool(paths.scripts, "installerbase", TOOL_DATA); + return fetch_tool(paths, "installerbase", TOOL_DATA); } Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir, const std::string& default_vs_path) -- cgit v1.2.3 From 1f62b32641045fe377ee80ff1854a785344687d2 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 22 Mar 2018 10:01:12 -0700 Subject: [vcpkg] Sort abi tags to ensure stability --- toolsrc/src/vcpkg/build.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index ebded2736..953e77460 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -449,6 +449,8 @@ namespace vcpkg::Build if (config.build_package_options.use_head_version == UseHeadVersion::YES) abi_tag_entries.emplace_back(AbiEntry{"head", ""}); + Util::sort(abi_tag_entries); + std::string full_abi_info = Strings::join("", abi_tag_entries, [](const AbiEntry& p) { return p.key + " " + p.value + "\n"; }); -- cgit v1.2.3