From 1f79c92eb099de356a5cb1e42234bb227e09d543 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 18 Sep 2018 20:55:35 -0700 Subject: Add command x-vsinstances --- toolsrc/src/vcpkg/commands.cpp | 1 + toolsrc/src/vcpkg/commands.xvsinstances.cpp | 29 +++++++++++++++++ toolsrc/src/vcpkg/visualstudio.cpp | 49 +++++++++++++++++++++-------- 3 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 toolsrc/src/vcpkg/commands.xvsinstances.cpp (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp index 7204b6e78..db265514f 100644 --- a/toolsrc/src/vcpkg/commands.cpp +++ b/toolsrc/src/vcpkg/commands.cpp @@ -46,6 +46,7 @@ namespace vcpkg::Commands {"autocomplete", &Autocomplete::perform_and_exit}, {"hash", &Hash::perform_and_exit}, {"fetch", &Fetch::perform_and_exit}, + {"x-vsinstances", &X_VSInstances::perform_and_exit}, }; return t; } diff --git a/toolsrc/src/vcpkg/commands.xvsinstances.cpp b/toolsrc/src/vcpkg/commands.xvsinstances.cpp new file mode 100644 index 000000000..3aa54f424 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.xvsinstances.cpp @@ -0,0 +1,29 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg::Commands::X_VSInstances +{ + const CommandStructure COMMAND_STRUCTURE = { + Help::create_example_string("x-vsinstances"), + 0, + 0, + {{}, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE); + + const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths); + for (const std::string& instance : instances) + { + System::println(instance); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index 9480a11bf..4f6b2a37b 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -22,6 +22,17 @@ namespace vcpkg::VisualStudio LEGACY }; + static std::string release_type_to_string(const ReleaseType& release_type) + { + switch (release_type) + { + case ReleaseType::STABLE: return "STABLE"; + case ReleaseType::PRERELEASE: return "PRERELEASE"; + case ReleaseType::LEGACY: return "LEGACY"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + static bool preferred_first_comparator(const VisualStudioInstance& left, const VisualStudioInstance& right) { const auto get_preference_weight = [](const ReleaseType& type) -> int { @@ -51,10 +62,15 @@ namespace vcpkg::VisualStudio std::string version; ReleaseType release_type; + std::string to_string() const + { + return Strings::format("%s, %s, %s", root_path.u8string(), version, release_type_to_string(release_type)); + } + std::string major_version() const { return version.substr(0, 2); } }; - static std::vector get_visual_studio_instances(const VcpkgPaths& paths) + static std::vector get_visual_studio_instances_internal(const VcpkgPaths& paths) { const auto& fs = paths.get_filesystem(); std::vector instances; @@ -114,9 +130,9 @@ namespace vcpkg::VisualStudio { // We want lexically_normal(), but it is not available // Correct root path might be 2 or 3 levels up, depending on if the path has trailing backslash. Try both. - auto common7_tools = fs::path{*path_as_string}; - append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path()); - append_if_has_cl(fs::path{*path_as_string}.parent_path().parent_path().parent_path()); + auto common7_tools = fs::path {*path_as_string}; + append_if_has_cl(fs::path {*path_as_string}.parent_path().parent_path()); + append_if_has_cl(fs::path {*path_as_string}.parent_path().parent_path().parent_path()); } // VS2015 instance from Program Files @@ -125,6 +141,13 @@ namespace vcpkg::VisualStudio return instances; } + std::vector get_visual_studio_instances(const VcpkgPaths& paths) + { + std::vector sorted {get_visual_studio_instances_internal(paths)}; + std::sort(sorted.begin(), sorted.end(), VisualStudioInstance::preferred_first_comparator); + return Util::fmap(sorted, [](const VisualStudioInstance& instance) { return instance.to_string(); }); + } + std::vector find_toolset_instances_preferred_first(const VcpkgPaths& paths) { using CPU = System::CPUArchitecture; @@ -137,8 +160,8 @@ namespace vcpkg::VisualStudio std::vector found_toolsets; std::vector excluded_toolsets; - const SortedVector sorted{get_visual_studio_instances(paths), - VisualStudioInstance::preferred_first_comparator}; + const SortedVector sorted {get_visual_studio_instances_internal(paths), + VisualStudioInstance::preferred_first_comparator}; const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; @@ -194,7 +217,7 @@ namespace vcpkg::VisualStudio paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - const Toolset v141_toolset{ + const Toolset v141_toolset { vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; const auto english_language_pack = dumpbin_path.parent_path() / "1033"; @@ -209,12 +232,12 @@ namespace vcpkg::VisualStudio if (v140_is_available) { - const Toolset v140_toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {"-vcvars_ver=14.0"}, - V_140, - supported_architectures}; + const Toolset v140_toolset {vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {"-vcvars_ver=14.0"}, + V_140, + supported_architectures}; found_toolsets.push_back(v140_toolset); } -- cgit v1.2.3 From a1a18eada148562d0906b103c70c9e36b6a648ce Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 18 Sep 2018 21:03:00 -0700 Subject: Add -all flag to vswhere.exe call --- toolsrc/src/vcpkg/visualstudio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/visualstudio.cpp b/toolsrc/src/vcpkg/visualstudio.cpp index 4f6b2a37b..e3656a7d2 100644 --- a/toolsrc/src/vcpkg/visualstudio.cpp +++ b/toolsrc/src/vcpkg/visualstudio.cpp @@ -82,7 +82,7 @@ namespace vcpkg::VisualStudio if (fs.exists(vswhere_exe)) { const auto code_and_output = System::cmd_execute_and_capture_output( - Strings::format(R"("%s" -prerelease -legacy -products * -format xml)", vswhere_exe.u8string())); + Strings::format(R"("%s" -all -prerelease -legacy -products * -format xml)", vswhere_exe.u8string())); Checks::check_exit(VCPKG_LINE_INFO, code_and_output.exit_code == 0, "Running vswhere.exe failed with message:\n%s", -- cgit v1.2.3 From 1faf5c7d289f5b693fbcaa98af8b41833e6a5a04 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 19 Sep 2018 17:09:27 -0700 Subject: [vcpkg] Hotfix build break on non-windows platforms in commands.xvsinstances.cpp --- toolsrc/src/vcpkg/commands.xvsinstances.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.xvsinstances.cpp b/toolsrc/src/vcpkg/commands.xvsinstances.cpp index 3aa54f424..d748b6b2f 100644 --- a/toolsrc/src/vcpkg/commands.xvsinstances.cpp +++ b/toolsrc/src/vcpkg/commands.xvsinstances.cpp @@ -16,6 +16,7 @@ namespace vcpkg::Commands::X_VSInstances void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { +#if defined(_WIN32) const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE); const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths); @@ -25,5 +26,8 @@ namespace vcpkg::Commands::X_VSInstances } Checks::exit_success(VCPKG_LINE_INFO); +#else + Checks::exit_with_message(VCPKG_LINE_INFO, "This command is not supported on non-windows platforms."); +#endif } } -- cgit v1.2.3 From e8e8c1499858db0bb0a450e86a0f7ace788d3788 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 4 Oct 2018 14:33:54 -0700 Subject: `vcpkg edit` now checks the default user-installer location for VSCode --- toolsrc/src/vcpkg/commands.edit.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 2569c2cea..0b1b348c2 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -92,8 +92,8 @@ namespace vcpkg::Commands::Edit void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; - static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; + static const fs::path VS_CODE_INSIDERS = fs::path {"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + static const fs::path VS_CODE = fs::path {"Microsoft VS Code"} / "Code.exe"; auto& fs = paths.get_filesystem(); @@ -128,6 +128,14 @@ namespace vcpkg::Commands::Edit candidate_paths.push_back(*pf / VS_CODE); } + const auto& app_data = System::get_environment_variable("APPDATA"); + if (const auto* ad = app_data.get()) + { + const fs::path default_base = fs::path {*ad}.parent_path() / "Local" / "Programs"; + candidate_paths.push_back(default_base / VS_CODE_INSIDERS); + candidate_paths.push_back(default_base / VS_CODE); + } + const std::vector from_registry = find_from_registry(); candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); -- cgit v1.2.3 From efffda88f0d4d6a0ba0640a96cd05bf08985c541 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 9 Oct 2018 20:14:26 -0700 Subject: [vcpkg ci] Remove src as well --- toolsrc/src/vcpkg/build.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 8e87fe7fe..1e931889b 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -440,7 +440,7 @@ namespace vcpkg::Build auto buildtree_files = fs.get_files_non_recursive(buildtrees_dir); for (auto&& file : buildtree_files) { - if (fs.is_directory(file) && file.filename() != "src") + if (fs.is_directory(file)) // Will only keep the logs { std::error_code ec; fs.remove_all(file, ec); -- cgit v1.2.3 From 7970ab0251c4607ef1690f397e4898dadefdb7ff Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 9 Oct 2018 20:14:38 -0700 Subject: clang-formatting --- toolsrc/src/vcpkg/build.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index 1e931889b..f5f2b9c6c 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -63,7 +63,7 @@ namespace vcpkg::Build::Command spec.name()); const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{ + const Build::BuildPackageOptions build_package_options { Build::UseHeadVersion::NO, Build::AllowDownloads::YES, Build::CleanBuildtrees::NO, @@ -76,8 +76,8 @@ namespace vcpkg::Build::Command std::set features_as_set(full_spec.features.begin(), full_spec.features.end()); features_as_set.emplace("core"); - const Build::BuildPackageConfig build_config{ - *scf, spec.triplet(), fs::path{port_dir}, build_package_options, features_as_set}; + const Build::BuildPackageConfig build_config { + *scf, spec.triplet(), fs::path {port_dir}, build_package_options, features_as_set}; const auto build_timer = Chrono::ElapsedTimer::create_started(); const auto result = Build::build_package(paths, build_config, status_db); @@ -464,22 +464,22 @@ namespace vcpkg::Build std::vector abi_tag_entries; - abi_tag_entries.emplace_back(AbiEntry{"cmake", paths.get_tool_version(Tools::CMAKE)}); + abi_tag_entries.emplace_back(AbiEntry {"cmake", paths.get_tool_version(Tools::CMAKE)}); abi_tag_entries.insert(abi_tag_entries.end(), dependency_abis.begin(), dependency_abis.end()); abi_tag_entries.emplace_back( - AbiEntry{"portfile", vcpkg::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); + AbiEntry {"portfile", vcpkg::Hash::get_file_hash(fs, config.port_dir / "portfile.cmake", "SHA1")}); abi_tag_entries.emplace_back( - AbiEntry{"control", vcpkg::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); + AbiEntry {"control", vcpkg::Hash::get_file_hash(fs, config.port_dir / "CONTROL", "SHA1")}); - abi_tag_entries.emplace_back(AbiEntry{"triplet", pre_build_info.triplet_abi_tag}); + abi_tag_entries.emplace_back(AbiEntry {"triplet", pre_build_info.triplet_abi_tag}); const std::string features = Strings::join(";", config.feature_list); - abi_tag_entries.emplace_back(AbiEntry{"features", features}); + abi_tag_entries.emplace_back(AbiEntry {"features", features}); if (config.build_package_options.use_head_version == UseHeadVersion::YES) - abi_tag_entries.emplace_back(AbiEntry{"head", ""}); + abi_tag_entries.emplace_back(AbiEntry {"head", ""}); Util::sort(abi_tag_entries); @@ -506,7 +506,7 @@ namespace vcpkg::Build const auto abi_file_path = paths.buildtrees / name / (triplet.canonical_name() + ".vcpkg_abi_info.txt"); fs.write_contents(abi_file_path, full_abi_info); - return AbiTagAndFile{Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; + return AbiTagAndFile {Hash::get_file_hash(fs, abi_file_path, "SHA1"), abi_file_path}; } System::println( @@ -596,7 +596,7 @@ namespace vcpkg::Build const auto status_it = status_db.find_installed(pspec); Checks::check_exit(VCPKG_LINE_INFO, status_it != status_db.end()); dependency_abis.emplace_back( - AbiEntry{status_it->get()->package.spec.name(), status_it->get()->package.abi}); + AbiEntry {status_it->get()->package.spec.name(), status_it->get()->package.abi}); } const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); @@ -642,7 +642,7 @@ namespace vcpkg::Build System::println("Could not locate cached archive: %s", archive_path.u8string()); ExtendedBuildResult result = do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile {}).tag, config); std::error_code ec; fs.create_directories(paths.package_dir(spec) / "share" / spec.name(), ec); @@ -679,7 +679,7 @@ namespace vcpkg::Build } return do_build_package_and_clean_buildtrees( - paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile{}).tag, config); + paths, pre_build_info, spec, maybe_abi_tag_and_file.value_or(AbiTagAndFile {}).tag, config); } const std::string& to_string(const BuildResult build_result) @@ -844,21 +844,21 @@ namespace vcpkg::Build if (variable_name == "VCPKG_PLATFORM_TOOLSET") { pre_build_info.platform_toolset = - variable_value.empty() ? nullopt : Optional{variable_value}; + variable_value.empty() ? nullopt : Optional {variable_value}; continue; } if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") { pre_build_info.visual_studio_path = - variable_value.empty() ? nullopt : Optional{variable_value}; + variable_value.empty() ? nullopt : Optional {variable_value}; continue; } if (variable_name == "VCPKG_CHAINLOAD_TOOLCHAIN_FILE") { pre_build_info.external_toolchain_file = - variable_value.empty() ? nullopt : Optional{variable_value}; + variable_value.empty() ? nullopt : Optional {variable_value}; continue; } -- cgit v1.2.3 From 20a8e393a01925f977689c70b58299372b725536 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 15 Oct 2018 21:29:34 -0700 Subject: [vcpkg env] Add argument to run a command --- toolsrc/src/vcpkg/commands.env.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp index d078baedb..f56bda1ec 100644 --- a/toolsrc/src/vcpkg/commands.env.cpp +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -23,9 +23,9 @@ namespace vcpkg::Commands::Env }}; const CommandStructure COMMAND_STRUCTURE = { - Help::create_example_string("env --triplet x64-windows"), - 0, + Help::create_example_string("env --triplet x64-windows"), 0, + 1, {SWITCHES, {}}, nullptr, }; @@ -64,11 +64,12 @@ namespace vcpkg::Commands::Env 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", extra_env); - else - System::cmd_execute_clean(env_cmd + " && cmd", extra_env); + std::string env_cmd_prefix = env_cmd.empty() ? "" : Strings::format("%s &&", env_cmd); + std::string env_cmd_suffix = + args.command_arguments.empty() ? "cmd" : Strings::format("cmd /c %s", args.command_arguments.at(0)); + const std::string cmd = Strings::format("%s %s", env_cmd_prefix, env_cmd_suffix); + System::cmd_execute_clean(cmd, extra_env); Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 10e7bd5772ca1a5d315200ba6c7541141e72b935 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 15 Oct 2018 17:08:27 -0700 Subject: Print out the error when dumpbin fails --- toolsrc/src/vcpkg/postbuildlint.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp index 6fe11951f..90dcb7d64 100644 --- a/toolsrc/src/vcpkg/postbuildlint.cpp +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -617,7 +617,11 @@ namespace vcpkg::PostBuildLint const std::string cmd_line = Strings::format(R"("%s" /directives "%s")", dumpbin_exe.u8string(), lib.u8string()); System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed with message:\n%s", + cmd_line, + ec_data.output); for (const BuildType& bad_build_type : bad_build_types) { -- cgit v1.2.3 From 56e1d2f6961693b45f2b61b6e6985229be56e674 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 16 Oct 2018 00:35:47 -0700 Subject: [vcpkg] Wrap all external process spawning in a Ctrl-C catcher to avoid corrupted consoles --- toolsrc/src/vcpkg.cpp | 6 ++++-- toolsrc/src/vcpkg/base/checks.cpp | 14 +++++++------ toolsrc/src/vcpkg/base/system.cpp | 22 ++++++++++++++------ toolsrc/src/vcpkg/globalstate.cpp | 42 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 14 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 6f10c503d..ba9710562 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -261,6 +261,7 @@ int main(const int argc, const char* const* const argv) #if defined(_WIN32) GlobalState::g_init_console_cp = GetConsoleCP(); GlobalState::g_init_console_output_cp = GetConsoleOutputCP(); + GlobalState::g_init_console_initialized = true; SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); @@ -275,6 +276,9 @@ int main(const int argc, const char* const* const argv) locked_metrics->track_property("cmdline", trimmed_command_line); #endif } + + Checks::register_console_ctrl_handler(); + load_config(); const auto vcpkg_feature_flags_env = System::get_environment_variable("VCPKG_FEATURE_FLAGS"); @@ -293,8 +297,6 @@ int main(const int argc, const char* const* const argv) if (const auto p = args.sendmetrics.get()) Metrics::g_metrics.lock()->set_send_metrics(*p); if (const auto p = args.debug.get()) GlobalState::debugging = *p; - Checks::register_console_ctrl_handler(); - if (GlobalState::debugging) { inner(args); diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 72176e58c..cc439adfe 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -24,8 +24,11 @@ namespace vcpkg::Checks metrics->flush(); #if defined(_WIN32) - SetConsoleCP(GlobalState::g_init_console_cp); - SetConsoleOutputCP(GlobalState::g_init_console_output_cp); + if (GlobalState::g_init_console_initialized) + { + SetConsoleCP(GlobalState::g_init_console_cp); + SetConsoleOutputCP(GlobalState::g_init_console_output_cp); + } #endif auto elapsed_us = GlobalState::timer.lock()->microseconds(); @@ -46,12 +49,11 @@ namespace vcpkg::Checks #if defined(_WIN32) static BOOL ctrl_handler(DWORD fdw_ctrl_type) { + switch (fdw_ctrl_type) { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type)); - locked_metrics->track_property("error", "CtrlHandler was fired."); + case CTRL_C_EVENT: GlobalState::g_ctrl_c_state.transition_handle_ctrl_c(); return TRUE; + default: return FALSE; } - cleanup_and_exit(EXIT_FAILURE); } void register_console_ctrl_handler() diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index d968c6dac..085471b19 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -133,7 +133,7 @@ namespace vcpkg::System static void windows_create_clean_process(const CStringView cmd_line, const std::unordered_map& extra_env, PROCESS_INFORMATION& process_info, - DWORD dwCreationFlags) + DWORD dwCreationFlags) noexcept { 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)"; @@ -242,7 +242,7 @@ namespace vcpkg::System #endif #if defined(_WIN32) - void cmd_execute_no_wait(const CStringView cmd_line) + void cmd_execute_no_wait(const CStringView cmd_line) noexcept { auto timer = Chrono::ElapsedTimer::create_started(); @@ -258,7 +258,8 @@ namespace vcpkg::System } #endif - int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) + int cmd_execute_clean(const CStringView cmd_line, + const std::unordered_map& extra_env) noexcept { auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) @@ -266,11 +267,13 @@ namespace vcpkg::System PROCESS_INFORMATION process_info; memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); + GlobalState::g_ctrl_c_state.transition_to_spawn_process(); windows_create_clean_process(cmd_line, extra_env, process_info, NULL); CloseHandle(process_info.hThread); const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); + GlobalState::g_ctrl_c_state.transition_from_spawn_process(); Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); DWORD exit_code = 0; @@ -279,6 +282,7 @@ namespace vcpkg::System CloseHandle(process_info.hProcess); Debug::println("CreateProcessW() returned %lu after %d us", exit_code, static_cast(timer.microseconds())); + return static_cast(exit_code); #else Debug::println("system(%s)", cmd_line.c_str()); @@ -289,16 +293,18 @@ namespace vcpkg::System #endif } - int cmd_execute(const CStringView cmd_line) + int cmd_execute(const CStringView cmd_line) noexcept { // Flush stdout before launching external process fflush(nullptr); - // Basically we are wrapping it in quotes #if defined(_WIN32) + // We are wrap the command line in quotes to cause cmd.exe to correctly process it const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line); Debug::println("_wsystem(%s)", actual_cmd_line); + GlobalState::g_ctrl_c_state.transition_to_spawn_process(); const int exit_code = _wsystem(Strings::to_utf16(actual_cmd_line).c_str()); + GlobalState::g_ctrl_c_state.transition_from_spawn_process(); Debug::println("_wsystem() returned %d", exit_code); #else Debug::println("_system(%s)", cmd_line); @@ -308,7 +314,7 @@ namespace vcpkg::System return exit_code; } - ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) + ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) noexcept { // Flush stdout before launching external process fflush(stdout); @@ -321,9 +327,11 @@ namespace vcpkg::System Debug::println("_wpopen(%s)", actual_cmd_line); std::wstring output; wchar_t buf[1024]; + GlobalState::g_ctrl_c_state.transition_to_spawn_process(); const auto pipe = _wpopen(Strings::to_utf16(actual_cmd_line).c_str(), L"r"); if (pipe == nullptr) { + GlobalState::g_ctrl_c_state.transition_from_spawn_process(); return {1, Strings::to_utf8(output.c_str())}; } while (fgetws(buf, 1024, pipe)) @@ -332,10 +340,12 @@ namespace vcpkg::System } if (!feof(pipe)) { + GlobalState::g_ctrl_c_state.transition_from_spawn_process(); return {1, Strings::to_utf8(output.c_str())}; } const auto ec = _pclose(pipe); + GlobalState::g_ctrl_c_state.transition_from_spawn_process(); // On Win7, output from powershell calls contain a utf-8 byte order mark in the utf-16 stream, so we strip it // out if it is present. 0xEF,0xBB,0xBF is the UTF-8 byte-order mark diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index a4100acf7..ee576f9ce 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -13,4 +13,46 @@ namespace vcpkg std::atomic GlobalState::g_init_console_cp(0); std::atomic GlobalState::g_init_console_output_cp(0); + std::atomic GlobalState::g_init_console_initialized(false); + + GlobalState::CtrlCStateMachine GlobalState::g_ctrl_c_state; + + void GlobalState::CtrlCStateMachine::transition_to_spawn_process() noexcept + { + auto expected = CtrlCState::normal; + auto transitioned = m_state.compare_exchange_strong(expected, CtrlCState::blocked_on_child); + if (!transitioned) + { + // Ctrl-C was hit and is asynchronously executing on another thread + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + void GlobalState::CtrlCStateMachine::transition_from_spawn_process() noexcept + { + auto expected = CtrlCState::blocked_on_child; + auto transitioned = m_state.compare_exchange_strong(expected, CtrlCState::normal); + if (!transitioned) + { + // Ctrl-C was hit while blocked on the child process + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + void GlobalState::CtrlCStateMachine::transition_handle_ctrl_c() noexcept + { + auto prev_state = m_state.exchange(CtrlCState::exit_requested); + + if (prev_state == CtrlCState::normal) + { + // Not currently blocked on a child process and Ctrl-C has not been hit. + Checks::exit_fail(VCPKG_LINE_INFO); + } + else if (prev_state == CtrlCState::exit_requested) + { + // Ctrl-C was hit previously + } + else + { + // This is the case where we are currently blocked on a child process + } + } } -- cgit v1.2.3 From faf7c2db7d154e113a65fc0efa3e4266680ed0c4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 16 Oct 2018 01:26:04 -0700 Subject: [vcpkg] Improve handling of ctrl-c inside `install` or `build`. --- toolsrc/src/vcpkg/base/system.cpp | 9 +++++---- toolsrc/src/vcpkg/build.cpp | 12 +++++++++--- toolsrc/src/vcpkg/commands.env.cpp | 4 ++-- 3 files changed, 16 insertions(+), 9 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 085471b19..78ba28324 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -223,7 +223,7 @@ namespace vcpkg::System memset(&startup_info, 0, sizeof(STARTUPINFOW)); startup_info.cb = sizeof(STARTUPINFOW); - // Basically we are wrapping it in quotes + // Wrapping the command in a single set of quotes causes cmd.exe to correctly execute const std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); Debug::println("CreateProcessW(%s)", actual_cmd_line); bool succeeded = TRUE == CreateProcessW(nullptr, @@ -316,9 +316,6 @@ namespace vcpkg::System ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) noexcept { - // Flush stdout before launching external process - fflush(stdout); - auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) @@ -328,6 +325,8 @@ namespace vcpkg::System std::wstring output; wchar_t buf[1024]; GlobalState::g_ctrl_c_state.transition_to_spawn_process(); + // Flush stdout before launching external process + fflush(stdout); const auto pipe = _wpopen(Strings::to_utf16(actual_cmd_line).c_str(), L"r"); if (pipe == nullptr) { @@ -364,6 +363,8 @@ namespace vcpkg::System Debug::println("popen(%s)", actual_cmd_line); std::string output; char buf[1024]; + // Flush stdout before launching external process + fflush(stdout); const auto pipe = popen(actual_cmd_line.c_str(), "r"); if (pipe == nullptr) { diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp index f5f2b9c6c..7569f340f 100644 --- a/toolsrc/src/vcpkg/build.cpp +++ b/toolsrc/src/vcpkg/build.cpp @@ -245,7 +245,7 @@ namespace vcpkg::Build const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); - return Strings::format(R"("%s" %s %s %s %s 2>&1)", + return Strings::format(R"("%s" %s %s %s %s 2>&1 0) extra_env.emplace("PATH", Strings::join(";", path_vars)); - std::string env_cmd_prefix = env_cmd.empty() ? "" : Strings::format("%s &&", env_cmd); + std::string env_cmd_prefix = env_cmd.empty() ? "" : Strings::format("%s && ", env_cmd); std::string env_cmd_suffix = args.command_arguments.empty() ? "cmd" : Strings::format("cmd /c %s", args.command_arguments.at(0)); - const std::string cmd = Strings::format("%s %s", env_cmd_prefix, env_cmd_suffix); + const std::string cmd = Strings::format("%s%s", env_cmd_prefix, env_cmd_suffix); System::cmd_execute_clean(cmd, extra_env); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From f451d95a39a6f5de31068e2499e30ef90430b28d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 16 Oct 2018 01:35:11 -0700 Subject: [vcpkg] Fix blocking on `vcpkg edit` with VSCode --- toolsrc/src/vcpkg/commands.edit.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 0b1b348c2..237feebdd 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -155,6 +155,16 @@ namespace vcpkg::Commands::Edit const std::vector arguments = create_editor_arguments(paths, options, ports); const auto args_as_string = Strings::join(" ", arguments); const auto cmd_line = Strings::format(R"("%s" %s -n)", env_editor.u8string(), args_as_string); + + auto editor_exe = env_editor.filename().u8string(); + +#ifdef _WIN32 + if (editor_exe == "Code.exe" || editor_exe == "Code - Insiders.exe") + { + System::cmd_execute_no_wait(cmd_line + " Date: Tue, 16 Oct 2018 11:43:36 +0100 Subject: Display names of environment variables correctly for non-Windows (#4471) platforms in help Currently vcpkg displays environment variable names in the help as %VARIABLENAME% on non-Windows platforms, where it should be $VARIABLENAME. This patch adds a macro to fix this. --- toolsrc/src/vcpkg/help.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp index 743619937..2b409373d 100644 --- a/toolsrc/src/vcpkg/help.cpp +++ b/toolsrc/src/vcpkg/help.cpp @@ -7,6 +7,13 @@ #include #include +// Write environment variable names as %VARIABLE% on Windows and $VARIABLE in *nix +#ifdef _WIN32 +#define ENVVAR(VARNAME) "%%" #VARNAME "%%" +#else +#define ENVVAR(VARNAME) "$" #VARNAME +#endif + namespace vcpkg::Help { struct Topic @@ -93,7 +100,7 @@ namespace vcpkg::Help "%s" // Integration help "\n" " vcpkg export ... [opt]... Exports a package\n" - " vcpkg edit Open up a port for editing (uses %%EDITOR%%, default 'code')\n" + " vcpkg edit Open up a port for editing (uses " ENVVAR(EDITOR) ", default 'code')\n" " vcpkg import Import a pre-built library\n" " vcpkg create \n" " [archivename] Create a new package\n" @@ -104,10 +111,10 @@ namespace vcpkg::Help "\n" "Options:\n" " --triplet Specify the target architecture triplet.\n" - " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" + " (default: " ENVVAR(VCPKG_DEFAULT_TRIPLET) ", see 'vcpkg help triplet')\n" "\n" " --vcpkg-root Specify the vcpkg root directory\n" - " (default: %%VCPKG_ROOT%%)\n" + " (default: " ENVVAR(VCPKG_ROOT) ")\n" "\n" "For more help (including examples) see the accompanying README.md.", Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); -- cgit v1.2.3 From df82d21f320285a8f4cbf16756d8e035cdc74e7c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 16 Oct 2018 05:53:57 -0700 Subject: [vcpkg] Fix OSX build for old GCC versions --- toolsrc/src/vcpkg/globalstate.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp index ee576f9ce..a54c596fb 100644 --- a/toolsrc/src/vcpkg/globalstate.cpp +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -17,6 +17,8 @@ namespace vcpkg GlobalState::CtrlCStateMachine GlobalState::g_ctrl_c_state; + GlobalState::CtrlCStateMachine::CtrlCStateMachine() : m_state(CtrlCState::normal) {} + void GlobalState::CtrlCStateMachine::transition_to_spawn_process() noexcept { auto expected = CtrlCState::normal; -- cgit v1.2.3 From 3d12e5ca72d948121463beec6e48290877684471 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Wed, 17 Oct 2018 12:46:27 -0600 Subject: Handle symlink when installing or removing a library (#4479) --- toolsrc/src/vcpkg/base/files.cpp | 8 ++++++++ toolsrc/src/vcpkg/install.cpp | 19 ++++++++++++++++++- toolsrc/src/vcpkg/remove.cpp | 4 ++-- 3 files changed, 28 insertions(+), 3 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp index 4ff0912d1..f9bce8631 100644 --- a/toolsrc/src/vcpkg/base/files.cpp +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -216,11 +216,19 @@ namespace vcpkg::Files { return fs::stdfs::copy_file(oldpath, newpath, opts, ec); } + virtual void copy_symlink(const fs::path& oldpath, const fs::path& newpath, std::error_code& ec) + { + return fs::stdfs::copy_symlink(oldpath, newpath, ec); + } virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override { return fs::stdfs::status(path, ec); } + virtual fs::file_status symlink_status(const fs::path& path, std::error_code& ec) const override + { + return fs::stdfs::symlink_status(path, ec); + } virtual void write_contents(const fs::path& file_path, const std::string& data, std::error_code& ec) override { ec.clear(); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 4bb84831e..1cfa2bf71 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -62,7 +62,7 @@ namespace vcpkg::Install auto files = fs.get_files_recursive(source_dir); for (auto&& file : files) { - const auto status = fs.status(file, ec); + const auto status = fs.symlink_status(file, ec); if (ec) { System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); @@ -111,6 +111,23 @@ namespace vcpkg::Install output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); break; } + case fs::file_type::symlink: + { + if (fs.exists(target)) + { + System::println(System::Color::warning, + "File %s was already present and will be overwritten", + target.u8string(), + ec.message()); + } + fs.copy_symlink(file, target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + } + output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); + break; + } default: System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); break; diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 13cc9325e..921a04c23 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -55,7 +55,7 @@ namespace vcpkg::Remove auto target = paths.installed / suffix; - const auto status = fs.status(target, ec); + const auto status = fs.symlink_status(target, ec); if (ec) { System::println(System::Color::error, "failed: status(%s): %s", target.u8string(), ec.message()); @@ -66,7 +66,7 @@ namespace vcpkg::Remove { dirs_touched.push_back(target); } - else if (fs::is_regular_file(status)) + else if (fs::is_regular_file(status) || fs::is_symlink(status)) { fs.remove(target, ec); if (ec) -- cgit v1.2.3 From cf199dba42735eac4065586dac0701fdfc6fd53d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 16 Oct 2018 15:58:50 -0700 Subject: Survey prompts are now shown only for intall/remove/export/update --- toolsrc/src/vcpkg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index ba9710562..bcce8ceb2 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -113,7 +113,7 @@ static void inner(const VcpkgCmdArguments& args) #endif Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); - if (args.command != "autocomplete") + if (args.command == "install" || args.command == "remove" || args.command == "export" || args.command == "update") { Commands::Version::warn_if_vcpkg_version_mismatch(paths); std::string surveydate = *GlobalState::g_surveydate.lock(); -- cgit v1.2.3 From f19df646a09d68856c5c4575174831f0d0a295e1 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 17 Oct 2018 19:05:24 -0700 Subject: Survey times. Refactor Chrono stuff. All times UTC, unless explicitly mentioned Survey is set to be every 6 months, but you also get one in the first 10 days. --- toolsrc/src/vcpkg.cpp | 18 ++++-- toolsrc/src/vcpkg/base/chrono.cpp | 96 ++++++++++++++++++++++++-------- toolsrc/src/vcpkg/base/system.cpp | 15 +---- toolsrc/src/vcpkg/commands.exportifw.cpp | 2 +- toolsrc/src/vcpkg/export.cpp | 10 ++-- 5 files changed, 92 insertions(+), 49 deletions(-) (limited to 'toolsrc/src') diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index bcce8ceb2..3589881a7 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -33,6 +33,12 @@ using namespace vcpkg; +// 24 hours/day * 30 days/month * 6 months +static constexpr int SURVEY_INTERVAL_IN_HOURS = 24 * 30 * 6; + +// Initial survey appears after 10 days. Therefore, subtract 24 hours/day * 10 days +static constexpr int SURVEY_INITIAL_OFFSET_IN_HOURS = SURVEY_INTERVAL_IN_HOURS - 24 * 10; + void invalid_command(const std::string& cmd) { System::println(System::Color::error, "invalid command: %s", cmd); @@ -120,12 +126,12 @@ static void inner(const VcpkgCmdArguments& args) auto maybe_surveydate = Chrono::CTime::parse(surveydate); if (auto p_surveydate = maybe_surveydate.get()) { - auto delta = std::chrono::system_clock::now() - p_surveydate->to_time_point(); - // 24 hours/day * 30 days/month - if (std::chrono::duration_cast(delta).count() > 24 * 30) + const auto now = Chrono::CTime::get_current_date_time().value_or_exit(VCPKG_LINE_INFO); + const auto delta = now.to_time_point() - p_surveydate->to_time_point(); + if (std::chrono::duration_cast(delta).count() > SURVEY_INTERVAL_IN_HOURS) { std::default_random_engine generator( - static_cast(std::chrono::system_clock::now().time_since_epoch().count())); + static_cast(now.to_time_point().time_since_epoch().count())); std::uniform_int_distribution distribution(1, 4); if (distribution(generator) == 1) @@ -214,7 +220,9 @@ static void load_config() if (config.last_completed_survey.empty()) { - config.last_completed_survey = config.user_time; + const auto now = Chrono::CTime::parse(config.user_time).value_or_exit(VCPKG_LINE_INFO); + const Chrono::CTime offset = now.add_hours(-SURVEY_INITIAL_OFFSET_IN_HOURS); + config.last_completed_survey = offset.to_string(); } GlobalState::g_surveydate.lock()->assign(config.last_completed_survey); diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp index 2a76f5df0..405e76605 100644 --- a/toolsrc/src/vcpkg/base/chrono.cpp +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -5,6 +5,61 @@ namespace vcpkg::Chrono { + static std::time_t get_current_time_as_time_since_epoch() + { + using std::chrono::system_clock; + return system_clock::to_time_t(system_clock::now()); + } + + static std::time_t utc_mktime(tm* time_ptr) + { +#if defined(_WIN32) + return _mkgmtime(time_ptr); +#else + return timegm(time_ptr); +#endif + } + + static tm to_local_time(const std::time_t& t) + { + tm parts {}; +#if defined(_WIN32) + localtime_s(&parts, &t); +#else + parts = *localtime(&t); +#endif + return parts; + } + + static Optional to_utc_time(const std::time_t& t) + { + tm parts {}; +#if defined(_WIN32) + const errno_t err = gmtime_s(&parts, &t); + if (err) + { + return nullopt; + } +#else + auto null_if_failed = gmtime_r(&t, &parts); + if (null_if_failed == nullptr) + { + return nullopt; + } +#endif + return parts; + } + + static tm date_plus_hours(tm* date, const int hours) + { + using namespace std::chrono_literals; + static constexpr std::chrono::seconds SECONDS_IN_ONE_HOUR = + std::chrono::duration_cast(1h); + + const std::time_t date_in_seconds = utc_mktime(date) + (hours * SECONDS_IN_ONE_HOUR.count()); + return to_utc_time(date_in_seconds).value_or_exit(VCPKG_LINE_INFO); + } + static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos) { using std::chrono::duration_cast; @@ -63,30 +118,14 @@ namespace vcpkg::Chrono Optional CTime::get_current_date_time() { - CTime ret; - -#if defined(_WIN32) - struct _timeb timebuffer; - - _ftime_s(&timebuffer); - - const errno_t err = gmtime_s(&ret.m_tm, &timebuffer.time); - - if (err) + const std::time_t ct = get_current_time_as_time_since_epoch(); + const Optional opt = to_utc_time(ct); + if (auto p_tm = opt.get()) { - return nullopt; + return CTime {*p_tm}; } -#else - time_t now = {0}; - time(&now); - auto null_if_failed = gmtime_r(&now, &ret.m_tm); - if (null_if_failed == nullptr) - { - return nullopt; - } -#endif - return ret; + return nullopt; } Optional CTime::parse(CStringView str) @@ -111,19 +150,28 @@ namespace vcpkg::Chrono ret.m_tm.tm_year -= 1900; if (ret.m_tm.tm_mon < 1) return nullopt; ret.m_tm.tm_mon -= 1; - mktime(&ret.m_tm); + utc_mktime(&ret.m_tm); + return ret; } + CTime CTime::add_hours(const int hours) const { return CTime {date_plus_hours(&this->m_tm, hours)}; } + std::string CTime::to_string() const { - std::array date{}; + std::array date {}; strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S.0Z", &m_tm); return &date[0]; } std::chrono::system_clock::time_point CTime::to_time_point() const { - const time_t t = mktime(&m_tm); + const time_t t = utc_mktime(&m_tm); return std::chrono::system_clock::from_time_t(t); } + + tm get_current_date_time_local() + { + const std::time_t now_time = get_current_time_as_time_since_epoch(); + return Chrono::to_local_time(now_time); + } } diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index 78ba28324..d95752bba 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -19,19 +19,6 @@ namespace vcpkg::System { - tm get_current_date_time() - { - using std::chrono::system_clock; - std::time_t now_time = system_clock::to_time_t(system_clock::now()); - tm parts{}; -#if defined(_WIN32) - localtime_s(&parts, &now_time); -#else - parts = *localtime(&now_time); -#endif - return parts; - } - fs::path get_exe_path_of_current_process() { #if defined(_WIN32) @@ -402,7 +389,7 @@ namespace vcpkg::System #if defined(_WIN32) const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; + CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info {}; GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); const auto original_color = console_screen_buffer_info.wAttributes; diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp index ae106196a..62725a90a 100644 --- a/toolsrc/src/vcpkg/commands.exportifw.cpp +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Export::IFW static std::string create_release_date() { - const tm date_time = System::get_current_date_time(); + const tm date_time = Chrono::get_current_date_time_local(); // Format is: YYYY-mm-dd // 10 characters + 1 null terminating character will be written for a total of 11 chars diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp index 8161c0a62..eec9a39f2 100644 --- a/toolsrc/src/vcpkg/export.cpp +++ b/toolsrc/src/vcpkg/export.cpp @@ -108,7 +108,7 @@ namespace vcpkg::Export static std::string create_export_id() { - const tm date_time = System::get_current_date_time(); + const tm date_time = Chrono::get_current_date_time_local(); // Format is: YYYYmmdd-HHMMSS // 15 characters + 1 null terminating character will be written for a total of 16 chars @@ -227,10 +227,10 @@ namespace vcpkg::Export { const std::vector integration_files_relative_to_root = { {".vcpkg-root"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, - {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, - {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, + {fs::path {"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, + {fs::path {"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, + {fs::path {"scripts"} / "buildsystems" / "vcpkg.cmake"}, + {fs::path {"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, }; for (const fs::path& file : integration_files_relative_to_root) -- cgit v1.2.3