aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-10-16 17:17:28 -0700
committerRobert Schumacher <roschuma@microsoft.com>2017-10-16 17:17:28 -0700
commitee2831c548b54cdccf064663b3fffda5d6a4c6b8 (patch)
tree70390dc6e2e22877cb6ede677076c8005fab8a1c /toolsrc/src
parentd88f53de9c284cfc67ba21707d60a44ba41ede8a (diff)
parent374253cb1b12a60925693130132f1a6ab6c3a83a (diff)
downloadvcpkg-ee2831c548b54cdccf064663b3fffda5d6a4c6b8.tar.gz
vcpkg-ee2831c548b54cdccf064663b3fffda5d6a4c6b8.zip
Merge from master
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/VcpkgPaths.cpp417
-rw-r--r--toolsrc/src/commands_build.cpp102
-rw-r--r--toolsrc/src/commands_ci.cpp98
-rw-r--r--toolsrc/src/commands_hash.cpp55
-rw-r--r--toolsrc/src/commands_version.cpp38
-rw-r--r--toolsrc/src/tests.arguments.cpp (renamed from toolsrc/src/tests_arguments.cpp)4
-rw-r--r--toolsrc/src/tests.dependencies.cpp (renamed from toolsrc/src/tests_dependencies.cpp)6
-rw-r--r--toolsrc/src/tests.installplan.cpp (renamed from toolsrc/src/test_install_plan.cpp)7
-rw-r--r--toolsrc/src/tests.packagespec.cpp (renamed from toolsrc/src/tests_package_spec.cpp)11
-rw-r--r--toolsrc/src/tests.paragraph.cpp (renamed from toolsrc/src/tests_paragraph.cpp)9
-rw-r--r--toolsrc/src/vcpkg.cpp109
-rw-r--r--toolsrc/src/vcpkg/base/checks.cpp (renamed from toolsrc/src/vcpkg_Checks.cpp)41
-rw-r--r--toolsrc/src/vcpkg/base/chrono.cpp (renamed from toolsrc/src/vcpkg_Chrono.cpp)24
-rw-r--r--toolsrc/src/vcpkg/base/cofffilereader.cpp (renamed from toolsrc/src/coff_file_reader.cpp)13
-rw-r--r--toolsrc/src/vcpkg/base/enums.cpp (renamed from toolsrc/src/vcpkg_Enums.cpp)4
-rw-r--r--toolsrc/src/vcpkg/base/files.cpp (renamed from toolsrc/src/vcpkg_Files.cpp)20
-rw-r--r--toolsrc/src/vcpkg/base/lineinfo.cpp (renamed from toolsrc/src/LineInfo.cpp)4
-rw-r--r--toolsrc/src/vcpkg/base/machinetype.cpp (renamed from toolsrc/src/MachineType.cpp)6
-rw-r--r--toolsrc/src/vcpkg/base/strings.cpp (renamed from toolsrc/src/vcpkg_Strings.cpp)84
-rw-r--r--toolsrc/src/vcpkg/base/system.cpp (renamed from toolsrc/src/vcpkg_System.cpp)215
-rw-r--r--toolsrc/src/vcpkg/binaryparagraph.cpp (renamed from toolsrc/src/BinaryParagraph.cpp)10
-rw-r--r--toolsrc/src/vcpkg/build.cpp (renamed from toolsrc/src/vcpkg_Build.cpp)235
-rw-r--r--toolsrc/src/vcpkg/commands.autocomplete.cpp141
-rw-r--r--toolsrc/src/vcpkg/commands.buildexternal.cpp (renamed from toolsrc/src/commands_build_external.cpp)17
-rw-r--r--toolsrc/src/vcpkg/commands.cache.cpp (renamed from toolsrc/src/commands_cache.cpp)17
-rw-r--r--toolsrc/src/vcpkg/commands.ci.cpp62
-rw-r--r--toolsrc/src/vcpkg/commands.contact.cpp (renamed from toolsrc/src/commands_contact.cpp)8
-rw-r--r--toolsrc/src/vcpkg/commands.cpp (renamed from toolsrc/src/commands_available_commands.cpp)18
-rw-r--r--toolsrc/src/vcpkg/commands.create.cpp (renamed from toolsrc/src/commands_create.cpp)22
-rw-r--r--toolsrc/src/vcpkg/commands.dependinfo.cpp (renamed from toolsrc/src/commands_depends.cpp)15
-rw-r--r--toolsrc/src/vcpkg/commands.edit.cpp (renamed from toolsrc/src/commands_edit.cpp)72
-rw-r--r--toolsrc/src/vcpkg/commands.env.cpp (renamed from toolsrc/src/commands_env.cpp)13
-rw-r--r--toolsrc/src/vcpkg/commands.exportifw.cpp490
-rw-r--r--toolsrc/src/vcpkg/commands.hash.cpp50
-rw-r--r--toolsrc/src/vcpkg/commands.import.cpp (renamed from toolsrc/src/commands_import.cpp)27
-rw-r--r--toolsrc/src/vcpkg/commands.integrate.cpp (renamed from toolsrc/src/commands_integrate.cpp)131
-rw-r--r--toolsrc/src/vcpkg/commands.list.cpp (renamed from toolsrc/src/commands_list.cpp)17
-rw-r--r--toolsrc/src/vcpkg/commands.owns.cpp (renamed from toolsrc/src/commands_owns.cpp)13
-rw-r--r--toolsrc/src/vcpkg/commands.portsdiff.cpp (renamed from toolsrc/src/commands_portsdiff.cpp)82
-rw-r--r--toolsrc/src/vcpkg/commands.search.cpp (renamed from toolsrc/src/commands_search.cpp)40
-rw-r--r--toolsrc/src/vcpkg/commands.version.cpp76
-rw-r--r--toolsrc/src/vcpkg/dependencies.cpp (renamed from toolsrc/src/vcpkg_Dependencies.cpp)50
-rw-r--r--toolsrc/src/vcpkg/export.cpp (renamed from toolsrc/src/commands_export.cpp)380
-rw-r--r--toolsrc/src/vcpkg/globalstate.cpp13
-rw-r--r--toolsrc/src/vcpkg/help.cpp (renamed from toolsrc/src/commands_help.cpp)14
-rw-r--r--toolsrc/src/vcpkg/input.cpp (renamed from toolsrc/src/vcpkg_Input.cpp)15
-rw-r--r--toolsrc/src/vcpkg/install.cpp (renamed from toolsrc/src/commands_install.cpp)246
-rw-r--r--toolsrc/src/vcpkg/metrics.cpp (renamed from toolsrc/src/metrics.cpp)198
-rw-r--r--toolsrc/src/vcpkg/packagespec.cpp (renamed from toolsrc/src/PackageSpec.cpp)10
-rw-r--r--toolsrc/src/vcpkg/packagespecparseresult.cpp (renamed from toolsrc/src/PackageSpecParseResult.cpp)5
-rw-r--r--toolsrc/src/vcpkg/paragraphparseresult.cpp (renamed from toolsrc/src/ParagraphParseResult.cpp)4
-rw-r--r--toolsrc/src/vcpkg/paragraphs.cpp (renamed from toolsrc/src/Paragraphs.cpp)28
-rw-r--r--toolsrc/src/vcpkg/parse.cpp (renamed from toolsrc/src/vcpkg_Parse.cpp)15
-rw-r--r--toolsrc/src/vcpkg/postbuildlint.buildtype.cpp (renamed from toolsrc/src/PostBuildLint_BuildType.cpp)4
-rw-r--r--toolsrc/src/vcpkg/postbuildlint.cpp (renamed from toolsrc/src/PostBuildLint.cpp)86
-rw-r--r--toolsrc/src/vcpkg/remove.cpp (renamed from toolsrc/src/commands_remove.cpp)152
-rw-r--r--toolsrc/src/vcpkg/sourceparagraph.cpp (renamed from toolsrc/src/SourceParagraph.cpp)85
-rw-r--r--toolsrc/src/vcpkg/statusparagraph.cpp (renamed from toolsrc/src/StatusParagraph.cpp)6
-rw-r--r--toolsrc/src/vcpkg/statusparagraphs.cpp (renamed from toolsrc/src/StatusParagraphs.cpp)7
-rw-r--r--toolsrc/src/vcpkg/triplet.cpp (renamed from toolsrc/src/triplet.cpp)24
-rw-r--r--toolsrc/src/vcpkg/update.cpp (renamed from toolsrc/src/commands_update.cpp)40
-rw-r--r--toolsrc/src/vcpkg/vcpkgcmdarguments.cpp (renamed from toolsrc/src/VcpkgCmdArguments.cpp)31
-rw-r--r--toolsrc/src/vcpkg/vcpkglib.cpp (renamed from toolsrc/src/vcpkglib.cpp)38
-rw-r--r--toolsrc/src/vcpkg/vcpkgpaths.cpp528
-rw-r--r--toolsrc/src/vcpkg/versiont.cpp (renamed from toolsrc/src/VersionT.cpp)4
-rw-r--r--toolsrc/src/vcpkg_Build_BuildPolicy.cpp40
-rw-r--r--toolsrc/src/vcpkg_GlobalState.cpp13
-rw-r--r--toolsrc/src/vcpkgmetricsuploader.cpp (renamed from toolsrc/src/vcpkg_metrics_uploader.cpp)8
68 files changed, 3004 insertions, 1863 deletions
diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp
deleted file mode 100644
index 865f2ce44..000000000
--- a/toolsrc/src/VcpkgPaths.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-#include "pch.h"
-
-#include "PackageSpec.h"
-#include "VcpkgPaths.h"
-#include "metrics.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include "vcpkg_expected.h"
-
-namespace vcpkg
-{
- static std::string WORKAROUND_ISSUE_1712(const std::string& line)
- {
- auto colon_pos = line.find(':');
- if (colon_pos != std::string::npos && colon_pos > 1)
- {
- return line.substr(colon_pos - 1);
- }
- return line;
- }
-
- static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd,
- const std::array<int, 3>& expected_version)
- {
- static const std::regex re(R"###((\d+)\.(\d+)\.(\d+))###");
-
- auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd));
- if (rc.exit_code != 0)
- {
- return false;
- }
-
- std::match_results<std::string::const_iterator> match;
- auto found = std::regex_search(rc.output, match, re);
- if (!found)
- {
- return false;
- }
-
- int d1 = atoi(match[1].str().c_str());
- int d2 = atoi(match[2].str().c_str());
- int d3 = atoi(match[3].str().c_str());
- if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) ||
- (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2]))
- {
- // satisfactory version found
- return true;
- }
-
- return false;
- }
-
- static Optional<fs::path> find_if_has_equal_or_greater_version(const std::vector<fs::path>& candidate_paths,
- const std::wstring& version_check_arguments,
- const std::array<int, 3>& expected_version)
- {
- auto it = Util::find_if(candidate_paths, [&](const fs::path& p) {
- const std::wstring cmd = Strings::wformat(LR"("%s" %s)", p.native(), version_check_arguments);
- return exists_and_has_equal_or_greater_version(cmd, expected_version);
- });
-
- if (it != candidate_paths.cend())
- {
- return std::move(*it);
- }
-
- return nullopt;
- }
-
- static fs::path fetch_dependency(const fs::path& scripts_folder,
- const std::wstring& tool_name,
- const fs::path& expected_downloaded_path,
- const std::array<int, 3>& version)
- {
- const fs::path script = scripts_folder / "fetchDependency.ps1";
- auto install_cmd = System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name));
- System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd);
- if (rc.exit_code)
- {
- const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]);
-
- System::println(System::Color::error,
- "Launching powershell failed or was denied when trying to fetch %s version %s.\n"
- "(No sufficient installed version was found)",
- Strings::to_utf8(tool_name),
- version_as_string);
- {
- auto locked_metrics = Metrics::g_metrics.lock();
- locked_metrics->track_property("error", "powershell install failed");
- locked_metrics->track_property("dependency", tool_name);
- }
- Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code);
- }
-
- const fs::path actual_downloaded_path = WORKAROUND_ISSUE_1712(Strings::trimmed(rc.output));
- std::error_code ec;
- auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec);
- Checks::check_exit(VCPKG_LINE_INFO,
- eq && !ec,
- "Expected dependency downloaded path to be %s, but was %s",
- expected_downloaded_path.u8string(),
- actual_downloaded_path.u8string());
- return actual_downloaded_path;
- }
-
- static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
- {
- static constexpr std::array<int, 3> expected_version = {3, 9, 1};
- static const std::wstring version_check_arguments = L"--version";
-
- const fs::path downloaded_copy = downloads_folder / "cmake-3.9.1-win32-x86" / "bin" / "cmake.exe";
- const std::vector<fs::path> from_path = Files::find_from_PATH(L"cmake");
-
- std::vector<fs::path> candidate_paths;
- candidate_paths.push_back(downloaded_copy);
- candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "CMake" / "bin" / "cmake.exe");
- candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "CMake" / "bin");
-
- const Optional<fs::path> path =
- find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version);
- if (auto p = path.get())
- {
- return *p;
- }
-
- return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, expected_version);
- }
-
- fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
- {
- static constexpr std::array<int, 3> expected_version = {4, 1, 0};
- static const std::wstring version_check_arguments = Strings::WEMPTY;
-
- const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe";
- const std::vector<fs::path> from_path = Files::find_from_PATH(L"nuget");
-
- std::vector<fs::path> candidate_paths;
- candidate_paths.push_back(downloaded_copy);
- candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
-
- auto path = find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version);
- if (auto p = path.get())
- {
- return *p;
- }
-
- return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, expected_version);
- }
-
- fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
- {
- static constexpr std::array<int, 3> expected_version = {2, 14, 1};
- static const std::wstring version_check_arguments = L"--version";
-
- const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe";
- const std::vector<fs::path> from_path = Files::find_from_PATH(L"git");
-
- std::vector<fs::path> candidate_paths;
- candidate_paths.push_back(downloaded_copy);
- candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "git" / "cmd" / "git.exe");
- candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "git" / "cmd" / "git.exe");
-
- const Optional<fs::path> path =
- find_if_has_equal_or_greater_version(candidate_paths, version_check_arguments, expected_version);
- if (auto p = path.get())
- {
- return *p;
- }
-
- return fetch_dependency(scripts_folder, L"git", downloaded_copy, expected_version);
- }
-
- Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir)
- {
- std::error_code ec;
- const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec);
- if (ec)
- {
- return ec;
- }
-
- VcpkgPaths paths;
- paths.root = canonical_vcpkg_root_dir;
-
- if (paths.root.empty())
- {
- Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory");
- Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string());
- }
-
- paths.packages = paths.root / "packages";
- paths.buildtrees = paths.root / "buildtrees";
- paths.downloads = paths.root / "downloads";
- paths.ports = paths.root / "ports";
- paths.installed = paths.root / "installed";
- paths.triplets = paths.root / "triplets";
- paths.scripts = paths.root / "scripts";
-
- paths.buildsystems = paths.scripts / "buildsystems";
- paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets";
-
- paths.vcpkg_dir = paths.installed / "vcpkg";
- paths.vcpkg_dir_status_file = paths.vcpkg_dir / "status";
- paths.vcpkg_dir_info = paths.vcpkg_dir / "info";
- paths.vcpkg_dir_updates = paths.vcpkg_dir / "updates";
-
- paths.ports_cmake = paths.scripts / "ports.cmake";
-
- return paths;
- }
-
- fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); }
-
- fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); }
- fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; }
-
- fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const
- {
- return this->package_dir(spec) / "BUILD_INFO";
- }
-
- fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const
- {
- return this->vcpkg_dir_info / (pgh.fullstem() + ".list");
- }
-
- bool VcpkgPaths::is_valid_triplet(const Triplet& t) const
- {
- for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets))
- {
- std::string triplet_file_name = path.stem().generic_u8string();
- if (t.canonical_name() == triplet_file_name) // TODO: fuzzy compare
- {
- // t.value = triplet_file_name; // NOTE: uncomment when implementing fuzzy compare
- return true;
- }
- }
- return false;
- }
-
- const fs::path& VcpkgPaths::get_cmake_exe() const
- {
- return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); });
- }
-
- const fs::path& VcpkgPaths::get_git_exe() const
- {
- return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); });
- }
-
- const fs::path& VcpkgPaths::get_nuget_exe() const
- {
- return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); });
- }
-
- static std::vector<std::string> get_VS2017_installation_instances(const VcpkgPaths& paths)
- {
- const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1";
- const std::wstring cmd = System::create_powershell_script_cmd(script);
- System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd);
- Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances");
- return Util::fmap(Strings::split(ec_data.output, "\n"), WORKAROUND_ISSUE_1712);
- }
-
- static Optional<fs::path> get_VS2015_installation_instance()
- {
- const Optional<std::wstring> vs2015_cmntools_optional = System::get_environment_variable(L"VS140COMNTOOLS");
- if (auto v = vs2015_cmntools_optional.get())
- {
- const fs::path vs2015_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because
- // the env variable has a trailing backslash
- return vs2015_cmntools.parent_path().parent_path();
- }
-
- return nullopt;
- }
-
- static std::vector<Toolset> find_toolset_instances(const VcpkgPaths& paths)
- {
- using CPU = System::CPUArchitecture;
-
- const auto& fs = paths.get_filesystem();
-
- const std::vector<std::string> vs2017_installation_instances = get_VS2017_installation_instances(paths);
- // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations.
- std::vector<fs::path> paths_examined;
-
- std::vector<Toolset> found_toolsets;
-
- // VS2015
- const Optional<fs::path> vs_2015_installation_instance = get_VS2015_installation_instance();
- if (auto v = vs_2015_installation_instance.get())
- {
- const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat";
-
- paths_examined.push_back(vs2015_vcvarsall_bat);
- if (fs.exists(vs2015_vcvarsall_bat))
- {
- const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe";
- paths_examined.push_back(vs2015_dumpbin_exe);
-
- const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin";
- std::vector<ToolsetArchOption> supported_architectures;
- if (fs.exists(vs2015_bin_dir / "vcvars32.bat"))
- supported_architectures.push_back({L"x86", CPU::X86, CPU::X86});
- if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat"))
- supported_architectures.push_back({L"x64", CPU::X64, CPU::X64});
- if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat"))
- supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64});
- if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat"))
- supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM});
- if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat"))
- supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86});
- if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat"))
- supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM});
-
- if (fs.exists(vs2015_dumpbin_exe))
- {
- found_toolsets.push_back(
- {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, L"v140", supported_architectures});
- }
- }
- }
-
- // VS2017
- Optional<Toolset> vs2017_toolset;
- for (const fs::path& instance : vs2017_installation_instances)
- {
- const fs::path vc_dir = instance / "VC";
-
- // Skip any instances that do not have vcvarsall.
- const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build";
- const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat";
- paths_examined.push_back(vcvarsall_bat);
- if (!fs.exists(vcvarsall_bat)) continue;
-
- // Get all supported architectures
- std::vector<ToolsetArchOption> supported_architectures;
- if (fs.exists(vcvarsall_dir / "vcvars32.bat"))
- supported_architectures.push_back({L"x86", CPU::X86, CPU::X86});
- if (fs.exists(vcvarsall_dir / "vcvars64.bat"))
- supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat"))
- supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64});
- if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat"))
- supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat"))
- supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86});
- if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat"))
- supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM});
-
- // Locate the "best" MSVC toolchain version
- const fs::path msvc_path = vc_dir / "Tools" / "MSVC";
- std::vector<fs::path> msvc_subdirectories = fs.get_files_non_recursive(msvc_path);
- Util::unstable_keep_if(msvc_subdirectories, [&fs](const fs::path& path) { return fs.is_directory(path); });
-
- // Sort them so that latest comes first
- std::sort(msvc_subdirectories.begin(),
- msvc_subdirectories.end(),
- [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); });
-
- for (const fs::path& subdir : msvc_subdirectories)
- {
- const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe";
- paths_examined.push_back(dumpbin_path);
- if (fs.exists(dumpbin_path))
- {
- vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, L"v141", supported_architectures};
- break;
- }
- }
- if (auto value = vs2017_toolset.get())
- {
- found_toolsets.push_back(*value);
- break;
- }
- }
-
- if (found_toolsets.empty())
- {
- System::println(System::Color::error, "Could not locate a complete toolset.");
- System::println("The following paths were examined:");
- for (const fs::path& path : paths_examined)
- {
- System::println(" %s", path.u8string());
- }
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- return found_toolsets;
- }
-
- const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const
- {
- // Invariant: toolsets are non-empty and sorted with newest at back()
- const auto& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); });
-
- if (toolset_version.empty())
- {
- return vs_toolsets.back();
- }
- else
- {
- const auto toolset = Util::find_if(vs_toolsets, [&](const Toolset& toolset) {
- return toolset_version == Strings::to_utf8(toolset.version);
- });
- Checks::check_exit(
- VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version);
- return *toolset;
- }
- }
-
- Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); }
-}
diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp
deleted file mode 100644
index 26a783a4b..000000000
--- a/toolsrc/src/commands_build.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#include "pch.h"
-
-#include "Paragraphs.h"
-#include "PostBuildLint.h"
-#include "StatusParagraphs.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Enums.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
-
-using vcpkg::Build::BuildResult;
-using vcpkg::Parse::ParseControlErrorInfo;
-using vcpkg::Parse::ParseExpected;
-
-namespace vcpkg::Commands::BuildCommand
-{
- using Dependencies::InstallPlanAction;
- using Dependencies::InstallPlanType;
-
- static const std::string OPTION_CHECKS_ONLY = "--checks-only";
-
- void perform_and_exit(const FullPackageSpec& full_spec,
- const fs::path& port_dir,
- const std::unordered_set<std::string>& options,
- const VcpkgPaths& paths)
- {
- const PackageSpec& spec = full_spec.package_spec;
- if (options.find(OPTION_CHECKS_ONLY) != options.end())
- {
- const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet());
- const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec));
- const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info);
- Checks::check_exit(VCPKG_LINE_INFO, error_count == 0);
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- const ParseExpected<SourceControlFile> source_control_file =
- Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
-
- if (!source_control_file.has_value())
- {
- print_error_message(source_control_file.error());
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- for (const std::string& str : full_spec.features)
- {
- System::println("%s \n", str);
- }
- const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO);
- Checks::check_exit(VCPKG_LINE_INFO,
- spec.name() == scf->core_paragraph->name,
- "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'",
- scf->core_paragraph->name,
- spec.name());
-
- const StatusParagraphs status_db = database_load_check(paths);
- const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES};
-
- const Build::BuildPackageConfig build_config{
- *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options};
-
- const auto result = Build::build_package(paths, build_config, status_db);
- if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
- {
- System::println(System::Color::error,
- "The build command requires all dependencies to be already installed.");
- System::println("The following dependencies are missing:");
- System::println();
- for (const auto& p : result.unmet_dependencies)
- {
- System::println(" %s", p);
- }
- System::println();
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- if (result.code != BuildResult::SUCCEEDED)
- {
- System::println(System::Color::error, Build::create_error_message(result.code, spec));
- System::println(Build::create_user_troubleshooting_message(spec));
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
- {
- static const std::string example = Commands::Help::create_example_string("build zlib:x64-windows");
- args.check_exact_arg_count(
- 1, example); // Build only takes a single package and all dependencies must already be installed
- const std::string command_argument = args.command_arguments.at(0);
- const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, example);
- Input::check_triplet(spec.package_spec.triplet(), paths);
- const std::unordered_set<std::string> options =
- args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY});
- perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths);
- }
-}
diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp
deleted file mode 100644
index f781adf69..000000000
--- a/toolsrc/src/commands_ci.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "pch.h"
-
-#include "Paragraphs.h"
-#include "vcpkg_Build.h"
-#include "vcpkg_Chrono.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include "vcpkglib.h"
-
-namespace vcpkg::Commands::CI
-{
- using Dependencies::InstallPlanAction;
- using Dependencies::InstallPlanType;
- using Build::BuildResult;
-
- static std::vector<PackageSpec> load_all_package_specs(Files::Filesystem& fs,
- const fs::path& ports_directory,
- const Triplet& triplet)
- {
- auto ports = Paragraphs::load_all_ports(fs, ports_directory);
- return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec {
- return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet)
- .value_or_exit(VCPKG_LINE_INFO);
- });
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
- {
- static const std::string example = Commands::Help::create_example_string("ci x64-windows");
- args.check_max_arg_count(1, example);
- const Triplet triplet = args.command_arguments.size() == 1
- ? Triplet::from_canonical_name(args.command_arguments.at(0))
- : default_triplet;
- Input::check_triplet(triplet, paths);
- args.check_and_get_optional_command_arguments({});
- const std::vector<PackageSpec> specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet);
-
- StatusParagraphs status_db = database_load_check(paths);
- const auto& paths_port_file = Dependencies::PathsPortFile(paths);
- const std::vector<InstallPlanAction> install_plan =
- Dependencies::create_install_plan(paths_port_file, specs, status_db);
- Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty");
-
- std::vector<BuildResult> results;
- std::vector<std::string> timing;
- const ElapsedTime timer = ElapsedTime::create_started();
- size_t counter = 0;
- const size_t package_count = install_plan.size();
- const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES};
-
- for (const InstallPlanAction& action : install_plan)
- {
- const ElapsedTime build_timer = ElapsedTime::create_started();
- counter++;
- const std::string display_name = action.spec.to_string();
- System::println("Starting package %d/%d: %s", counter, package_count, display_name);
-
- timing.push_back("0");
- results.push_back(BuildResult::NULLVALUE);
-
- const BuildResult result =
- Install::perform_install_plan_action(paths, action, install_plan_options, status_db);
- timing.back() = build_timer.to_string();
- results.back() = result;
- System::println("Elapsed time for package %s: %s", action.spec, build_timer.to_string());
- }
-
- System::println("Total time taken: %s", timer.to_string());
-
- for (size_t i = 0; i < results.size(); i++)
- {
- System::println("%s: %s: %s", install_plan[i].spec, Build::to_string(results[i]), timing[i]);
- }
-
- std::map<BuildResult, int> summary;
- for (const BuildResult& v : Build::BuildResult_values)
- {
- summary[v] = 0;
- }
-
- for (const BuildResult& r : results)
- {
- summary[r]++;
- }
-
- System::println("\n\nSUMMARY");
- for (const std::pair<const BuildResult, int>& entry : summary)
- {
- System::println(" %s: %d", Build::to_string(entry.first), entry.second);
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp
deleted file mode 100644
index b3211b9f8..000000000
--- a/toolsrc/src/commands_hash.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#include "pch.h"
-
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-
-namespace vcpkg::Commands::Hash
-{
- static void do_file_hash(fs::path const& path, std::wstring const& hash_type)
- {
- const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type);
- const auto 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", Strings::to_utf8(cmd_line));
-
- std::string const& output = ec_data.output;
-
- const auto start = output.find_first_of("\r\n");
- Checks::check_exit(VCPKG_LINE_INFO,
- start != std::string::npos,
- "Unexpected output format from command: %s",
- Strings::to_utf8(cmd_line));
-
- const auto end = output.find_first_of("\r\n", start + 1);
- Checks::check_exit(VCPKG_LINE_INFO,
- end != std::string::npos,
- "Unexpected output format from command: %s",
- Strings::to_utf8(cmd_line));
-
- auto hash = output.substr(start, end - start);
- Util::erase_remove_if(hash, isspace);
- System::println(hash);
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args)
- {
- static const std::string EXAMPLE =
- Strings::format("The argument should be a file path\n%s",
- Commands::Help::create_example_string("hash boost_1_62_0.tar.bz2"));
- args.check_min_arg_count(1, EXAMPLE);
- args.check_max_arg_count(2, EXAMPLE);
- args.check_and_get_optional_command_arguments({});
-
- if (args.command_arguments.size() == 1)
- {
- do_file_hash(args.command_arguments[0], L"SHA512");
- }
- if (args.command_arguments.size() == 2)
- {
- do_file_hash(args.command_arguments[0], Strings::to_utf16(args.command_arguments[1]));
- }
-
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp
deleted file mode 100644
index af81cd26e..000000000
--- a/toolsrc/src/commands_version.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "pch.h"
-
-#include "metrics.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
-
-#define STRINGIFY(...) #__VA_ARGS__
-#define MACRO_TO_STRING(X) STRINGIFY(X)
-
-#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION)
-
-namespace vcpkg::Commands::Version
-{
- const std::string& version()
- {
- static const std::string s_version =
-#include "../VERSION.txt"
-
- +std::string(VCPKG_VERSION_AS_STRING)
-#ifndef NDEBUG
- + std::string("-debug")
-#endif
- + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external");
- return s_version;
- }
-
- void perform_and_exit(const VcpkgCmdArguments& args)
- {
- args.check_exact_arg_count(0);
- args.check_and_get_optional_command_arguments({});
-
- System::println("Vcpkg package management program version %s\n"
- "\n"
- "See LICENSE.txt for license information.",
- version());
- Checks::exit_success(VCPKG_LINE_INFO);
- }
-}
diff --git a/toolsrc/src/tests_arguments.cpp b/toolsrc/src/tests.arguments.cpp
index 14b3c3d4f..25bf0f085 100644
--- a/toolsrc/src/tests_arguments.cpp
+++ b/toolsrc/src/tests.arguments.cpp
@@ -1,5 +1,5 @@
-#include "CppUnitTest.h"
-#include "VcpkgCmdArguments.h"
+#include <CppUnitTest.h>
+#include <vcpkg/vcpkgcmdarguments.h>
#pragma comment(lib, "version")
#pragma comment(lib, "winhttp")
diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests.dependencies.cpp
index 6a6981d73..3f6e0dd10 100644
--- a/toolsrc/src/tests_dependencies.cpp
+++ b/toolsrc/src/tests.dependencies.cpp
@@ -1,6 +1,6 @@
-#include "CppUnitTest.h"
-#include "SourceParagraph.h"
-#include "Triplet.h"
+#include <CppUnitTest.h>
+#include <vcpkg/sourceparagraph.h>
+#include <vcpkg/triplet.h>
#pragma comment(lib, "version")
#pragma comment(lib, "winhttp")
diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/tests.installplan.cpp
index 6c9311264..120009db5 100644
--- a/toolsrc/src/test_install_plan.cpp
+++ b/toolsrc/src/tests.installplan.cpp
@@ -1,6 +1,7 @@
-#include "CppUnitTest.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Util.h"
+#include <CppUnitTest.h>
+#include <vcpkg/dependencies.h>
+
+#include <vcpkg/base/util.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
diff --git a/toolsrc/src/tests_package_spec.cpp b/toolsrc/src/tests.packagespec.cpp
index fa201b372..cb5c41af0 100644
--- a/toolsrc/src/tests_package_spec.cpp
+++ b/toolsrc/src/tests.packagespec.cpp
@@ -1,7 +1,8 @@
-#include "BinaryParagraph.h"
-#include "CppUnitTest.h"
-#include "Paragraphs.h"
-#include "vcpkg_Strings.h"
+#include <CppUnitTest.h>
+#include <vcpkg/binaryparagraph.h>
+#include <vcpkg/paragraphs.h>
+
+#include <vcpkg/base/strings.h>
#pragma comment(lib, "version")
#pragma comment(lib, "winhttp")
@@ -43,7 +44,7 @@ namespace UnitTest1
std::array<const char*, 6> features = {"", "0", "1", "", "2", "3"};
std::array<PackageSpec*, 6> specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec};
- for (int i = 0; i < features.size(); ++i)
+ for (size_t i = 0; i < features.size(); ++i)
{
Assert::AreEqual(features[i], fspecs[i].feature().c_str());
Assert::AreEqual(*specs[i], fspecs[i].spec());
diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests.paragraph.cpp
index 47a07e12d..d9301abd0 100644
--- a/toolsrc/src/tests_paragraph.cpp
+++ b/toolsrc/src/tests.paragraph.cpp
@@ -1,7 +1,8 @@
-#include "BinaryParagraph.h"
-#include "CppUnitTest.h"
-#include "Paragraphs.h"
-#include "vcpkg_Strings.h"
+#include <CppUnitTest.h>
+#include <vcpkg/binaryparagraph.h>
+#include <vcpkg/paragraphs.h>
+
+#include <vcpkg/base/strings.h>
#pragma comment(lib, "version")
#pragma comment(lib, "winhttp")
diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp
index 781f03585..e1e2240e7 100644
--- a/toolsrc/src/vcpkg.cpp
+++ b/toolsrc/src/vcpkg.cpp
@@ -1,27 +1,40 @@
+#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
-#include "Paragraphs.h"
-#include "metrics.h"
-#include "vcpkg_Chrono.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_Strings.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#pragma warning(push)
+#pragma warning(disable : 4768)
#include <Shlobj.h>
+#pragma warning(pop)
+#else
+#include <unistd.h>
+#endif
+
+#include <vcpkg/base/chrono.h>
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/vcpkglib.h>
+
#include <cassert>
#include <fstream>
#include <memory>
+#pragma comment(lib, "ole32")
+#pragma comment(lib, "shell32")
+
using namespace vcpkg;
void invalid_command(const std::string& cmd)
{
System::println(System::Color::error, "invalid command: %s", cmd);
- Commands::Help::print_usage();
+ Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
}
@@ -30,13 +43,26 @@ static void inner(const VcpkgCmdArguments& args)
Metrics::g_metrics.lock()->track_property("command", args.command);
if (args.command.empty())
{
- Commands::Help::print_usage();
+ Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
}
- if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_c()))
+ static const auto find_command = [&](auto&& commands) {
+ auto it = Util::find_if(commands, [&](auto&& commandc) {
+ return Strings::case_insensitive_ascii_equals(commandc.name, args.command);
+ });
+ using std::end;
+ if (it != end(commands))
+ {
+ return &*it;
+ }
+ else
+ return static_cast<decltype(&*it)>(nullptr);
+ };
+
+ if (const auto command_function = find_command(Commands::get_available_commands_type_c()))
{
- return command_function(args);
+ return command_function->function(args);
}
fs::path vcpkg_root_dir;
@@ -46,15 +72,21 @@ static void inner(const VcpkgCmdArguments& args)
}
else
{
- const Optional<std::wstring> vcpkg_root_dir_env = System::get_environment_variable(L"VCPKG_ROOT");
+ const auto vcpkg_root_dir_env = System::get_environment_variable("VCPKG_ROOT");
if (const auto v = vcpkg_root_dir_env.get())
{
vcpkg_root_dir = fs::stdfs::absolute(*v);
}
else
{
- vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(
- fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root");
+ const fs::path current_path = fs::stdfs::current_path();
+ vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(current_path, ".vcpkg-root");
+
+ if (vcpkg_root_dir.empty())
+ {
+ vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(
+ fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root");
+ }
}
}
@@ -67,12 +99,18 @@ static void inner(const VcpkgCmdArguments& args)
vcpkg_root_dir.string(),
expected_paths.error().message());
const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO);
+
+#if defined(_WIN32)
const int exit_code = _wchdir(paths.root.c_str());
+#else
+ const int exit_code = chdir(paths.root.c_str());
+#endif
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed");
+ Commands::Version::warn_if_vcpkg_version_mismatch(paths);
- if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_b()))
+ if (const auto command_function = find_command(Commands::get_available_commands_type_b()))
{
- return command_function(args, paths);
+ return command_function->function(args, paths);
}
Triplet default_triplet;
@@ -82,11 +120,10 @@ static void inner(const VcpkgCmdArguments& args)
}
else
{
- const Optional<std::wstring> vcpkg_default_triplet_env =
- System::get_environment_variable(L"VCPKG_DEFAULT_TRIPLET");
+ const auto vcpkg_default_triplet_env = System::get_environment_variable("VCPKG_DEFAULT_TRIPLET");
if (const auto v = vcpkg_default_triplet_env.get())
{
- default_triplet = Triplet::from_canonical_name(Strings::to_utf8(*v));
+ default_triplet = Triplet::from_canonical_name(*v);
}
else
{
@@ -96,16 +133,17 @@ static void inner(const VcpkgCmdArguments& args)
Input::check_triplet(default_triplet, paths);
- if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_a()))
+ if (const auto command_function = find_command(Commands::get_available_commands_type_a()))
{
- return command_function(args, paths, default_triplet);
+ return command_function->function(args, paths, default_triplet);
}
return invalid_command(args.command);
}
-static void loadConfig()
+static void load_config()
{
+#if defined(_WIN32)
fs::path localappdata;
{
// Config path in AppDataLocal
@@ -165,6 +203,7 @@ static void loadConfig()
catch (...)
{
}
+#endif
}
static std::string trim_path_from_command_line(const std::string& full_command_line)
@@ -188,26 +227,34 @@ static std::string trim_path_from_command_line(const std::string& full_command_l
return std::string(it, full_command_line.cend());
}
+#if defined(_WIN32)
int wmain(const int argc, const wchar_t* const* const argv)
+#else
+int main(const int argc, const char* const* const argv)
+#endif
{
if (argc == 0) std::abort();
+ *GlobalState::timer.lock() = Chrono::ElapsedTime::create_started();
+
+#if defined(_WIN32)
GlobalState::g_init_console_cp = GetConsoleCP();
GlobalState::g_init_console_output_cp = GetConsoleOutputCP();
SetConsoleCP(65001);
SetConsoleOutputCP(65001);
- *GlobalState::timer.lock() = ElapsedTime::create_started();
-
const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW()));
+#endif
{
auto locked_metrics = Metrics::g_metrics.lock();
locked_metrics->track_property("version", Commands::Version::version());
+#if defined(_WIN32)
locked_metrics->track_property("cmdline", trimmed_command_line);
+#endif
}
- loadConfig();
+ load_config();
Metrics::g_metrics.lock()->track_property("sqmuser", Metrics::get_SQM_user());
const VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(argc, argv);
@@ -254,6 +301,12 @@ int wmain(const int argc, const wchar_t* const* const argv)
exc_msg);
fflush(stdout);
for (int x = 0; x < argc; ++x)
+ {
+#if defined(_WIN32)
System::println("%s|", Strings::to_utf8(argv[x]));
+#else
+ System::println("%s|", argv[x]);
+#endif
+ }
fflush(stdout);
}
diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp
index 3692a0e9a..ed28d6e2b 100644
--- a/toolsrc/src/vcpkg_Checks.cpp
+++ b/toolsrc/src/vcpkg/base/checks.cpp
@@ -1,41 +1,54 @@
#include "pch.h"
-#include "metrics.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/globalstate.h>
+#include <vcpkg/metrics.h>
+
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/system.h>
namespace vcpkg::Checks
{
[[noreturn]] static void cleanup_and_exit(const int exit_code)
{
- auto elapsed_us = GlobalState::timer.lock()->microseconds();
+ const auto elapsed_us = GlobalState::timer.lock()->microseconds();
auto metrics = Metrics::g_metrics.lock();
metrics->track_metric("elapsed_us", elapsed_us);
GlobalState::debugging = false;
metrics->flush();
+#if defined(_WIN32)
SetConsoleCP(GlobalState::g_init_console_cp);
SetConsoleOutputCP(GlobalState::g_init_console_output_cp);
+#endif
fflush(nullptr);
+#if defined(_WIN32)
::TerminateProcess(::GetCurrentProcess(), exit_code);
+#else
+ ::exit(exit_code);
+#endif
}
- static BOOL CtrlHandler(DWORD fdwCtrlType)
+#if defined(_WIN32)
+ static BOOL ctrl_handler(DWORD fdw_ctrl_type)
{
{
auto locked_metrics = Metrics::g_metrics.lock();
- locked_metrics->track_property("CtrlHandler", std::to_string(fdwCtrlType));
+ locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type));
locked_metrics->track_property("error", "CtrlHandler was fired.");
}
cleanup_and_exit(EXIT_FAILURE);
}
- void register_console_ctrl_handler() { SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); }
+ void register_console_ctrl_handler()
+ {
+ SetConsoleCtrlHandler(reinterpret_cast<PHANDLER_ROUTINE>(ctrl_handler), TRUE);
+ }
+#else
+ void register_console_ctrl_handler() {}
+#endif
[[noreturn]] void unreachable(const LineInfo& line_info)
{
@@ -54,9 +67,9 @@ namespace vcpkg::Checks
cleanup_and_exit(exit_code);
}
- [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView errorMessage)
+ [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message)
{
- System::println(System::Color::error, errorMessage);
+ System::println(System::Color::error, error_message);
exit_fail(line_info);
}
@@ -64,15 +77,15 @@ namespace vcpkg::Checks
{
if (!expression)
{
- exit_with_message(line_info, Strings::EMPTY);
+ exit_with_message(line_info, "");
}
}
- void check_exit(const LineInfo& line_info, bool expression, const CStringView errorMessage)
+ void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message)
{
if (!expression)
{
- exit_with_message(line_info, errorMessage);
+ exit_with_message(line_info, error_message);
}
}
}
diff --git a/toolsrc/src/vcpkg_Chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp
index d70f4a054..5d28909fc 100644
--- a/toolsrc/src/vcpkg_Chrono.cpp
+++ b/toolsrc/src/vcpkg/base/chrono.cpp
@@ -1,49 +1,49 @@
#include "pch.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Chrono.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/chrono.h>
-namespace vcpkg
+namespace vcpkg::Chrono
{
static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos)
{
+ using std::chrono::duration_cast;
using std::chrono::hours;
- using std::chrono::minutes;
- using std::chrono::seconds;
- using std::chrono::milliseconds;
using std::chrono::microseconds;
+ using std::chrono::milliseconds;
+ using std::chrono::minutes;
using std::chrono::nanoseconds;
- using std::chrono::duration_cast;
+ using std::chrono::seconds;
const double nanos_as_double = static_cast<double>(nanos.count());
if (duration_cast<hours>(nanos) > hours())
{
- auto t = nanos_as_double / duration_cast<nanoseconds>(hours(1)).count();
+ const auto t = nanos_as_double / duration_cast<nanoseconds>(hours(1)).count();
return Strings::format("%.4g h", t);
}
if (duration_cast<minutes>(nanos) > minutes())
{
- auto t = nanos_as_double / duration_cast<nanoseconds>(minutes(1)).count();
+ const auto t = nanos_as_double / duration_cast<nanoseconds>(minutes(1)).count();
return Strings::format("%.4g min", t);
}
if (duration_cast<seconds>(nanos) > seconds())
{
- auto t = nanos_as_double / duration_cast<nanoseconds>(seconds(1)).count();
+ const auto t = nanos_as_double / duration_cast<nanoseconds>(seconds(1)).count();
return Strings::format("%.4g s", t);
}
if (duration_cast<milliseconds>(nanos) > milliseconds())
{
- auto t = nanos_as_double / duration_cast<nanoseconds>(milliseconds(1)).count();
+ const auto t = nanos_as_double / duration_cast<nanoseconds>(milliseconds(1)).count();
return Strings::format("%.4g ms", t);
}
if (duration_cast<microseconds>(nanos) > microseconds())
{
- auto t = nanos_as_double / duration_cast<nanoseconds>(microseconds(1)).count();
+ const auto t = nanos_as_double / duration_cast<nanoseconds>(microseconds(1)).count();
return Strings::format("%.4g us", t);
}
diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp
index 10c1437c6..1927e0b5e 100644
--- a/toolsrc/src/coff_file_reader.cpp
+++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp
@@ -1,12 +1,13 @@
#include "pch.h"
-#include "coff_file_reader.h"
-#include "vcpkg_Checks.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/cofffilereader.h>
using namespace std;
-namespace vcpkg::COFFFileReader
+namespace vcpkg::CoffFileReader
{
+#if defined(_WIN32)
template<class T>
static T reinterpret_bytes(const char* data)
{
@@ -24,7 +25,7 @@ namespace vcpkg::COFFFileReader
template<class T>
static T peek_value_from_stream(fstream& fs)
{
- const fpos_t original_pos = fs.tellg().seekpos();
+ const std::streampos original_pos = fs.tellg();
T data;
fs.read(reinterpret_cast<char*>(&data), sizeof data);
fs.seekg(original_pos);
@@ -305,4 +306,8 @@ namespace vcpkg::COFFFileReader
return {std::vector<MachineType>(machine_types.cbegin(), machine_types.cend())};
}
+#else
+ DllInfo read_dll(const fs::path& path) { exit(-1); }
+ LibInfo read_lib(const fs::path& path) { exit(-1); }
+#endif
}
diff --git a/toolsrc/src/vcpkg_Enums.cpp b/toolsrc/src/vcpkg/base/enums.cpp
index 51ba9d5dc..aa124f3aa 100644
--- a/toolsrc/src/vcpkg_Enums.cpp
+++ b/toolsrc/src/vcpkg/base/enums.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Enums.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/enums.h>
namespace vcpkg::Enums
{
diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg/base/files.cpp
index ad1fcebc6..6e43debb1 100644
--- a/toolsrc/src/vcpkg_Files.cpp
+++ b/toolsrc/src/vcpkg/base/files.cpp
@@ -1,9 +1,8 @@
#include "pch.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include <thread>
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
namespace vcpkg::Files
{
@@ -164,7 +163,12 @@ namespace vcpkg::Files
virtual void write_contents(const fs::path& file_path, const std::string& data) override
{
FILE* f = nullptr;
+#if defined(_WIN32)
auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb");
+#else
+ f = fopen(file_path.native().c_str(), "wb");
+ int ec = f != nullptr ? 0 : 1;
+#endif
Checks::check_exit(
VCPKG_LINE_INFO, ec == 0, "Error: Could not open file for writing: %s", file_path.u8string().c_str());
auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f);
@@ -195,9 +199,13 @@ namespace vcpkg::Files
System::println();
}
- std::vector<fs::path> find_from_PATH(const std::wstring& name)
+ std::vector<fs::path> find_from_PATH(const std::string& name)
{
- const std::wstring cmd = Strings::wformat(L"where.exe %s", name);
+#if defined(_WIN32)
+ const std::string cmd = Strings::format("where.exe %s", name);
+#else
+ const std::string cmd = Strings::format("which %s", name);
+#endif
auto out = System::cmd_execute_and_capture_output(cmd);
if (out.exit_code != 0)
{
diff --git a/toolsrc/src/LineInfo.cpp b/toolsrc/src/vcpkg/base/lineinfo.cpp
index d1bf9a4b1..7435ed666 100644
--- a/toolsrc/src/LineInfo.cpp
+++ b/toolsrc/src/vcpkg/base/lineinfo.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
-#include "LineInfo.h"
-#include "vcpkg_Strings.h"
+#include <vcpkg/base/lineinfo.h>
+#include <vcpkg/base/strings.h>
namespace vcpkg
{
diff --git a/toolsrc/src/MachineType.cpp b/toolsrc/src/vcpkg/base/machinetype.cpp
index 2f44ce21a..2b7bd5e3a 100644
--- a/toolsrc/src/MachineType.cpp
+++ b/toolsrc/src/vcpkg/base/machinetype.cpp
@@ -1,13 +1,13 @@
#include "pch.h"
-#include "MachineType.h"
-#include "vcpkg_Checks.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/machinetype.h>
namespace vcpkg
{
MachineType to_machine_type(const uint16_t value)
{
- MachineType t = static_cast<MachineType>(value);
+ const MachineType t = static_cast<MachineType>(value);
switch (t)
{
case MachineType::UNKNOWN:
diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp
index 15851829d..af41eed9a 100644
--- a/toolsrc/src/vcpkg_Strings.cpp
+++ b/toolsrc/src/vcpkg/base/strings.cpp
@@ -1,8 +1,8 @@
#include "pch.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Strings.h"
-#include "vcpkg_Util.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/util.h>
namespace vcpkg::Strings::details
{
@@ -37,31 +37,8 @@ namespace vcpkg::Strings::details
#if defined(_WIN32)
_vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args);
#else
- vsnprintf(&output.at(0), output.size() + 1, fmtstr, args);
-#endif
- va_end(args);
-
- return output;
- }
-
- std::wstring wformat_internal(const wchar_t* fmtstr, ...)
- {
- va_list args;
va_start(args, fmtstr);
-
-#if defined(_WIN32)
- const int sz = _vscwprintf_l(fmtstr, c_locale(), args);
-#else
- const int sz = vswprintf(nullptr, 0, fmtstr, args);
-#endif
- Checks::check_exit(VCPKG_LINE_INFO, sz > 0);
-
- std::wstring output(sz, L'\0');
-
-#if defined(_WIN32)
- _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args);
-#else
- vswprintf(&output.at(0), output.size() + 1, fmtstr, args);
+ auto res = vsnprintf(&output.at(0), output.size() + 1, fmtstr, args);
#endif
va_end(args);
@@ -71,16 +48,30 @@ namespace vcpkg::Strings::details
namespace vcpkg::Strings
{
- std::wstring to_utf16(const CStringView s)
+ std::wstring to_utf16(const CStringView& s)
{
- std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
- return conversion.from_bytes(s);
+#if defined(_WIN32)
+ const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0);
+ std::wstring output;
+ output.resize(size - 1);
+ MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1);
+ return output;
+#else
+ Checks::unreachable(VCPKG_LINE_INFO);
+#endif
}
- std::string to_utf8(const CWStringView w)
+ std::string to_utf8(const CWStringView& w)
{
- std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
- return conversion.to_bytes(w);
+#if defined(_WIN32)
+ const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr);
+ std::string output;
+ output.resize(size - 1);
+ WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr);
+ return output;
+#else
+ Checks::unreachable(VCPKG_LINE_INFO);
+#endif
}
std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern)
@@ -98,9 +89,13 @@ namespace vcpkg::Strings
return case_insensitive_ascii_find(s, pattern) != s.end();
}
- int case_insensitive_ascii_compare(const CStringView left, const CStringView right)
+ bool case_insensitive_ascii_equals(const CStringView left, const CStringView right)
{
- return _stricmp(left, right);
+#if defined(_WIN32)
+ return _stricmp(left.c_str(), right.c_str()) == 0;
+#else
+ return strcasecmp(left.c_str(), right.c_str()) == 0;
+#endif
}
std::string ascii_to_lowercase(const std::string& input)
@@ -110,6 +105,15 @@ namespace vcpkg::Strings
return output;
}
+ bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern)
+ {
+#if defined(_WIN32)
+ return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0;
+#else
+ return strncasecmp(s.c_str(), pattern.c_str(), pattern.size()) == 0;
+#endif
+ }
+
void trim(std::string* s)
{
s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end());
@@ -137,11 +141,19 @@ namespace vcpkg::Strings
{
std::vector<std::string> output;
+ if (delimiter.empty())
+ {
+ output.push_back(s);
+ return output;
+ }
+
+ const size_t delimiter_length = delimiter.length();
size_t i = 0;
for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos))
{
output.push_back(s.substr(i, pos - i));
- i = ++pos;
+ pos += delimiter_length;
+ i = pos;
}
// Add the rest of the string after the last delimiter, unless there is nothing after it
diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg/base/system.cpp
index f5106b25e..b04f79414 100644
--- a/toolsrc/src/vcpkg_System.cpp
+++ b/toolsrc/src/vcpkg/base/system.cpp
@@ -1,9 +1,12 @@
#include "pch.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/globalstate.h>
+
+#include <time.h>
+
+#pragma comment(lib, "Advapi32")
namespace vcpkg::System
{
@@ -12,35 +15,46 @@ namespace vcpkg::System
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)
wchar_t buf[_MAX_PATH];
const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH);
if (bytes == 0) std::abort();
return fs::path(buf, buf + bytes);
+#else
+ std::array<char, 1024 * 4> buf;
+ auto written = readlink("/proc/self/exe", buf.data(), buf.size());
+ Checks::check_exit(VCPKG_LINE_INFO, written != -1, "Could not determine current executable path.");
+ return fs::path(buf.data(), buf.data() + written);
+#endif
}
- Optional<CPUArchitecture> to_cpu_architecture(CStringView arch)
+ Optional<CPUArchitecture> to_cpu_architecture(const CStringView& arch)
{
- if (Strings::case_insensitive_ascii_compare(arch, "x86") == 0) return CPUArchitecture::X86;
- if (Strings::case_insensitive_ascii_compare(arch, "x64") == 0) return CPUArchitecture::X64;
- if (Strings::case_insensitive_ascii_compare(arch, "amd64") == 0) return CPUArchitecture::X64;
- if (Strings::case_insensitive_ascii_compare(arch, "arm") == 0) return CPUArchitecture::ARM;
- if (Strings::case_insensitive_ascii_compare(arch, "arm64") == 0) return CPUArchitecture::ARM64;
+ if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86;
+ if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64;
+ if (Strings::case_insensitive_ascii_equals(arch, "amd64")) return CPUArchitecture::X64;
+ if (Strings::case_insensitive_ascii_equals(arch, "arm")) return CPUArchitecture::ARM;
+ if (Strings::case_insensitive_ascii_equals(arch, "arm64")) return CPUArchitecture::ARM64;
return nullopt;
}
CPUArchitecture get_host_processor()
{
- auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432");
- if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO);
+ auto w6432 = get_environment_variable("PROCESSOR_ARCHITEW6432");
+ if (const auto p = w6432.get()) return to_cpu_architecture(*p).value_or_exit(VCPKG_LINE_INFO);
- const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO);
- return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO);
+ const auto procarch = get_environment_variable("PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO);
+ return to_cpu_architecture(procarch).value_or_exit(VCPKG_LINE_INFO);
}
std::vector<CPUArchitecture> get_supported_host_architectures()
@@ -57,12 +71,13 @@ namespace vcpkg::System
return supported_architectures;
}
- int cmd_execute_clean(const CWStringView cmd_line)
+ int cmd_execute_clean(const CStringView cmd_line)
{
- static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO);
- static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)";
- static const std::wstring NEW_PATH = Strings::wformat(
- LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32);
+#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(
+ R"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32);
std::vector<std::wstring> env_wstrings = {
L"ALLUSERSPROFILE",
@@ -106,6 +121,8 @@ namespace vcpkg::System
L"HTTPS_PROXY",
// Enables find_package(CUDA) in CMake
L"CUDA_PATH",
+ // Environmental variable generated automatically by CUDA after installation
+ L"NVCUDASAMPLES_ROOT",
};
// Flush stdout before launching external process
@@ -115,17 +132,17 @@ namespace vcpkg::System
for (auto&& env_wstring : env_wstrings)
{
- const Optional<std::wstring> value = System::get_environment_variable(env_wstring);
+ const Optional<std::string> value = System::get_environment_variable(Strings::to_utf8(env_wstring));
const auto v = value.get();
if (!v || v->empty()) continue;
env_cstr.append(env_wstring);
env_cstr.push_back(L'=');
- env_cstr.append(*v);
+ env_cstr.append(Strings::to_utf16(*v));
env_cstr.push_back(L'\0');
}
- env_cstr.append(NEW_PATH);
+ env_cstr.append(Strings::to_utf16(NEW_PATH));
env_cstr.push_back(L'\0');
STARTUPINFOW startup_info;
@@ -136,10 +153,10 @@ namespace vcpkg::System
memset(&process_info, 0, sizeof(PROCESS_INFORMATION));
// Basically we are wrapping it in quotes
- std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line);
- Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line));
+ 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,
- actual_cmd_line.data(),
+ Strings::to_utf16(actual_cmd_line).data(),
nullptr,
nullptr,
FALSE,
@@ -161,32 +178,54 @@ namespace vcpkg::System
Debug::println("CreateProcessW() returned %lu", exit_code);
return static_cast<int>(exit_code);
+#else
+ fflush(nullptr);
+ return system(cmd_line.c_str());
+#endif
}
- int cmd_execute(const CWStringView cmd_line)
+ int cmd_execute(const CStringView cmd_line)
{
// Flush stdout before launching external process
fflush(nullptr);
// Basically we are wrapping it in quotes
- const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
- Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line));
- const int exit_code = _wsystem(actual_cmd_line.c_str());
+ const std::string& actual_cmd_line = Strings::format(R"###("%s")###", cmd_line);
+#if defined(_WIN32)
+ 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() returned %d", exit_code);
+#endif
return exit_code;
}
- ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line)
+ // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present
+ static void remove_byte_order_marks(std::wstring* s)
+ {
+ const wchar_t* a = s->c_str();
+ // This is the UTF-8 byte-order mark
+ while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF)
+ {
+ s->erase(0, 3);
+ }
+ }
+
+ ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line)
{
// Flush stdout before launching external process
fflush(stdout);
- const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line);
+#if defined(_WIN32)
+ const auto actual_cmd_line = Strings::format(R"###("%s 2>&1")###", cmd_line);
- Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line));
+ Debug::println("_wpopen(%s)", actual_cmd_line);
std::wstring output;
wchar_t buf[1024];
- const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r");
+ const auto pipe = _wpopen(Strings::to_utf16(actual_cmd_line).c_str(), L"r");
if (pipe == nullptr)
{
return {1, Strings::to_utf8(output)};
@@ -202,28 +241,54 @@ namespace vcpkg::System
const auto ec = _pclose(pipe);
Debug::println("_pclose() returned %d", ec);
+ remove_byte_order_marks(&output);
return {ec, Strings::to_utf8(output)};
+#else
+ const auto actual_cmd_line = Strings::format(R"###(%s 2>&1)###", cmd_line);
+
+ Debug::println("popen(%s)", actual_cmd_line);
+ std::string output;
+ char buf[1024];
+ const auto pipe = popen(actual_cmd_line.c_str(), "r");
+ if (pipe == nullptr)
+ {
+ return {1, output};
+ }
+ while (fgets(buf, 1024, pipe))
+ {
+ output.append(buf);
+ }
+ if (!feof(pipe))
+ {
+ return {1, output};
+ }
+
+ const auto ec = pclose(pipe);
+ Debug::println("pclose() returned %d", ec);
+ return {ec, output};
+#endif
}
- std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args)
+ std::string create_powershell_script_cmd(const fs::path& script_path, const CStringView args)
{
// TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned
- return Strings::wformat(
- LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args);
+ return Strings::format(
+ R"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.u8string(), args);
}
- void println() { println(Strings::EMPTY); }
+ void println() { putchar('\n'); }
- void print(const CStringView message) { fputs(message, stdout); }
+ void print(const CStringView message) { fputs(message.c_str(), stdout); }
void println(const CStringView message)
{
print(message);
- putchar('\n');
+ println();
}
void print(const Color c, const CStringView message)
{
+#if defined(_WIN32)
const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{};
@@ -233,86 +298,110 @@ namespace vcpkg::System
SetConsoleTextAttribute(console_handle, static_cast<WORD>(c) | (original_color & 0xF0));
print(message);
SetConsoleTextAttribute(console_handle, original_color);
+#else
+ print(message);
+#endif
}
void println(const Color c, const CStringView message)
{
print(c, message);
- putchar('\n');
+ println();
}
- Optional<std::wstring> get_environment_variable(const CWStringView varname) noexcept
+ Optional<std::string> get_environment_variable(const CStringView varname) noexcept
{
- const auto sz = GetEnvironmentVariableW(varname, nullptr, 0);
+#if defined(_WIN32)
+ const auto w_varname = Strings::to_utf16(varname);
+ const auto sz = GetEnvironmentVariableW(w_varname.c_str(), nullptr, 0);
if (sz == 0) return nullopt;
std::wstring ret(sz, L'\0');
Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size());
- const auto sz2 = GetEnvironmentVariableW(varname, ret.data(), static_cast<DWORD>(ret.size()));
+ const auto sz2 = GetEnvironmentVariableW(w_varname.c_str(), ret.data(), static_cast<DWORD>(ret.size()));
Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz);
ret.pop_back();
- return ret;
+ return Strings::to_utf8(ret);
+#else
+ auto v = getenv(varname.c_str());
+ if (!v) return nullopt;
+ return std::string(v);
+#endif
}
- static bool is_string_keytype(DWORD hkey_type)
+#if defined(_WIN32)
+ static bool is_string_keytype(const DWORD hkey_type)
{
return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ;
}
- Optional<std::wstring> get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename)
+ Optional<std::string> get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename)
{
HKEY k = nullptr;
- const LSTATUS ec = RegOpenKeyExW(base, sub_key, NULL, KEY_READ, &k);
+ const LSTATUS ec =
+ RegOpenKeyExW(reinterpret_cast<HKEY>(base_hkey), Strings::to_utf16(sub_key).c_str(), NULL, KEY_READ, &k);
if (ec != ERROR_SUCCESS) return nullopt;
DWORD dw_buffer_size = 0;
DWORD dw_type = 0;
- auto rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, nullptr, &dw_buffer_size);
+ auto rc =
+ RegQueryValueExW(k, Strings::to_utf16(valuename).c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size);
if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 ||
dw_buffer_size % sizeof(wchar_t) != 0)
return nullopt;
std::wstring ret;
ret.resize(dw_buffer_size / sizeof(wchar_t));
- rc = RegQueryValueExW(k, valuename, nullptr, &dw_type, reinterpret_cast<LPBYTE>(ret.data()), &dw_buffer_size);
+ rc = RegQueryValueExW(k,
+ Strings::to_utf16(valuename).c_str(),
+ nullptr,
+ &dw_type,
+ reinterpret_cast<LPBYTE>(ret.data()),
+ &dw_buffer_size);
if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size())
return nullopt;
ret.pop_back(); // remove extra trailing null byte
- return ret;
+ return Strings::to_utf8(ret);
+ }
+#else
+ Optional<std::string> get_registry_string(void* base_hkey, const CStringView sub_key, const CStringView valuename)
+ {
+ return nullopt;
}
+#endif
- static const fs::path& get_ProgramFiles()
+ static const fs::path& get_program_files()
{
- static const fs::path p = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO);
- return p;
+ static const fs::path PATH = System::get_environment_variable("PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO);
+ return PATH;
}
- const fs::path& get_ProgramFiles_32_bit()
+ const fs::path& get_program_files_32_bit()
{
- static const fs::path p = []() -> fs::path {
- auto value = System::get_environment_variable(L"ProgramFiles(x86)");
+ static const fs::path PATH = []() -> fs::path {
+ auto value = System::get_environment_variable("ProgramFiles(x86)");
if (auto v = value.get())
{
return std::move(*v);
}
- return get_ProgramFiles();
+ return get_program_files();
}();
- return p;
+ return PATH;
}
- const fs::path& get_ProgramFiles_platform_bitness()
+ const fs::path& get_program_files_platform_bitness()
{
- static const fs::path p = []() -> fs::path {
- auto value = System::get_environment_variable(L"ProgramW6432");
+ static const fs::path PATH = []() -> fs::path {
+ auto value = System::get_environment_variable("ProgramW6432");
if (auto v = value.get())
{
return std::move(*v);
}
- return get_ProgramFiles();
+ return get_program_files();
}();
- return p;
+ return PATH;
}
}
diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp
index 1504912ab..3a493eb4c 100644
--- a/toolsrc/src/BinaryParagraph.cpp
+++ b/toolsrc/src/vcpkg/binaryparagraph.cpp
@@ -1,8 +1,8 @@
#include "pch.h"
-#include "BinaryParagraph.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Parse.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/binaryparagraph.h>
+#include <vcpkg/parse.h>
namespace vcpkg
{
@@ -80,10 +80,10 @@ namespace vcpkg
BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet)
{
this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO);
- this->version = Strings::EMPTY;
+ this->version = "";
this->feature = fpgh.name;
this->description = fpgh.description;
- this->maintainer = Strings::EMPTY;
+ this->maintainer = "";
this->depends = filter_dependencies(fpgh.depends, triplet);
}
diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg/build.cpp
index a2fa99ac8..cf16c8f9c 100644
--- a/toolsrc/src/vcpkg_Build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -1,20 +1,150 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "PostBuildLint.h"
-#include "metrics.h"
-#include "vcpkg_Build.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Chrono.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Enums.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_System.h"
-#include "vcpkg_optional.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/chrono.h>
+#include <vcpkg/base/enums.h>
+#include <vcpkg/base/optional.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/build.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/dependencies.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/postbuildlint.h>
+#include <vcpkg/statusparagraphs.h>
+#include <vcpkg/vcpkglib.h>
+
+using vcpkg::Build::BuildResult;
+using vcpkg::Parse::ParseControlErrorInfo;
+using vcpkg::Parse::ParseExpected;
+
+namespace vcpkg::Build::Command
+{
+ using Dependencies::InstallPlanAction;
+ using Dependencies::InstallPlanType;
+
+ static const std::string OPTION_CHECKS_ONLY = "--checks-only";
+
+ void perform_and_exit(const FullPackageSpec& full_spec,
+ const fs::path& port_dir,
+ const std::unordered_set<std::string>& options,
+ const VcpkgPaths& paths)
+ {
+ const PackageSpec& spec = full_spec.package_spec;
+ if (options.find(OPTION_CHECKS_ONLY) != options.end())
+ {
+ const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet());
+ const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec));
+ const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info);
+ Checks::check_exit(VCPKG_LINE_INFO, error_count == 0);
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+
+ const ParseExpected<SourceControlFile> source_control_file =
+ Paragraphs::try_load_port(paths.get_filesystem(), port_dir);
+
+ if (!source_control_file.has_value())
+ {
+ print_error_message(source_control_file.error());
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ for (const std::string& str : full_spec.features)
+ {
+ System::println("%s \n", str);
+ }
+ const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ spec.name() == scf->core_paragraph->name,
+ "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'",
+ scf->core_paragraph->name,
+ spec.name());
+
+ const StatusParagraphs status_db = database_load_check(paths);
+ const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES};
+
+ const Build::BuildPackageConfig build_config{
+ *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options};
+
+ const auto build_timer = Chrono::ElapsedTime::create_started();
+ const auto result = Build::build_package(paths, build_config, status_db);
+ System::println("Elapsed time for package %s: %s", spec.to_string(), build_timer.to_string());
+
+ if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
+ {
+ System::println(System::Color::error,
+ "The build command requires all dependencies to be already installed.");
+ System::println("The following dependencies are missing:");
+ System::println();
+ for (const auto& p : result.unmet_dependencies)
+ {
+ System::println(" %s", p);
+ }
+ System::println();
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ if (result.code != BuildResult::SUCCEEDED)
+ {
+ System::println(System::Color::error, Build::create_error_message(result.code, spec));
+ System::println(Build::create_user_troubleshooting_message(spec));
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
+ {
+ static const std::string EXAMPLE = Help::create_example_string("build zlib:x64-windows");
+ // Build only takes a single package and all dependencies must already be installed
+ args.check_exact_arg_count(1, EXAMPLE);
+ const std::string command_argument = args.command_arguments.at(0);
+ const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE);
+ Input::check_triplet(spec.package_spec.triplet(), paths);
+ const std::unordered_set<std::string> options =
+ args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY});
+ perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths);
+ }
+}
namespace vcpkg::Build
{
+ static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage";
+ static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs";
+ static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT";
+ static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder";
+ static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt";
+
+ const std::string& to_string(BuildPolicy policy)
+ {
+ switch (policy)
+ {
+ case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE;
+ case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS;
+ case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT;
+ case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER;
+ case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT;
+ default: Checks::unreachable(VCPKG_LINE_INFO);
+ }
+ }
+
+ CStringView to_cmake_variable(BuildPolicy policy)
+ {
+ switch (policy)
+ {
+ case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE";
+ case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS";
+ case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT";
+ case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER";
+ case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT";
+ default: Checks::unreachable(VCPKG_LINE_INFO);
+ }
+ }
+
Optional<LinkageType> to_linkage_type(const std::string& str)
{
if (str == "dynamic") return LinkageType::DYNAMIC;
@@ -28,16 +158,16 @@ namespace vcpkg::Build
static const std::string LIBRARY_LINKAGE = "LibraryLinkage";
}
- CWStringView to_vcvarsall_target(const std::string& cmake_system_name)
+ CStringView to_vcvarsall_target(const std::string& cmake_system_name)
{
- if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY;
- if (cmake_system_name == "Windows") return Strings::WEMPTY;
- if (cmake_system_name == "WindowsStore") return L"store";
+ if (cmake_system_name.empty()) return "";
+ if (cmake_system_name == "Windows") return "";
+ if (cmake_system_name == "WindowsStore") return "store";
Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name);
}
- CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset)
+ CStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset)
{
auto maybe_target_arch = System::to_cpu_architecture(target_architecture);
Checks::check_exit(
@@ -56,18 +186,23 @@ namespace vcpkg::Build
Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture);
}
- std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset)
+ std::string make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset)
{
- const wchar_t* tonull = L" >nul";
+ const char* tonull = " >nul";
if (GlobalState::debugging)
{
- tonull = Strings::WEMPTY;
+ tonull = "";
}
const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset);
const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name);
- return Strings::wformat(LR"("%s" %s %s %s 2>&1)", toolset.vcvarsall.native(), arch, target, tonull);
+ return Strings::format(R"("%s" %s %s %s %s 2>&1)",
+ toolset.vcvarsall.u8string(),
+ Strings::join(" ", toolset.vcvarsall_options),
+ arch,
+ target,
+ tonull);
}
static void create_binary_feature_control_file(const SourceParagraph& source_paragraph,
@@ -133,8 +268,6 @@ namespace vcpkg::Build
const fs::path ports_cmake_script_path = paths.ports_cmake;
const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet);
- const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset);
- const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset);
std::string features;
if (GlobalState::feature_packages)
@@ -152,24 +285,28 @@ namespace vcpkg::Build
}
}
- const std::wstring cmd_launch_cmake = make_cmake_cmd(
+ const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path);
+
+ const std::string cmd_launch_cmake = make_cmake_cmd(
cmake_exe_path,
ports_cmake_script_path,
{
- {L"CMD", L"BUILD"},
- {L"PORT", config.src.name},
- {L"CURRENT_PORT_DIR", config.port_dir / "/."},
- {L"TARGET_TRIPLET", triplet.canonical_name()},
- {L"VCPKG_PLATFORM_TOOLSET", toolset.version},
- {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"},
- {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"},
- {L"GIT", git_exe_path},
- {L"FEATURES", features},
+ {"CMD", "BUILD"},
+ {"PORT", config.src.name},
+ {"CURRENT_PORT_DIR", config.port_dir / "/."},
+ {"TARGET_TRIPLET", triplet.canonical_name()},
+ {"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()},
+ {"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? "1" : "0"},
+ {"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? "1" : "0"},
+ {"GIT", git_exe_path},
+ {"FEATURES", features},
});
- const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake);
+ std::string command;
+ const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset);
+ command = Strings::format(R"(%s && %s)", cmd_set_environment, cmd_launch_cmake);
- const ElapsedTime timer = ElapsedTime::create_started();
+ const auto timer = Chrono::ElapsedTime::create_started();
const int return_code = System::cmd_execute_clean(command);
const auto buildtimeus = timer.microseconds();
@@ -289,7 +426,7 @@ namespace vcpkg::Build
if (!version.empty()) build_info.version = std::move(version);
std::map<BuildPolicy, bool> policies;
- for (auto policy : g_all_policies)
+ for (auto policy : G_ALL_POLICIES)
{
const auto setting = parser.optional_field(to_string(policy));
if (setting.empty()) continue;
@@ -329,14 +466,12 @@ namespace vcpkg::Build
const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake";
const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake");
- const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path,
- ports_cmake_script_path,
- {
- {L"CMAKE_TRIPLET_FILE", triplet_file_path},
- });
-
- const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake);
- const auto ec_data = System::cmd_execute_and_capture_output(command);
+ const auto cmd_launch_cmake = make_cmake_cmd(cmake_exe_path,
+ ports_cmake_script_path,
+ {
+ {"CMAKE_TRIPLET_FILE", triplet_file_path},
+ });
+ const auto ec_data = System::cmd_execute_and_capture_output(cmd_launch_cmake);
Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0);
const std::vector<std::string> lines = Strings::split(ec_data.output, "\n");
@@ -359,7 +494,7 @@ namespace vcpkg::Build
const bool variable_with_no_value = s.size() == 1;
const std::string variable_name = s.at(0);
- const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1);
+ const std::string variable_value = variable_with_no_value ? "" : s.at(1);
if (variable_name == "VCPKG_TARGET_ARCHITECTURE")
{
@@ -381,7 +516,15 @@ namespace vcpkg::Build
if (variable_name == "VCPKG_PLATFORM_TOOLSET")
{
- pre_build_info.platform_toolset = variable_value;
+ pre_build_info.platform_toolset =
+ variable_value.empty() ? nullopt : Optional<std::string>{variable_value};
+ continue;
+ }
+
+ if (variable_name == "VCPKG_VISUAL_STUDIO_PATH")
+ {
+ pre_build_info.visual_studio_path =
+ variable_value.empty() ? nullopt : Optional<fs::path>{variable_value};
continue;
}
diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp
new file mode 100644
index 000000000..addb9edaf
--- /dev/null
+++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp
@@ -0,0 +1,141 @@
+#include "pch.h"
+
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/install.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/remove.h>
+#include <vcpkg/vcpkglib.h>
+
+namespace vcpkg::Commands::Autocomplete
+{
+ [[noreturn]] static void output_sorted_results_and_exit(const LineInfo& line_info,
+ std::vector<std::string>&& results)
+ {
+ const SortedVector<std::string> sorted_results(results);
+ System::println(Strings::join("\n", sorted_results));
+
+ Checks::exit_success(line_info);
+ }
+
+ std::vector<std::string> combine_port_with_triplets(const std::string& port,
+ const std::vector<std::string>& triplets)
+ {
+ return Util::fmap(triplets,
+ [&](const std::string& triplet) { return Strings::format("%s:%s", port, triplet); });
+ }
+
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
+ {
+ Metrics::g_metrics.lock()->set_send_metrics(false);
+ const std::string to_autocomplete = Strings::join(" ", args.command_arguments);
+ const std::vector<std::string> tokens = Strings::split(to_autocomplete, " ");
+
+ std::smatch match;
+
+ // Handles vcpkg <command>
+ if (std::regex_match(to_autocomplete, match, std::regex{R"###(^(\S*)$)###"}))
+ {
+ const std::string requested_command = match[1].str();
+
+ std::vector<std::string> valid_commands = {
+ "install",
+ "search",
+ "remove",
+ "list",
+ "update",
+ "hash",
+ "help",
+ "integrate",
+ "export",
+ "edit",
+ "create",
+ "owns",
+ "cache",
+ "version",
+ "contact",
+ };
+
+ Util::unstable_keep_if(valid_commands, [&](const std::string& s) {
+ return Strings::case_insensitive_ascii_starts_with(s, requested_command);
+ });
+
+ output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands));
+ }
+
+ // Handles vcpkg install package:<triplet>
+ if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install(.*|)\s([^:]+):(\S*)$)###"}))
+ {
+ const auto port_name = match[2].str();
+ const auto triplet_prefix = match[3].str();
+
+ auto maybe_port = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(port_name));
+ if (maybe_port.error())
+ {
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+
+ std::vector<std::string> triplets = paths.get_available_triplets();
+ Util::unstable_keep_if(triplets, [&](const std::string& s) {
+ return Strings::case_insensitive_ascii_starts_with(s, triplet_prefix);
+ });
+
+ auto result = combine_port_with_triplets(port_name, triplets);
+
+ output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(result));
+ }
+
+ struct CommandEntry
+ {
+ constexpr CommandEntry(const CStringView& name, const CStringView& regex, const CommandStructure& structure)
+ : name(name), regex(regex), structure(structure)
+ {
+ }
+
+ CStringView name;
+ CStringView regex;
+ const CommandStructure& structure;
+ };
+
+ static constexpr CommandEntry COMMANDS[] = {
+ CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE},
+ CommandEntry{"install", R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE},
+ CommandEntry{"edit", R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE},
+ CommandEntry{"remove", R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE},
+ };
+
+ for (auto&& command : COMMANDS)
+ {
+ if (std::regex_match(to_autocomplete, match, std::regex{command.regex.c_str()}))
+ {
+ const auto prefix = match[2].str();
+ std::vector<std::string> results;
+
+ if (Strings::case_insensitive_ascii_starts_with(prefix, "-"))
+ {
+ results = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; });
+ }
+ else
+ {
+ results = command.structure.valid_arguments(paths);
+ }
+
+ Util::unstable_keep_if(results, [&](const std::string& s) {
+ return Strings::case_insensitive_ascii_starts_with(s, prefix);
+ });
+
+ if (command.name == "install" && results.size() == 1)
+ {
+ const auto port_at_each_triplet =
+ combine_port_with_triplets(results[0], paths.get_available_triplets());
+ Util::Vectors::concatenate(&results, port_at_each_triplet);
+ }
+
+ output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(results));
+ }
+ }
+
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+}
diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp
index ff70e9cf2..3991beb62 100644
--- a/toolsrc/src/commands_build_external.cpp
+++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp
@@ -1,22 +1,23 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
+#include <vcpkg/build.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
namespace vcpkg::Commands::BuildExternal
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string example =
- Commands::Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)");
- args.check_exact_arg_count(2, example);
+ static const std::string EXAMPLE =
+ Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)");
+ args.check_exact_arg_count(2, EXAMPLE);
const FullPackageSpec spec =
- Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, example);
+ Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE);
Input::check_triplet(spec.package_spec.triplet(), paths);
const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({});
const fs::path port_dir = args.command_arguments.at(1);
- BuildCommand::perform_and_exit(spec, port_dir, options, paths);
+ Build::Command::perform_and_exit(spec, port_dir, options, paths);
}
}
diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp
index fa0c62ee4..77f0a20f6 100644
--- a/toolsrc/src/commands_cache.cpp
+++ b/toolsrc/src/vcpkg/commands.cache.cpp
@@ -1,10 +1,11 @@
#include "pch.h"
-#include "BinaryParagraph.h"
-#include "Paragraphs.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/binaryparagraph.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
namespace vcpkg::Commands::Cache
{
@@ -27,10 +28,10 @@ namespace vcpkg::Commands::Cache
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Strings::format(
+ static const std::string EXAMPLE = Strings::format(
"The argument should be a substring to search for, or no argument to display all cached libraries.\n%s",
- Commands::Help::create_example_string("cache png"));
- args.check_max_arg_count(1, example);
+ Help::create_example_string("cache png"));
+ args.check_max_arg_count(1, EXAMPLE);
args.check_and_get_optional_command_arguments({});
const std::vector<BinaryParagraph> binary_paragraphs = read_all_binary_paragraphs(paths);
diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp
new file mode 100644
index 000000000..1c98d1d83
--- /dev/null
+++ b/toolsrc/src/vcpkg/commands.ci.cpp
@@ -0,0 +1,62 @@
+#include "pch.h"
+
+#include <vcpkg/base/chrono.h>
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/build.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/dependencies.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/install.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/vcpkglib.h>
+
+namespace vcpkg::Commands::CI
+{
+ using Build::BuildResult;
+ using Dependencies::InstallPlanAction;
+ using Dependencies::InstallPlanType;
+
+ static std::vector<PackageSpec> load_all_package_specs(Files::Filesystem& fs,
+ const fs::path& ports_directory,
+ const Triplet& triplet)
+ {
+ auto ports = Paragraphs::load_all_ports(fs, ports_directory);
+ return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec {
+ return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet)
+ .value_or_exit(VCPKG_LINE_INFO);
+ });
+ }
+
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
+ {
+ static const std::string EXAMPLE = Help::create_example_string("ci x64-windows");
+ args.check_max_arg_count(1, EXAMPLE);
+ const Triplet triplet = args.command_arguments.size() == 1
+ ? Triplet::from_canonical_name(args.command_arguments.at(0))
+ : default_triplet;
+ Input::check_triplet(triplet, paths);
+ args.check_and_get_optional_command_arguments({});
+ const std::vector<PackageSpec> specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet);
+
+ StatusParagraphs status_db = database_load_check(paths);
+ const auto& paths_port_file = Dependencies::PathsPortFile(paths);
+ std::vector<InstallPlanAction> install_plan =
+ Dependencies::create_install_plan(paths_port_file, specs, status_db);
+ Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty");
+
+ const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES};
+
+ const std::vector<Dependencies::AnyAction> action_plan =
+ Util::fmap(install_plan, [](InstallPlanAction& install_action) {
+ return Dependencies::AnyAction(std::move(install_action));
+ });
+
+ Install::perform_and_exit_ex(
+ action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db);
+
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+}
diff --git a/toolsrc/src/commands_contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp
index 7f4161802..421b8a230 100644
--- a/toolsrc/src/commands_contact.cpp
+++ b/toolsrc/src/vcpkg/commands.contact.cpp
@@ -1,14 +1,14 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
namespace vcpkg::Commands::Contact
{
const std::string& email()
{
- static const std::string s_email = R"(vcpkg@microsoft.com)";
- return s_email;
+ static const std::string S_EMAIL = R"(vcpkg@microsoft.com)";
+ return S_EMAIL;
}
void perform_and_exit(const VcpkgCmdArguments& args)
diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/vcpkg/commands.cpp
index 87cc43dca..9d969ea28 100644
--- a/toolsrc/src/commands_available_commands.cpp
+++ b/toolsrc/src/vcpkg/commands.cpp
@@ -1,16 +1,22 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
+#include <vcpkg/build.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/export.h>
+#include <vcpkg/help.h>
+#include <vcpkg/install.h>
+#include <vcpkg/remove.h>
+#include <vcpkg/update.h>
namespace vcpkg::Commands
{
- const std::vector<PackageNameAndFunction<CommandTypeA>>& get_available_commands_type_a()
+ Span<const PackageNameAndFunction<CommandTypeA>> get_available_commands_type_a()
{
static std::vector<PackageNameAndFunction<CommandTypeA>> t = {
{"install", &Install::perform_and_exit},
{"ci", &CI::perform_and_exit},
{"remove", &Remove::perform_and_exit},
- {"build", &BuildCommand::perform_and_exit},
+ {"build", &Build::Command::perform_and_exit},
{"env", &Env::perform_and_exit},
{"build-external", &BuildExternal::perform_and_exit},
{"export", &Export::perform_and_exit},
@@ -18,7 +24,7 @@ namespace vcpkg::Commands
return t;
}
- const std::vector<PackageNameAndFunction<CommandTypeB>>& get_available_commands_type_b()
+ Span<const PackageNameAndFunction<CommandTypeB>> get_available_commands_type_b()
{
static std::vector<PackageNameAndFunction<CommandTypeB>> t = {
{"/?", &Help::perform_and_exit},
@@ -34,11 +40,11 @@ namespace vcpkg::Commands
{"import", &Import::perform_and_exit},
{"cache", &Cache::perform_and_exit},
{"portsdiff", &PortsDiff::perform_and_exit},
- };
+ {"autocomplete", &Autocomplete::perform_and_exit}};
return t;
}
- const std::vector<PackageNameAndFunction<CommandTypeC>>& get_available_commands_type_c()
+ Span<const PackageNameAndFunction<CommandTypeC>> get_available_commands_type_c()
{
static std::vector<PackageNameAndFunction<CommandTypeC>> t = {
{"version", &Version::perform_and_exit},
diff --git a/toolsrc/src/commands_create.cpp b/toolsrc/src/vcpkg/commands.create.cpp
index 7f85b776a..85763f25e 100644
--- a/toolsrc/src/commands_create.cpp
+++ b/toolsrc/src/vcpkg/commands.create.cpp
@@ -1,26 +1,26 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/vcpkglib.h>
namespace vcpkg::Commands::Create
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Commands::Help::create_example_string(
+ static const std::string EXAMPLE = Help::create_example_string(
R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###");
- args.check_max_arg_count(3, example);
- args.check_min_arg_count(2, example);
+ args.check_max_arg_count(3, EXAMPLE);
+ args.check_min_arg_count(2, EXAMPLE);
args.check_and_get_optional_command_arguments({});
const std::string port_name = args.command_arguments.at(0);
const std::string url = args.command_arguments.at(1);
const fs::path& cmake_exe = paths.get_cmake_exe();
- std::vector<CMakeVariable> cmake_args{{L"CMD", L"CREATE"}, {L"PORT", port_name}, {L"URL", url}};
+ std::vector<CMakeVariable> cmake_args{{"CMD", "CREATE"}, {"PORT", port_name}, {"URL", url}};
if (args.command_arguments.size() >= 3)
{
@@ -30,10 +30,10 @@ namespace vcpkg::Commands::Create
R"(Filename cannot contain invalid chars %s, but was %s)",
Files::FILESYSTEM_INVALID_CHARACTERS,
zip_file_name);
- cmake_args.push_back({L"FILENAME", zip_file_name});
+ cmake_args.push_back({"FILENAME", zip_file_name});
}
- const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args);
+ const std::string cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args);
Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute_clean(cmd_launch_cmake));
}
}
diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp
index ffad91226..89c7e0c7f 100644
--- a/toolsrc/src/commands_depends.cpp
+++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp
@@ -1,17 +1,18 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Strings.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
namespace vcpkg::Commands::DependInfo
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Commands::Help::create_example_string(R"###(depend-info [pat])###");
- args.check_max_arg_count(1, example);
+ static const std::string EXAMPLE = Help::create_example_string(R"###(depend-info [pat])###");
+ args.check_max_arg_count(1, EXAMPLE);
args.check_and_get_optional_command_arguments({});
std::vector<std::unique_ptr<SourceControlFile>> source_control_files =
diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp
index f71d4d44c..668ec9b1a 100644
--- a/toolsrc/src/commands_edit.cpp
+++ b/toolsrc/src/vcpkg/commands.edit.cpp
@@ -1,42 +1,69 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
namespace vcpkg::Commands::Edit
{
static std::vector<fs::path> find_from_registry()
{
- static const std::array<const wchar_t*, 4> REGKEYS = {
- LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)",
- LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)",
- LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)",
- LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)",
+ static const std::array<const char*, 3> REGKEYS = {
+ R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)",
+ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)",
+ R"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)",
};
std::vector<fs::path> output;
+#if defined(_WIN32)
for (auto&& keypath : REGKEYS)
{
- const Optional<std::wstring> code_installpath =
- System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation");
+ const Optional<std::string> code_installpath =
+ System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, "InstallLocation");
if (const auto c = code_installpath.get())
{
const fs::path install_path = fs::path(*c);
- output.push_back(install_path / "Code.exe");
output.push_back(install_path / "Code - Insiders.exe");
+ output.push_back(install_path / "Code.exe");
}
}
+#endif
return output;
}
+ static const std::string OPTION_BUILDTREES = "--buildtrees";
+
+ static const std::array<std::string, 1> SWITCHES = {
+ OPTION_BUILDTREES,
+ };
+ static const std::array<std::string, 0> SETTINGS;
+
+ static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
+ {
+ auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports);
+
+ return Util::fmap(sources_and_errors.paragraphs,
+ [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; });
+ }
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ "edit zlib",
+ 1,
+ 1,
+ SWITCHES,
+ SETTINGS,
+ &valid_arguments,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string OPTION_BUILDTREES = "--buildtrees";
+ 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();
- static const std::string EXAMPLE = Commands::Help::create_example_string("edit zlib");
+ static const std::string EXAMPLE = Help::create_example_string("edit zlib");
args.check_exact_arg_count(1, EXAMPLE);
const std::unordered_set<std::string> options =
args.check_and_get_optional_command_arguments({OPTION_BUILDTREES});
@@ -46,10 +73,12 @@ namespace vcpkg::Commands::Edit
Checks::check_exit(VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name);
std::vector<fs::path> candidate_paths;
- const std::vector<fs::path> from_path = Files::find_from_PATH(L"EDITOR");
+ const std::vector<fs::path> from_path = Files::find_from_PATH("EDITOR");
candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
- candidate_paths.push_back(System::get_ProgramFiles_platform_bitness() / "Microsoft VS Code" / "Code.exe");
- candidate_paths.push_back(System::get_ProgramFiles_32_bit() / "Microsoft VS Code" / "Code.exe");
+ 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 std::vector<fs::path> from_registry = find_from_registry();
candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend());
@@ -70,13 +99,16 @@ namespace vcpkg::Commands::Edit
{
const auto buildtrees_current_dir = paths.buildtrees / port_name;
- const std::wstring cmd_line =
- Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native());
+ const auto cmd_line =
+ Strings::format(R"("%s" "%s" -n)", env_editor.u8string(), buildtrees_current_dir.u8string());
Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line));
}
- const std::wstring cmd_line = Strings::wformat(
- LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native());
+ const auto cmd_line = Strings::format(
+ R"("%s" "%s" "%s" -n)",
+ env_editor.u8string(),
+ portpath.u8string(),
+ (portpath / "portfile.cmake").u8string());
Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line));
}
}
diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/vcpkg/commands.env.cpp
index 073c501f5..9f8ae5207 100644
--- a/toolsrc/src/commands_env.cpp
+++ b/toolsrc/src/vcpkg/commands.env.cpp
@@ -1,20 +1,21 @@
#include "pch.h"
-#include "vcpkg_Build.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/build.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
namespace vcpkg::Commands::Env
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string EXAMPLE = Commands::Help::create_example_string(R"(env --Triplet x64-windows)");
+ static const std::string EXAMPLE = Help::create_example_string(R"(env --triplet x64-windows)");
args.check_exact_arg_count(0, EXAMPLE);
args.check_and_get_optional_command_arguments({});
const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet);
- System::cmd_execute_clean(
- Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd");
+ const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path);
+ System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + " && cmd");
Checks::exit_success(VCPKG_LINE_INFO);
}
diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp
new file mode 100644
index 000000000..682267acb
--- /dev/null
+++ b/toolsrc/src/vcpkg/commands.exportifw.cpp
@@ -0,0 +1,490 @@
+#include "pch.h"
+
+#include <vcpkg/commands.h>
+#include <vcpkg/export.h>
+#include <vcpkg/export.ifw.h>
+#include <vcpkg/install.h>
+
+namespace vcpkg::Export::IFW
+{
+ using Dependencies::ExportPlanAction;
+ using Dependencies::ExportPlanType;
+ using Install::InstallDir;
+
+ static std::string create_release_date()
+ {
+ const tm date_time = System::get_current_date_time();
+
+ // Format is: YYYY-mm-dd
+ // 10 characters + 1 null terminating character will be written for a total of 11 chars
+ char mbstr[11];
+ const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ bytes_written == 10,
+ "Expected 10 bytes to be written, but %u were written",
+ bytes_written);
+ const std::string date_time_as_string(mbstr);
+ return date_time_as_string;
+ }
+
+ std::string safe_rich_from_plain_text(const std::string& text)
+ {
+ // match standalone ampersand, no HTML number or name
+ std::regex standalone_ampersand(R"###(&(?!(#[0-9]+|\w+);))###");
+
+ return std::regex_replace(text, standalone_ampersand, "&amp;");
+ }
+
+ fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ return ifw_options.maybe_packages_dir_path.has_value()
+ ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO))
+ : paths.root / (export_id + "-ifw-packages");
+ }
+
+ fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ return ifw_options.maybe_repository_dir_path.has_value()
+ ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO))
+ : paths.root / (export_id + "-ifw-repository");
+ }
+
+ fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ return ifw_options.maybe_config_file_path.has_value()
+ ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO))
+ : paths.root / (export_id + "-ifw-configuration.xml");
+ }
+
+ fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ return ifw_options.maybe_installer_file_path.has_value()
+ ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO))
+ : paths.root / (export_id + "-ifw-installer.exe");
+ }
+
+ fs::path export_real_package(const fs::path& ifw_packages_dir_path,
+ const ExportPlanAction& action,
+ Files::Filesystem& fs)
+ {
+ std::error_code ec;
+
+ const BinaryParagraph& binary_paragraph =
+ action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph;
+
+ // Prepare meta dir
+ const fs::path package_xml_file_path =
+ ifw_packages_dir_path /
+ Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" /
+ "package.xml";
+ const fs::path package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+
+ auto deps = Strings::join(
+ ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; });
+
+ if (!deps.empty()) deps = "\n <Dependencies>" + deps + "</Dependencies>";
+
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>%s</DisplayName>
+ <Version>%s</Version>
+ <ReleaseDate>%s</ReleaseDate>
+ <AutoDependOn>packages.%s:,triplets.%s:</AutoDependOn>%s
+ <Virtual>true</Virtual>
+</Package>
+)###",
+ action.spec.to_string(),
+ binary_paragraph.version,
+ create_release_date(),
+ action.spec.name(),
+ action.spec.triplet().canonical_name(),
+ deps));
+
+ // Return dir path for export package data
+ return ifw_packages_dir_path /
+ Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" /
+ "installed";
+ }
+
+ void export_unique_packages(const fs::path& raw_exported_dir_path,
+ std::map<std::string, const ExportPlanAction*> unique_packages,
+ Files::Filesystem& fs)
+ {
+ std::error_code ec;
+
+ // packages
+
+ fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml";
+ fs::path package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>Packages</DisplayName>
+ <Version>1.0.0</Version>
+ <ReleaseDate>%s</ReleaseDate>
+</Package>
+)###",
+ create_release_date()));
+
+ for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package)
+ {
+ const ExportPlanAction& action = *(package->second);
+ const BinaryParagraph& binary_paragraph =
+ action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph;
+
+ package_xml_file_path =
+ raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml";
+ package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>%s</DisplayName>
+ <Description>%s</Description>
+ <Version>%s</Version>
+ <ReleaseDate>%s</ReleaseDate>
+</Package>
+)###",
+ action.spec.name(),
+ safe_rich_from_plain_text(binary_paragraph.description),
+ binary_paragraph.version,
+ create_release_date()));
+ }
+ }
+
+ void export_unique_triplets(const fs::path& raw_exported_dir_path,
+ std::set<std::string> unique_triplets,
+ Files::Filesystem& fs)
+ {
+ std::error_code ec;
+
+ // triplets
+
+ fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml";
+ fs::path package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>Triplets</DisplayName>
+ <Version>1.0.0</Version>
+ <ReleaseDate>%s</ReleaseDate>
+</Package>
+)###",
+ create_release_date()));
+
+ for (const std::string& triplet : unique_triplets)
+ {
+ package_xml_file_path =
+ raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml";
+ package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>%s</DisplayName>
+ <Version>1.0.0</Version>
+ <ReleaseDate>%s</ReleaseDate>
+</Package>
+)###",
+ triplet,
+ create_release_date()));
+ }
+ }
+
+ void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs)
+ {
+ std::error_code ec;
+
+ // integration
+ fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml";
+ fs::path package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>Integration</DisplayName>
+ <Version>1.0.0</Version>
+ <ReleaseDate>%s</ReleaseDate>
+</Package>
+)###",
+ create_release_date()));
+ }
+
+ void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ std::error_code ec;
+ Files::Filesystem& fs = paths.get_filesystem();
+
+ const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths);
+
+ fs::path config_xml_dir_path = config_xml_file_path.parent_path();
+ fs.create_directories(config_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for configuration file %s",
+ config_xml_file_path.generic_string());
+
+ std::string formatted_repo_url;
+ std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or("");
+ if (!ifw_repo_url.empty())
+ {
+ formatted_repo_url = Strings::format(R"###(
+ <RemoteRepositories>
+ <Repository>
+ <Url>%s</Url>
+ </Repository>
+ </RemoteRepositories>)###",
+ ifw_repo_url);
+ }
+
+ fs.write_contents(config_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Installer>
+ <Name>vcpkg</Name>
+ <Version>1.0.0</Version>
+ <StartMenuDir>vcpkg</StartMenuDir>
+ <TargetDir>@RootDir@/src/vcpkg</TargetDir>%s
+</Installer>
+)###",
+ formatted_repo_url));
+ }
+
+ void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths)
+ {
+ System::println("Exporting maintenance tool... ");
+
+ std::error_code ec;
+ Files::Filesystem& fs = paths.get_filesystem();
+
+ const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe();
+ fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe";
+ fs.create_directories(tempmaintenancetool.parent_path(), ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ tempmaintenancetool.generic_string());
+ fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string());
+
+ fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml";
+ fs::path package_xml_dir_path = package_xml_file_path.parent_path();
+ fs.create_directories(package_xml_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not create directory for package file %s",
+ package_xml_file_path.generic_string());
+ fs.write_contents(package_xml_file_path,
+ Strings::format(
+ R"###(<?xml version="1.0"?>
+<Package>
+ <DisplayName>Maintenance Tool</DisplayName>
+ <Description>Maintenance Tool</Description>
+ <Version>1.0.0</Version>
+ <ReleaseDate>%s</ReleaseDate>
+ <Script>maintenance.qs</Script>
+ <Essential>true</Essential>
+ <Virtual>true</Virtual>
+ <ForcedInstallation>true</ForcedInstallation>
+</Package>
+)###",
+ create_release_date()));
+ const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs";
+ const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs";
+ fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string());
+
+ System::println("Exporting maintenance tool... done");
+ }
+
+ void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ const fs::path& repogen_exe = paths.get_ifw_repogen_exe();
+ const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths);
+ const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths);
+
+ System::println("Generating repository %s...", repository_dir.generic_string());
+
+ std::error_code ec;
+ Files::Filesystem& fs = paths.get_filesystem();
+
+ fs.remove_all(repository_dir, ec);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string());
+
+ const auto cmd_line = Strings::format(R"("%s" --packages "%s" "%s" > nul)",
+ repogen_exe.u8string(),
+ packages_dir.u8string(),
+ repository_dir.u8string());
+
+ const int exit_code = System::cmd_execute_clean(cmd_line);
+ Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed");
+
+ System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string());
+ }
+
+ void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
+ {
+ const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe();
+ const fs::path config_file = get_config_file_path(export_id, ifw_options, paths);
+ const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths);
+ const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths);
+ const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths);
+
+ System::println("Generating installer %s...", installer_file.generic_string());
+
+ std::string cmd_line;
+
+ std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or("");
+ if (!ifw_repo_url.empty())
+ {
+ cmd_line = Strings::format(R"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)",
+ binarycreator_exe.u8string(),
+ config_file.u8string(),
+ repository_dir.u8string(),
+ installer_file.u8string());
+ }
+ else
+ {
+ cmd_line = Strings::format(R"("%s" --config "%s" --packages "%s" "%s" > nul)",
+ binarycreator_exe.u8string(),
+ config_file.u8string(),
+ packages_dir.u8string(),
+ installer_file.u8string());
+ }
+
+ const int exit_code = System::cmd_execute_clean(cmd_line);
+ Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed");
+
+ System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string());
+ }
+
+ void do_export(const std::vector<ExportPlanAction>& export_plan,
+ const std::string& export_id,
+ const Options& ifw_options,
+ const VcpkgPaths& paths)
+ {
+ std::error_code ec;
+ Files::Filesystem& fs = paths.get_filesystem();
+
+ // Prepare packages directory
+ const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths);
+
+ fs.remove_all(ifw_packages_dir_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !ec,
+ "Could not remove outdated packages directory %s",
+ ifw_packages_dir_path.generic_string());
+
+ fs.create_directory(ifw_packages_dir_path, ec);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string());
+
+ // Export maintenance tool
+ export_maintenance_tool(ifw_packages_dir_path, paths);
+
+ System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string());
+
+ // execute the plan
+ std::map<std::string, const ExportPlanAction*> unique_packages;
+ std::set<std::string> unique_triplets;
+ for (const ExportPlanAction& action : export_plan)
+ {
+ if (action.plan_type != ExportPlanType::ALREADY_BUILT)
+ {
+ Checks::unreachable(VCPKG_LINE_INFO);
+ }
+
+ const std::string display_name = action.spec.to_string();
+ System::println("Exporting package %s... ", display_name);
+
+ const BinaryParagraph& binary_paragraph =
+ action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph;
+
+ unique_packages[action.spec.name()] = &action;
+ unique_triplets.insert(action.spec.triplet().canonical_name());
+
+ // Export real package and return data dir for installation
+ fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs);
+
+ // Copy package data
+ const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path,
+ action.spec.triplet().to_string(),
+ ifw_package_dir_path / "vcpkg" / "info" /
+ (binary_paragraph.fullstem() + ".list"));
+
+ Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs);
+ System::println("Exporting package %s... done", display_name);
+ }
+
+ System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string());
+
+ const fs::path config_file = get_config_file_path(export_id, ifw_options, paths);
+
+ System::println("Generating configuration %s...", config_file.generic_string());
+
+ // Unique packages
+ export_unique_packages(ifw_packages_dir_path, unique_packages, fs);
+
+ // Unique triplets
+ export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs);
+
+ // Copy files needed for integration
+ export_integration_files(ifw_packages_dir_path / "integration" / "data", paths);
+ // Integration
+ export_integration(ifw_packages_dir_path, fs);
+
+ // Configuration
+ export_config(export_id, ifw_options, paths);
+
+ System::println("Generating configuration %s... done.", config_file.generic_string());
+
+ // Do repository (optional)
+ std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or("");
+ if (!ifw_repo_url.empty())
+ {
+ do_repository(export_id, ifw_options, paths);
+ }
+
+ // Do installer
+ do_installer(export_id, ifw_options, paths);
+ }
+}
diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp
new file mode 100644
index 000000000..4bc58b509
--- /dev/null
+++ b/toolsrc/src/vcpkg/commands.hash.cpp
@@ -0,0 +1,50 @@
+#include "pch.h"
+
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+
+namespace vcpkg::Commands::Hash
+{
+ static void do_file_hash(fs::path const& path, std::string const& hash_type)
+ {
+ const auto cmd_line = Strings::format(R"(CertUtil.exe -hashfile "%s" %s)", path.u8string().c_str(), hash_type);
+ const auto 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);
+
+ std::string const& output = ec_data.output;
+
+ const auto start = output.find_first_of("\r\n");
+ Checks::check_exit(
+ VCPKG_LINE_INFO, start != std::string::npos, "Unexpected output format from command: %s", cmd_line);
+
+ const auto end = output.find_first_of("\r\n", start + 1);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", cmd_line);
+
+ auto hash = output.substr(start, end - start);
+ Util::erase_remove_if(hash, isspace);
+ System::println(hash);
+ }
+
+ void perform_and_exit(const VcpkgCmdArguments& args)
+ {
+ static const std::string EXAMPLE = Strings::format("The argument should be a file path\n%s",
+ Help::create_example_string("hash boost_1_62_0.tar.bz2"));
+ args.check_min_arg_count(1, EXAMPLE);
+ args.check_max_arg_count(2, EXAMPLE);
+ args.check_and_get_optional_command_arguments({});
+
+ if (args.command_arguments.size() == 1)
+ {
+ do_file_hash(args.command_arguments[0], "SHA512");
+ }
+ if (args.command_arguments.size() == 2)
+ {
+ do_file_hash(args.command_arguments[0], args.command_arguments[1]);
+ }
+
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+}
diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/vcpkg/commands.import.cpp
index 5db1885b2..119aee022 100644
--- a/toolsrc/src/commands_import.cpp
+++ b/toolsrc/src/vcpkg/commands.import.cpp
@@ -1,9 +1,10 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "StatusParagraph.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Files.h"
+#include <vcpkg/base/files.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/statusparagraph.h>
namespace vcpkg::Commands::Import
{
@@ -28,7 +29,7 @@ namespace vcpkg::Commands::Import
for (auto&& file : files)
{
if (fs.is_directory(file)) continue;
- auto ext = file.extension();
+ const auto ext = file.extension();
if (ext == ".dll")
binaries.dlls.push_back(std::move(file));
else if (ext == ".lib")
@@ -46,7 +47,7 @@ namespace vcpkg::Commands::Import
for (auto const& src_path : files)
{
- fs::path dest_path = destination_folder / src_path.filename();
+ const fs::path dest_path = destination_folder / src_path.filename();
fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing);
}
}
@@ -59,10 +60,10 @@ namespace vcpkg::Commands::Import
check_is_directory(VCPKG_LINE_INFO, fs, include_directory);
check_is_directory(VCPKG_LINE_INFO, fs, project_directory);
check_is_directory(VCPKG_LINE_INFO, fs, destination_path);
- Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug");
- Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release");
+ const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug");
+ const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release");
- fs::path destination_include_directory = destination_path / "include";
+ const fs::path destination_include_directory = destination_path / "include";
fs.copy(include_directory,
destination_include_directory,
fs::copy_options::recursive | fs::copy_options::overwrite_existing);
@@ -82,20 +83,20 @@ namespace vcpkg::Commands::Import
const BinaryParagraph& control_file_data)
{
auto& fs = paths.get_filesystem();
- fs::path library_destination_path = paths.package_dir(control_file_data.spec);
+ const fs::path library_destination_path = paths.package_dir(control_file_data.spec);
std::error_code ec;
fs.create_directory(library_destination_path, ec);
place_library_files_in(paths.get_filesystem(), include_directory, project_directory, library_destination_path);
- fs::path control_file_path = library_destination_path / "CONTROL";
+ const fs::path control_file_path = library_destination_path / "CONTROL";
fs.write_contents(control_file_path, Strings::serialize(control_file_data));
}
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Commands::Help::create_example_string(
+ static const std::string EXAMPLE = Help::create_example_string(
R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)");
- args.check_exact_arg_count(3, example);
+ args.check_exact_arg_count(3, EXAMPLE);
args.check_and_get_optional_command_arguments({});
const fs::path control_file_path(args.command_arguments[0]);
diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp
index c5942f9fc..0d185476e 100644
--- a/toolsrc/src/commands_integrate.cpp
+++ b/toolsrc/src/vcpkg/commands.integrate.cpp
@@ -1,19 +1,13 @@
#include "pch.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/commands.h>
namespace vcpkg::Commands::Integrate
{
- static const std::array<fs::path, 2> old_system_target_files = {
- System::get_ProgramFiles_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets",
- System::get_ProgramFiles_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"};
- static const fs::path system_wide_targets_file =
- System::get_ProgramFiles_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props";
-
static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept
{
return Strings::format(R"###(
@@ -82,7 +76,7 @@ namespace vcpkg::Commands::Integrate
const std::string& nuget_id,
const std::string& nupkg_version)
{
- static constexpr auto content_template = R"(
+ static constexpr auto CONTENT_TEMPLATE = R"(
<package>
<metadata>
<id>@NUGET_ID@</id>
@@ -99,7 +93,7 @@ namespace vcpkg::Commands::Integrate
</package>
)";
- std::string content = std::regex_replace(content_template, std::regex("@NUGET_ID@"), nuget_id);
+ std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id);
content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string());
content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version);
return content;
@@ -111,52 +105,67 @@ namespace vcpkg::Commands::Integrate
NO
};
+#if defined(_WIN32)
static ElevationPromptChoice elevated_cmd_execute(const std::string& param)
{
- SHELLEXECUTEINFO shExInfo = {0};
- shExInfo.cbSize = sizeof(shExInfo);
- shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
- shExInfo.hwnd = nullptr;
- shExInfo.lpVerb = "runas";
- shExInfo.lpFile = "cmd"; // Application to start
-
- shExInfo.lpParameters = param.c_str(); // Additional parameters
- shExInfo.lpDirectory = nullptr;
- shExInfo.nShow = SW_HIDE;
- shExInfo.hInstApp = nullptr;
-
- if (!ShellExecuteExA(&shExInfo))
+ SHELLEXECUTEINFOW sh_ex_info = {0};
+ sh_ex_info.cbSize = sizeof(sh_ex_info);
+ sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
+ sh_ex_info.hwnd = nullptr;
+ sh_ex_info.lpVerb = L"runas";
+ sh_ex_info.lpFile = L"cmd"; // Application to start
+
+ auto wparam = Strings::to_utf16(param);
+ sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters
+ sh_ex_info.lpDirectory = nullptr;
+ sh_ex_info.nShow = SW_HIDE;
+ sh_ex_info.hInstApp = nullptr;
+
+ if (!ShellExecuteExW(&sh_ex_info))
{
return ElevationPromptChoice::NO;
}
- if (shExInfo.hProcess == nullptr)
+ if (sh_ex_info.hProcess == nullptr)
{
return ElevationPromptChoice::NO;
}
- WaitForSingleObject(shExInfo.hProcess, INFINITE);
- CloseHandle(shExInfo.hProcess);
+ WaitForSingleObject(sh_ex_info.hProcess, INFINITE);
+ CloseHandle(sh_ex_info.hProcess);
return ElevationPromptChoice::YES;
}
+#endif
+#if defined(_WIN32)
static fs::path get_appdata_targets_path()
{
- static const fs::path local_app_data =
- fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO));
- return local_app_data / "vcpkg" / "vcpkg.user.targets";
+ static const fs::path LOCAL_APP_DATA =
+ fs::path(System::get_environment_variable("LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO));
+ return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets";
}
+#endif
+#if defined(_WIN32)
static void integrate_install(const VcpkgPaths& paths)
{
+ static const std::array<fs::path, 2> OLD_SYSTEM_TARGET_FILES = {
+ System::get_program_files_32_bit() /
+ "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets",
+ System::get_program_files_32_bit() /
+ "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"};
+ static const fs::path SYSTEM_WIDE_TARGETS_FILE =
+ System::get_program_files_32_bit() /
+ "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props";
+
auto& fs = paths.get_filesystem();
// TODO: This block of code should eventually be removed
- for (auto&& old_system_wide_targets_file : old_system_target_files)
+ for (auto&& old_system_wide_targets_file : OLD_SYSTEM_TARGET_FILES)
{
if (fs.exists(old_system_wide_targets_file))
{
const std::string param =
Strings::format(R"(/c DEL "%s" /Q > nul)", old_system_wide_targets_file.string());
- ElevationPromptChoice user_choice = elevated_cmd_execute(param);
+ const ElevationPromptChoice user_choice = elevated_cmd_execute(param);
switch (user_choice)
{
case ElevationPromptChoice::YES: break;
@@ -174,15 +183,15 @@ namespace vcpkg::Commands::Integrate
fs.create_directory(tmp_dir, ec);
bool should_install_system = true;
- const Expected<std::string> system_wide_file_contents = fs.read_contents(system_wide_targets_file);
- if (auto contents_data = system_wide_file_contents.get())
+ const Expected<std::string> system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE);
+ static const std::regex RE(R"###(<!-- version (\d+) -->)###");
+ if (const auto contents_data = system_wide_file_contents.get())
{
- std::regex re(R"###(<!-- version (\d+) -->)###");
std::match_results<std::string::const_iterator> match;
- auto found = std::regex_search(*contents_data, match, re);
+ const auto found = std::regex_search(*contents_data, match, RE);
if (found)
{
- int ver = atoi(match[1].str().c_str());
+ const int ver = atoi(match[1].str().c_str());
if (ver >= 1) should_install_system = false;
}
}
@@ -193,10 +202,10 @@ namespace vcpkg::Commands::Integrate
fs.write_contents(sys_src_path, create_system_targets_shortcut());
const std::string param = Strings::format(R"(/c mkdir "%s" & copy "%s" "%s" /Y > nul)",
- system_wide_targets_file.parent_path().string(),
+ SYSTEM_WIDE_TARGETS_FILE.parent_path().string(),
sys_src_path.string(),
- system_wide_targets_file.string());
- ElevationPromptChoice user_choice = elevated_cmd_execute(param);
+ SYSTEM_WIDE_TARGETS_FILE.string());
+ const ElevationPromptChoice user_choice = elevated_cmd_execute(param);
switch (user_choice)
{
case ElevationPromptChoice::YES: break;
@@ -207,9 +216,9 @@ namespace vcpkg::Commands::Integrate
}
Checks::check_exit(VCPKG_LINE_INFO,
- fs.exists(system_wide_targets_file),
+ fs.exists(SYSTEM_WIDE_TARGETS_FILE),
"Error: failed to copy targets file to %s",
- system_wide_targets_file.string());
+ SYSTEM_WIDE_TARGETS_FILE.string());
}
const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets";
@@ -217,7 +226,7 @@ namespace vcpkg::Commands::Integrate
create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string()));
auto appdata_dst_path = get_appdata_targets_path();
- auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec);
+ const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec);
if (!rc || ec)
{
@@ -229,13 +238,14 @@ namespace vcpkg::Commands::Integrate
}
System::println(System::Color::success, "Applied user-wide integration for this vcpkg root.");
const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake";
- System::println("\n"
- "All MSBuild C++ projects can now #include any installed libraries.\n"
- "Linking will be handled automatically.\n"
- "Installing new libraries will make them instantly available.\n"
- "\n"
- "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s",
- cmake_toolchain.generic_string());
+ System::println(
+ R"(
+All MSBuild C++ projects can now #include any installed libraries.
+Linking will be handled automatically.
+Installing new libraries will make them instantly available.
+
+CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")",
+ cmake_toolchain.generic_string());
Checks::exit_success(VCPKG_LINE_INFO);
}
@@ -245,7 +255,7 @@ namespace vcpkg::Commands::Integrate
const fs::path path = get_appdata_targets_path();
std::error_code ec;
- bool was_deleted = fs.remove(path, ec);
+ const bool was_deleted = fs.remove(path, ec);
Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message());
@@ -260,6 +270,7 @@ namespace vcpkg::Commands::Integrate
Checks::exit_success(VCPKG_LINE_INFO);
}
+#endif
static void integrate_project(const VcpkgPaths& paths)
{
@@ -284,10 +295,10 @@ namespace vcpkg::Commands::Integrate
fs.write_contents(nuspec_file_path, create_nuspec_file_contents(paths.root, nuget_id, nupkg_version));
// Using all forward slashes for the command line
- const std::wstring cmd_line = Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" > nul)",
- nuget_exe.native(),
- buildsystems_dir.native(),
- nuspec_file_path.native());
+ const std::string cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" > nul)",
+ nuget_exe.u8string(),
+ buildsystems_dir.u8string(),
+ nuspec_file_path.u8string());
const int exit_code = System::cmd_execute_clean(cmd_line);
@@ -317,12 +328,13 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Strings::format("Commands:\n"
+ static const std::string EXAMPLE = Strings::format("Commands:\n"
"%s",
INTEGRATE_COMMAND_HELPSTRING);
- args.check_exact_arg_count(1, example);
+ args.check_exact_arg_count(1, EXAMPLE);
args.check_and_get_optional_command_arguments({});
+#if defined(_WIN32)
if (args.command_arguments[0] == "install")
{
return integrate_install(paths);
@@ -335,6 +347,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
{
return integrate_project(paths);
}
+#endif
Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]);
}
diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/vcpkg/commands.list.cpp
index 3cfa7e184..d0e8e00b4 100644
--- a/toolsrc/src/commands_list.cpp
+++ b/toolsrc/src/vcpkg/commands.list.cpp
@@ -1,16 +1,17 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/vcpkglib.h>
namespace vcpkg::Commands::List
{
static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually
- static void do_print(const StatusParagraph& pgh, bool FullDesc)
+ static void do_print(const StatusParagraph& pgh, bool full_desc)
{
- if (FullDesc)
+ if (full_desc)
{
System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description);
}
@@ -25,10 +26,10 @@ namespace vcpkg::Commands::List
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Strings::format(
+ static const std::string EXAMPLE = Strings::format(
"The argument should be a substring to search for, or no argument to display all installed libraries.\n%s",
- Commands::Help::create_example_string("list png"));
- args.check_max_arg_count(1, example);
+ Help::create_example_string("list png"));
+ args.check_max_arg_count(1, EXAMPLE);
const std::unordered_set<std::string> options =
args.check_and_get_optional_command_arguments({OPTION_FULLDESC});
diff --git a/toolsrc/src/commands_owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp
index 757292e96..69079e829 100644
--- a/toolsrc/src/commands_owns.cpp
+++ b/toolsrc/src/vcpkg/commands.owns.cpp
@@ -1,8 +1,9 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/vcpkglib.h>
namespace vcpkg::Commands::Owns
{
@@ -25,9 +26,9 @@ namespace vcpkg::Commands::Owns
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Strings::format("The argument should be a pattern to search for. %s",
- Commands::Help::create_example_string("owns zlib.dll"));
- args.check_exact_arg_count(1, example);
+ static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s",
+ Help::create_example_string("owns zlib.dll"));
+ args.check_exact_arg_count(1, EXAMPLE);
args.check_and_get_optional_command_arguments({});
StatusParagraphs status_db = database_load_check(paths);
diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp
index 83d62896f..a8c043751 100644
--- a/toolsrc/src/commands_portsdiff.cpp
+++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp
@@ -1,11 +1,12 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "SortedVector.h"
-#include "SourceParagraph.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Maps.h"
-#include "vcpkg_System.h"
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
+
+#include <vcpkg/base/sortedvector.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
namespace vcpkg::Commands::PortsDiff
{
@@ -69,33 +70,33 @@ namespace vcpkg::Commands::PortsDiff
for (const std::string& name : ports_to_print)
{
const VersionT& version = names_and_versions.at(name);
- System::println("%-20s %-16s", name, version);
+ System::println(" - %-14s %-16s", name, version);
}
}
static std::map<std::string, VersionT> read_ports_from_commit(const VcpkgPaths& paths,
- const std::wstring& git_commit_id)
+ const std::string& git_commit_id)
{
std::error_code ec;
auto& fs = paths.get_filesystem();
const fs::path& git_exe = paths.get_git_exe();
const fs::path dot_git_dir = paths.root / ".git";
- const std::wstring ports_dir_name_as_string = paths.ports.filename().native();
+ const std::string ports_dir_name_as_string = paths.ports.filename().u8string();
const fs::path temp_checkout_path =
- paths.root / Strings::wformat(L"%s-%s", ports_dir_name_as_string, git_commit_id);
+ paths.root / Strings::format("%s-%s", ports_dir_name_as_string, git_commit_id);
fs.create_directory(temp_checkout_path, ec);
- const std::wstring checkout_this_dir =
- Strings::wformat(LR"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository
-
- const std::wstring cmd =
- Strings::wformat(LR"("%s" --git-dir="%s" --work-tree="%s" checkout %s -f -q -- %s %s & "%s" reset >NUL)",
- git_exe.native(),
- dot_git_dir.native(),
- temp_checkout_path.native(),
- git_commit_id,
- checkout_this_dir,
- L".vcpkg-root",
- git_exe.native());
+ const auto checkout_this_dir =
+ Strings::format(R"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository
+
+ const std::string cmd =
+ Strings::format(R"("%s" --git-dir="%s" --work-tree="%s" checkout %s -f -q -- %s %s & "%s" reset >NUL)",
+ git_exe.u8string(),
+ dot_git_dir.u8string(),
+ temp_checkout_path.u8string(),
+ git_commit_id,
+ checkout_this_dir,
+ ".vcpkg-root",
+ git_exe.u8string());
System::cmd_execute_clean(cmd);
const std::map<std::string, VersionT> names_and_versions = Paragraphs::load_all_port_names_and_versions(
paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string);
@@ -103,32 +104,29 @@ namespace vcpkg::Commands::PortsDiff
return names_and_versions;
}
- static void check_commit_exists(const fs::path& git_exe, const std::wstring& git_commit_id)
+ static void check_commit_exists(const fs::path& git_exe, const std::string& git_commit_id)
{
static const std::string VALID_COMMIT_OUTPUT = "commit\n";
- const std::wstring cmd = Strings::wformat(LR"("%s" cat-file -t %s)", git_exe.native(), git_commit_id);
+ const auto cmd = Strings::format(R"("%s" cat-file -t %s)", git_exe.u8string(), git_commit_id);
const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd);
- Checks::check_exit(VCPKG_LINE_INFO,
- output.output == VALID_COMMIT_OUTPUT,
- "Invalid commit id %s",
- Strings::to_utf8(git_commit_id));
+ Checks::check_exit(
+ VCPKG_LINE_INFO, output.output == VALID_COMMIT_OUTPUT, "Invalid commit id %s", git_commit_id);
}
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example =
- Strings::format("The argument should be a branch/tag/hash to checkout.\n%s",
- Commands::Help::create_example_string("portsdiff mybranchname"));
- args.check_min_arg_count(1, example);
- args.check_max_arg_count(2, example);
+ static const std::string EXAMPLE = Strings::format("The argument should be a branch/tag/hash to checkout.\n%s",
+ Help::create_example_string("portsdiff mybranchname"));
+ args.check_min_arg_count(1, EXAMPLE);
+ args.check_max_arg_count(2, EXAMPLE);
args.check_and_get_optional_command_arguments({});
const fs::path& git_exe = paths.get_git_exe();
- const std::wstring git_commit_id_for_previous_snapshot = Strings::to_utf16(args.command_arguments.at(0));
- const std::wstring git_commit_id_for_current_snapshot =
- args.command_arguments.size() < 2 ? L"HEAD" : Strings::to_utf16(args.command_arguments.at(1));
+ const std::string git_commit_id_for_previous_snapshot = args.command_arguments.at(0);
+ const std::string git_commit_id_for_current_snapshot =
+ args.command_arguments.size() < 2 ? "HEAD" : args.command_arguments.at(1);
check_commit_exists(git_exe, git_commit_id_for_current_snapshot);
check_commit_exists(git_exe, git_commit_id_for_previous_snapshot);
@@ -139,8 +137,8 @@ namespace vcpkg::Commands::PortsDiff
read_ports_from_commit(paths, git_commit_id_for_previous_snapshot);
// Already sorted, so set_difference can work on std::vector too
- std::vector<std::string> current_ports = Maps::extract_keys(current_names_and_versions);
- std::vector<std::string> previous_ports = Maps::extract_keys(previous_names_and_versions);
+ const std::vector<std::string> current_ports = Util::extract_keys(current_names_and_versions);
+ const std::vector<std::string> previous_ports = Util::extract_keys(previous_names_and_versions);
const SetElementPresence<std::string> setp =
SetElementPresence<std::string>::create(current_ports, previous_ports);
@@ -148,14 +146,14 @@ namespace vcpkg::Commands::PortsDiff
const std::vector<std::string>& added_ports = setp.only_left;
if (!added_ports.empty())
{
- System::println("\nThe following %d ports were added:\n", added_ports.size());
+ System::println("\nThe following %d ports were added:", added_ports.size());
do_print_name_and_version(added_ports, current_names_and_versions);
}
const std::vector<std::string>& removed_ports = setp.only_right;
if (!removed_ports.empty())
{
- System::println("\nThe following %d ports were removed:\n", removed_ports.size());
+ System::println("\nThe following %d ports were removed:", removed_ports.size());
do_print_name_and_version(removed_ports, previous_names_and_versions);
}
@@ -165,10 +163,10 @@ namespace vcpkg::Commands::PortsDiff
if (!updated_ports.empty())
{
- System::println("\nThe following %d ports were updated:\n", updated_ports.size());
+ System::println("\nThe following %d ports were updated:", updated_ports.size());
for (const UpdatedPort& p : updated_ports)
{
- System::println("%-20s %-16s", p.port, p.version_diff.to_string());
+ System::println(" - %-14s %-16s", p.port, p.version_diff.to_string());
}
}
diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/vcpkg/commands.search.cpp
index 529d52a8b..3ba8707de 100644
--- a/toolsrc/src/commands_search.cpp
+++ b/toolsrc/src/vcpkg/commands.search.cpp
@@ -1,11 +1,12 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "SourceParagraph.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/sourceparagraph.h>
+#include <vcpkg/vcpkglib.h>
namespace vcpkg::Commands::Search
{
@@ -80,34 +81,15 @@ namespace vcpkg::Commands::Search
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
- static const std::string example = Strings::format(
+ static const std::string EXAMPLE = Strings::format(
"The argument should be a substring to search for, or no argument to display all libraries.\n%s",
- Commands::Help::create_example_string("search png"));
- args.check_max_arg_count(1, example);
+ Help::create_example_string("search png"));
+ args.check_max_arg_count(1, EXAMPLE);
const std::unordered_set<std::string> options =
args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC});
- auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports);
+ auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
- if (!sources_and_errors.errors.empty())
- {
- if (GlobalState::debugging)
- {
- print_error_message(sources_and_errors.errors);
- }
- else
- {
- for (auto&& error : sources_and_errors.errors)
- {
- System::println(
- System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name);
- }
- System::println(System::Color::warning,
- "Use '--debug' to get more information about the parse failures.\n");
- }
- }
-
- auto& source_paragraphs = sources_and_errors.paragraphs;
if (options.find(OPTION_GRAPH) != options.cend())
{
const std::string graph_as_string = create_graph_as_string(source_paragraphs);
diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp
new file mode 100644
index 000000000..403c355b5
--- /dev/null
+++ b/toolsrc/src/vcpkg/commands.version.cpp
@@ -0,0 +1,76 @@
+#include "pch.h"
+
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/metrics.h>
+
+#define STRINGIFY(...) #__VA_ARGS__
+#define MACRO_TO_STRING(X) STRINGIFY(X)
+
+#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION)
+
+namespace vcpkg::Commands::Version
+{
+ const std::string& version()
+ {
+ static const std::string S_VERSION =
+#include "../VERSION.txt"
+
+ +std::string(VCPKG_VERSION_AS_STRING)
+#ifndef NDEBUG
+ + std::string("-debug")
+#endif
+ + std::string(Metrics::get_compiled_metrics_enabled() ? "" : "-external");
+ return S_VERSION;
+ }
+
+ static int scan3(const char* input, const char* pattern, int* a, int* b, int* c)
+ {
+#if defined(_WIN32)
+ return sscanf_s(input, pattern, a, b, c);
+#else
+ return sscanf(input, pattern, a, b, c);
+#endif
+ }
+
+ void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths)
+ {
+ auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt");
+ if (const auto version_contents = version_file.get())
+ {
+ int maj1, min1, rev1;
+ const auto num1 = scan3(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1);
+
+ int maj2, min2, rev2;
+ const auto num2 = scan3(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2);
+
+ if (num1 == 3 && num2 == 3)
+ {
+ if (maj1 != maj2 || min1 != min2 || rev1 != rev2)
+ {
+ System::println(System::Color::warning,
+ "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use "
+ ".\\bootstrap-vcpkg.bat to update.",
+ maj2,
+ min2,
+ rev2,
+ maj1,
+ min1,
+ rev1);
+ }
+ }
+ }
+ }
+
+ void perform_and_exit(const VcpkgCmdArguments& args)
+ {
+ args.check_exact_arg_count(0);
+ args.check_and_get_optional_command_arguments({});
+
+ System::println("Vcpkg package management program version %s\n"
+ "\n"
+ "See LICENSE.txt for license information.",
+ version());
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+}
diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp
index 1a0f0a6ed..02b2ec785 100644
--- a/toolsrc/src/vcpkg_Dependencies.cpp
+++ b/toolsrc/src/vcpkg/dependencies.cpp
@@ -1,15 +1,15 @@
#include "pch.h"
-#include "PackageSpec.h"
-#include "Paragraphs.h"
-#include "StatusParagraphs.h"
-#include "VcpkgPaths.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_Graphs.h"
-#include "vcpkg_Strings.h"
-#include "vcpkg_Util.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/graphs.h>
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/dependencies.h>
+#include <vcpkg/packagespec.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/statusparagraphs.h>
+#include <vcpkg/vcpkglib.h>
+#include <vcpkg/vcpkgpaths.h>
namespace vcpkg::Dependencies
{
@@ -43,14 +43,17 @@ namespace vcpkg::Dependencies
bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; }
}
-template<>
-struct std::hash<vcpkg::Dependencies::ClusterPtr>
+namespace std
{
- size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const
+ template<>
+ struct hash<vcpkg::Dependencies::ClusterPtr>
{
- return std::hash<vcpkg::PackageSpec>()(value.ptr->spec);
- }
-};
+ size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const
+ {
+ return std::hash<vcpkg::PackageSpec>()(value.ptr->spec);
+ }
+ };
+}
namespace vcpkg::Dependencies
{
@@ -213,6 +216,21 @@ namespace vcpkg::Dependencies
{
}
+ const PackageSpec& AnyAction::spec() const
+ {
+ if (const auto p = install_plan.get())
+ {
+ return p->spec;
+ }
+
+ if (const auto p = remove_plan.get())
+ {
+ return p->spec;
+ }
+
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Null action");
+ }
+
bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right)
{
return left->spec.name() < right->spec.name();
diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/vcpkg/export.cpp
index dbfb09aab..5e27d4126 100644
--- a/toolsrc/src/commands_export.cpp
+++ b/toolsrc/src/vcpkg/export.cpp
@@ -1,15 +1,19 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/dependencies.h>
+#include <vcpkg/export.ifw.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/install.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/vcpkglib.h>
+
#include <regex>
-namespace vcpkg::Commands::Export
+namespace vcpkg::Export
{
using Dependencies::ExportPlanAction;
using Dependencies::ExportPlanType;
@@ -21,7 +25,7 @@ namespace vcpkg::Commands::Export
const std::string& nuget_id,
const std::string& nupkg_version)
{
- static constexpr auto content_template = R"(
+ static constexpr auto CONTENT_TEMPLATE = R"(
<package>
<metadata>
<id>@NUGET_ID@</id>
@@ -40,7 +44,7 @@ namespace vcpkg::Commands::Export
</package>
)";
- std::string nuspec_file_content = std::regex_replace(content_template, std::regex("@NUGET_ID@"), nuget_id);
+ std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id);
nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version);
nuspec_file_content =
std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir);
@@ -62,10 +66,10 @@ namespace vcpkg::Commands::Export
static void print_plan(const std::map<ExportPlanType, std::vector<const ExportPlanAction*>>& group_by_plan_type)
{
- static constexpr std::array<ExportPlanType, 2> order = {ExportPlanType::ALREADY_BUILT,
+ static constexpr std::array<ExportPlanType, 2> ORDER = {ExportPlanType::ALREADY_BUILT,
ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT};
- for (const ExportPlanType plan_type : order)
+ for (const ExportPlanType plan_type : ORDER)
{
const auto it = group_by_plan_type.find(plan_type);
if (it == group_by_plan_type.cend())
@@ -133,11 +137,10 @@ namespace vcpkg::Commands::Export
fs.write_contents(nuspec_file_path, nuspec_file_content);
// -NoDefaultExcludes is needed for ".vcpkg-root"
- const std::wstring cmd_line =
- Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)",
- nuget_exe.native(),
- output_dir.native(),
- nuspec_file_path.native());
+ const auto cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)",
+ nuget_exe.u8string(),
+ output_dir.u8string(),
+ nuspec_file_path.u8string());
const int exit_code = System::cmd_execute_clean(cmd_line);
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed");
@@ -151,30 +154,30 @@ namespace vcpkg::Commands::Export
enum class BackingEnum
{
ZIP = 1,
- _7ZIP,
+ SEVEN_ZIP,
};
constexpr ArchiveFormat() = delete;
- constexpr ArchiveFormat(BackingEnum backing_enum, const wchar_t* extension, const wchar_t* cmake_option)
+ constexpr ArchiveFormat(BackingEnum backing_enum, const char* extension, const char* cmake_option)
: backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option)
{
}
constexpr operator BackingEnum() const { return backing_enum; }
- constexpr CWStringView extension() const { return this->m_extension; }
- constexpr CWStringView cmake_option() const { return this->m_cmake_option; }
+ constexpr CStringView extension() const { return this->m_extension; }
+ constexpr CStringView cmake_option() const { return this->m_cmake_option; }
private:
BackingEnum backing_enum;
- const wchar_t* m_extension;
- const wchar_t* m_cmake_option;
+ const char* m_extension;
+ const char* m_cmake_option;
};
namespace ArchiveFormatC
{
- constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip");
- constexpr const ArchiveFormat _7ZIP(ArchiveFormat::BackingEnum::_7ZIP, L"7z", L"7zip");
+ constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, "zip", "zip");
+ constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, "7z", "7zip");
}
static fs::path do_archive_export(const VcpkgPaths& paths,
@@ -184,17 +187,17 @@ namespace vcpkg::Commands::Export
{
const fs::path& cmake_exe = paths.get_cmake_exe();
- const std::wstring exported_dir_filename = raw_exported_dir.filename().native();
- const std::wstring exported_archive_filename =
- Strings::wformat(L"%s.%s", exported_dir_filename, format.extension());
+ const std::string exported_dir_filename = raw_exported_dir.filename().u8string();
+ const std::string exported_archive_filename =
+ Strings::format("%s.%s", exported_dir_filename, format.extension());
const fs::path exported_archive_path = (output_dir / exported_archive_filename);
// -NoDefaultExcludes is needed for ".vcpkg-root"
- const std::wstring cmd_line = Strings::wformat(LR"("%s" -E tar "cf" "%s" --format=%s -- "%s")",
- cmake_exe.native(),
- exported_archive_path.native(),
- format.cmake_option(),
- raw_exported_dir.native());
+ const auto cmd_line = Strings::format(R"("%s" -E tar "cf" "%s" --format=%s -- "%s")",
+ cmake_exe.u8string(),
+ exported_archive_path.u8string(),
+ format.cmake_option(),
+ raw_exported_dir.u8string());
const int exit_code = System::cmd_execute_clean(cmd_line);
Checks::check_exit(
@@ -210,103 +213,167 @@ namespace vcpkg::Commands::Export
return nullopt;
}
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
+ void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths)
+ {
+ const std::vector<fs::path> 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"} / "getWindowsSDK.ps1"},
+ {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"},
+ {fs::path{"scripts"} / "getProgramFiles32bit.ps1"},
+ };
+
+ for (const fs::path& file : integration_files_relative_to_root)
+ {
+ const fs::path source = paths.root / file;
+ fs::path destination = raw_exported_dir_path / file;
+ Files::Filesystem& fs = paths.get_filesystem();
+ std::error_code ec;
+ fs.create_directories(destination.parent_path(), ec);
+ Checks::check_exit(VCPKG_LINE_INFO, !ec);
+ fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec);
+ Checks::check_exit(VCPKG_LINE_INFO, !ec);
+ }
+ }
+
+ struct ExportArguments
{
+ bool dry_run;
+ bool raw;
+ bool nuget;
+ bool ifw;
+ bool zip;
+ bool seven_zip;
+
+ Optional<std::string> maybe_nuget_id;
+ Optional<std::string> maybe_nuget_version;
+
+ IFW::Options ifw_options;
+ std::vector<PackageSpec> specs;
+ };
+
+ static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args,
+ const Triplet& default_triplet)
+ {
+ ExportArguments ret;
+
static const std::string OPTION_DRY_RUN = "--dry-run";
static const std::string OPTION_RAW = "--raw";
static const std::string OPTION_NUGET = "--nuget";
+ static const std::string OPTION_IFW = "--ifw";
static const std::string OPTION_ZIP = "--zip";
- static const std::string OPTION_7ZIP = "--7zip";
+ static const std::string OPTION_SEVEN_ZIP = "--7zip";
static const std::string OPTION_NUGET_ID = "--nuget-id";
static const std::string OPTION_NUGET_VERSION = "--nuget-version";
+ static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url";
+ static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path";
+ static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path";
+ static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path";
+ static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path";
// input sanitization
- static const std::string example =
- Commands::Help::create_example_string("export zlib zlib:x64-windows boost --nuget");
- args.check_min_arg_count(1, example);
+ static const std::string EXAMPLE = Help::create_example_string("export zlib zlib:x64-windows boost --nuget");
+ args.check_min_arg_count(1, EXAMPLE);
- const std::vector<PackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(arg, default_triplet, example);
+ ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
+ return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE);
});
- for (auto&& spec : specs)
- Input::check_triplet(spec.triplet(), paths);
const auto options = args.check_and_get_optional_command_arguments(
{
OPTION_DRY_RUN,
OPTION_RAW,
OPTION_NUGET,
+ OPTION_IFW,
OPTION_ZIP,
- OPTION_7ZIP,
+ OPTION_SEVEN_ZIP,
},
{
OPTION_NUGET_ID,
OPTION_NUGET_VERSION,
+ OPTION_IFW_REPOSITORY_URL,
+ OPTION_IFW_PACKAGES_DIR_PATH,
+ OPTION_IFW_REPOSITORY_DIR_PATH,
+ OPTION_IFW_CONFIG_FILE_PATH,
+ OPTION_IFW_INSTALLER_FILE_PATH,
});
- const bool dryRun = options.switches.find(OPTION_DRY_RUN) != options.switches.cend();
- const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend();
- const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend();
- const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend();
- const bool _7zip = options.switches.find(OPTION_7ZIP) != options.switches.cend();
-
- if (!raw && !nuget && !zip && !_7zip && !dryRun)
- {
- System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --zip --7zip");
- System::print(example);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
-
- auto maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID);
- auto maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION);
-
- Checks::check_exit(VCPKG_LINE_INFO, !maybe_nuget_id || nuget, "--nuget-id is only valid with --nuget");
- Checks::check_exit(
- VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget");
-
- // create the plan
- const StatusParagraphs status_db = database_load_check(paths);
- std::vector<ExportPlanAction> export_plan = Dependencies::create_export_plan(paths, specs, status_db);
- Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty");
-
- std::map<ExportPlanType, std::vector<const ExportPlanAction*>> group_by_plan_type;
- Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; });
- print_plan(group_by_plan_type);
-
- const bool has_non_user_requested_packages =
- Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool {
- return package.request_type != RequestType::USER_REQUESTED;
- }) != export_plan.cend();
-
- if (has_non_user_requested_packages)
- {
- System::println(System::Color::warning,
- "Additional packages (*) need to be exported to complete this operation.");
- }
-
- const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT);
- if (it != group_by_plan_type.cend() && !it->second.empty())
+ ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend();
+ ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend();
+ ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend();
+ ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend();
+ ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend();
+ ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend();
+
+ if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run)
{
- System::println(System::Color::error, "There are packages that have not been built.");
-
- // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest.
- std::vector<const ExportPlanAction*> unbuilt = it->second;
- Util::erase_remove_if(
- unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; });
-
- const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); });
- System::println("To build them, run:\n"
- " vcpkg install %s",
- s);
+ System::println(System::Color::error,
+ "Must provide at least one export type: --raw --nuget --ifw --zip --7zip");
+ System::print(EXAMPLE);
Checks::exit_fail(VCPKG_LINE_INFO);
}
- if (dryRun)
+ struct OptionPair
{
- Checks::exit_success(VCPKG_LINE_INFO);
- }
+ const std::string& name;
+ Optional<std::string>& out_opt;
+ };
+ const auto options_implies =
+ [&](const std::string& main_opt_name, bool main_opt, Span<const OptionPair> implying_opts) {
+ if (main_opt)
+ {
+ for (auto&& opt : implying_opts)
+ opt.out_opt = maybe_lookup(options.settings, opt.name);
+ }
+ else
+ {
+ for (auto&& opt : implying_opts)
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !maybe_lookup(options.settings, opt.name),
+ "%s is only valid with %s",
+ opt.name,
+ main_opt_name);
+ }
+ };
+
+ options_implies(OPTION_NUGET,
+ ret.nuget,
+ {
+ {OPTION_NUGET_ID, ret.maybe_nuget_id},
+ {OPTION_NUGET_VERSION, ret.maybe_nuget_version},
+ });
+
+ options_implies(OPTION_IFW,
+ ret.ifw,
+ {
+ {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url},
+ {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path},
+ {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path},
+ {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path},
+ {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path},
+ });
+ return ret;
+ }
- const std::string export_id = create_export_id();
+ static void print_next_step_info(const fs::path& prefix)
+ {
+ const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake";
+ const CMakeVariable cmake_variable = CMakeVariable("CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string());
+ System::println("\n"
+ "To use the exported libraries in CMake projects use:"
+ "\n"
+ " %s"
+ "\n",
+ cmake_variable.s);
+ };
+ static void handle_raw_based_export(Span<const ExportPlanAction> export_plan,
+ const ExportArguments& opts,
+ const std::string& export_id,
+ const VcpkgPaths& paths)
+ {
Files::Filesystem& fs = paths.get_filesystem();
const fs::path export_to_path = paths.root;
const fs::path raw_exported_dir_path = export_to_path / export_id;
@@ -327,6 +394,7 @@ namespace vcpkg::Commands::Export
const BinaryParagraph& binary_paragraph =
action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph;
+
const InstallDir dirs = InstallDir::from_destination_root(
raw_exported_dir_path / "installed",
action.spec.triplet().to_string(),
@@ -337,52 +405,21 @@ namespace vcpkg::Commands::Export
}
// Copy files needed for integration
- const std::vector<fs::path> 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"} / "getWindowsSDK.ps1"},
- {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"},
- {fs::path{"scripts"} / "getProgramFiles32bit.ps1"},
- };
-
- for (const fs::path& file : integration_files_relative_to_root)
- {
- const fs::path source = paths.root / file;
- const fs::path destination = raw_exported_dir_path / file;
- fs.create_directories(destination.parent_path(), ec);
- Checks::check_exit(VCPKG_LINE_INFO, !ec);
- fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec);
- Checks::check_exit(VCPKG_LINE_INFO, !ec);
- }
+ export_integration_files(raw_exported_dir_path, paths);
- const auto print_next_step_info = [](const fs::path& prefix) {
- const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake";
- const CMakeVariable cmake_variable =
- CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string());
- System::println("\n"
- "To use the exported libraries in CMake projects use:"
- "\n"
- " %s"
- "\n",
- Strings::to_utf8(cmake_variable.s));
- };
-
- if (raw)
+ if (opts.raw)
{
System::println(
System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string());
print_next_step_info(export_to_path);
}
- if (nuget)
+ if (opts.nuget)
{
System::println("Creating nuget package... ");
- const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string());
- const std::string nuget_version = maybe_nuget_version.value_or("1.0.0");
+ const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string());
+ const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0");
const fs::path output_path =
do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path);
System::println(System::Color::success, "Creating nuget package... done");
@@ -397,7 +434,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
output_path.parent_path().u8string());
}
- if (zip)
+ if (opts.zip)
{
System::println("Creating zip archive... ");
const fs::path output_path =
@@ -407,20 +444,83 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
print_next_step_info("[...]");
}
- if (_7zip)
+ if (opts.seven_zip)
{
System::println("Creating 7zip archive... ");
const fs::path output_path =
- do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::_7ZIP);
+ do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP);
System::println(System::Color::success, "Creating 7zip archive... done");
System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string());
print_next_step_info("[...]");
}
- if (!raw)
+ if (!opts.raw)
{
fs.remove_all(raw_exported_dir_path, ec);
}
+ }
+
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
+ {
+ const auto opts = handle_export_command_arguments(args, default_triplet);
+ for (auto&& spec : opts.specs)
+ Input::check_triplet(spec.triplet(), paths);
+
+ // create the plan
+ const StatusParagraphs status_db = database_load_check(paths);
+ std::vector<ExportPlanAction> export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db);
+ Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty");
+
+ std::map<ExportPlanType, std::vector<const ExportPlanAction*>> group_by_plan_type;
+ Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; });
+ print_plan(group_by_plan_type);
+
+ const bool has_non_user_requested_packages =
+ Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool {
+ return package.request_type != RequestType::USER_REQUESTED;
+ }) != export_plan.cend();
+
+ if (has_non_user_requested_packages)
+ {
+ System::println(System::Color::warning,
+ "Additional packages (*) need to be exported to complete this operation.");
+ }
+
+ const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT);
+ if (it != group_by_plan_type.cend() && !it->second.empty())
+ {
+ System::println(System::Color::error, "There are packages that have not been built.");
+
+ // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest.
+ std::vector<const ExportPlanAction*> unbuilt = it->second;
+ Util::erase_remove_if(
+ unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; });
+
+ const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); });
+ System::println("To build them, run:\n"
+ " vcpkg install %s",
+ s);
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ if (opts.dry_run)
+ {
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+
+ std::string export_id = create_export_id();
+
+ if (opts.raw || opts.nuget || opts.zip || opts.seven_zip)
+ {
+ handle_raw_based_export(export_plan, opts, export_id, paths);
+ }
+
+ if (opts.ifw)
+ {
+ IFW::do_export(export_plan, export_id, opts.ifw_options, paths);
+
+ print_next_step_info("@RootDir@/src/vcpkg");
+ }
Checks::exit_success(VCPKG_LINE_INFO);
}
diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp
new file mode 100644
index 000000000..43230fa4b
--- /dev/null
+++ b/toolsrc/src/vcpkg/globalstate.cpp
@@ -0,0 +1,13 @@
+#include "pch.h"
+
+#include <vcpkg/globalstate.h>
+
+namespace vcpkg
+{
+ Util::LockGuarded<Chrono::ElapsedTime> GlobalState::timer;
+ std::atomic<bool> GlobalState::debugging(false);
+ std::atomic<bool> GlobalState::feature_packages(false);
+
+ std::atomic<int> GlobalState::g_init_console_cp(0);
+ std::atomic<int> GlobalState::g_init_console_output_cp(0);
+}
diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/vcpkg/help.cpp
index a12f9003d..2a0578211 100644
--- a/toolsrc/src/commands_help.cpp
+++ b/toolsrc/src/vcpkg/help.cpp
@@ -1,9 +1,9 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
-namespace vcpkg::Commands::Help
+namespace vcpkg::Help
{
void help_topics()
{
@@ -16,9 +16,9 @@ namespace vcpkg::Commands::Help
void help_topic_valid_triplet(const VcpkgPaths& paths)
{
System::println("Available architecture triplets:");
- for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets))
+ for (auto&& triplet : paths.get_available_triplets())
{
- System::println(" %s", path.stem().filename().string());
+ System::println(" %s", triplet);
}
}
@@ -75,7 +75,7 @@ namespace vcpkg::Commands::Help
" (default: %%VCPKG_ROOT%%)\n"
"\n"
"For more help (including examples) see the accompanying README.md.",
- Integrate::INTEGRATE_COMMAND_HELPSTRING);
+ Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING);
}
std::string create_example_string(const std::string& command_and_arguments)
@@ -114,7 +114,7 @@ namespace vcpkg::Commands::Help
{
System::print("Commands:\n"
"%s",
- Integrate::INTEGRATE_COMMAND_HELPSTRING);
+ Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING);
}
else if (topic == "topics")
{
diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg/input.cpp
index 153e6a942..aee0fac7f 100644
--- a/toolsrc/src/vcpkg_Input.cpp
+++ b/toolsrc/src/vcpkg/input.cpp
@@ -1,9 +1,10 @@
#include "pch.h"
-#include "metrics.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/metrics.h>
namespace vcpkg::Input
{
@@ -13,7 +14,7 @@ namespace vcpkg::Input
{
const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string);
auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet);
- if (auto spec = expected_spec.get())
+ if (const auto spec = expected_spec.get())
{
return PackageSpec{spec->package_spec};
}
@@ -30,7 +31,7 @@ namespace vcpkg::Input
{
System::println(System::Color::error, "Error: invalid triplet: %s", t);
Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string());
- Commands::Help::help_topic_valid_triplet(paths);
+ Help::help_topic_valid_triplet(paths);
Checks::exit_fail(VCPKG_LINE_INFO);
}
}
@@ -41,7 +42,7 @@ namespace vcpkg::Input
{
const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string);
auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet);
- if (auto spec = expected_spec.get())
+ if (const auto spec = expected_spec.get())
{
return *spec;
}
diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/vcpkg/install.cpp
index 8b1eec5eb..adbd8c943 100644
--- a/toolsrc/src/commands_install.cpp
+++ b/toolsrc/src/vcpkg/install.cpp
@@ -1,18 +1,21 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "metrics.h"
-#include "vcpkg_Build.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include "vcpkglib.h"
-
-namespace vcpkg::Commands::Install
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/build.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/dependencies.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/install.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/remove.h>
+#include <vcpkg/vcpkglib.h>
+
+namespace vcpkg::Install
{
using namespace Dependencies;
@@ -59,7 +62,7 @@ namespace vcpkg::Commands::Install
auto files = fs.get_files_recursive(source_dir);
for (auto&& file : files)
{
- auto status = fs.status(file, ec);
+ const auto status = fs.status(file, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message());
@@ -67,9 +70,8 @@ namespace vcpkg::Commands::Install
}
const std::string filename = file.filename().generic_string();
- if (fs::is_regular_file(status) &&
- (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") == 0 ||
- Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO") == 0))
+ if (fs::is_regular_file(status) && (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") ||
+ Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO")))
{
// Do not copy the control file
continue;
@@ -142,7 +144,7 @@ namespace vcpkg::Commands::Install
continue;
}
- output.insert(output.end(), t.files.begin(), t.files.end());
+ Util::Vectors::concatenate(&output, t.files);
}
std::sort(output.begin(), output.end());
@@ -309,7 +311,7 @@ namespace vcpkg::Commands::Install
const BinaryControlFile bcf =
Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO);
System::println("Installing package %s... ", display_name_with_features);
- auto install_result = install_package(paths, bcf, &status_db);
+ const auto install_result = install_package(paths, bcf, &status_db);
switch (install_result)
{
case InstallResult::SUCCESS:
@@ -328,7 +330,7 @@ namespace vcpkg::Commands::Install
System::Color::warning, "Package %s is already built -- not building from HEAD", display_name);
}
System::println("Installing package %s... ", display_name);
- auto install_result = install_package(
+ const auto install_result = install_package(
paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db);
switch (install_result)
{
@@ -442,20 +444,126 @@ namespace vcpkg::Commands::Install
}
}
- void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
+ void perform_and_exit_ex(const std::vector<AnyAction>& action_plan,
+ const Build::BuildPackageOptions& install_plan_options,
+ const KeepGoing keep_going,
+ const PrintSummary print_summary,
+ const VcpkgPaths& paths,
+ StatusParagraphs& status_db)
{
- static const std::string OPTION_DRY_RUN = "--dry-run";
- static const std::string OPTION_USE_HEAD_VERSION = "--head";
- static const std::string OPTION_NO_DOWNLOADS = "--no-downloads";
- static const std::string OPTION_RECURSE = "--recurse";
+ std::vector<BuildResult> results;
+ std::vector<std::string> timing;
+ const auto timer = Chrono::ElapsedTime::create_started();
+ size_t counter = 0;
+ const size_t package_count = action_plan.size();
+
+ for (const auto& action : action_plan)
+ {
+ const auto build_timer = Chrono::ElapsedTime::create_started();
+ counter++;
+
+ const std::string display_name = action.spec().to_string();
+ System::println("Starting package %d/%d: %s", counter, package_count, display_name);
+
+ timing.push_back("0");
+ results.push_back(BuildResult::NULLVALUE);
+
+ if (const auto install_action = action.install_plan.get())
+ {
+ const BuildResult result =
+ perform_install_plan_action(paths, *install_action, install_plan_options, status_db);
+ if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO)
+ {
+ System::println(Build::create_user_troubleshooting_message(install_action->spec));
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ results.back() = result;
+ }
+ else if (const auto remove_action = action.remove_plan.get())
+ {
+ Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages);
+ Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db);
+ }
+ else
+ {
+ Checks::unreachable(VCPKG_LINE_INFO);
+ }
+
+ timing.back() = build_timer.to_string();
+ System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string());
+ }
+
+ System::println("Total time taken: %s", timer.to_string());
+
+ if (print_summary == PrintSummary::YES)
+ {
+ for (size_t i = 0; i < results.size(); i++)
+ {
+ System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]);
+ }
+
+ std::map<BuildResult, int> summary;
+ for (const BuildResult& v : Build::BUILD_RESULT_VALUES)
+ {
+ summary[v] = 0;
+ }
+
+ for (const BuildResult& r : results)
+ {
+ summary[r]++;
+ }
+
+ System::println("\n\nSUMMARY");
+ for (const std::pair<const BuildResult, int>& entry : summary)
+ {
+ System::println(" %s: %d", Build::to_string(entry.first), entry.second);
+ }
+ }
+
+ Checks::exit_success(VCPKG_LINE_INFO);
+ }
+
+ static const std::string OPTION_DRY_RUN = "--dry-run";
+ static const std::string OPTION_USE_HEAD_VERSION = "--head";
+ static const std::string OPTION_NO_DOWNLOADS = "--no-downloads";
+ static const std::string OPTION_RECURSE = "--recurse";
+ static const std::string OPTION_KEEP_GOING = "--keep-going";
+
+ static const std::array<std::string, 5> INSTALL_SWITCHES = {
+ OPTION_DRY_RUN,
+ OPTION_USE_HEAD_VERSION,
+ OPTION_NO_DOWNLOADS,
+ OPTION_RECURSE,
+ OPTION_KEEP_GOING,
+ };
+ static const std::array<std::string, 0> INSTALL_SETTINGS;
+ static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
+ {
+ auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports);
+
+ return Util::fmap(sources_and_errors.paragraphs,
+ [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; });
+ }
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ "install zlib zlib:x64-windows curl boost",
+ 1,
+ SIZE_MAX,
+ INSTALL_SWITCHES,
+ INSTALL_SETTINGS,
+ &valid_arguments,
+ };
+
+ void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
+ {
// input sanitization
- static const std::string example =
- Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost");
- args.check_min_arg_count(1, example);
+ static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost");
+ args.check_min_arg_count(1, EXAMPLE);
const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_full_package_spec(arg, default_triplet, example);
+ return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE);
});
for (auto&& spec : specs)
@@ -469,11 +577,13 @@ namespace vcpkg::Commands::Install
}
const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments(
- {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE});
- const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend();
+ {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING});
+ const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend();
const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend();
const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend();
const bool is_recursive = options.find(OPTION_RECURSE) != options.cend();
+ const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend());
+ const PrintSummary print_summary = to_print_summary(keep_going == KeepGoing::YES);
// create the plan
StatusParagraphs status_db = database_load_check(paths);
@@ -486,8 +596,8 @@ namespace vcpkg::Commands::Install
if (GlobalState::feature_packages)
{
std::unordered_map<std::string, SourceControlFile> scf_map;
- auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports);
- for (auto&& port : all_ports.paragraphs)
+ auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports);
+ for (auto&& port : all_ports)
{
scf_map[port->core_paragraph->name] = std::move(*port);
}
@@ -519,78 +629,12 @@ namespace vcpkg::Commands::Install
print_plan(action_plan, is_recursive);
- if (dryRun)
+ if (dry_run)
{
Checks::exit_success(VCPKG_LINE_INFO);
}
- // execute the plan
- if (GlobalState::feature_packages)
- {
- for (const auto& action : action_plan)
- {
- if (auto install_action = action.install_plan.get())
- {
- const BuildResult result =
- perform_install_plan_action(paths, *install_action, install_plan_options, status_db);
- if (result != BuildResult::SUCCEEDED)
- {
- System::println(Build::create_user_troubleshooting_message(install_action->spec));
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
- else if (auto remove_action = action.remove_plan.get())
- {
- static const std::string OPTION_PURGE = "--purge";
- static const std::string OPTION_NO_PURGE = "--no-purge";
-
- const bool alsoRemoveFolderFromPackages = options.find(OPTION_NO_PURGE) == options.end();
- if (options.find(OPTION_PURGE) != options.end() && !alsoRemoveFolderFromPackages)
- {
- // User specified --purge and --no-purge
- System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge.");
- System::print(example);
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- const std::string display_name = remove_action->spec.to_string();
- switch (remove_action->plan_type)
- {
- case RemovePlanType::NOT_INSTALLED:
- System::println(System::Color::success, "Package %s is not installed", display_name);
- break;
- case RemovePlanType::REMOVE:
- System::println("Removing package %s... ", display_name);
- Commands::Remove::remove_package(paths, remove_action->spec, &status_db);
- System::println(System::Color::success, "Removing package %s... done", display_name);
- break;
- case RemovePlanType::UNKNOWN:
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (alsoRemoveFolderFromPackages)
- {
- System::println("Purging package %s... ", display_name);
- Files::Filesystem& fs = paths.get_filesystem();
- std::error_code ec;
- fs.remove_all(paths.packages / remove_action->spec.dir(), ec);
- System::println(System::Color::success, "Purging package %s... done", display_name);
- }
- }
- }
- }
- else
- {
- for (const auto& action : action_plan)
- {
- const auto& iaction = action.install_plan.value_or_exit(VCPKG_LINE_INFO);
- const BuildResult result = perform_install_plan_action(paths, iaction, install_plan_options, status_db);
- if (result != BuildResult::SUCCEEDED)
- {
- System::println(Build::create_user_troubleshooting_message(iaction.spec));
- Checks::exit_fail(VCPKG_LINE_INFO);
- }
- }
- }
+ perform_and_exit_ex(action_plan, install_plan_options, keep_going, print_summary, paths, status_db);
Checks::exit_success(VCPKG_LINE_INFO);
}
diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp
index 8a7d02a30..8f2575886 100644
--- a/toolsrc/src/metrics.cpp
+++ b/toolsrc/src/vcpkg/metrics.cpp
@@ -1,10 +1,13 @@
#include "pch.h"
-#include "filesystem_fs.h"
-#include "metrics.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_Strings.h"
-#include "vcpkg_System.h"
+#include <vcpkg/metrics.h>
+
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/system.h>
+
+#pragma comment(lib, "version")
+#pragma comment(lib, "winhttp")
namespace vcpkg::Metrics
{
@@ -16,17 +19,25 @@ namespace vcpkg::Metrics
std::array<char, 80> date;
date.fill(0);
+#if defined(_WIN32)
struct _timeb timebuffer;
_ftime_s(&timebuffer);
time_t now = timebuffer.time;
- int milli = timebuffer.millitm;
+ const int milli = timebuffer.millitm;
+
+ const errno_t err = gmtime_s(&newtime, &now);
- errno_t err = gmtime_s(&newtime, &now);
if (err)
{
- return Strings::EMPTY;
+ return "";
}
+#else
+ time_t now;
+ time(&now);
+ gmtime_r(&now, &newtime);
+ const int milli = 0;
+#endif
strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime);
return std::string(&date[0]) + "." + std::to_string(milli) + "Z";
@@ -34,7 +45,7 @@ namespace vcpkg::Metrics
static std::string generate_random_UUID()
{
- int partSizes[] = {8, 4, 4, 4, 12};
+ int part_sizes[] = {8, 4, 4, 4, 12};
char uuid[37];
memset(uuid, 0, sizeof(uuid));
int num;
@@ -50,7 +61,7 @@ namespace vcpkg::Metrics
// Generating UUID format version 4
// http://en.wikipedia.org/wiki/Universally_unique_identifier
- for (int i = 0; i < partSizes[part]; i++, index++)
+ for (int i = 0; i < part_sizes[part]; i++, index++)
{
if (part == 2 && i == 0)
{
@@ -81,8 +92,8 @@ namespace vcpkg::Metrics
static const std::string& get_session_id()
{
- static const std::string id = generate_random_UUID();
- return id;
+ static const std::string ID = generate_random_UUID();
+ return ID;
}
static std::string to_json_string(const std::string& str)
@@ -101,11 +112,11 @@ namespace vcpkg::Metrics
else if (ch < 0x20 || ch >= 0x80)
{
// Note: this treats incoming Strings as Latin-1
- static constexpr const char hex[16] = {
+ static constexpr const char HEX[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
encoded.append("\\u00");
- encoded.push_back(hex[ch / 16]);
- encoded.push_back(hex[ch % 16]);
+ encoded.push_back(HEX[ch / 16]);
+ encoded.push_back(HEX[ch % 16]);
}
else
{
@@ -118,23 +129,24 @@ namespace vcpkg::Metrics
static std::string get_os_version_string()
{
+#if defined(_WIN32)
std::wstring path;
path.resize(MAX_PATH);
- auto n = GetSystemDirectoryW(&path[0], static_cast<UINT>(path.size()));
+ const auto n = GetSystemDirectoryW(&path[0], static_cast<UINT>(path.size()));
path.resize(n);
path += L"\\kernel32.dll";
- auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr);
- if (versz == 0) return Strings::EMPTY;
+ const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr);
+ if (versz == 0) return "";
std::vector<char> verbuf;
verbuf.resize(versz);
- if (!GetFileVersionInfoW(path.c_str(), 0, static_cast<DWORD>(verbuf.size()), &verbuf[0])) return Strings::EMPTY;
+ if (!GetFileVersionInfoW(path.c_str(), 0, static_cast<DWORD>(verbuf.size()), &verbuf[0])) return "";
void* rootblock;
UINT rootblocksize;
- if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY;
+ if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return "";
auto rootblock_ffi = static_cast<VS_FIXEDFILEINFO*>(rootblock);
@@ -142,6 +154,9 @@ namespace vcpkg::Metrics
static_cast<int>(HIWORD(rootblock_ffi->dwProductVersionMS)),
static_cast<int>(LOWORD(rootblock_ffi->dwProductVersionMS)),
static_cast<int>(HIWORD(rootblock_ffi->dwProductVersionLS)));
+#else
+ return "unknown";
+#endif
}
struct MetricMessage
@@ -152,7 +167,7 @@ namespace vcpkg::Metrics
std::string properties;
std::string measurements;
- void TrackProperty(const std::string& name, const std::string& value)
+ void track_property(const std::string& name, const std::string& value)
{
if (properties.size() != 0) properties.push_back(',');
properties.append(to_json_string(name));
@@ -160,7 +175,7 @@ namespace vcpkg::Metrics
properties.append(to_json_string(value));
}
- void TrackMetric(const std::string& name, double value)
+ void track_metric(const std::string& name, double value)
{
if (measurements.size() != 0) measurements.push_back(',');
measurements.append(to_json_string(name));
@@ -218,11 +233,15 @@ namespace vcpkg::Metrics
bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; }
- std::wstring get_SQM_user()
+ std::string get_SQM_user()
{
+#if defined(_WIN32)
auto hkcu_sqmclient =
- System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId");
- return hkcu_sqmclient.value_or(L"{}");
+ System::get_registry_string(HKEY_CURRENT_USER, R"(Software\Microsoft\SQMClient)", "UserId");
+ return hkcu_sqmclient.value_or("{}");
+#else
+ return "{}";
+#endif
}
void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time)
@@ -241,95 +260,85 @@ namespace vcpkg::Metrics
void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; }
- void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.TrackMetric(name, value); }
-
- void Metrics::track_property(const std::string& name, const std::wstring& value)
- {
- // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes.
- std::string converted_value;
- converted_value.resize(value.size());
- std::transform(
- value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast<char>(ch); });
-
- g_metricmessage.TrackProperty(name, converted_value);
- }
+ void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); }
void Metrics::track_property(const std::string& name, const std::string& value)
{
- g_metricmessage.TrackProperty(name, value);
+ g_metricmessage.track_property(name, value);
}
void Metrics::upload(const std::string& payload)
{
- HINTERNET hSession = nullptr, hConnect = nullptr, hRequest = nullptr;
- BOOL bResults = FALSE;
+#if defined(_WIN32)
+ HINTERNET connect = nullptr, request = nullptr;
+ BOOL results = FALSE;
- hSession = WinHttpOpen(
+ const HINTERNET session = WinHttpOpen(
L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
- if (hSession)
- hConnect = WinHttpConnect(hSession, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
-
- if (hConnect)
- hRequest = WinHttpOpenRequest(hConnect,
- L"POST",
- L"/v2/track",
- nullptr,
- WINHTTP_NO_REFERER,
- WINHTTP_DEFAULT_ACCEPT_TYPES,
- WINHTTP_FLAG_SECURE);
-
- if (hRequest)
+ if (session) connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
+
+ if (connect)
+ request = WinHttpOpenRequest(connect,
+ L"POST",
+ L"/v2/track",
+ nullptr,
+ WINHTTP_NO_REFERER,
+ WINHTTP_DEFAULT_ACCEPT_TYPES,
+ WINHTTP_FLAG_SECURE);
+
+ if (request)
{
if (MAXDWORD <= payload.size()) abort();
std::wstring hdrs = L"Content-Type: application/json\r\n";
- bResults = WinHttpSendRequest(hRequest,
- hdrs.c_str(),
- static_cast<DWORD>(hdrs.size()),
- (void*)&payload[0],
- static_cast<DWORD>(payload.size()),
- static_cast<DWORD>(payload.size()),
- 0);
+ std::string& p = const_cast<std::string&>(payload);
+ results = WinHttpSendRequest(request,
+ hdrs.c_str(),
+ static_cast<DWORD>(hdrs.size()),
+ static_cast<void*>(&p[0]),
+ static_cast<DWORD>(payload.size()),
+ static_cast<DWORD>(payload.size()),
+ 0);
}
- if (bResults)
+ if (results)
{
- bResults = WinHttpReceiveResponse(hRequest, nullptr);
+ results = WinHttpReceiveResponse(request, nullptr);
}
DWORD http_code = 0, junk = sizeof(DWORD);
- if (bResults)
+ if (results)
{
- bResults = WinHttpQueryHeaders(hRequest,
- WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
- nullptr,
- &http_code,
- &junk,
- WINHTTP_NO_HEADER_INDEX);
+ results = WinHttpQueryHeaders(request,
+ WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
+ nullptr,
+ &http_code,
+ &junk,
+ WINHTTP_NO_HEADER_INDEX);
}
- std::vector<char> responseBuffer;
- if (bResults)
+ std::vector<char> response_buffer;
+ if (results)
{
- DWORD availableData = 0, readData = 0, totalData = 0;
- while ((bResults = WinHttpQueryDataAvailable(hRequest, &availableData)) == TRUE && availableData > 0)
+ DWORD available_data = 0, read_data = 0, total_data = 0;
+ while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0)
{
- responseBuffer.resize(responseBuffer.size() + availableData);
+ response_buffer.resize(response_buffer.size() + available_data);
- bResults = WinHttpReadData(hRequest, &responseBuffer.data()[totalData], availableData, &readData);
+ results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data);
- if (!bResults)
+ if (!results)
{
break;
}
- totalData += readData;
+ total_data += read_data;
- responseBuffer.resize(totalData);
+ response_buffer.resize(total_data);
}
}
- if (!bResults)
+ if (!results)
{
#ifndef NDEBUG
__debugbreak();
@@ -338,22 +347,16 @@ namespace vcpkg::Metrics
#endif
}
- if (hRequest) WinHttpCloseHandle(hRequest);
- if (hConnect) WinHttpCloseHandle(hConnect);
- if (hSession) WinHttpCloseHandle(hSession);
- }
-
- static fs::path get_bindir()
- {
- wchar_t buf[_MAX_PATH];
- int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH);
- if (bytes == 0) std::abort();
- return fs::path(buf, buf + bytes);
+ if (request) WinHttpCloseHandle(request);
+ if (connect) WinHttpCloseHandle(connect);
+ if (session) WinHttpCloseHandle(session);
+#endif
}
void Metrics::flush()
{
- std::string payload = g_metricmessage.format_event_data_template();
+#if defined(_WIN32)
+ const std::string payload = g_metricmessage.format_event_data_template();
if (g_should_print_metrics) std::cerr << payload << "\n";
if (!g_should_send_metrics) return;
@@ -370,14 +373,14 @@ namespace vcpkg::Metrics
if (true)
{
const fs::path exe_path = [&fs]() -> fs::path {
- auto vcpkgdir = get_bindir().parent_path();
+ auto vcpkgdir = System::get_exe_path_of_current_process().parent_path();
auto path = vcpkgdir / "vcpkgmetricsuploader.exe";
if (fs.exists(path)) return path;
path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe";
if (fs.exists(path)) return path;
- return Strings::WEMPTY;
+ return "";
}();
std::error_code ec;
@@ -388,8 +391,9 @@ namespace vcpkg::Metrics
const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt");
fs.write_contents(vcpkg_metrics_txt_path, payload);
- const std::wstring cmdLine =
- Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native());
- System::cmd_execute_clean(cmdLine);
+ const std::string cmd_line =
+ Strings::format("start %s %s", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string());
+ System::cmd_execute_clean(cmd_line);
+#endif
}
}
diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/vcpkg/packagespec.cpp
index 890de8899..6e40d70f5 100644
--- a/toolsrc/src/PackageSpec.cpp
+++ b/toolsrc/src/vcpkg/packagespec.cpp
@@ -1,8 +1,8 @@
#include "pch.h"
-#include "PackageSpec.h"
-#include "vcpkg_Parse.h"
-#include "vcpkg_Util.h"
+#include <vcpkg/base/util.h>
+#include <vcpkg/packagespec.h>
+#include <vcpkg/parse.h>
using vcpkg::Parse::parse_comma_list;
@@ -38,7 +38,7 @@ namespace vcpkg
for (auto&& feature : spec->features)
f_specs.push_back(FeatureSpec{pspec, feature});
- if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY});
+ if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, ""});
}
else
{
@@ -56,7 +56,7 @@ namespace vcpkg
std::vector<FeatureSpec> ret;
for (auto&& spec : specs)
{
- ret.emplace_back(spec.package_spec, Strings::EMPTY);
+ ret.emplace_back(spec.package_spec, "");
for (auto&& feature : spec.features)
ret.emplace_back(spec.package_spec, feature);
}
diff --git a/toolsrc/src/PackageSpecParseResult.cpp b/toolsrc/src/vcpkg/packagespecparseresult.cpp
index 838c788ba..b12bd12d0 100644
--- a/toolsrc/src/PackageSpecParseResult.cpp
+++ b/toolsrc/src/vcpkg/packagespecparseresult.cpp
@@ -1,7 +1,8 @@
#include "pch.h"
-#include "PackageSpecParseResult.h"
-#include "vcpkg_Checks.h"
+#include <vcpkg/packagespecparseresult.h>
+
+#include <vcpkg/base/checks.h>
namespace vcpkg
{
diff --git a/toolsrc/src/ParagraphParseResult.cpp b/toolsrc/src/vcpkg/paragraphparseresult.cpp
index 5c8c1d59d..920a4b16b 100644
--- a/toolsrc/src/ParagraphParseResult.cpp
+++ b/toolsrc/src/vcpkg/paragraphparseresult.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
-#include "ParagraphParseResult.h"
-#include "vcpkg_Checks.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/paragraphparseresult.h>
namespace vcpkg
{
diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp
index a7dee4fd3..b93de190c 100644
--- a/toolsrc/src/Paragraphs.cpp
+++ b/toolsrc/src/vcpkg/paragraphs.cpp
@@ -1,10 +1,10 @@
#include "pch.h"
-#include "ParagraphParseResult.h"
-#include "Paragraphs.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_Util.h"
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/paragraphparseresult.h>
+#include <vcpkg/paragraphs.h>
using namespace vcpkg::Parse;
@@ -254,7 +254,7 @@ namespace vcpkg::Paragraphs
for (auto&& path : fs.get_files_non_recursive(ports_dir))
{
auto maybe_spgh = try_load_port(fs, path);
- if (auto spgh = maybe_spgh.get())
+ if (const auto spgh = maybe_spgh.get())
{
ret.paragraphs.emplace_back(std::move(*spgh));
}
@@ -272,8 +272,20 @@ namespace vcpkg::Paragraphs
auto results = try_load_all_ports(fs, ports_dir);
if (!results.errors.empty())
{
- print_error_message(results.errors);
- Checks::exit_fail(VCPKG_LINE_INFO);
+ if (GlobalState::debugging)
+ {
+ print_error_message(results.errors);
+ }
+ else
+ {
+ for (auto&& error : results.errors)
+ {
+ System::println(
+ System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name);
+ }
+ System::println(System::Color::warning,
+ "Use '--debug' to get more information about the parse failures.\n");
+ }
}
return std::move(results.paragraphs);
}
diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg/parse.cpp
index b54f7360b..c2670f561 100644
--- a/toolsrc/src/vcpkg_Parse.cpp
+++ b/toolsrc/src/vcpkg/parse.cpp
@@ -1,8 +1,9 @@
#include "pch.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Maps.h"
-#include "vcpkg_Parse.h"
+#include <vcpkg/parse.h>
+
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/util.h>
namespace vcpkg::Parse
{
@@ -23,14 +24,14 @@ namespace vcpkg::Parse
void ParagraphParser::required_field(const std::string& fieldname, std::string& out)
{
auto maybe_field = remove_field(&fields, fieldname);
- if (auto field = maybe_field.get())
+ if (const auto field = maybe_field.get())
out = std::move(*field);
else
missing_fields.push_back(fieldname);
}
- std::string ParagraphParser::optional_field(const std::string& fieldname)
+ std::string ParagraphParser::optional_field(const std::string& fieldname) const
{
- return remove_field(&fields, fieldname).value_or(Strings::EMPTY);
+ return remove_field(&fields, fieldname).value_or("");
}
std::unique_ptr<ParseControlErrorInfo> ParagraphParser::error_info(const std::string& name) const
{
@@ -38,7 +39,7 @@ namespace vcpkg::Parse
{
auto err = std::make_unique<ParseControlErrorInfo>();
err->name = name;
- err->extra_fields = Maps::extract_keys(fields);
+ err->extra_fields = Util::extract_keys(fields);
err->missing_fields = std::move(missing_fields);
return err;
}
diff --git a/toolsrc/src/PostBuildLint_BuildType.cpp b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp
index 649f0ccca..2baaddb5e 100644
--- a/toolsrc/src/PostBuildLint_BuildType.cpp
+++ b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
-#include "PostBuildLint_BuildType.h"
-#include "vcpkg_Checks.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/postbuildlint.buildtype.h>
namespace vcpkg::PostBuildLint
{
diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp
index 473c81cfa..0063f8d98 100644
--- a/toolsrc/src/PostBuildLint.cpp
+++ b/toolsrc/src/vcpkg/postbuildlint.cpp
@@ -1,14 +1,14 @@
#include "pch.h"
-#include "PackageSpec.h"
-#include "PostBuildLint.h"
-#include "PostBuildLint_BuildType.h"
-#include "VcpkgPaths.h"
-#include "coff_file_reader.h"
-#include "vcpkg_Build.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
+#include <vcpkg/base/cofffilereader.h>
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/build.h>
+#include <vcpkg/packagespec.h>
+#include <vcpkg/postbuildlint.buildtype.h>
+#include <vcpkg/postbuildlint.h>
+#include <vcpkg/vcpkgpaths.h>
using vcpkg::Build::BuildInfo;
using vcpkg::Build::BuildPolicy;
@@ -38,9 +38,9 @@ namespace vcpkg::PostBuildLint
}
};
- const std::vector<OutdatedDynamicCrt>& get_outdated_dynamic_crts()
+ Span<const OutdatedDynamicCrt> get_outdated_dynamic_crts(CStringView toolset)
{
- static const std::vector<OutdatedDynamicCrt> v_no_msvcrt = {
+ static const std::vector<OutdatedDynamicCrt> V_NO_MSVCRT = {
{"msvcp100.dll", R"(msvcp100\.dll)"},
{"msvcp100d.dll", R"(msvcp100d\.dll)"},
{"msvcp110.dll", R"(msvcp110\.dll)"},
@@ -59,7 +59,7 @@ namespace vcpkg::PostBuildLint
{"msvcrt20.dll", R"(msvcrt20\.dll)"},
{"msvcrt40.dll", R"(msvcrt40\.dll)"}};
- return v_no_msvcrt;
+ return V_NO_MSVCRT;
}
static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs,
@@ -284,13 +284,10 @@ namespace vcpkg::PostBuildLint
std::vector<fs::path> dlls_with_no_exports;
for (const fs::path& dll : dlls)
{
- const std::wstring cmd_line =
- Strings::wformat(LR"("%s" /exports "%s")", dumpbin_exe.native(), dll.native());
+ const std::string cmd_line =
+ Strings::format(R"("%s" /exports "%s")", dumpbin_exe.u8string(), dll.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",
- Strings::to_utf8(cmd_line));
+ Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line);
if (ec_data.output.find("ordinal hint RVA name") == std::string::npos)
{
@@ -321,13 +318,10 @@ namespace vcpkg::PostBuildLint
std::vector<fs::path> dlls_with_improper_uwp_bit;
for (const fs::path& dll : dlls)
{
- const std::wstring cmd_line =
- Strings::wformat(LR"("%s" /headers "%s")", dumpbin_exe.native(), dll.native());
+ const std::string cmd_line =
+ Strings::format(R"("%s" /headers "%s")", dumpbin_exe.u8string(), dll.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",
- Strings::to_utf8(cmd_line));
+ Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line);
if (ec_data.output.find("App Container") == std::string::npos)
{
@@ -361,6 +355,7 @@ namespace vcpkg::PostBuildLint
case MachineType::I386: return "x86";
case MachineType::ARM:
case MachineType::ARMNT: return "arm";
+ case MachineType::ARM64: return "arm64";
default: return "Machine Type Code = " + std::to_string(static_cast<uint16_t>(machine_type));
}
}
@@ -389,7 +384,7 @@ namespace vcpkg::PostBuildLint
file.extension() == ".dll",
"The file extension was not .dll: %s",
file.generic_string());
- COFFFileReader::DllInfo info = COFFFileReader::read_dll(file);
+ const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file);
const std::string actual_architecture = get_actual_architecture(info.machine_type);
if (expected_architecture != actual_architecture)
@@ -418,7 +413,7 @@ namespace vcpkg::PostBuildLint
file.extension() == ".lib",
"The file extension was not .lib: %s",
file.generic_string());
- COFFFileReader::LibInfo info = COFFFileReader::read_lib(file);
+ CoffFileReader::LibInfo info = CoffFileReader::read_lib(file);
// This is zero for folly's debug library
// TODO: Why?
@@ -580,7 +575,7 @@ namespace vcpkg::PostBuildLint
return LintStatus::SUCCESS;
}
- struct BuildType_and_file
+ struct BuildTypeAndFile
{
fs::path file;
BuildType build_type;
@@ -594,17 +589,14 @@ namespace vcpkg::PostBuildLint
bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type),
bad_build_types.end());
- std::vector<BuildType_and_file> libs_with_invalid_crt;
+ std::vector<BuildTypeAndFile> libs_with_invalid_crt;
for (const fs::path& lib : libs)
{
- const std::wstring cmd_line =
- Strings::wformat(LR"("%s" /directives "%s")", dumpbin_exe.native(), lib.native());
+ 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",
- Strings::to_utf8(cmd_line));
+ Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line);
for (const BuildType& bad_build_type : bad_build_types)
{
@@ -622,7 +614,7 @@ namespace vcpkg::PostBuildLint
"Expected %s crt linkage, but the following libs had invalid crt linkage:",
expected_build_type.to_string());
System::println();
- for (const BuildType_and_file btf : libs_with_invalid_crt)
+ for (const BuildTypeAndFile btf : libs_with_invalid_crt)
{
System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string());
}
@@ -636,12 +628,12 @@ namespace vcpkg::PostBuildLint
return LintStatus::SUCCESS;
}
- struct OutdatedDynamicCrt_and_file
+ struct OutdatedDynamicCrtAndFile
{
fs::path file;
OutdatedDynamicCrt outdated_crt;
- OutdatedDynamicCrt_and_file() = delete;
+ OutdatedDynamicCrtAndFile() = delete;
};
static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector<fs::path>& dlls,
@@ -650,19 +642,15 @@ namespace vcpkg::PostBuildLint
{
if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS;
- std::vector<OutdatedDynamicCrt_and_file> dlls_with_outdated_crt;
+ std::vector<OutdatedDynamicCrtAndFile> dlls_with_outdated_crt;
for (const fs::path& dll : dlls)
{
- const std::wstring cmd_line =
- Strings::wformat(LR"("%s" /dependents "%s")", dumpbin_exe.native(), dll.native());
+ const auto cmd_line = Strings::format(R"("%s" /dependents "%s")", dumpbin_exe.u8string(), dll.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",
- Strings::to_utf8(cmd_line));
+ Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", cmd_line);
- for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts())
+ for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141"))
{
if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex))
{
@@ -676,7 +664,7 @@ namespace vcpkg::PostBuildLint
{
System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:");
System::println();
- for (const OutdatedDynamicCrt_and_file btf : dlls_with_outdated_crt)
+ for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt)
{
System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name);
}
@@ -695,8 +683,8 @@ namespace vcpkg::PostBuildLint
std::vector<fs::path> misplaced_files = fs.get_files_non_recursive(dir);
Util::unstable_keep_if(misplaced_files, [&fs](const fs::path& path) {
const std::string filename = path.filename().generic_string();
- if (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") == 0 ||
- Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO") == 0)
+ if (Strings::case_insensitive_ascii_equals(filename.c_str(), "CONTROL") ||
+ Strings::case_insensitive_ascii_equals(filename.c_str(), "BUILD_INFO"))
return false;
return !fs.is_directory(path);
});
@@ -722,7 +710,7 @@ namespace vcpkg::PostBuildLint
const auto& fs = paths.get_filesystem();
// for dumpbin
- const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset);
+ const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path);
const fs::path package_dir = paths.package_dir(spec);
size_t error_count = 0;
diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/vcpkg/remove.cpp
index cca541c85..2ec32855a 100644
--- a/toolsrc/src/commands_remove.cpp
+++ b/toolsrc/src/vcpkg/remove.cpp
@@ -1,13 +1,16 @@
#include "pch.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Dependencies.h"
-#include "vcpkg_Input.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include "vcpkglib.h"
-
-namespace vcpkg::Commands::Remove
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/dependencies.h>
+#include <vcpkg/help.h>
+#include <vcpkg/input.h>
+#include <vcpkg/remove.h>
+#include <vcpkg/update.h>
+#include <vcpkg/vcpkglib.h>
+
+namespace vcpkg::Remove
{
using Dependencies::RemovePlanAction;
using Dependencies::RemovePlanType;
@@ -18,7 +21,7 @@ namespace vcpkg::Commands::Remove
{
auto& fs = paths.get_filesystem();
auto spghs = status_db->find_all(spec.name(), spec.triplet());
- auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY);
+ const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), "");
for (auto&& spgh : spghs)
{
@@ -31,7 +34,7 @@ namespace vcpkg::Commands::Remove
auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package));
- if (auto lines = maybe_lines.get())
+ if (const auto lines = maybe_lines.get())
{
std::vector<fs::path> dirs_touched;
for (auto&& suffix : *lines)
@@ -42,7 +45,7 @@ namespace vcpkg::Commands::Remove
auto target = paths.installed / suffix;
- auto status = fs.status(target, ec);
+ const auto status = fs.status(target, ec);
if (ec)
{
System::println(System::Color::error, "failed: %s", ec.message());
@@ -72,7 +75,7 @@ namespace vcpkg::Commands::Remove
}
auto b = dirs_touched.rbegin();
- auto e = dirs_touched.rend();
+ const auto e = dirs_touched.rend();
for (; b != e; ++b)
{
if (fs.is_empty(*b))
@@ -100,11 +103,11 @@ namespace vcpkg::Commands::Remove
static void print_plan(const std::map<RemovePlanType, std::vector<const RemovePlanAction*>>& group_by_plan_type)
{
- static constexpr std::array<RemovePlanType, 2> order = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE};
+ static constexpr std::array<RemovePlanType, 2> ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE};
- for (const RemovePlanType plan_type : order)
+ for (const RemovePlanType plan_type : ORDER)
{
- auto it = group_by_plan_type.find(plan_type);
+ const auto it = group_by_plan_type.find(plan_type);
if (it == group_by_plan_type.cend())
{
continue;
@@ -129,15 +132,72 @@ namespace vcpkg::Commands::Remove
}
}
+ void perform_remove_plan_action(const VcpkgPaths& paths,
+ const RemovePlanAction& action,
+ const Purge purge,
+ StatusParagraphs& status_db)
+ {
+ const std::string display_name = action.spec.to_string();
+
+ switch (action.plan_type)
+ {
+ case RemovePlanType::NOT_INSTALLED:
+ System::println(System::Color::success, "Package %s is not installed", display_name);
+ break;
+ case RemovePlanType::REMOVE:
+ System::println("Removing package %s... ", display_name);
+ remove_package(paths, action.spec, &status_db);
+ System::println(System::Color::success, "Removing package %s... done", display_name);
+ break;
+ case RemovePlanType::UNKNOWN:
+ default: Checks::unreachable(VCPKG_LINE_INFO);
+ }
+
+ if (purge == Purge::YES)
+ {
+ System::println("Purging package %s... ", display_name);
+ Files::Filesystem& fs = paths.get_filesystem();
+ std::error_code ec;
+ fs.remove_all(paths.packages / action.spec.dir(), ec);
+ System::println(System::Color::success, "Purging package %s... done", display_name);
+ }
+ }
+
+ static const std::string OPTION_PURGE = "--purge";
+ static const std::string OPTION_NO_PURGE = "--no-purge";
+ static const std::string OPTION_RECURSE = "--recurse";
+ static const std::string OPTION_DRY_RUN = "--dry-run";
+ static const std::string OPTION_OUTDATED = "--outdated";
+
+ static const std::array<std::string, 5> REMOVE_SWITCHES = {
+ OPTION_PURGE,
+ OPTION_NO_PURGE,
+ OPTION_RECURSE,
+ OPTION_DRY_RUN,
+ OPTION_OUTDATED,
+ };
+ static const std::array<std::string, 0> REMOVE_SETTINGS;
+
+ static std::vector<std::string> valid_arguments(const VcpkgPaths& paths)
+ {
+ const StatusParagraphs status_db = database_load_check(paths);
+ const std::vector<StatusParagraph*> installed_packages = get_installed_ports(status_db);
+
+ return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh->package.spec.to_string(); });
+ }
+
+ const CommandStructure COMMAND_STRUCTURE = {
+ "remove zlib zlib:x64-windows curl boost",
+ 1,
+ SIZE_MAX,
+ REMOVE_SWITCHES,
+ REMOVE_SETTINGS,
+ &valid_arguments,
+ };
+
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
- static const std::string OPTION_PURGE = "--purge";
- static const std::string OPTION_NO_PURGE = "--no-purge";
- static const std::string OPTION_RECURSE = "--recurse";
- static const std::string OPTION_DRY_RUN = "--dry-run";
- static const std::string OPTION_OUTDATED = "--outdated";
- static const std::string example =
- Commands::Help::create_example_string("remove zlib zlib:x64-windows curl boost");
+ static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost");
const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments(
{OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED});
@@ -145,7 +205,7 @@ namespace vcpkg::Commands::Remove
std::vector<PackageSpec> specs;
if (options.find(OPTION_OUTDATED) != options.cend())
{
- args.check_exact_arg_count(0, example);
+ args.check_exact_arg_count(0, EXAMPLE);
specs = Util::fmap(Update::find_outdated_packages(paths, status_db),
[](auto&& outdated) { return outdated.spec; });
@@ -157,25 +217,26 @@ namespace vcpkg::Commands::Remove
}
else
{
- args.check_min_arg_count(1, example);
+ args.check_min_arg_count(1, EXAMPLE);
specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
- return Input::check_and_get_package_spec(arg, default_triplet, example);
+ return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE);
});
for (auto&& spec : specs)
Input::check_triplet(spec.triplet(), paths);
}
- const bool alsoRemoveFolderFromPackages = options.find(OPTION_NO_PURGE) == options.end();
- if (options.find(OPTION_PURGE) != options.end() && !alsoRemoveFolderFromPackages)
+ const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end();
+ const bool purge_was_passed = options.find(OPTION_PURGE) != options.end();
+ if (purge_was_passed && no_purge_was_passed)
{
- // User specified --purge and --no-purge
System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge.");
- System::print(example);
+ System::print(EXAMPLE);
Checks::exit_fail(VCPKG_LINE_INFO);
}
- const bool isRecursive = options.find(OPTION_RECURSE) != options.cend();
- const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend();
+ const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed);
+ const bool is_recursive = options.find(OPTION_RECURSE) != options.cend();
+ const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend();
const std::vector<RemovePlanAction> remove_plan = Dependencies::create_remove_plan(specs, status_db);
Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty");
@@ -194,7 +255,7 @@ namespace vcpkg::Commands::Remove
System::println(System::Color::warning,
"Additional packages (*) need to be removed to complete this operation.");
- if (!isRecursive)
+ if (!is_recursive)
{
System::println(System::Color::warning,
"If you are sure you want to remove them, run the command with the --recurse option");
@@ -202,37 +263,14 @@ namespace vcpkg::Commands::Remove
}
}
- if (dryRun)
+ if (dry_run)
{
Checks::exit_success(VCPKG_LINE_INFO);
}
for (const RemovePlanAction& action : remove_plan)
{
- const std::string display_name = action.spec.to_string();
-
- switch (action.plan_type)
- {
- case RemovePlanType::NOT_INSTALLED:
- System::println(System::Color::success, "Package %s is not installed", display_name);
- break;
- case RemovePlanType::REMOVE:
- System::println("Removing package %s... ", display_name);
- remove_package(paths, action.spec, &status_db);
- System::println(System::Color::success, "Removing package %s... done", display_name);
- break;
- case RemovePlanType::UNKNOWN:
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
-
- if (alsoRemoveFolderFromPackages)
- {
- System::println("Purging package %s... ", display_name);
- Files::Filesystem& fs = paths.get_filesystem();
- std::error_code ec;
- fs.remove_all(paths.packages / action.spec.dir(), ec);
- System::println(System::Color::success, "Purging package %s... done", display_name);
- }
+ perform_remove_plan_action(paths, action, purge, status_db);
}
Checks::exit_success(VCPKG_LINE_INFO);
diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp
index 50d6ecf07..2a9480538 100644
--- a/toolsrc/src/SourceParagraph.cpp
+++ b/toolsrc/src/vcpkg/sourceparagraph.cpp
@@ -1,19 +1,19 @@
#include "pch.h"
-#include "PackageSpec.h"
-#include "SourceParagraph.h"
-#include "Triplet.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Maps.h"
-#include "vcpkg_System.h"
-#include "vcpkg_Util.h"
-#include "vcpkg_expected.h"
+#include <vcpkg/packagespec.h>
+#include <vcpkg/sourceparagraph.h>
+#include <vcpkg/triplet.h>
+
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/expected.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
namespace vcpkg
{
using namespace vcpkg::Parse;
- namespace Fields
+ namespace SourceParagraphFields
{
static const std::string BUILD_DEPENDS = "Build-Depends";
static const std::string DEFAULTFEATURES = "Default-Features";
@@ -25,20 +25,20 @@ namespace vcpkg
static const std::string VERSION = "Version";
}
- static span<const std::string> get_list_of_valid_fields()
+ static Span<const std::string> get_list_of_valid_fields()
{
static const std::string valid_fields[] = {
- Fields::SOURCE,
- Fields::VERSION,
- Fields::DESCRIPTION,
- Fields::MAINTAINER,
- Fields::BUILD_DEPENDS,
+ SourceParagraphFields::SOURCE,
+ SourceParagraphFields::VERSION,
+ SourceParagraphFields::DESCRIPTION,
+ SourceParagraphFields::MAINTAINER,
+ SourceParagraphFields::BUILD_DEPENDS,
};
return valid_fields;
}
- void print_error_message(span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list)
+ void print_error_message(Span<const std::unique_ptr<Parse::ParseControlErrorInfo>> error_info_list)
{
Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0);
@@ -92,14 +92,15 @@ namespace vcpkg
auto spgh = std::make_unique<SourceParagraph>();
- parser.required_field(Fields::SOURCE, spgh->name);
- parser.required_field(Fields::VERSION, spgh->version);
+ parser.required_field(SourceParagraphFields::SOURCE, spgh->name);
+ parser.required_field(SourceParagraphFields::VERSION, spgh->version);
- spgh->description = parser.optional_field(Fields::DESCRIPTION);
- spgh->maintainer = parser.optional_field(Fields::MAINTAINER);
- spgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS)));
- spgh->supports = parse_comma_list(parser.optional_field(Fields::SUPPORTS));
- spgh->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES));
+ spgh->description = parser.optional_field(SourceParagraphFields::DESCRIPTION);
+ spgh->maintainer = parser.optional_field(SourceParagraphFields::MAINTAINER);
+ spgh->depends = expand_qualified_dependencies(
+ parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS)));
+ spgh->supports = parse_comma_list(parser.optional_field(SourceParagraphFields::SUPPORTS));
+ spgh->default_features = parse_comma_list(parser.optional_field(SourceParagraphFields::DEFAULTFEATURES));
auto err = parser.error_info(spgh->name);
if (err)
@@ -114,10 +115,11 @@ namespace vcpkg
auto fpgh = std::make_unique<FeatureParagraph>();
- parser.required_field(Fields::FEATURE, fpgh->name);
- parser.required_field(Fields::DESCRIPTION, fpgh->description);
+ parser.required_field(SourceParagraphFields::FEATURE, fpgh->name);
+ parser.required_field(SourceParagraphFields::DESCRIPTION, fpgh->description);
- fpgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS)));
+ fpgh->depends = expand_qualified_dependencies(
+ parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS)));
auto err = parser.error_info(fpgh->name);
if (err)
@@ -137,7 +139,7 @@ namespace vcpkg
auto control_file = std::make_unique<SourceControlFile>();
auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front()));
- if (auto source = maybe_source.get())
+ if (const auto source = maybe_source.get())
control_file->core_paragraph = std::move(*source);
else
return std::move(maybe_source).error();
@@ -147,7 +149,7 @@ namespace vcpkg
for (auto&& feature_pgh : control_paragraphs)
{
auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh));
- if (auto feature = maybe_feature.get())
+ if (const auto feature = maybe_feature.get())
control_file->feature_paragraphs.emplace_back(std::move(*feature));
else
return std::move(maybe_feature).error();
@@ -170,24 +172,17 @@ namespace vcpkg
std::string Dependency::name() const
{
- std::string str = this->depend.name;
- if (this->depend.features.empty()) return str;
+ if (this->depend.features.empty()) return this->depend.name;
- str += "[";
- for (auto&& s : this->depend.features)
- {
- str += s + ",";
- }
- str.pop_back();
- str += "]";
- return str;
+ const std::string features = Strings::join(",", this->depend.features);
+ return Strings::format("%s[%s]", this->depend.name, features);
}
- std::vector<Dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)
+ std::vector<Dependency> expand_qualified_dependencies(const std::vector<std::string>& depends)
{
return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency {
auto pos = depend_string.find(' ');
- if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY);
+ if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, "");
// expect of the form "\w+ \[\w+\]"
Dependency dep;
@@ -195,7 +190,7 @@ namespace vcpkg
if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')')
{
// Error, but for now just slurp the entire string.
- return Dependency::parse_dependency(depend_string, Strings::EMPTY);
+ return Dependency::parse_dependency(depend_string, "");
}
dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3);
return dep;
@@ -220,11 +215,7 @@ namespace vcpkg
return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t);
}
- const std::string to_string(const Dependency& dep)
- {
- std::string name = dep.name();
- return name;
- }
+ std::string to_string(const Dependency& dep) { return dep.name(); }
ExpectedT<Supports, std::vector<std::string>> Supports::parse(const std::vector<std::string>& strs)
{
@@ -263,7 +254,7 @@ namespace vcpkg
bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools)
{
- auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); };
+ const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); };
if (!is_in_or_empty(arch, architectures)) return false;
if (!is_in_or_empty(plat, platforms)) return false;
if (!is_in_or_empty(crt, crt_linkages)) return false;
diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp
index 5b5c3978f..5f00825e1 100644
--- a/toolsrc/src/StatusParagraph.cpp
+++ b/toolsrc/src/vcpkg/statusparagraph.cpp
@@ -1,6 +1,6 @@
#include "pch.h"
-#include "StatusParagraph.h"
+#include <vcpkg/statusparagraph.h>
using namespace vcpkg::Parse;
@@ -33,8 +33,8 @@ namespace vcpkg
this->package = BinaryParagraph(std::move(fields));
auto b = status_field.begin();
- auto mark = b;
- auto e = status_field.end();
+ const auto mark = b;
+ const auto e = status_field.end();
// Todo: improve error handling
while (b != e && *b != ' ')
diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp
index 02ee61f75..647ed6d3f 100644
--- a/toolsrc/src/StatusParagraphs.cpp
+++ b/toolsrc/src/vcpkg/statusparagraphs.cpp
@@ -1,8 +1,7 @@
#include "pch.h"
-#include "StatusParagraphs.h"
-#include "vcpkg_Checks.h"
-#include <algorithm>
+#include <vcpkg/base/checks.h>
+#include <vcpkg/statusparagraphs.h>
namespace vcpkg
{
@@ -67,7 +66,7 @@ namespace vcpkg
{
Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph");
const PackageSpec& spec = pgh->package.spec;
- auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature);
+ const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature);
if (ptr == end())
{
paragraphs.push_back(std::move(pgh));
diff --git a/toolsrc/src/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp
index 451deb040..4cba1523d 100644
--- a/toolsrc/src/triplet.cpp
+++ b/toolsrc/src/vcpkg/triplet.cpp
@@ -1,8 +1,8 @@
#include "pch.h"
-#include "Triplet.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Strings.h"
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/strings.h>
+#include <vcpkg/triplet.h>
namespace vcpkg
{
@@ -15,14 +15,17 @@ namespace vcpkg
bool operator==(const TripletInstance& o) const { return o.value == value; }
};
- const TripletInstance Triplet::default_instance({});
+ const TripletInstance Triplet::DEFAULT_INSTANCE({});
}
-template<>
-struct std::hash<vcpkg::TripletInstance>
+namespace std
{
- size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; }
-};
+ template<>
+ struct hash<vcpkg::TripletInstance>
+ {
+ size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; }
+ };
+}
namespace vcpkg
{
@@ -41,10 +44,7 @@ namespace vcpkg
Triplet Triplet::from_canonical_name(const std::string& triplet_as_string)
{
std::string s(Strings::ascii_to_lowercase(triplet_as_string));
- auto it = std::find(s.cbegin(), s.cend(), '-');
- Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string);
-
- auto p = g_triplet_instances.emplace(std::move(s));
+ const auto p = g_triplet_instances.emplace(std::move(s));
return &*p.first;
}
diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/vcpkg/update.cpp
index 35f24af12..168949bc1 100644
--- a/toolsrc/src/commands_update.cpp
+++ b/toolsrc/src/vcpkg/update.cpp
@@ -1,12 +1,13 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_System.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/help.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/update.h>
+#include <vcpkg/vcpkglib.h>
-namespace vcpkg::Commands::Update
+namespace vcpkg::Update
{
bool OutdatedPackage::compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right)
{
@@ -22,7 +23,7 @@ namespace vcpkg::Commands::Update
std::vector<OutdatedPackage> output;
for (const StatusParagraph* pgh : installed_packages)
{
- auto it = src_names_to_versions.find(pgh->package.spec.name());
+ const auto it = src_names_to_versions.find(pgh->package.spec.name());
if (it == src_names_to_versions.end())
{
// Package was not installed from portfile
@@ -69,31 +70,6 @@ namespace vcpkg::Commands::Update
install_line);
}
- auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt");
- if (auto version_contents = version_file.get())
- {
- int maj1, min1, rev1;
- auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1);
-
- int maj2, min2, rev2;
- auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2);
-
- if (num1 == 3 && num2 == 3)
- {
- if (maj1 != maj2 || min1 != min2 || rev1 != rev2)
- {
- System::println("Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use "
- ".\\bootstrap-vcpkg.bat to update.",
- maj2,
- min2,
- rev2,
- maj1,
- min1,
- rev1);
- }
- }
- }
-
Checks::exit_success(VCPKG_LINE_INFO);
}
}
diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
index cb261930e..209f6a3f2 100644
--- a/toolsrc/src/VcpkgCmdArguments.cpp
+++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp
@@ -1,10 +1,11 @@
#include "pch.h"
-#include "VcpkgCmdArguments.h"
-#include "metrics.h"
-#include "vcpkg_Commands.h"
-#include "vcpkg_GlobalState.h"
-#include "vcpkg_System.h"
+#include <vcpkg/base/system.h>
+#include <vcpkg/commands.h>
+#include <vcpkg/globalstate.h>
+#include <vcpkg/help.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/vcpkgcmdarguments.h>
namespace vcpkg
{
@@ -17,7 +18,7 @@ namespace vcpkg
{
System::println(System::Color::error, "Error: expected value after %s", option_name);
Metrics::g_metrics.lock()->track_property("error", "error option name");
- Commands::Help::print_usage();
+ Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
}
@@ -25,7 +26,7 @@ namespace vcpkg
{
System::println(System::Color::error, "Error: %s specified multiple times", option_name);
Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times");
- Commands::Help::print_usage();
+ Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
}
@@ -38,18 +39,26 @@ namespace vcpkg
{
System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name);
Metrics::g_metrics.lock()->track_property("error", "error conflicting switches");
- Commands::Help::print_usage();
+ Help::print_usage();
Checks::exit_fail(VCPKG_LINE_INFO);
}
option_field = new_setting;
}
+#if defined(_WIN32)
VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv)
+#else
+ VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const char* const* const argv)
+#endif
{
std::vector<std::string> v;
for (int i = 1; i < argc; ++i)
{
+#if defined(_WIN32)
v.push_back(Strings::to_utf8(argv[i]));
+#else
+ v.push_back(argv[i]);
+#endif
}
return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size());
@@ -222,17 +231,17 @@ namespace vcpkg
void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const
{
- return check_max_arg_count(expected_arg_count, Strings::EMPTY);
+ return check_max_arg_count(expected_arg_count, "");
}
void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const
{
- return check_min_arg_count(expected_arg_count, Strings::EMPTY);
+ return check_min_arg_count(expected_arg_count, "");
}
void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const
{
- return check_exact_arg_count(expected_arg_count, Strings::EMPTY);
+ return check_exact_arg_count(expected_arg_count, "");
}
void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const
diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp
index 5cdafdbc8..38b130f6f 100644
--- a/toolsrc/src/vcpkglib.cpp
+++ b/toolsrc/src/vcpkg/vcpkglib.cpp
@@ -1,11 +1,11 @@
#include "pch.h"
-#include "Paragraphs.h"
-#include "metrics.h"
-#include "vcpkg_Files.h"
-#include "vcpkg_Strings.h"
-#include "vcpkg_Util.h"
-#include "vcpkglib.h"
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/paragraphs.h>
+#include <vcpkg/vcpkglib.h>
namespace vcpkg
{
@@ -212,30 +212,26 @@ namespace vcpkg
return installed_files;
}
- CMakeVariable::CMakeVariable(const CWStringView varname, const wchar_t* varvalue)
- : s(Strings::wformat(LR"("-D%s=%s")", varname, varvalue))
+ CMakeVariable::CMakeVariable(const CStringView varname, const char* varvalue)
+ : s(Strings::format(R"("-D%s=%s")", varname, varvalue))
{
}
- CMakeVariable::CMakeVariable(const CWStringView varname, const std::string& varvalue)
- : CMakeVariable(varname, Strings::to_utf16(varvalue).c_str())
- {
- }
- CMakeVariable::CMakeVariable(const CWStringView varname, const std::wstring& varvalue)
+ CMakeVariable::CMakeVariable(const CStringView varname, const std::string& varvalue)
: CMakeVariable(varname, varvalue.c_str())
{
}
- CMakeVariable::CMakeVariable(const CWStringView varname, const fs::path& path)
- : CMakeVariable(varname, path.generic_wstring())
+ CMakeVariable::CMakeVariable(const CStringView varname, const fs::path& path)
+ : CMakeVariable(varname, path.generic_u8string())
{
}
- std::wstring make_cmake_cmd(const fs::path& cmake_exe,
- const fs::path& cmake_script,
- const std::vector<CMakeVariable>& pass_variables)
+ std::string make_cmake_cmd(const fs::path& cmake_exe,
+ const fs::path& cmake_script,
+ const std::vector<CMakeVariable>& pass_variables)
{
- const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; });
- return Strings::wformat(
- LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring());
+ const std::string cmd_cmake_pass_variables = Strings::join(" ", pass_variables, [](auto&& v) { return v.s; });
+ return Strings::format(
+ R"("%s" %s -P "%s")", cmake_exe.u8string(), cmd_cmake_pass_variables, cmake_script.generic_u8string());
}
std::string shorten_text(const std::string& desc, size_t length)
diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp
new file mode 100644
index 000000000..90f9cb00b
--- /dev/null
+++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp
@@ -0,0 +1,528 @@
+#include "pch.h"
+
+#include <vcpkg/base/expected.h>
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/system.h>
+#include <vcpkg/base/util.h>
+#include <vcpkg/metrics.h>
+#include <vcpkg/packagespec.h>
+#include <vcpkg/vcpkgpaths.h>
+
+namespace vcpkg
+{
+ static constexpr CStringView V_120 = "v120";
+ static constexpr CStringView V_140 = "v140";
+ static constexpr CStringView V_141 = "v141";
+
+ static bool exists_and_has_equal_or_greater_version(const std::string& version_cmd,
+ const std::array<int, 3>& expected_version)
+ {
+ static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###");
+
+ const auto rc = System::cmd_execute_and_capture_output(Strings::format(R"(%s)", version_cmd));
+ if (rc.exit_code != 0)
+ {
+ return false;
+ }
+
+ std::match_results<std::string::const_iterator> match;
+ const auto found = std::regex_search(rc.output, match, RE);
+ if (!found)
+ {
+ return false;
+ }
+
+ const int d1 = atoi(match[1].str().c_str());
+ const int d2 = atoi(match[2].str().c_str());
+ const int d3 = atoi(match[3].str().c_str());
+ if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) ||
+ (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2]))
+ {
+ // satisfactory version found
+ return true;
+ }
+
+ return false;
+ }
+
+ static Optional<fs::path> find_if_has_equal_or_greater_version(const std::vector<fs::path>& candidate_paths,
+ const std::string& version_check_arguments,
+ const std::array<int, 3>& expected_version)
+ {
+ auto it = Util::find_if(candidate_paths, [&](const fs::path& p) {
+ const std::string cmd = Strings::format(R"("%s" %s)", p.u8string(), version_check_arguments);
+ return exists_and_has_equal_or_greater_version(cmd, expected_version);
+ });
+
+ if (it != candidate_paths.cend())
+ {
+ return std::move(*it);
+ }
+
+ return nullopt;
+ }
+
+ static fs::path fetch_dependency(const fs::path& scripts_folder,
+ const std::string& tool_name,
+ const fs::path& expected_downloaded_path,
+ const std::array<int, 3>& version)
+ {
+ const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]);
+ System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...",
+ tool_name,
+ version_as_string,
+ tool_name,
+ version_as_string);
+ const fs::path script = scripts_folder / "fetchDependency.ps1";
+ const auto install_cmd =
+ System::create_powershell_script_cmd(script, Strings::format("-Dependency %s", tool_name));
+ const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd);
+ if (rc.exit_code)
+ {
+ System::println(System::Color::error,
+ "Launching powershell failed or was denied when trying to fetch %s version %s.\n"
+ "(No sufficient installed version was found)",
+ tool_name,
+ version_as_string);
+ {
+ auto locked_metrics = Metrics::g_metrics.lock();
+ locked_metrics->track_property("error", "powershell install failed");
+ locked_metrics->track_property("dependency", tool_name);
+ }
+ Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code);
+ }
+
+ const fs::path actual_downloaded_path = Strings::trimmed(rc.output);
+ std::error_code ec;
+ const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec);
+ Checks::check_exit(VCPKG_LINE_INFO,
+ eq && !ec,
+ "Expected dependency downloaded path to be %s, but was %s",
+ expected_downloaded_path.u8string(),
+ actual_downloaded_path.u8string());
+ return actual_downloaded_path;
+ }
+
+ static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
+ {
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {3, 9, 3};
+ static const std::string VERSION_CHECK_ARGUMENTS = "--version";
+
+ const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe";
+ const std::vector<fs::path> from_path = Files::find_from_PATH("cmake");
+
+ std::vector<fs::path> candidate_paths;
+ candidate_paths.push_back(downloaded_copy);
+ 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 Optional<fs::path> path =
+ find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
+ {
+ return *p;
+ }
+
+ return fetch_dependency(scripts_folder, "cmake", downloaded_copy, EXPECTED_VERSION);
+ }
+
+ fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
+ {
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {4, 3, 0};
+
+ const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe";
+ const std::vector<fs::path> from_path = Files::find_from_PATH("nuget");
+
+ std::vector<fs::path> candidate_paths;
+ candidate_paths.push_back(downloaded_copy);
+ candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
+
+ auto path = find_if_has_equal_or_greater_version(candidate_paths, "", EXPECTED_VERSION);
+ if (const auto p = path.get())
+ {
+ return *p;
+ }
+
+ return fetch_dependency(scripts_folder, "nuget", downloaded_copy, EXPECTED_VERSION);
+ }
+
+ fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
+ {
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {2, 14, 1};
+ static const std::string VERSION_CHECK_ARGUMENTS = "--version";
+
+ const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe";
+ const std::vector<fs::path> from_path = Files::find_from_PATH("git");
+
+ std::vector<fs::path> candidate_paths;
+ candidate_paths.push_back(downloaded_copy);
+ 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 Optional<fs::path> path =
+ find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
+ {
+ return *p;
+ }
+
+ return fetch_dependency(scripts_folder, "git", downloaded_copy, EXPECTED_VERSION);
+ }
+
+ static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder)
+ {
+ static constexpr std::array<int, 3> EXPECTED_VERSION = {3, 1, 81};
+ static const std::string VERSION_CHECK_ARGUMENTS = "--framework-version";
+
+ const fs::path downloaded_copy =
+ downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe";
+
+ std::vector<fs::path> candidate_paths;
+ candidate_paths.push_back(downloaded_copy);
+ // TODO: Uncomment later
+ // const std::vector<fs::path> from_path = Files::find_from_PATH("installerbase");
+ // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend());
+ // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" /
+ // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe");
+ // candidate_paths.push_back(fs::path(System::get_environment_variable("HOMEDRIVE").value_or("C:")) / "Qt" /
+ // "QtIFW-3.1.0" / "bin" / "installerbase.exe");
+
+ const Optional<fs::path> path =
+ find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION);
+ if (const auto p = path.get())
+ {
+ return *p;
+ }
+
+ return fetch_dependency(scripts_folder, "installerbase", downloaded_copy, EXPECTED_VERSION);
+ }
+
+ Expected<VcpkgPaths> VcpkgPaths::create(const fs::path& vcpkg_root_dir)
+ {
+ std::error_code ec;
+ const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec);
+ if (ec)
+ {
+ return ec;
+ }
+
+ VcpkgPaths paths;
+ paths.root = canonical_vcpkg_root_dir;
+
+ if (paths.root.empty())
+ {
+ Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory");
+ Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string());
+ }
+
+ paths.packages = paths.root / "packages";
+ paths.buildtrees = paths.root / "buildtrees";
+ paths.downloads = paths.root / "downloads";
+ paths.ports = paths.root / "ports";
+ paths.installed = paths.root / "installed";
+ paths.triplets = paths.root / "triplets";
+ paths.scripts = paths.root / "scripts";
+
+ paths.buildsystems = paths.scripts / "buildsystems";
+ paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets";
+
+ paths.vcpkg_dir = paths.installed / "vcpkg";
+ paths.vcpkg_dir_status_file = paths.vcpkg_dir / "status";
+ paths.vcpkg_dir_info = paths.vcpkg_dir / "info";
+ paths.vcpkg_dir_updates = paths.vcpkg_dir / "updates";
+
+ paths.ports_cmake = paths.scripts / "ports.cmake";
+
+ return paths;
+ }
+
+ fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); }
+
+ fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); }
+ fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; }
+
+ fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const
+ {
+ return this->package_dir(spec) / "BUILD_INFO";
+ }
+
+ fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const
+ {
+ return this->vcpkg_dir_info / (pgh.fullstem() + ".list");
+ }
+
+ const std::vector<std::string>& VcpkgPaths::get_available_triplets() const
+ {
+ return this->available_triplets.get_lazy([this]() -> std::vector<std::string> {
+
+ std::vector<std::string> output;
+ for (auto&& path : this->get_filesystem().get_files_non_recursive(this->triplets))
+ {
+ output.push_back(path.stem().filename().string());
+ }
+
+ return output;
+ });
+ }
+
+ bool VcpkgPaths::is_valid_triplet(const Triplet& t) const
+ {
+ auto it = Util::find_if(this->get_available_triplets(),
+ [&](auto&& available_triplet) { return t.canonical_name() == available_triplet; });
+ return it != this->get_available_triplets().cend();
+ }
+
+ const fs::path& VcpkgPaths::get_cmake_exe() const
+ {
+ return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); });
+ }
+
+ const fs::path& VcpkgPaths::get_git_exe() const
+ {
+ return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); });
+ }
+
+ const fs::path& VcpkgPaths::get_nuget_exe() const
+ {
+ return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); });
+ }
+
+ const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const
+ {
+ return this->ifw_installerbase_exe.get_lazy(
+ [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); });
+ }
+
+ const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const
+ {
+ return this->ifw_binarycreator_exe.get_lazy(
+ [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; });
+ }
+
+ const fs::path& VcpkgPaths::get_ifw_repogen_exe() const
+ {
+ return this->ifw_repogen_exe.get_lazy(
+ [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; });
+ }
+
+ struct VisualStudioInstance
+ {
+ fs::path root_path;
+ std::string version;
+ std::string release_type;
+ std::string preference_weight; // Mostly unused, just for verification that order is as intended
+
+ std::string major_version() const { return version.substr(0, 2); }
+ };
+
+ static std::vector<VisualStudioInstance> get_visual_studio_instances(const VcpkgPaths& paths)
+ {
+ const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1";
+ const std::string cmd = System::create_powershell_script_cmd(script);
+ const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd);
+ Checks::check_exit(
+ VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances");
+
+ const std::vector<std::string> instances_as_strings = Strings::split(ec_data.output, "\n");
+ std::vector<VisualStudioInstance> output;
+ for (const std::string& instance_as_string : instances_as_strings)
+ {
+ const std::vector<std::string> split = Strings::split(instance_as_string, "::");
+ output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)});
+ }
+
+ return output;
+ }
+
+ static std::vector<Toolset> find_toolset_instances(const VcpkgPaths& paths)
+ {
+ using CPU = System::CPUArchitecture;
+
+ const auto& fs = paths.get_filesystem();
+
+ // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations.
+ std::vector<fs::path> paths_examined;
+
+ std::vector<Toolset> found_toolsets;
+
+ const std::vector<VisualStudioInstance> vs_instances = get_visual_studio_instances(paths);
+ const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) {
+ return vs_instance.major_version() == "14";
+ }) != vs_instances.cend();
+
+ for (const VisualStudioInstance& vs_instance : vs_instances)
+ {
+ const std::string major_version = vs_instance.major_version();
+ if (major_version == "15")
+ {
+ const fs::path vc_dir = vs_instance.root_path / "VC";
+
+ // Skip any instances that do not have vcvarsall.
+ const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build";
+ const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat";
+ paths_examined.push_back(vcvarsall_bat);
+ if (!fs.exists(vcvarsall_bat)) continue;
+
+ // Get all supported architectures
+ std::vector<ToolsetArchOption> supported_architectures;
+ if (fs.exists(vcvarsall_dir / "vcvars32.bat"))
+ supported_architectures.push_back({"x86", CPU::X86, CPU::X86});
+ if (fs.exists(vcvarsall_dir / "vcvars64.bat"))
+ supported_architectures.push_back({"amd64", CPU::X64, CPU::X64});
+ if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat"))
+ supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64});
+ if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat"))
+ supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM});
+ if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat"))
+ supported_architectures.push_back({"x86_arm64", CPU::X86, CPU::ARM64});
+ if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat"))
+ supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86});
+ if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat"))
+ supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM});
+ if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat"))
+ supported_architectures.push_back({"amd64_arm64", CPU::X64, CPU::ARM64});
+
+ // Locate the "best" MSVC toolchain version
+ const fs::path msvc_path = vc_dir / "Tools" / "MSVC";
+ std::vector<fs::path> msvc_subdirectories = fs.get_files_non_recursive(msvc_path);
+ Util::unstable_keep_if(msvc_subdirectories,
+ [&fs](const fs::path& path) { return fs.is_directory(path); });
+
+ // Sort them so that latest comes first
+ std::sort(
+ msvc_subdirectories.begin(),
+ msvc_subdirectories.end(),
+ [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); });
+
+ for (const fs::path& subdir : msvc_subdirectories)
+ {
+ const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe";
+ paths_examined.push_back(dumpbin_path);
+ if (fs.exists(dumpbin_path))
+ {
+ found_toolsets.push_back(Toolset{
+ vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures});
+
+ if (v140_is_available)
+ {
+ found_toolsets.push_back(Toolset{vs_instance.root_path,
+ dumpbin_path,
+ vcvarsall_bat,
+ {"-vcvars_ver=14.0"},
+ V_140,
+ supported_architectures});
+ }
+
+ break;
+ }
+ }
+
+ continue;
+ }
+
+ if (major_version == "14")
+ {
+ const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat";
+
+ paths_examined.push_back(vcvarsall_bat);
+ if (fs.exists(vcvarsall_bat))
+ {
+ const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe";
+ paths_examined.push_back(vs2015_dumpbin_exe);
+
+ const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin";
+ std::vector<ToolsetArchOption> supported_architectures;
+ if (fs.exists(vs2015_bin_dir / "vcvars32.bat"))
+ supported_architectures.push_back({"x86", CPU::X86, CPU::X86});
+ if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat"))
+ supported_architectures.push_back({"x64", CPU::X64, CPU::X64});
+ if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat"))
+ supported_architectures.push_back({"x86_amd64", CPU::X86, CPU::X64});
+ if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat"))
+ supported_architectures.push_back({"x86_arm", CPU::X86, CPU::ARM});
+ if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat"))
+ supported_architectures.push_back({"amd64_x86", CPU::X64, CPU::X86});
+ if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat"))
+ supported_architectures.push_back({"amd64_arm", CPU::X64, CPU::ARM});
+
+ if (fs.exists(vs2015_dumpbin_exe))
+ {
+ found_toolsets.push_back({vs_instance.root_path,
+ vs2015_dumpbin_exe,
+ vcvarsall_bat,
+ {},
+ V_140,
+ supported_architectures});
+ }
+ }
+ }
+ }
+
+ if (found_toolsets.empty())
+ {
+ System::println(System::Color::error, "Could not locate a complete toolset.");
+ System::println("The following paths were examined:");
+ for (const fs::path& path : paths_examined)
+ {
+ System::println(" %s", path.u8string());
+ }
+ Checks::exit_fail(VCPKG_LINE_INFO);
+ }
+
+ return found_toolsets;
+ }
+
+ const Toolset& VcpkgPaths::get_toolset(const Optional<std::string>& toolset_version,
+ const Optional<fs::path>& visual_studio_path) const
+ {
+ // Invariant: toolsets are non-empty and sorted with newest at back()
+ const std::vector<Toolset>& vs_toolsets =
+ this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); });
+
+ std::vector<const Toolset*> candidates = Util::element_pointers(vs_toolsets);
+ const auto tsv = toolset_version.get();
+ const auto vsp = visual_studio_path.get();
+
+ if (tsv && vsp)
+ {
+ Util::stable_keep_if(
+ candidates, [&](const Toolset* t) { return *tsv == t->version && *vsp == t->visual_studio_root_path; });
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !candidates.empty(),
+ "Could not find Visual Studio instace at %s with %s toolset.",
+ vsp->u8string(),
+ *tsv);
+
+ Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1);
+ return *candidates.back();
+ }
+
+ if (tsv)
+ {
+ Util::stable_keep_if(candidates, [&](const Toolset* t) { return *tsv == t->version; });
+ Checks::check_exit(
+ VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv);
+ }
+
+ if (vsp)
+ {
+ const fs::path vs_root_path = *vsp;
+ Util::stable_keep_if(candidates,
+ [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; });
+ Checks::check_exit(VCPKG_LINE_INFO,
+ !candidates.empty(),
+ "Could not find Visual Studio instace at %s.",
+ vs_root_path.generic_string());
+ }
+
+ return *candidates.front();
+ }
+
+ Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); }
+}
diff --git a/toolsrc/src/VersionT.cpp b/toolsrc/src/vcpkg/versiont.cpp
index 738d2ce88..1c52d674a 100644
--- a/toolsrc/src/VersionT.cpp
+++ b/toolsrc/src/vcpkg/versiont.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
-#include "VersionT.h"
-#include "vcpkg_Strings.h"
+#include <vcpkg/base/strings.h>
+#include <vcpkg/versiont.h>
namespace vcpkg
{
diff --git a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp
deleted file mode 100644
index b3bb778dc..000000000
--- a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "pch.h"
-
-#include "vcpkg_Build.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Enums.h"
-
-namespace vcpkg::Build
-{
- static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage";
- static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs";
- static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT";
- static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder";
- static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt";
-
- const std::string& to_string(BuildPolicy policy)
- {
- switch (policy)
- {
- case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE;
- case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS;
- case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT;
- case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER;
- case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT;
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-
- CStringView to_cmake_variable(BuildPolicy policy)
- {
- switch (policy)
- {
- case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE";
- case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS";
- case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT";
- case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER";
- case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT";
- default: Checks::unreachable(VCPKG_LINE_INFO);
- }
- }
-}
diff --git a/toolsrc/src/vcpkg_GlobalState.cpp b/toolsrc/src/vcpkg_GlobalState.cpp
deleted file mode 100644
index 2221222c0..000000000
--- a/toolsrc/src/vcpkg_GlobalState.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "pch.h"
-
-#include "vcpkg_GlobalState.h"
-
-namespace vcpkg
-{
- Util::LockGuarded<ElapsedTime> GlobalState::timer;
- std::atomic<bool> GlobalState::debugging = false;
- std::atomic<bool> GlobalState::feature_packages = false;
-
- std::atomic<int> GlobalState::g_init_console_cp = 0;
- std::atomic<int> GlobalState::g_init_console_output_cp = 0;
-}
diff --git a/toolsrc/src/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkgmetricsuploader.cpp
index cef4f4756..2239fe750 100644
--- a/toolsrc/src/vcpkg_metrics_uploader.cpp
+++ b/toolsrc/src/vcpkgmetricsuploader.cpp
@@ -1,6 +1,8 @@
-#include "metrics.h"
-#include "vcpkg_Checks.h"
-#include "vcpkg_Files.h"
+#include <vcpkg/metrics.h>
+
+#include <vcpkg/base/checks.h>
+#include <vcpkg/base/files.h>
+
#include <Windows.h>
using namespace vcpkg;