aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-02-21 13:39:36 -0800
committerGitHub <noreply@github.com>2017-02-21 13:39:36 -0800
commit7d4df89c1dfff0b2bad0165ac4579f6352935a94 (patch)
tree8b87d29fb74fb24984d5aff9b021f14d95afb5ab /toolsrc/src
parentd9462fdf490d3396cac58b1a935b1b8a982b3a72 (diff)
parentb921dce5fc17bd4c1c206b79eb0a7b8758dcf5bf (diff)
downloadvcpkg-7d4df89c1dfff0b2bad0165ac4579f6352935a94.tar.gz
vcpkg-7d4df89c1dfff0b2bad0165ac4579f6352935a94.zip
Merge branch 'master' into master
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/BinaryParagraph.cpp16
-rw-r--r--toolsrc/src/PostBuildLint.cpp62
-rw-r--r--toolsrc/src/PostBuildLint_BuildInfo.cpp11
-rw-r--r--toolsrc/src/PostBuildLint_BuildPolicies.cpp27
-rw-r--r--toolsrc/src/PostBuildLint_BuildType.cpp67
-rw-r--r--toolsrc/src/PostBuildLint_ConfigurationType.cpp27
-rw-r--r--toolsrc/src/PostBuildLint_LinkageType.cpp45
-rw-r--r--toolsrc/src/StatusParagraphs.cpp4
-rw-r--r--toolsrc/src/commands_available_commands.cpp1
-rw-r--r--toolsrc/src/commands_build.cpp133
-rw-r--r--toolsrc/src/commands_build_external.cpp23
-rw-r--r--toolsrc/src/commands_cache.cpp1
-rw-r--r--toolsrc/src/commands_ci.cpp124
-rw-r--r--toolsrc/src/commands_contact.cpp13
-rw-r--r--toolsrc/src/commands_create.cpp3
-rw-r--r--toolsrc/src/commands_edit.cpp14
-rw-r--r--toolsrc/src/commands_hash.cpp1
-rw-r--r--toolsrc/src/commands_help.cpp2
-rw-r--r--toolsrc/src/commands_import.cpp1
-rw-r--r--toolsrc/src/commands_install.cpp19
-rw-r--r--toolsrc/src/commands_integrate.cpp18
-rw-r--r--toolsrc/src/commands_list.cpp1
-rw-r--r--toolsrc/src/commands_owns.cpp1
-rw-r--r--toolsrc/src/commands_portsdiff.cpp1
-rw-r--r--toolsrc/src/commands_remove.cpp8
-rw-r--r--toolsrc/src/commands_search.cpp1
-rw-r--r--toolsrc/src/commands_update.cpp4
-rw-r--r--toolsrc/src/commands_version.cpp24
-rw-r--r--toolsrc/src/metrics.cpp13
-rw-r--r--toolsrc/src/triplet.cpp5
-rw-r--r--toolsrc/src/vcpkg.cpp20
-rw-r--r--toolsrc/src/vcpkg_Checks.cpp8
-rw-r--r--toolsrc/src/vcpkg_Chrono.cpp (renamed from toolsrc/src/Stopwatch.cpp)102
-rw-r--r--toolsrc/src/vcpkg_Dependencies.cpp4
-rw-r--r--toolsrc/src/vcpkg_Enums.cpp21
-rw-r--r--toolsrc/src/vcpkg_Environment.cpp125
-rw-r--r--toolsrc/src/vcpkg_Files.cpp4
-rw-r--r--toolsrc/src/vcpkg_Strings.cpp19
-rw-r--r--toolsrc/src/vcpkg_System.cpp31
-rw-r--r--toolsrc/src/vcpkg_info.cpp35
-rw-r--r--toolsrc/src/vcpkg_metrics_uploader.cpp8
-rw-r--r--toolsrc/src/vcpkglib.cpp2
42 files changed, 661 insertions, 388 deletions
diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp
index f949677a3..8605cd276 100644
--- a/toolsrc/src/BinaryParagraph.cpp
+++ b/toolsrc/src/BinaryParagraph.cpp
@@ -23,22 +23,6 @@ namespace vcpkg
static const std::string DEPENDS = "Depends";
}
- static const std::vector<std::string>& get_list_of_valid_fields()
- {
- static const std::vector<std::string> valid_fields =
- {
- BinaryParagraphRequiredField::PACKAGE,
- BinaryParagraphRequiredField::VERSION,
- BinaryParagraphRequiredField::ARCHITECTURE,
-
- BinaryParagraphOptionalField::DESCRIPTION,
- BinaryParagraphOptionalField::MAINTAINER,
- BinaryParagraphOptionalField::DEPENDS
- };
-
- return valid_fields;
- }
-
BinaryParagraph::BinaryParagraph() = default;
BinaryParagraph::BinaryParagraph(std::unordered_map<std::string, std::string> fields)
diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp
index 90bd55843..c4ddbc62e 100644
--- a/toolsrc/src/PostBuildLint.cpp
+++ b/toolsrc/src/PostBuildLint.cpp
@@ -22,7 +22,8 @@ namespace vcpkg::PostBuildLint
std::regex regex;
OutdatedDynamicCrt(const std::string& name, const std::string& regex_as_string)
- : name(name), regex(std::regex(regex_as_string, std::regex_constants::icase)) {}
+ : name(name),
+ regex(std::regex(regex_as_string, std::regex_constants::icase)) {}
};
const std::vector<OutdatedDynamicCrt>& get_outdated_dynamic_crts()
@@ -424,24 +425,6 @@ namespace vcpkg::PostBuildLint
return lint_status::SUCCESS;
}
- static lint_status check_no_subdirectories(const fs::path& dir)
- {
- const std::vector<fs::path> subdirectories = Files::recursive_find_matching_paths_in_dir(dir, [&](const fs::path& current)
- {
- return fs::is_directory(current);
- });
-
- if (!subdirectories.empty())
- {
- System::println(System::color::warning, "Directory %s should have no subdirectories", dir.generic_string());
- System::println("The following subdirectories were found: ");
- Files::print_paths(subdirectories);
- return lint_status::ERROR_DETECTED;
- }
-
- return lint_status::SUCCESS;
- }
-
static lint_status check_bin_folders_are_not_present_in_static_build(const fs::path& package_dir)
{
const fs::path bin = package_dir / "bin";
@@ -486,7 +469,7 @@ namespace vcpkg::PostBuildLint
System::println("The following empty directories were found: ");
Files::print_paths(empty_directories);
System::println(System::color::warning, "If a directory should be populated but is not, this might indicate an error in the portfile.\n"
- "If the directories are not needed and their creation cannot be disabled, use something like this in the portfile to remove them)\n"
+ "If the directories are not needed and their creation cannot be disabled, use something like this in the portfile to remove them:\n"
"\n"
R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/a/dir ${CURRENT_PACKAGES_DIR}/some/other/dir))###""\n"
"\n");
@@ -499,12 +482,12 @@ namespace vcpkg::PostBuildLint
struct BuildType_and_file
{
fs::path file;
- BuildType build_type;
+ BuildType::type build_type;
};
- static lint_status check_crt_linkage_of_libs(const BuildType& expected_build_type, const std::vector<fs::path>& libs, const fs::path dumpbin_exe)
+ static lint_status check_crt_linkage_of_libs(const BuildType::type& expected_build_type, const std::vector<fs::path>& libs, const fs::path dumpbin_exe)
{
- std::vector<BuildType> bad_build_types = BuildType::values();
+ std::vector<BuildType::type> bad_build_types(BuildType::values.cbegin(), BuildType::values.cend());
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;
@@ -515,7 +498,7 @@ namespace vcpkg::PostBuildLint
System::exit_code_and_output ec_data = System::cmd_execute_and_capture_output(cmd_line);
Checks::check_exit(ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::utf16_to_utf8(cmd_line));
- for (const BuildType& bad_build_type : bad_build_types)
+ for (const BuildType::type& bad_build_type : bad_build_types)
{
if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), bad_build_type.crt_regex()))
{
@@ -546,6 +529,8 @@ namespace vcpkg::PostBuildLint
{
fs::path file;
OutdatedDynamicCrt outdated_crt;
+
+ OutdatedDynamicCrt_and_file() = delete;
};
static lint_status check_outdated_crt_linkage_of_dlls(const std::vector<fs::path>& dlls, const fs::path dumpbin_exe)
@@ -616,6 +601,7 @@ namespace vcpkg::PostBuildLint
left += static_cast<size_t>(right);
}
+
static size_t perform_all_checks_and_return_error_count(const package_spec& spec, const vcpkg_paths& paths)
{
const fs::path dumpbin_exe = Environment::get_dumpbin_exe(paths);
@@ -657,9 +643,9 @@ namespace vcpkg::PostBuildLint
error_count += check_lib_architecture(spec.target_triplet().architecture(), libs);
- switch (linkage_type_value_of(build_info.library_linkage))
+ switch (build_info.library_linkage)
{
- case LinkageType::DYNAMIC:
+ case LinkageType::backing_enum_t::DYNAMIC:
{
const std::vector<fs::path> debug_dlls = Files::recursive_find_files_with_extension_in_dir(debug_bin_dir, ".dll");
const std::vector<fs::path> release_dlls = Files::recursive_find_files_with_extension_in_dir(release_bin_dir, ".dll");
@@ -680,7 +666,7 @@ namespace vcpkg::PostBuildLint
error_count += check_outdated_crt_linkage_of_dlls(dlls, dumpbin_exe);
break;
}
- case LinkageType::STATIC:
+ case LinkageType::backing_enum_t::STATIC:
{
std::vector<fs::path> dlls;
Files::recursive_find_files_with_extension_in_dir(package_dir, ".dll", &dlls);
@@ -688,23 +674,14 @@ namespace vcpkg::PostBuildLint
error_count += check_bin_folders_are_not_present_in_static_build(package_dir);
- error_count += check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, linkage_type_value_of(build_info.crt_linkage)), debug_libs, dumpbin_exe);
- error_count += check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, linkage_type_value_of(build_info.crt_linkage)), release_libs, dumpbin_exe);
- break;
- }
- case LinkageType::UNKNOWN:
- {
- error_count += 1;
- System::println(System::color::warning, "Unknown library_linkage architecture: [ %s ]", build_info.library_linkage);
+ error_count += check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), debug_libs, dumpbin_exe);
+ error_count += check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), release_libs, dumpbin_exe);
break;
}
+ case LinkageType::backing_enum_t::NULLVALUE:
default:
Checks::unreachable();
}
-#if 0
- error_count += check_no_subdirectories(package_dir / "lib");
- error_count += check_no_subdirectories(package_dir / "debug" / "lib");
-#endif
error_count += check_no_empty_folders(package_dir);
error_count += check_no_files_in_package_dir_and_debug_dir(package_dir);
@@ -712,19 +689,18 @@ namespace vcpkg::PostBuildLint
return error_count;
}
- void perform_all_checks(const package_spec& spec, const vcpkg_paths& paths)
+ size_t perform_all_checks(const package_spec& spec, const vcpkg_paths& paths)
{
System::println("-- Performing post-build validation");
-
const size_t error_count = perform_all_checks_and_return_error_count(spec, paths);
+ System::println("-- Performing post-build validation done");
if (error_count != 0)
{
const fs::path portfile = paths.ports / spec.name() / "portfile.cmake";
System::println(System::color::error, "Found %u error(s). Please correct the portfile:\n %s", error_count, portfile.string());
- exit(EXIT_FAILURE);
}
- System::println("-- Performing post-build validation done");
+ return error_count;
}
}
diff --git a/toolsrc/src/PostBuildLint_BuildInfo.cpp b/toolsrc/src/PostBuildLint_BuildInfo.cpp
index 63107acd1..7308c9bac 100644
--- a/toolsrc/src/PostBuildLint_BuildInfo.cpp
+++ b/toolsrc/src/PostBuildLint_BuildInfo.cpp
@@ -16,14 +16,19 @@ namespace vcpkg::PostBuildLint
BuildInfo BuildInfo::create(std::unordered_map<std::string, std::string> pgh)
{
BuildInfo build_info;
- build_info.crt_linkage = details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE);
- build_info.library_linkage = details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE);
+ const std::string crt_linkage_as_string = details::remove_required_field(&pgh, BuildInfoRequiredField::CRT_LINKAGE);
+ build_info.crt_linkage = LinkageType::value_of(crt_linkage_as_string);
+ Checks::check_exit(build_info.crt_linkage != LinkageType::NULLVALUE, "Invalid crt linkage type: [%s]", crt_linkage_as_string);
+
+ const std::string library_linkage_as_string = details::remove_required_field(&pgh, BuildInfoRequiredField::LIBRARY_LINKAGE);
+ build_info.library_linkage = LinkageType::value_of(library_linkage_as_string);
+ Checks::check_exit(build_info.library_linkage != LinkageType::NULLVALUE, "Invalid library linkage type: [%s]", library_linkage_as_string);
// The remaining entries are policies
for (const std::unordered_map<std::string, std::string>::value_type& p : pgh)
{
const BuildPolicies::type policy = BuildPolicies::parse(p.first);
- Checks::check_exit(policy != BuildPolicies::UNKNOWN, "Unknown policy found: %s", p.first);
+ Checks::check_exit(policy != BuildPolicies::NULLVALUE, "Unknown policy found: %s", p.first);
const opt_bool_t status = opt_bool::parse(p.second);
build_info.policies.emplace(policy, status);
}
diff --git a/toolsrc/src/PostBuildLint_BuildPolicies.cpp b/toolsrc/src/PostBuildLint_BuildPolicies.cpp
index 4e5ac3cea..53dfcf95a 100644
--- a/toolsrc/src/PostBuildLint_BuildPolicies.cpp
+++ b/toolsrc/src/PostBuildLint_BuildPolicies.cpp
@@ -1,10 +1,11 @@
#include "pch.h"
#include "PostBuildLint_BuildPolicies.h"
-#include "vcpkg_Checks.h"
+#include "vcpkg_Enums.h"
namespace vcpkg::PostBuildLint::BuildPolicies
{
- static const std::string NAME_UNKNOWN = "PolicyUnknown";
+ static const std::string NULLVALUE_STRING = Enums::nullvalue_toString(ENUM_NAME);
+
static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage";
static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs";
@@ -16,10 +17,10 @@ namespace vcpkg::PostBuildLint::BuildPolicies
return NAME_EMPTY_PACKAGE;
case DLLS_WITHOUT_LIBS:
return NAME_DLLS_WITHOUT_LIBS;
- case UNKNOWN:
- return NAME_UNKNOWN;
+ case NULLVALUE:
+ return NULLVALUE_STRING;
default:
- Checks::unreachable();
+ Enums::unreachable(ENUM_NAME);
}
}
@@ -34,21 +35,13 @@ namespace vcpkg::PostBuildLint::BuildPolicies
return CMAKE_VARIABLE_EMPTY_PACKAGE;
case DLLS_WITHOUT_LIBS:
return CMAKE_VARIABLE_DLLS_WITHOUT_LIBS;
- case UNKNOWN:
- Checks::exit_with_message("No CMake command corresponds to UNKNOWN");
+ case NULLVALUE:
+ Enums::nullvalue_used(ENUM_NAME);
default:
- Checks::unreachable();
+ Enums::unreachable(ENUM_NAME);
}
}
- type::type(): backing_enum(backing_enum_t::UNKNOWN) {}
-
- const std::vector<type>& values()
- {
- static const std::vector<type>& v = {UNKNOWN, EMPTY_PACKAGE, DLLS_WITHOUT_LIBS};
- return v;
- }
-
type parse(const std::string& s)
{
if (s == NAME_EMPTY_PACKAGE)
@@ -61,6 +54,6 @@ namespace vcpkg::PostBuildLint::BuildPolicies
return BuildPolicies::DLLS_WITHOUT_LIBS;
}
- return BuildPolicies::UNKNOWN;
+ return BuildPolicies::NULLVALUE;
}
}
diff --git a/toolsrc/src/PostBuildLint_BuildType.cpp b/toolsrc/src/PostBuildLint_BuildType.cpp
index b4e199aee..f2fb292d7 100644
--- a/toolsrc/src/PostBuildLint_BuildType.cpp
+++ b/toolsrc/src/PostBuildLint_BuildType.cpp
@@ -1,15 +1,10 @@
#include "pch.h"
#include "PostBuildLint_BuildType.h"
-#include "vcpkg_Checks.h"
+#include "vcpkg_Enums.h"
-namespace vcpkg::PostBuildLint
+namespace vcpkg::PostBuildLint::BuildType
{
- const BuildType BuildType::DEBUG_STATIC = BuildType(ConfigurationType::DEBUG, LinkageType::STATIC, R"(/DEFAULTLIB:LIBCMTD)");
- const BuildType BuildType::DEBUG_DYNAMIC = BuildType(ConfigurationType::DEBUG, LinkageType::DYNAMIC, R"(/DEFAULTLIB:MSVCRTD)");
- const BuildType BuildType::RELEASE_STATIC = BuildType(ConfigurationType::RELEASE, LinkageType::STATIC, R"(/DEFAULTLIB:LIBCMT[^D])");
- const BuildType BuildType::RELEASE_DYNAMIC = BuildType(ConfigurationType::RELEASE, LinkageType::DYNAMIC, R"(/DEFAULTLIB:MSVCRT[^D])");
-
- BuildType BuildType::value_of(const ConfigurationType& config, const LinkageType& linkage)
+ type value_of(const ConfigurationType::type& config, const LinkageType::type& linkage)
{
if (config == ConfigurationType::DEBUG && linkage == LinkageType::STATIC)
{
@@ -31,38 +26,60 @@ namespace vcpkg::PostBuildLint
return RELEASE_DYNAMIC;
}
- Checks::unreachable();
+ Enums::unreachable(ENUM_NAME);
}
- const ConfigurationType& BuildType::config() const
+ const ConfigurationType::type& type::config() const
{
return this->m_config;
}
- const LinkageType& BuildType::linkage() const
+ const LinkageType::type& type::linkage() const
{
return this->m_linkage;
}
- std::regex BuildType::crt_regex() const
+ const std::regex& type::crt_regex() const
{
- const std::regex r(this->m_crt_regex_as_string, std::regex_constants::icase);
- return r;
- }
+ static const std::regex REGEX_DEBUG_STATIC(R"(/DEFAULTLIB:LIBCMTD)", std::regex_constants::icase);
+ static const std::regex REGEX_DEBUG_DYNAMIC(R"(/DEFAULTLIB:MSVCRTD)", std::regex_constants::icase);
+ static const std::regex REGEX_RELEASE_STATIC(R"(/DEFAULTLIB:LIBCMT[^D])", std::regex_constants::icase);
+ static const std::regex REGEX_RELEASE_DYNAMIC(R"(/DEFAULTLIB:MSVCRT[^D])", std::regex_constants::icase);
- std::string BuildType::toString() const
- {
- const std::string s = Strings::format("[%s,%s]", to_string(this->m_config), to_string(this->m_linkage));
- return s;
+ switch (backing_enum)
+ {
+ case BuildType::DEBUG_STATIC:
+ return REGEX_DEBUG_STATIC;
+ case BuildType::DEBUG_DYNAMIC:
+ return REGEX_DEBUG_DYNAMIC;
+ case BuildType::RELEASE_STATIC:
+ return REGEX_RELEASE_STATIC;
+ case BuildType::RELEASE_DYNAMIC:
+ return REGEX_RELEASE_DYNAMIC;
+ default:
+ Enums::unreachable(ENUM_NAME);
+ }
}
- bool operator==(const BuildType& lhs, const BuildType& rhs)
+ const std::string& type::toString() const
{
- return lhs.config() == rhs.config() && lhs.linkage() == rhs.linkage();
- }
+ static const std::string NAME_DEBUG_STATIC("Debug,Static");
+ static const std::string NAME_DEBUG_DYNAMIC("Debug,Dynamic");
+ static const std::string NAME_RELEASE_STATIC("Release,Static");
+ static const std::string NAME_RELEASE_DYNAMIC("Release,Dynamic");
- bool operator!=(const BuildType& lhs, const BuildType& rhs)
- {
- return !(lhs == rhs);
+ switch (backing_enum)
+ {
+ case BuildType::DEBUG_STATIC:
+ return NAME_DEBUG_STATIC;
+ case BuildType::DEBUG_DYNAMIC:
+ return NAME_DEBUG_DYNAMIC;
+ case BuildType::RELEASE_STATIC:
+ return NAME_RELEASE_STATIC;
+ case BuildType::RELEASE_DYNAMIC:
+ return NAME_RELEASE_DYNAMIC;
+ default:
+ Enums::unreachable(ENUM_NAME);
+ }
}
}
diff --git a/toolsrc/src/PostBuildLint_ConfigurationType.cpp b/toolsrc/src/PostBuildLint_ConfigurationType.cpp
index 9c3499cac..990b10a37 100644
--- a/toolsrc/src/PostBuildLint_ConfigurationType.cpp
+++ b/toolsrc/src/PostBuildLint_ConfigurationType.cpp
@@ -1,19 +1,26 @@
#include "pch.h"
#include "PostBuildLint_ConfigurationType.h"
-#include "vcpkg_Checks.h"
+#include "vcpkg_Enums.h"
-namespace vcpkg::PostBuildLint
+namespace vcpkg::PostBuildLint::ConfigurationType
{
- std::string to_string(const ConfigurationType& conf)
+ static const std::string NULLVALUE_STRING = Enums::nullvalue_toString(ENUM_NAME);
+
+ static const std::string NAME_DEBUG = "Debug";
+ static const std::string NAME_RELEASE = "Release";
+
+ const std::string& type::toString() const
{
- switch (conf)
+ switch (this->backing_enum)
{
- case ConfigurationType::DEBUG:
- return "Debug";
- case ConfigurationType::RELEASE:
- return "Release";
- default:
- Checks::unreachable();
+ case ConfigurationType::DEBUG:
+ return NAME_DEBUG;
+ case ConfigurationType::RELEASE:
+ return NAME_RELEASE;
+ case ConfigurationType::NULLVALUE:
+ return NULLVALUE_STRING;
+ default:
+ Enums::unreachable(ENUM_NAME);
}
}
}
diff --git a/toolsrc/src/PostBuildLint_LinkageType.cpp b/toolsrc/src/PostBuildLint_LinkageType.cpp
index 8a3f35be8..6d2c2c935 100644
--- a/toolsrc/src/PostBuildLint_LinkageType.cpp
+++ b/toolsrc/src/PostBuildLint_LinkageType.cpp
@@ -1,34 +1,41 @@
#include "pch.h"
#include "PostBuildLint_LinkageType.h"
-#include "vcpkg_Checks.h"
+#include "vcpkg_Enums.h"
-namespace vcpkg::PostBuildLint
+namespace vcpkg::PostBuildLint::LinkageType
{
- LinkageType linkage_type_value_of(const std::string& as_string)
+ static const std::string NULLVALUE_STRING = Enums::nullvalue_toString(ENUM_NAME);
+
+ static const std::string NAME_DYNAMIC = "dynamic";
+ static const std::string NAME_STATIC = "static";
+
+ const std::string& type::toString() const
{
- if (as_string == "dynamic")
+ switch (this->backing_enum)
{
- return LinkageType::DYNAMIC;
+ case LinkageType::DYNAMIC:
+ return NAME_DYNAMIC;
+ case LinkageType::STATIC:
+ return NAME_STATIC;
+ case LinkageType::NULLVALUE:
+ return NULLVALUE_STRING;
+ default:
+ Enums::unreachable(ENUM_NAME);
}
+ }
- if (as_string == "static")
+ type value_of(const std::string& as_string)
+ {
+ if (as_string == NAME_DYNAMIC)
{
- return LinkageType::STATIC;
+ return LinkageType::DYNAMIC;
}
- return LinkageType::UNKNOWN;
- }
-
- std::string to_string(const LinkageType& build_info)
- {
- switch (build_info)
+ if (as_string == NAME_STATIC)
{
- case LinkageType::STATIC:
- return "static";
- case LinkageType::DYNAMIC:
- return "dynamic";
- default:
- Checks::unreachable();
+ return LinkageType::STATIC;
}
+
+ return LinkageType::NULLVALUE;
}
}
diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp
index c2398d2b8..48bc0b062 100644
--- a/toolsrc/src/StatusParagraphs.cpp
+++ b/toolsrc/src/StatusParagraphs.cpp
@@ -29,9 +29,9 @@ namespace vcpkg
});
}
- StatusParagraphs::iterator StatusParagraphs::find_installed(const std::string& name, const triplet& target_triplet)
+ StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, const triplet& target_triplet) const
{
- auto it = find(name, target_triplet);
+ const const_iterator it = find(name, target_triplet);
if (it != end() && (*it)->want == want_t::install)
{
return it;
diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/commands_available_commands.cpp
index 56056218b..4c7e0df2c 100644
--- a/toolsrc/src/commands_available_commands.cpp
+++ b/toolsrc/src/commands_available_commands.cpp
@@ -7,6 +7,7 @@ namespace vcpkg::Commands
{
static std::vector<package_name_and_function<command_type_a>> t = {
{"install", &Install::perform_and_exit},
+ { "ci", &CI::perform_and_exit },
{"remove", &Remove::perform_and_exit},
{"build", &Build::perform_and_exit},
{"build_external", &BuildExternal::perform_and_exit}
diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp
index 743be216a..ec4124922 100644
--- a/toolsrc/src/commands_build.cpp
+++ b/toolsrc/src/commands_build.cpp
@@ -8,7 +8,7 @@
#include "vcpkg_System.h"
#include "vcpkg_Environment.h"
#include "metrics.h"
-#include "vcpkg_info.h"
+#include "vcpkg_Enums.h"
namespace vcpkg::Commands::Build
{
@@ -24,10 +24,18 @@ namespace vcpkg::Commands::Build
std::ofstream(binary_control_file) << bpgh;
}
- void build_package(const SourceParagraph& source_paragraph, const package_spec& spec, const vcpkg_paths& paths, const fs::path& port_dir)
+ BuildResult build_package(const SourceParagraph& source_paragraph, const package_spec& spec, const vcpkg_paths& paths, const fs::path& port_dir, const StatusParagraphs& status_db)
{
- Checks::check_exit(spec.name() == source_paragraph.name, "inconsistent arguments to build_internal()");
+ Checks::check_exit(spec.name() == source_paragraph.name, "inconsistent arguments to build_package()");
+
const triplet& target_triplet = spec.target_triplet();
+ for (auto&& dep : source_paragraph.depends)
+ {
+ if (status_db.find_installed(dep.name, target_triplet) == status_db.end())
+ {
+ return BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES;
+ }
+ }
const fs::path ports_cmake_script_path = paths.ports_cmake;
const Environment::vcvarsall_and_platform_toolset vcvarsall_bat = Environment::get_vcvarsall_bat(paths);
@@ -48,71 +56,91 @@ namespace vcpkg::Commands::Build
if (return_code != 0)
{
- System::println(System::color::error, "Error: building package %s failed", spec.toString());
- System::println("Please ensure sure you're using the latest portfiles with `.\\vcpkg update`, then\n"
- "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n"
- " Package: %s\n"
- " Vcpkg version: %s\n"
- "\n"
- "Additionally, attach any relevant sections from the log files above."
- , spec.toString(), Info::version());
TrackProperty("error", "build failed");
TrackProperty("build_error", spec.toString());
- exit(EXIT_FAILURE);
+ return BuildResult::BUILD_FAILED;
}
- PostBuildLint::perform_all_checks(spec, paths);
+ const size_t error_count = PostBuildLint::perform_all_checks(spec, paths);
+
+ if (error_count != 0)
+ {
+ return BuildResult::POST_BUILD_CHECKS_FAILED;
+ }
create_binary_control_file(paths, source_paragraph, target_triplet);
// const fs::path port_buildtrees_dir = paths.buildtrees / spec.name;
// delete_directory(port_buildtrees_dir);
+
+ return BuildResult::SUCCEEDED;
}
- void perform_and_exit(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet)
+ const std::string& to_string(const BuildResult build_result)
{
- static const std::string example = Commands::Help::create_example_string("build zlib:x64-windows");
+ static const std::string NULLVALUE_STRING = Enums::nullvalue_toString("vcpkg::Commands::Build::BuildResult");
+ static const std::string SUCCEEDED_STRING = "SUCCEEDED";
+ static const std::string BUILD_FAILED_STRING = "BUILD_FAILED";
+ static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED";
+ static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES";
- // Installing multiple packages leads to unintuitive behavior if one of them depends on another.
- // Allowing only 1 package for now.
-
- args.check_exact_arg_count(1, example);
+ switch (build_result)
+ {
+ case BuildResult::NULLVALUE: return NULLVALUE_STRING;
+ case BuildResult::SUCCEEDED: return SUCCEEDED_STRING;
+ case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING;
+ case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING;
+ case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING;
+ default: Checks::unreachable();
+ }
+ }
- StatusParagraphs status_db = database_load_check(paths);
+ std::string create_error_message(const BuildResult build_result, const package_spec& spec)
+ {
+ return Strings::format("Error: Building package %s failed with: %s", spec.toString(), Build::to_string(build_result));
+ }
- const package_spec spec = Input::check_and_get_package_spec(args.command_arguments.at(0), default_target_triplet, example);
- Input::check_triplet(spec.target_triplet(), paths);
+ std::string create_user_troubleshooting_message(const package_spec& spec)
+ {
+ return Strings::format("Please ensure sure you're using the latest portfiles with `.\\vcpkg update`, then\n"
+ "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n"
+ " Package: %s\n"
+ " Vcpkg version: %s\n"
+ "\n"
+ "Additionally, attach any relevant sections from the log files above."
+ , spec.toString(), Version::version());
+ }
- const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY});
+ void perform_and_exit(const package_spec& spec, const fs::path& port_dir, const std::unordered_set<std::string>& options, const vcpkg_paths& paths)
+ {
if (options.find(OPTION_CHECKS_ONLY) != options.end())
{
- PostBuildLint::perform_all_checks(spec, paths);
+ const size_t error_count = PostBuildLint::perform_all_checks(spec, paths);
+ if (error_count > 0)
+ {
+ exit(EXIT_FAILURE);
+ }
exit(EXIT_SUCCESS);
}
- // Explicitly load and use the portfile's build dependencies when resolving the build command (instead of a cached package's dependencies).
- const expected<SourceParagraph> maybe_spgh = try_load_port(paths, spec.name());
+ const expected<SourceParagraph> maybe_spgh = try_load_port(port_dir);
Checks::check_exit(!maybe_spgh.error_code(), "Could not find package named %s: %s", spec, maybe_spgh.error_code().message());
const SourceParagraph& spgh = *maybe_spgh.get();
- const std::vector<std::string> first_level_deps = filter_dependencies(spgh.depends, spec.target_triplet());
-
- std::vector<package_spec> first_level_deps_specs;
- for (const std::string& dep : first_level_deps)
- {
- first_level_deps_specs.push_back(package_spec::from_name_and_triplet(dep, spec.target_triplet()).get_or_throw());
- }
-
- std::vector<package_spec_with_install_plan> unmet_dependencies = Dependencies::create_install_plan(paths, first_level_deps_specs, status_db);
- unmet_dependencies.erase(
- std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [](const package_spec_with_install_plan& p)
- {
- return p.plan.plan_type == install_plan_type::ALREADY_INSTALLED;
- }),
- unmet_dependencies.end());
-
- if (!unmet_dependencies.empty())
+ Environment::ensure_utilities_on_path(paths);
+ StatusParagraphs status_db = database_load_check(paths);
+ const BuildResult result = build_package(spgh, spec, paths, paths.port_dir(spec), status_db);
+ if (result == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES)
{
+ std::vector<package_spec_with_install_plan> unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db);
+ unmet_dependencies.erase(
+ std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [&spec](const package_spec_with_install_plan& p)
+ {
+ return (p.spec == spec) || (p.plan.plan_type == install_plan_type::ALREADY_INSTALLED);
+ }),
+ unmet_dependencies.end());
+
+ Checks::check_exit(!unmet_dependencies.empty());
System::println(System::color::error, "The build command requires all dependencies to be already installed.");
System::println("The following dependencies are missing:");
System::println("");
@@ -124,8 +152,23 @@ namespace vcpkg::Commands::Build
exit(EXIT_FAILURE);
}
- Environment::ensure_utilities_on_path(paths);
- build_package(spgh, spec, paths, paths.port_dir(spec));
+ if (result != BuildResult::SUCCEEDED)
+ {
+ System::println(System::color::error, Build::create_error_message(result, spec));
+ System::println(Build::create_user_troubleshooting_message(spec));
+ exit(EXIT_FAILURE);
+ }
+
exit(EXIT_SUCCESS);
}
+
+ void perform_and_exit(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_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 package_spec spec = Input::check_and_get_package_spec(args.command_arguments.at(0), default_target_triplet, example);
+ Input::check_triplet(spec.target_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), options, paths);
+ }
}
diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/commands_build_external.cpp
index 5c3fa9857..06bd1374c 100644
--- a/toolsrc/src/commands_build_external.cpp
+++ b/toolsrc/src/commands_build_external.cpp
@@ -3,7 +3,6 @@
#include "vcpkg_System.h"
#include "vcpkg_Environment.h"
#include "vcpkg_Input.h"
-#include "vcpkglib.h"
namespace vcpkg::Commands::BuildExternal
{
@@ -11,23 +10,11 @@ namespace vcpkg::Commands::BuildExternal
{
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);
+ const package_spec spec = Input::check_and_get_package_spec(args.command_arguments.at(0), default_target_triplet, example);
+ Input::check_triplet(spec.target_triplet(), paths);
+ const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({});
- expected<package_spec> maybe_current_spec = package_spec::from_string(args.command_arguments[0], default_target_triplet);
- if (auto spec = maybe_current_spec.get())
- {
- Input::check_triplet(spec->target_triplet(), paths);
- Environment::ensure_utilities_on_path(paths);
- const fs::path port_dir = args.command_arguments.at(1);
- const expected<SourceParagraph> maybe_spgh = try_load_port(port_dir);
- if (auto spgh = maybe_spgh.get())
- {
- Commands::Build::build_package(*spgh, *spec, paths, port_dir);
- exit(EXIT_SUCCESS);
- }
- }
-
- System::println(System::color::error, "Error: %s: %s", maybe_current_spec.error_code().message(), args.command_arguments[0]);
- Commands::Help::print_example(Strings::format("%s zlib:x64-windows", args.command));
- exit(EXIT_FAILURE);
+ const fs::path port_dir = args.command_arguments.at(1);
+ Build::perform_and_exit(spec, port_dir, options, paths);
}
}
diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/commands_cache.cpp
index fa49a647f..e255b5dff 100644
--- a/toolsrc/src/commands_cache.cpp
+++ b/toolsrc/src/commands_cache.cpp
@@ -40,6 +40,7 @@ namespace vcpkg::Commands::Cache
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);
+ args.check_and_get_optional_command_arguments({});
const std::vector<BinaryParagraph> binary_paragraphs = read_all_binary_paragraphs(paths);
if (binary_paragraphs.empty())
diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp
new file mode 100644
index 000000000..db37db123
--- /dev/null
+++ b/toolsrc/src/commands_ci.cpp
@@ -0,0 +1,124 @@
+#include "pch.h"
+#include "vcpkg_Commands.h"
+#include "vcpkglib.h"
+#include "vcpkg_Environment.h"
+#include "vcpkg_Files.h"
+#include "vcpkg_System.h"
+#include "vcpkg_Dependencies.h"
+#include "vcpkg_Input.h"
+#include "vcpkg_Chrono.h"
+
+namespace vcpkg::Commands::CI
+{
+ using Dependencies::package_spec_with_install_plan;
+ using Dependencies::install_plan_type;
+ using Build::BuildResult;
+
+ static std::vector<package_spec> load_all_package_specs(const fs::path& directory, const triplet& target_triplet)
+ {
+ std::vector<fs::path> port_folders;
+ Files::non_recursive_find_matching_paths_in_dir(directory, [](const fs::path& current)
+ {
+ return fs::is_directory(current);
+ }, &port_folders);
+
+ std::vector<package_spec> specs;
+ for (const fs::path& p : port_folders)
+ {
+ specs.push_back(package_spec::from_name_and_triplet(p.filename().generic_string(), target_triplet).get_or_throw());
+ }
+
+ return specs;
+ }
+
+ void perform_and_exit(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths, const triplet& default_target_triplet)
+ {
+ static const std::string example = Commands::Help::create_example_string("ci x64-windows");
+ args.check_max_arg_count(1, example);
+ const triplet target_triplet = args.command_arguments.size() == 1 ? triplet::from_canonical_name(args.command_arguments.at(0)) : default_target_triplet;
+ Input::check_triplet(target_triplet, paths);
+ args.check_and_get_optional_command_arguments({});
+ const std::vector<package_spec> specs = load_all_package_specs(paths.ports, target_triplet);
+
+ StatusParagraphs status_db = database_load_check(paths);
+ const std::vector<package_spec_with_install_plan> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
+ Checks::check_exit(!install_plan.empty(), "Install plan cannot be empty");
+
+ Environment::ensure_utilities_on_path(paths);
+
+ std::vector<BuildResult> results;
+ const ElapsedTime timer = ElapsedTime::createStarted();
+ size_t counter = 0;
+ const size_t package_count = install_plan.size();
+ for (const package_spec_with_install_plan& action : install_plan)
+ {
+ counter++;
+ System::println("Starting package %d/%d: %s. Time Elapsed: %s", counter, package_count, action.spec.toString(), timer.toString());
+ try
+ {
+ if (action.plan.plan_type == install_plan_type::ALREADY_INSTALLED)
+ {
+ results.push_back(BuildResult::SUCCEEDED);
+ System::println(System::color::success, "Package %s is already installed", action.spec);
+ }
+ else if (action.plan.plan_type == install_plan_type::BUILD_AND_INSTALL)
+ {
+ const BuildResult result = Commands::Build::build_package(*action.plan.source_pgh, action.spec, paths, paths.port_dir(action.spec), status_db);
+ results.push_back(result);
+ if (result != BuildResult::SUCCEEDED)
+ {
+ System::println(System::color::error, Build::create_error_message(result, action.spec));
+ continue;
+ }
+ const BinaryParagraph bpgh = try_load_cached_package(paths, action.spec).get_or_throw();
+ Install::install_package(paths, bpgh, &status_db);
+ System::println(System::color::success, "Package %s is installed", action.spec);
+ }
+ else if (action.plan.plan_type == install_plan_type::INSTALL)
+ {
+ results.push_back(BuildResult::SUCCEEDED);
+ Install::install_package(paths, *action.plan.binary_pgh, &status_db);
+ System::println(System::color::success, "Package %s is installed", action.spec);
+ }
+ else
+ Checks::unreachable();
+ }
+ catch (const std::exception& e)
+ {
+ System::println(System::color::error, "Error: Could not install package %s: %s", action.spec, e.what());
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ System::println(timer.toString());
+
+ for (size_t i = 0; i < results.size(); i++)
+ {
+ if (results[i] == BuildResult::SUCCEEDED)
+ {
+ continue;
+ }
+
+ System::println("%s: %s", install_plan[i].spec.toString(), Build::to_string(results[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);
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+}
diff --git a/toolsrc/src/commands_contact.cpp b/toolsrc/src/commands_contact.cpp
index 2be468fb8..29f0d4d27 100644
--- a/toolsrc/src/commands_contact.cpp
+++ b/toolsrc/src/commands_contact.cpp
@@ -1,14 +1,21 @@
#include "pch.h"
#include "vcpkg_Commands.h"
#include "vcpkg_System.h"
-#include "vcpkg_info.h"
namespace vcpkg::Commands::Contact
{
- void perform_and_exit(const vcpkg_cmd_arguments& args)
+ const std::string& email()
+ {
+ static const std::string s_email = R"(vcpkg@microsoft.com)";
+ return s_email;
+ }
+
+ void perform_and_exit(const vcpkg_cmd_arguments& args)
{
args.check_exact_arg_count(0);
- System::println("Send an email to %s with any feedback.", Info::email());
+ args.check_and_get_optional_command_arguments({});
+
+ System::println("Send an email to %s with any feedback.", email());
exit(EXIT_SUCCESS);
}
}
diff --git a/toolsrc/src/commands_create.cpp b/toolsrc/src/commands_create.cpp
index 5042ab97b..494c2aa08 100644
--- a/toolsrc/src/commands_create.cpp
+++ b/toolsrc/src/commands_create.cpp
@@ -12,8 +12,9 @@ namespace vcpkg::Commands::Create
static const std::string example = Commands::Help::create_example_string(R"###(create zlib2 http://zlib.net/zlib128.zip "zlib128-2.zip")###");
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);
+
Environment::ensure_utilities_on_path(paths);
// Space OR define the FILENAME with proper spacing
diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp
index dff30f7ad..5a2433e5a 100644
--- a/toolsrc/src/commands_edit.cpp
+++ b/toolsrc/src/commands_edit.cpp
@@ -2,6 +2,7 @@
#include "vcpkg_Commands.h"
#include "vcpkg_System.h"
#include "vcpkg_Input.h"
+#include "vcpkg_Environment.h"
namespace vcpkg::Commands::Edit
{
@@ -9,16 +10,23 @@ namespace vcpkg::Commands::Edit
{
static const std::string example = Commands::Help::create_example_string("edit zlib");
args.check_exact_arg_count(1, example);
+ args.check_and_get_optional_command_arguments({});
const std::string port_name = args.command_arguments.at(0);
const fs::path portpath = paths.ports / port_name;
Checks::check_exit(fs::is_directory(portpath), R"(Could not find port named "%s")", port_name);
// Find editor
- std::wstring env_EDITOR = System::wdupenv_str(L"EDITOR");
- if (env_EDITOR.empty())
+ const optional<std::wstring> env_EDITOR_optional = System::get_environmental_variable(L"EDITOR");
+ std::wstring env_EDITOR;
+
+ if (env_EDITOR_optional)
+ {
+ env_EDITOR = *env_EDITOR_optional;
+ }
+ else
{
- static const std::wstring CODE_EXE_PATH = LR"(C:\Program Files (x86)\Microsoft VS Code\Code.exe)";
+ static const fs::path CODE_EXE_PATH = Environment::get_ProgramFiles_32_bit() / "Microsoft VS Code/Code.exe";
if (fs::exists(CODE_EXE_PATH))
{
env_EDITOR = CODE_EXE_PATH;
diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp
index 4c0028f53..805da4153 100644
--- a/toolsrc/src/commands_hash.cpp
+++ b/toolsrc/src/commands_hash.cpp
@@ -30,6 +30,7 @@ namespace vcpkg::Commands::Hash
"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)
{
diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/commands_help.cpp
index 6068c22fb..49b5697c3 100644
--- a/toolsrc/src/commands_help.cpp
+++ b/toolsrc/src/commands_help.cpp
@@ -67,6 +67,8 @@ namespace vcpkg::Commands::Help
void perform_and_exit(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths)
{
args.check_max_arg_count(1);
+ args.check_and_get_optional_command_arguments({});
+
if (args.command_arguments.empty())
{
print_usage();
diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp
index 7af2c7185..4b71fc290 100644
--- a/toolsrc/src/commands_import.cpp
+++ b/toolsrc/src/commands_import.cpp
@@ -79,6 +79,7 @@ namespace vcpkg::Commands::Import
{
static const std::string example = Commands::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_and_get_optional_command_arguments({});
const fs::path control_file_path(args.command_arguments[0]);
const fs::path include_directory(args.command_arguments[1]);
diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp
index 1f5a2234d..4ae311f83 100644
--- a/toolsrc/src/commands_install.cpp
+++ b/toolsrc/src/commands_install.cpp
@@ -24,7 +24,7 @@ namespace vcpkg::Commands::Install
const std::string& target_triplet_as_string = target_triplet.canonical_name();
std::error_code ec;
fs::create_directory(paths.installed / target_triplet_as_string, ec);
- output.push_back(Strings::format(R"(%s)", target_triplet_as_string));
+ output.push_back(Strings::format(R"(%s/)", target_triplet_as_string));
for (auto it = fs::recursive_directory_iterator(package_prefix_path); it != fs::recursive_directory_iterator(); ++it)
{
@@ -54,7 +54,7 @@ namespace vcpkg::Commands::Install
}
// Trailing backslash for directories
- output.push_back(Strings::format(R"(%s/%s)", target_triplet_as_string, suffix));
+ output.push_back(Strings::format(R"(%s/%s/)", target_triplet_as_string, suffix));
continue;
}
@@ -82,6 +82,8 @@ namespace vcpkg::Commands::Install
System::println(System::color::error, "failed: %s: cannot handle file type", it->path().u8string());
}
+ std::sort(output.begin(), output.end());
+
Files::write_all_lines(paths.listfile_path(bpgh), output);
}
@@ -185,10 +187,11 @@ namespace vcpkg::Commands::Install
{
static const std::string example = Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost");
args.check_min_arg_count(1, example);
- StatusParagraphs status_db = database_load_check(paths);
-
std::vector<package_spec> specs = Input::check_and_get_package_specs(args.command_arguments, default_target_triplet, example);
Input::check_triplets(specs, paths);
+ args.check_and_get_optional_command_arguments({});
+
+ StatusParagraphs status_db = database_load_check(paths);
std::vector<package_spec_with_install_plan> install_plan = Dependencies::create_install_plan(paths, specs, status_db);
Checks::check_exit(!install_plan.empty(), "Install plan cannot be empty");
@@ -214,7 +217,13 @@ namespace vcpkg::Commands::Install
}
else if (action.plan.plan_type == install_plan_type::BUILD_AND_INSTALL)
{
- Commands::Build::build_package(*action.plan.source_pgh, action.spec, paths, paths.port_dir(action.spec));
+ const Build::BuildResult result = Commands::Build::build_package(*action.plan.source_pgh, action.spec, paths, paths.port_dir(action.spec), status_db);
+ if (result != Build::BuildResult::SUCCEEDED)
+ {
+ System::println(System::color::error, Build::create_error_message(result, action.spec));
+ System::println(Build::create_user_troubleshooting_message(action.spec));
+ exit(EXIT_FAILURE);
+ }
const BinaryParagraph bpgh = try_load_cached_package(paths, action.spec).get_or_throw();
install_package(paths, bpgh, &status_db);
System::println(System::color::success, "Package %s is installed", action.spec);
diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp
index 03c51b5a7..94af19e96 100644
--- a/toolsrc/src/commands_integrate.cpp
+++ b/toolsrc/src/commands_integrate.cpp
@@ -8,10 +8,10 @@
namespace vcpkg::Commands::Integrate
{
static const std::array<fs::path, 2> old_system_target_files = {
- "C:/Program Files (x86)/MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets",
- "C:/Program Files (x86)/MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"
+ Environment::get_ProgramFiles_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets",
+ Environment::get_ProgramFiles_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"
};
- static const fs::path system_wide_targets_file = "C:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props";
+ static const fs::path system_wide_targets_file = Environment::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
{
@@ -109,7 +109,7 @@ namespace vcpkg::Commands::Integrate
static elevation_prompt_user_choice elevated_cmd_execute(const std::string& param)
{
- SHELLEXECUTEINFO shExInfo = {0};
+ SHELLEXECUTEINFO shExInfo = { 0 };
shExInfo.cbSize = sizeof(shExInfo);
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExInfo.hwnd = nullptr;
@@ -136,7 +136,7 @@ namespace vcpkg::Commands::Integrate
static fs::path get_appdata_targets_path()
{
- return fs::path(System::wdupenv_str(L"LOCALAPPDATA")) / "vcpkg" / "vcpkg.user.targets";
+ return fs::path(*System::get_environmental_variable(L"LOCALAPPDATA")) / "vcpkg" / "vcpkg.user.targets";
}
static void integrate_install(const vcpkg_paths& paths)
@@ -214,10 +214,13 @@ namespace vcpkg::Commands::Integrate
exit(EXIT_FAILURE);
}
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 C++ projects can now #include any installed libraries.\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.");
+ "Installing new libraries will make them instantly available.\n"
+ "\n"
+ "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", cmake_toolchain.generic_string());
exit(EXIT_SUCCESS);
}
@@ -293,6 +296,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
static const std::string example = Strings::format("Commands:\n"
"%s", INTEGRATE_COMMAND_HELPSTRING);
args.check_exact_arg_count(1, example);
+ args.check_and_get_optional_command_arguments({});
if (args.command_arguments[0] == "install")
{
diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp
index 34a9c2fc8..7bfc11f1b 100644
--- a/toolsrc/src/commands_list.cpp
+++ b/toolsrc/src/commands_list.cpp
@@ -19,6 +19,7 @@ namespace vcpkg::Commands::List
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);
+ args.check_and_get_optional_command_arguments({});
const StatusParagraphs status_paragraphs = database_load_check(paths);
std::vector<StatusParagraph> installed_packages;
diff --git a/toolsrc/src/commands_owns.cpp b/toolsrc/src/commands_owns.cpp
index 6c4c20c44..16bb986e2 100644
--- a/toolsrc/src/commands_owns.cpp
+++ b/toolsrc/src/commands_owns.cpp
@@ -26,6 +26,7 @@ namespace vcpkg::Commands::Owns
{
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);
+ args.check_and_get_optional_command_arguments({});
StatusParagraphs status_db = database_load_check(paths);
search_file(paths, args.command_arguments[0], status_db);
diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp
index e75633b3c..119997485 100644
--- a/toolsrc/src/commands_portsdiff.cpp
+++ b/toolsrc/src/commands_portsdiff.cpp
@@ -98,6 +98,7 @@ namespace vcpkg::Commands::PortsDiff
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);
+ args.check_and_get_optional_command_arguments({});
Environment::ensure_git_on_path(paths);
const std::wstring git_commit_id_for_previous_snapshot = Strings::utf8_to_utf16(args.command_arguments.at(0));
diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp
index f49104d1e..1daacb944 100644
--- a/toolsrc/src/commands_remove.cpp
+++ b/toolsrc/src/commands_remove.cpp
@@ -167,16 +167,14 @@ namespace vcpkg::Commands::Remove
{
static const std::string example = Commands::Help::create_example_string("remove zlib zlib:x64-windows curl boost");
args.check_min_arg_count(1, example);
-
- const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({OPTION_PURGE, OPTION_RECURSE});
- auto status_db = database_load_check(paths);
-
std::vector<package_spec> specs = Input::check_and_get_package_specs(args.command_arguments, default_target_triplet, example);
Input::check_triplets(specs, paths);
+ const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({ OPTION_PURGE, OPTION_RECURSE });
const bool alsoRemoveFolderFromPackages = options.find(OPTION_PURGE) != options.end();
const bool isRecursive = options.find(OPTION_RECURSE) != options.end();
- const std::vector<package_spec_with_remove_plan> remove_plan = Dependencies::create_remove_plan(paths, specs, status_db);
+ auto status_db = database_load_check(paths);
+ const std::vector<package_spec_with_remove_plan> remove_plan = Dependencies::create_remove_plan(specs, status_db);
Checks::check_exit(!remove_plan.empty(), "Remove plan cannot be empty");
print_plan(remove_plan);
diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp
index 3a3226e4b..5dba71149 100644
--- a/toolsrc/src/commands_search.cpp
+++ b/toolsrc/src/commands_search.cpp
@@ -46,6 +46,7 @@ namespace vcpkg::Commands::Search
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);
+ args.check_and_get_optional_command_arguments({});
const std::vector<SourceParagraph> source_paragraphs = read_all_source_paragraphs(paths);
diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp
index a42ae5341..d4519ca14 100644
--- a/toolsrc/src/commands_update.cpp
+++ b/toolsrc/src/commands_update.cpp
@@ -4,13 +4,13 @@
#include "vcpkg_System.h"
#include "vcpkg_Files.h"
#include "Paragraphs.h"
-#include "vcpkg_info.h"
namespace vcpkg::Commands::Update
{
void perform_and_exit(const vcpkg_cmd_arguments& args, const vcpkg_paths& paths)
{
args.check_exact_arg_count(0);
+ args.check_and_get_optional_command_arguments({});
System::println("Using local portfile versions. To update the local portfiles, use `git pull`.");
auto status_db = database_load_check(paths);
@@ -79,7 +79,7 @@ namespace vcpkg::Commands::Update
auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1);
int maj2, min2, rev2;
- auto num2 = sscanf_s(Info::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2);
+ auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2);
if (num1 == 3 && num2 == 3)
{
diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp
index a521b2567..4789e2409 100644
--- a/toolsrc/src/commands_version.cpp
+++ b/toolsrc/src/commands_version.cpp
@@ -1,16 +1,36 @@
#include "pch.h"
#include "vcpkg_Commands.h"
#include "vcpkg_System.h"
-#include "vcpkg_info.h"
+#include "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(GetCompiledMetricsEnabled() ? "" : "-external");
+ return s_version;
+ }
+
void perform_and_exit(const vcpkg_cmd_arguments& 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.", Info::version()
+ "See LICENSE.txt for license information.", version()
);
exit(EXIT_SUCCESS);
}
diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp
index 263d6eb74..4ac43c5c6 100644
--- a/toolsrc/src/metrics.cpp
+++ b/toolsrc/src/metrics.cpp
@@ -32,7 +32,7 @@ namespace vcpkg
static std::string GenerateRandomUUID()
{
- int partSizes[] = {8, 4, 4, 4, 12};
+ int partSizes[] = { 8, 4, 4, 4, 12 };
char uuid[37];
memset(uuid, 0, sizeof(uuid));
int num;
@@ -101,7 +101,7 @@ namespace vcpkg
// Note: this treats incoming Strings as Latin-1
static constexpr const char hex[16] = {
'0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
encoded.append("\\u00");
encoded.push_back(hex[ch / 16]);
encoded.push_back(hex[ch % 16]);
@@ -229,8 +229,10 @@ true
{
LONG err;
- struct RAII_HKEY {
+ struct RAII_HKEY
+ {
HKEY hkey = nullptr;
+
~RAII_HKEY()
{
if (hkey != nullptr)
@@ -244,7 +246,7 @@ true
return L"{}";
}
- std::array<wchar_t,128> buffer;
+ std::array<wchar_t, 128> buffer;
DWORD lType = 0;
DWORD dwBufferSize = static_cast<DWORD>(buffer.size() * sizeof(wchar_t));
err = RegQueryValueExW(HKCU_SQMClient.hkey, L"UserId", nullptr, &lType, reinterpret_cast<LPBYTE>(buffer.data()), &dwBufferSize);
@@ -356,8 +358,7 @@ true
if (bResults)
{
DWORD availableData = 0, readData = 0, totalData = 0;
-
- while ((bResults = WinHttpQueryDataAvailable(hRequest, &availableData)) && availableData > 0)
+ while ((bResults = WinHttpQueryDataAvailable(hRequest, &availableData)) == TRUE && availableData > 0)
{
responseBuffer.resize(responseBuffer.size() + availableData);
diff --git a/toolsrc/src/triplet.cpp b/toolsrc/src/triplet.cpp
index e1302d9ed..d91e0e68f 100644
--- a/toolsrc/src/triplet.cpp
+++ b/toolsrc/src/triplet.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include "triplet.h"
#include "vcpkg_Checks.h"
+#include "vcpkg_Strings.h"
namespace vcpkg
{
@@ -37,9 +38,7 @@ namespace vcpkg
triplet triplet::from_canonical_name(const std::string& triplet_as_string)
{
- std::string s(triplet_as_string);
- std::transform(s.begin(), s.end(), s.begin(), ::tolower);
-
+ const std::string s(Strings::ascii_to_lowercase(triplet_as_string));
auto it = std::find(s.cbegin(), s.cend(), '-');
Checks::check_exit(it != s.cend(), "Invalid triplet: %s", triplet_as_string);
diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp
index 3e313c702..f40126ecf 100644
--- a/toolsrc/src/vcpkg.cpp
+++ b/toolsrc/src/vcpkg.cpp
@@ -12,7 +12,6 @@
#include "vcpkg_System.h"
#include "vcpkg_Input.h"
#include "Paragraphs.h"
-#include "vcpkg_info.h"
#include "vcpkg_Strings.h"
using namespace vcpkg;
@@ -47,11 +46,10 @@ static void inner(const vcpkg_cmd_arguments& args)
}
else
{
- auto vcpkg_root_dir_env = System::wdupenv_str(L"VCPKG_ROOT");
-
- if (!vcpkg_root_dir_env.empty())
+ const optional<std::wstring> vcpkg_root_dir_env = System::get_environmental_variable(L"VCPKG_ROOT");
+ if (vcpkg_root_dir_env)
{
- vcpkg_root_dir = fs::absolute(vcpkg_root_dir_env);
+ vcpkg_root_dir = fs::absolute(*vcpkg_root_dir_env);
}
else
{
@@ -79,10 +77,10 @@ static void inner(const vcpkg_cmd_arguments& args)
}
else
{
- const auto vcpkg_default_triplet_env = System::wdupenv_str(L"VCPKG_DEFAULT_TRIPLET");
- if (!vcpkg_default_triplet_env.empty())
+ const optional<std::wstring> vcpkg_default_triplet_env = System::get_environmental_variable(L"VCPKG_DEFAULT_TRIPLET");
+ if (vcpkg_default_triplet_env)
{
- default_target_triplet = triplet::from_canonical_name(Strings::utf16_to_utf8(vcpkg_default_triplet_env));
+ default_target_triplet = triplet::from_canonical_name(Strings::utf16_to_utf8(*vcpkg_default_triplet_env));
}
else
{
@@ -193,7 +191,7 @@ int wmain(const int argc, const wchar_t* const* const argv)
Flush();
});
- TrackProperty("version", Info::version());
+ TrackProperty("version", Commands::Version::version());
const std::string trimmed_command_line = trim_path_from_command_line(Strings::utf16_to_utf8(GetCommandLineW()));
TrackProperty("cmdline", trimmed_command_line);
@@ -236,10 +234,10 @@ int wmain(const int argc, const wchar_t* const* const argv)
std::cerr
<< "vcpkg.exe has crashed.\n"
<< "Please send an email to:\n"
- << " " << Info::email() << "\n"
+ << " " << Commands::Contact::email() << "\n"
<< "containing a brief summary of what you were trying to do and the following data blob:\n"
<< "\n"
- << "Version=" << Info::version() << "\n"
+ << "Version=" << Commands::Version::version() << "\n"
<< "EXCEPTION='" << exc_msg << "'\n"
<< "CMD=\n";
for (int x = 0; x < argc; ++x)
diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp
index 5c3fef27a..f02addc08 100644
--- a/toolsrc/src/vcpkg_Checks.cpp
+++ b/toolsrc/src/vcpkg_Checks.cpp
@@ -33,6 +33,14 @@ namespace vcpkg::Checks
}
}
+ void check_exit(bool expression)
+ {
+ if (!expression)
+ {
+ exit(EXIT_FAILURE);
+ }
+ }
+
void check_exit(bool expression, const char* errorMessage)
{
if (!expression)
diff --git a/toolsrc/src/Stopwatch.cpp b/toolsrc/src/vcpkg_Chrono.cpp
index ec7af60b6..1bcb439be 100644
--- a/toolsrc/src/Stopwatch.cpp
+++ b/toolsrc/src/vcpkg_Chrono.cpp
@@ -1,49 +1,10 @@
#include "pch.h"
-#include "Stopwatch.h"
+#include "vcpkg_Chrono.h"
#include "vcpkg_Checks.h"
namespace vcpkg
{
- Stopwatch Stopwatch::createUnstarted()
- {
- return Stopwatch();
- }
-
- Stopwatch Stopwatch::createStarted()
- {
- return Stopwatch().start();
- }
-
- bool Stopwatch::isRunning() const
- {
- return this->m_isRunning;
- }
-
- const Stopwatch& Stopwatch::start()
- {
- Checks::check_exit(!this->m_isRunning, "This stopwatch is already running.");
- this->m_isRunning = true;
- this->m_startTick = std::chrono::high_resolution_clock::now();
- return *this;
- }
-
- const Stopwatch& Stopwatch::stop()
- {
- auto tick = std::chrono::high_resolution_clock::now();
- Checks::check_exit(this->m_isRunning, "This stopwatch is already stopped.");
- this->m_isRunning = false;
- this->m_elapsedNanos += tick - this->m_startTick;
- return *this;
- }
-
- Stopwatch& Stopwatch::reset()
- {
- this->m_elapsedNanos = std::chrono::nanoseconds();
- this->m_isRunning = false;
- return *this;
- }
-
- std::string Stopwatch::toString() const
+ static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos)
{
using std::chrono::hours;
using std::chrono::minutes;
@@ -53,8 +14,7 @@ namespace vcpkg
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
- auto nanos = elapsedNanos();
- auto nanos_as_double = static_cast<double>(nanos.count());
+ const double nanos_as_double = static_cast<double>(nanos.count());
if (duration_cast<hours>(nanos) > hours())
{
@@ -89,10 +49,64 @@ namespace vcpkg
return Strings::format("%.4g ns", nanos_as_double);
}
- Stopwatch::Stopwatch() : m_isRunning(false), m_elapsedNanos(0), m_startTick()
+ ElapsedTime ElapsedTime::createStarted()
{
+ ElapsedTime t;
+ t.m_startTick = std::chrono::high_resolution_clock::now();
+ return t;
}
+ std::string ElapsedTime::toString() const
+ {
+ return format_time_userfriendly(elapsed<std::chrono::nanoseconds>());
+ }
+
+ Stopwatch Stopwatch::createUnstarted()
+ {
+ return Stopwatch();
+ }
+
+ Stopwatch Stopwatch::createStarted()
+ {
+ return Stopwatch().start();
+ }
+
+ bool Stopwatch::isRunning() const
+ {
+ return this->m_isRunning;
+ }
+
+ const Stopwatch& Stopwatch::start()
+ {
+ Checks::check_exit(!this->m_isRunning, "This stopwatch is already running.");
+ this->m_isRunning = true;
+ this->m_startTick = std::chrono::high_resolution_clock::now();
+ return *this;
+ }
+
+ const Stopwatch& Stopwatch::stop()
+ {
+ auto tick = std::chrono::high_resolution_clock::now();
+ Checks::check_exit(this->m_isRunning, "This stopwatch is already stopped.");
+ this->m_isRunning = false;
+ this->m_elapsedNanos += tick - this->m_startTick;
+ return *this;
+ }
+
+ Stopwatch& Stopwatch::reset()
+ {
+ this->m_elapsedNanos = std::chrono::nanoseconds();
+ this->m_isRunning = false;
+ return *this;
+ }
+
+ std::string Stopwatch::toString() const
+ {
+ return format_time_userfriendly(this->elapsedNanos());
+ }
+
+ Stopwatch::Stopwatch() : m_isRunning(false), m_elapsedNanos(0), m_startTick() { }
+
std::chrono::nanoseconds Stopwatch::elapsedNanos() const
{
if (this->m_isRunning)
diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp
index 5bd6c3eb9..b255cc77b 100644
--- a/toolsrc/src/vcpkg_Dependencies.cpp
+++ b/toolsrc/src/vcpkg_Dependencies.cpp
@@ -80,7 +80,7 @@ namespace vcpkg::Dependencies
continue;
}
- expected<SourceParagraph> maybe_spgh = try_load_port(paths, spec.name());
+ expected<SourceParagraph> maybe_spgh = try_load_port(paths.port_dir(spec));
SourceParagraph* spgh = maybe_spgh.get();
Checks::check_exit(spgh != nullptr, "Cannot find package %s", spec.name());
process_dependencies(filter_dependencies(spgh->depends, spec.target_triplet()));
@@ -97,7 +97,7 @@ namespace vcpkg::Dependencies
return ret;
}
- std::vector<package_spec_with_remove_plan> create_remove_plan(const vcpkg_paths& paths, const std::vector<package_spec>& specs, const StatusParagraphs& status_db)
+ std::vector<package_spec_with_remove_plan> create_remove_plan(const std::vector<package_spec>& specs, const StatusParagraphs& status_db)
{
std::unordered_set<package_spec> specs_as_set(specs.cbegin(), specs.cend());
diff --git a/toolsrc/src/vcpkg_Enums.cpp b/toolsrc/src/vcpkg_Enums.cpp
new file mode 100644
index 000000000..5e698659d
--- /dev/null
+++ b/toolsrc/src/vcpkg_Enums.cpp
@@ -0,0 +1,21 @@
+#include "pch.h"
+#include "vcpkg_Enums.h"
+#include "vcpkg_Checks.h"
+
+namespace vcpkg::Enums
+{
+ std::string nullvalue_toString(const std::string& enum_name)
+ {
+ return Strings::format("%s_NULLVALUE", enum_name);
+ }
+
+ void nullvalue_used(const std::string& enum_name)
+ {
+ Checks::exit_with_message("NULLVALUE of enum %s was used", enum_name);
+ }
+
+ void unreachable(const std::string& enum_name)
+ {
+ Checks::exit_with_message("Unreachable code for enum, %s", enum_name);
+ }
+}
diff --git a/toolsrc/src/vcpkg_Environment.cpp b/toolsrc/src/vcpkg_Environment.cpp
index 1babdc547..527d8de89 100644
--- a/toolsrc/src/vcpkg_Environment.cpp
+++ b/toolsrc/src/vcpkg_Environment.cpp
@@ -8,11 +8,6 @@
namespace vcpkg::Environment
{
- static const fs::path default_cmake_installation_dir = "C:/Program Files/CMake/bin";
- static const fs::path default_cmake_installation_dir_x86 = "C:/Program Files (x86)/CMake/bin";
- static const fs::path default_git_installation_dir = "C:/Program Files/git/cmd";
- static const fs::path default_git_installation_dir_x86 = "C:/Program Files (x86)/git/cmd";
-
static void ensure_on_path(const std::array<int, 3>& version, const std::wstring& version_check_cmd, const std::wstring& install_cmd)
{
System::exit_code_and_output ec_data = System::cmd_execute_and_capture_output(version_check_cmd);
@@ -54,15 +49,21 @@ namespace vcpkg::Environment
void ensure_git_on_path(const vcpkg_paths& paths)
{
- const fs::path downloaded_git = paths.downloads / "PortableGit" / "cmd";
- const std::wstring path_buf = Strings::wformat(L"%s;%s;%s;%s",
- downloaded_git.native(),
- System::wdupenv_str(L"PATH"),
+ static const fs::path default_git_installation_dir = Environment::get_ProgramFiles_platform_bitness() / "git/cmd";
+ static const fs::path default_git_installation_dir_32 = Environment::get_ProgramFiles_32_bit() / "git/cmd";
+
+ const fs::path portable_git = paths.downloads / "PortableGit" / "cmd"; // TODO: Remove next time we bump the version
+ const fs::path min_git = paths.downloads / "MinGit-2.11.1-32-bit" / "cmd";
+ const std::wstring path_buf = Strings::wformat(L"%s;%s;%s;%s;%s",
+ min_git.native(),
+ portable_git.native(),
+ *System::get_environmental_variable(L"PATH"),
default_git_installation_dir.native(),
- default_git_installation_dir_x86.native());
- _wputenv_s(L"PATH", path_buf.c_str());
+ default_git_installation_dir_32.native());
- static constexpr std::array<int, 3> git_version = {2,0,0};
+ System::set_environmental_variable(L"PATH", path_buf.c_str());
+
+ static constexpr std::array<int, 3> git_version = { 2,0,0 };
static const std::wstring version_check_cmd = L"git --version 2>&1";
const std::wstring install_cmd = create_default_install_cmd(paths, L"git");
ensure_on_path(git_version, version_check_cmd, install_cmd);
@@ -70,15 +71,18 @@ namespace vcpkg::Environment
void ensure_cmake_on_path(const vcpkg_paths& paths)
{
- const fs::path downloaded_cmake = paths.downloads / "cmake-3.7.2-win32-x86" / "bin";
+ static const fs::path default_cmake_installation_dir = Environment::get_ProgramFiles_platform_bitness() / "CMake/bin";
+ static const fs::path default_cmake_installation_dir_32 = Environment::get_ProgramFiles_32_bit() / "CMake/bin";
+
+ const fs::path downloaded_cmake = paths.downloads / "cmake-3.8.0-rc1-win32-x86" / "bin";
const std::wstring path_buf = Strings::wformat(L"%s;%s;%s;%s",
downloaded_cmake.native(),
- System::wdupenv_str(L"PATH"),
+ *System::get_environmental_variable(L"PATH"),
default_cmake_installation_dir.native(),
- default_cmake_installation_dir_x86.native());
- _wputenv_s(L"PATH", path_buf.c_str());
+ default_cmake_installation_dir_32.native());
+ System::set_environmental_variable(L"PATH", path_buf.c_str());
- static constexpr std::array<int, 3> cmake_version = {3,7,2};
+ static constexpr std::array<int, 3> cmake_version = { 3,8,0 };
static const std::wstring version_check_cmd = L"cmake --version 2>&1";
const std::wstring install_cmd = create_default_install_cmd(paths, L"cmake");
ensure_on_path(cmake_version, version_check_cmd, install_cmd);
@@ -87,10 +91,10 @@ namespace vcpkg::Environment
void ensure_nuget_on_path(const vcpkg_paths& paths)
{
const fs::path downloaded_nuget = paths.downloads / "nuget-3.5.0";
- const std::wstring path_buf = Strings::wformat(L"%s;%s", downloaded_nuget.native(), System::wdupenv_str(L"PATH"));
- _wputenv_s(L"PATH", path_buf.c_str());
+ const std::wstring path_buf = Strings::wformat(L"%s;%s", downloaded_nuget.native(), *System::get_environmental_variable(L"PATH"));
+ System::set_environmental_variable(L"PATH", path_buf.c_str());
- static constexpr std::array<int, 3> nuget_version = {3,3,0};
+ static constexpr std::array<int, 3> nuget_version = { 3,3,0 };
static const std::wstring version_check_cmd = L"nuget 2>&1";
const std::wstring install_cmd = create_default_install_cmd(paths, L"nuget");
ensure_on_path(nuget_version, version_check_cmd, install_cmd);
@@ -105,10 +109,22 @@ namespace vcpkg::Environment
return Strings::split(ec_data.output, "\n");
}
- static const fs::path& get_VS2015_installation_instance()
+ static optional<fs::path> find_vs2015_installation_instance()
{
- static const fs::path vs2015_cmntools = fs::path(System::wdupenv_str(L"VS140COMNTOOLS")).parent_path(); // The call to parent_path() is needed because the env variable has a trailing backslash
+ const optional<std::wstring> vs2015_cmntools_optional = System::get_environmental_variable(L"VS140COMNTOOLS");
+ if (!vs2015_cmntools_optional)
+ {
+ return nullptr;
+ }
+
+ static const fs::path vs2015_cmntools = fs::path(*vs2015_cmntools_optional).parent_path(); // The call to parent_path() is needed because the env variable has a trailing backslash
static const fs::path vs2015_path = vs2015_cmntools.parent_path().parent_path();
+ return std::make_unique<fs::path>(vs2015_path);
+ }
+
+ static const optional<fs::path>& get_VS2015_installation_instance()
+ {
+ static const optional<fs::path> vs2015_path = find_vs2015_installation_instance();
return vs2015_path;
}
@@ -145,11 +161,15 @@ namespace vcpkg::Environment
}
// VS2015
- const fs::path vs2015_dumpbin_exe = get_VS2015_installation_instance() / "VC" / "bin" / "dumpbin.exe";
- paths_examined.push_back(vs2015_dumpbin_exe);
- if (fs::exists(vs2015_dumpbin_exe))
+ const optional<fs::path>& vs_2015_installation_instance = get_VS2015_installation_instance();
+ if (vs_2015_installation_instance)
{
- return vs2015_dumpbin_exe;
+ const fs::path vs2015_dumpbin_exe = *vs_2015_installation_instance / "VC" / "bin" / "dumpbin.exe";
+ paths_examined.push_back(vs2015_dumpbin_exe);
+ if (fs::exists(vs2015_dumpbin_exe))
+ {
+ return vs2015_dumpbin_exe;
+ }
}
System::println(System::color::error, "Could not detect dumpbin.exe.");
@@ -179,23 +199,28 @@ namespace vcpkg::Environment
paths_examined.push_back(vcvarsall_bat);
if (fs::exists(vcvarsall_bat))
{
- return { vcvarsall_bat , L"v141"};
+ return { vcvarsall_bat , L"v141" };
}
}
// VS2015
- const fs::path vs2015_vcvarsall_bat = get_VS2015_installation_instance() / "VC" / "vcvarsall.bat";
- paths_examined.push_back(vs2015_vcvarsall_bat);
- if (fs::exists(vs2015_vcvarsall_bat))
+ const optional<fs::path>& vs_2015_installation_instance = get_VS2015_installation_instance();
+ if (vs_2015_installation_instance)
{
- return { vs2015_vcvarsall_bat, L"v140" };
+ const fs::path vs2015_vcvarsall_bat = *vs_2015_installation_instance / "VC" / "vcvarsall.bat";
+
+ paths_examined.push_back(vs2015_vcvarsall_bat);
+ if (fs::exists(vs2015_vcvarsall_bat))
+ {
+ return { vs2015_vcvarsall_bat, L"v140" };
+ }
}
- System::println(System::color::error, "Could not detect vccarsall.bat.");
+ System::println(System::color::error, "Could not detect vcvarsall.bat.");
System::println("The following paths were examined:");
for (const fs::path& path : paths_examined)
{
- System::println(" %s",path.generic_string());
+ System::println(" %s", path.generic_string());
}
exit(EXIT_FAILURE);
}
@@ -205,4 +230,38 @@ namespace vcpkg::Environment
static const vcvarsall_and_platform_toolset vcvarsall_bat = find_vcvarsall_bat(paths);
return vcvarsall_bat;
}
+
+ static fs::path find_ProgramFiles_32_bit()
+ {
+ const optional<std::wstring> program_files_X86 = System::get_environmental_variable(L"ProgramFiles(x86)");
+ if (program_files_X86)
+ {
+ return *program_files_X86;
+ }
+
+ return *System::get_environmental_variable(L"PROGRAMFILES");
+ }
+
+ const fs::path& get_ProgramFiles_32_bit()
+ {
+ static const fs::path p = find_ProgramFiles_32_bit();
+ return p;
+ }
+
+ static fs::path find_ProgramFiles_platform_bitness()
+ {
+ const optional<std::wstring> program_files_W6432 = System::get_environmental_variable(L"ProgramW6432");
+ if (program_files_W6432)
+ {
+ return *program_files_W6432;
+ }
+
+ return *System::get_environmental_variable(L"PROGRAMFILES");
+ }
+
+ const fs::path& get_ProgramFiles_platform_bitness()
+ {
+ static const fs::path p = find_ProgramFiles_platform_bitness();
+ return p;
+ }
}
diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp
index 87700238d..57d4c665c 100644
--- a/toolsrc/src/vcpkg_Files.cpp
+++ b/toolsrc/src/vcpkg_Files.cpp
@@ -102,7 +102,7 @@ namespace vcpkg::Files
void recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output)
{
- recursive_find_matching_paths_in_dir(dir, [&](const fs::path& current)
+ recursive_find_matching_paths_in_dir(dir, [](const fs::path& current)
{
return !fs::is_directory(current);
}, output);
@@ -117,7 +117,7 @@ namespace vcpkg::Files
void non_recursive_find_all_files_in_dir(const fs::path& dir, std::vector<fs::path>* output)
{
- non_recursive_find_matching_paths_in_dir(dir, [&](const fs::path& current)
+ non_recursive_find_matching_paths_in_dir(dir, [](const fs::path& current)
{
return !fs::is_directory(current);
}, output);
diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp
index 3b9d6a859..35ebcc90f 100644
--- a/toolsrc/src/vcpkg_Strings.cpp
+++ b/toolsrc/src/vcpkg_Strings.cpp
@@ -9,12 +9,18 @@ namespace vcpkg::Strings::details
return std::isspace(c);
};
+ // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower()
+ static char tolower_char(const char c)
+ {
+ return static_cast<char>(std::tolower(c));
+ }
+
std::string format_internal(const char* fmtstr, ...)
{
va_list lst;
va_start(lst, fmtstr);
- auto sz = _vscprintf(fmtstr, lst);
+ const int sz = _vscprintf(fmtstr, lst);
std::string output(sz, '\0');
_vsnprintf_s(&output[0], output.size() + 1, output.size() + 1, fmtstr, lst);
va_end(lst);
@@ -27,7 +33,7 @@ namespace vcpkg::Strings::details
va_list lst;
va_start(lst, fmtstr);
- auto sz = _vscwprintf(fmtstr, lst);
+ const int sz = _vscwprintf(fmtstr, lst);
std::wstring output(sz, '\0');
_vsnwprintf_s(&output[0], output.size() + 1, output.size() + 1, fmtstr, lst);
va_end(lst);
@@ -52,18 +58,17 @@ namespace vcpkg::Strings
std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern)
{
- std::string pattern_as_lower_case;
- std::transform(pattern.begin(), pattern.end(), back_inserter(pattern_as_lower_case), tolower);
+ const std::string pattern_as_lower_case(ascii_to_lowercase(pattern));
return search(s.begin(), s.end(), pattern_as_lower_case.begin(), pattern_as_lower_case.end(), [](const char a, const char b)
{
- return tolower(a) == b;
+ return details::tolower_char(a) == b;
});
}
std::string ascii_to_lowercase(const std::string& input)
{
- std::string output = input;
- std::transform(output.begin(), output.end(), output.begin(), ::tolower);
+ std::string output(input);
+ std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char);
return output;
}
diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp
index 754a26741..90ec9c99c 100644
--- a/toolsrc/src/vcpkg_System.cpp
+++ b/toolsrc/src/vcpkg_System.cpp
@@ -14,6 +14,9 @@ namespace vcpkg::System
int cmd_execute(const wchar_t* cmd_line)
{
+ // Flush cout before launching external process
+ std::cout << std::flush;
+
// Basically we are wrapping it in quotes
const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
int exit_code = _wsystem(actual_cmd_line.c_str());
@@ -22,6 +25,9 @@ namespace vcpkg::System
exit_code_and_output cmd_execute_and_capture_output(const wchar_t* cmd_line)
{
+ // Flush cout before launching external process
+ std::cout << std::flush;
+
const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line);
std::string output;
@@ -29,7 +35,7 @@ namespace vcpkg::System
auto pipe = _wpopen(actual_cmd_line.c_str(), L"r");
if (pipe == nullptr)
{
- return {1, output};
+ return { 1, output };
}
while (fgets(buf, 1024, pipe))
{
@@ -37,10 +43,10 @@ namespace vcpkg::System
}
if (!feof(pipe))
{
- return {1, output};
+ return { 1, output };
}
auto ec = _pclose(pipe);
- return {ec, output};
+ return { ec, output };
}
void print(const char* message)
@@ -62,7 +68,7 @@ namespace vcpkg::System
GetConsoleScreenBufferInfo(hConsole, &consoleScreenBufferInfo);
auto original_color = consoleScreenBufferInfo.wAttributes;
- SetConsoleTextAttribute(hConsole, static_cast<int>(c) | (original_color & 0xF0));
+ SetConsoleTextAttribute(hConsole, static_cast<WORD>(c) | (original_color & 0xF0));
std::cout << message;
SetConsoleTextAttribute(hConsole, original_color);
}
@@ -73,17 +79,22 @@ namespace vcpkg::System
std::cout << "\n";
}
- std::wstring wdupenv_str(const wchar_t* varname) noexcept
+ optional<std::wstring> get_environmental_variable(const wchar_t* varname) noexcept
{
- std::wstring ret;
wchar_t* buffer;
_wdupenv_s(&buffer, nullptr, varname);
- if (buffer != nullptr)
+
+ if (buffer == nullptr)
{
- ret = buffer;
- free(buffer);
+ return nullptr;
}
- return ret;
+ std::unique_ptr<wchar_t, void(__cdecl *)(void*)> bufptr(buffer, free);
+ return std::make_unique<std::wstring>(buffer);
+ }
+
+ void set_environmental_variable(const wchar_t* varname, const wchar_t* varvalue) noexcept
+ {
+ _wputenv_s(varname, varvalue);
}
void Stopwatch2::start()
diff --git a/toolsrc/src/vcpkg_info.cpp b/toolsrc/src/vcpkg_info.cpp
deleted file mode 100644
index f8e214998..000000000
--- a/toolsrc/src/vcpkg_info.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "pch.h"
-#include "vcpkg_info.h"
-#include "metrics.h"
-
-#define STRINGIFY(X) #X
-#define MACRO_TO_STRING(X) STRINGIFY(X)
-
-#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION)"" // Double quotes needed at the end to prevent blank token
-
-namespace vcpkg::Info
-{
- const std::string& version()
- {
- static const std::string s_version =
-#include "../VERSION.txt"
-
-
-#pragma warning( push )
-#pragma warning( disable : 4003)
- // VCPKG_VERSION can be defined but have no value, which yields C4003.
- + std::string(VCPKG_VERSION_AS_STRING)
-#pragma warning( pop )
-#ifndef NDEBUG
- + std::string("-debug")
-#endif
- + std::string(GetCompiledMetricsEnabled() ? "" : "-external");
- return s_version;
- }
-
- const std::string& email()
- {
- static const std::string s_email = R"(vcpkg@microsoft.com)";
- return s_email;
- }
-}
diff --git a/toolsrc/src/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkg_metrics_uploader.cpp
index 14fc9ae48..82dcd4b03 100644
--- a/toolsrc/src/vcpkg_metrics_uploader.cpp
+++ b/toolsrc/src/vcpkg_metrics_uploader.cpp
@@ -5,13 +5,7 @@
using namespace vcpkg;
-int WINAPI
-WinMain(
- _In_ HINSTANCE hInstance,
- _In_opt_ HINSTANCE hPrevInstance,
- _In_ LPSTR lpCmdLine,
- _In_ int nShowCmd
-)
+int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int)
{
LPWSTR* szArgList;
int argCount;
diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp
index 06487684c..78918e62c 100644
--- a/toolsrc/src/vcpkglib.cpp
+++ b/toolsrc/src/vcpkglib.cpp
@@ -164,12 +164,10 @@ static void upgrade_to_slash_terminated_sorted_format(std::vector<std::string>*
// The new format is lexicographically sorted
std::sort(lines->begin(), lines->end());
-#if 0
// Replace the listfile on disk
const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated";
Files::write_all_lines(updated_listfile_path, *lines);
fs::rename(updated_listfile_path, listfile_path);
-#endif
}
std::vector<StatusParagraph_and_associated_files> vcpkg::get_installed_files(const vcpkg_paths& paths, const StatusParagraphs& status_db)