aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/src
diff options
context:
space:
mode:
Diffstat (limited to 'toolsrc/src')
-rw-r--r--toolsrc/src/BinaryParagraph.cpp4
-rw-r--r--toolsrc/src/SourceParagraph.cpp83
-rw-r--r--toolsrc/src/commands_installation.cpp11
-rw-r--r--toolsrc/src/lib.cpp40
-rw-r--r--toolsrc/src/tests_dependencies.cpp39
-rw-r--r--toolsrc/src/tests_paragraph.cpp (renamed from toolsrc/src/test.cpp)50
-rw-r--r--toolsrc/src/vcpkg_Checks.cpp3
-rw-r--r--toolsrc/src/vcpkg_Dependencies.cpp8
-rw-r--r--toolsrc/src/vcpkglib_helpers.cpp33
9 files changed, 196 insertions, 75 deletions
diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp
index 6dceb66d9..ad85a1f8a 100644
--- a/toolsrc/src/BinaryParagraph.cpp
+++ b/toolsrc/src/BinaryParagraph.cpp
@@ -56,7 +56,7 @@ namespace vcpkg
Checks::check_exit(multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch);
std::string deps = details::remove_optional_field(&fields, BinaryParagraphOptionalField::DEPENDS);
- this->depends = details::parse_depends(deps);
+ this->depends = parse_depends(deps);
}
BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const triplet& target_triplet)
@@ -65,7 +65,7 @@ namespace vcpkg
this->version = spgh.version;
this->description = spgh.description;
this->maintainer = spgh.maintainer;
- this->depends = spgh.depends;
+ this->depends = filter_dependencies(spgh.depends, target_triplet);
}
std::string BinaryParagraph::displayname() const
diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp
index 6f25dbded..bdf15a737 100644
--- a/toolsrc/src/SourceParagraph.cpp
+++ b/toolsrc/src/SourceParagraph.cpp
@@ -2,6 +2,7 @@
#include "vcpkglib_helpers.h"
#include "vcpkg_System.h"
#include "vcpkg_Maps.h"
+#include "triplet.h"
namespace vcpkg
{
@@ -44,7 +45,7 @@ namespace vcpkg
this->maintainer = details::remove_optional_field(&fields, SourceParagraphOptionalField::MAINTAINER);
std::string deps = details::remove_optional_field(&fields, SourceParagraphOptionalField::BUILD_DEPENDS);
- this->depends = details::parse_depends(deps);
+ this->depends = expand_qualified_dependencies(parse_depends(deps));
if (!fields.empty())
{
@@ -60,4 +61,84 @@ namespace vcpkg
exit(EXIT_FAILURE);
}
}
+
+ std::vector<dependency> vcpkg::expand_qualified_dependencies(const std::vector<std::string>& depends)
+ {
+ auto convert = [&](const std::string& depend_string) -> dependency {
+ auto pos = depend_string.find(' ');
+ if (pos == std::string::npos)
+ return{ depend_string, "" };
+ // expect of the form "\w+ \[\w+\]"
+ dependency dep;
+ dep.name = depend_string.substr(0, pos);
+ if (depend_string.c_str()[pos + 1] != '[' || depend_string[depend_string.size() - 1] != ']')
+ {
+ // Error, but for now just slurp the entire string.
+ return{ depend_string, "" };
+ }
+ dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3);
+ return dep;
+ };
+
+ std::vector<vcpkg::dependency> ret;
+
+ for (auto&& depend_string : depends)
+ {
+ ret.push_back(convert(depend_string));
+ }
+
+ return ret;
+ }
+
+ std::vector<std::string> parse_depends(const std::string& depends_string)
+ {
+ if (depends_string.empty())
+ {
+ return{};
+ }
+
+ std::vector<std::string> out;
+
+ size_t cur = 0;
+ do
+ {
+ auto pos = depends_string.find(',', cur);
+ if (pos == std::string::npos)
+ {
+ out.push_back(depends_string.substr(cur));
+ break;
+ }
+ out.push_back(depends_string.substr(cur, pos - cur));
+
+ // skip comma and space
+ ++pos;
+ if (depends_string[pos] == ' ')
+ {
+ ++pos;
+ }
+
+ cur = pos;
+ } while (cur != std::string::npos);
+
+ return out;
+ }
+
+ std::vector<std::string> filter_dependencies(const std::vector<vcpkg::dependency>& deps, const triplet& t)
+ {
+ std::vector<std::string> ret;
+ for (auto&& dep : deps)
+ {
+ if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos)
+ {
+ ret.push_back(dep.name);
+ }
+ }
+ return ret;
+ }
+
+ std::ostream & operator<<(std::ostream & os, const dependency & p)
+ {
+ os << p.name;
+ return os;
+ }
}
diff --git a/toolsrc/src/commands_installation.cpp b/toolsrc/src/commands_installation.cpp
index 022b87139..f6aeafa02 100644
--- a/toolsrc/src/commands_installation.cpp
+++ b/toolsrc/src/commands_installation.cpp
@@ -138,7 +138,16 @@ namespace vcpkg
const package_spec spec = Input::check_and_get_package_spec(args.command_arguments.at(0), default_target_triplet, example.c_str());
Input::check_triplet(spec.target_triplet(), paths);
- std::unordered_set<package_spec> unmet_dependencies = Dependencies::find_unmet_dependencies(paths, spec, status_db);
+
+ // Explicitly load and use the portfile's build dependencies when resolving the build command (instead of a cached package's dependencies).
+ auto first_level_deps = get_unmet_package_build_dependencies(paths, spec, status_db);
+ std::vector<package_spec> first_level_deps_specs;
+ for (auto&& dep : first_level_deps)
+ {
+ first_level_deps_specs.push_back(package_spec::from_name_and_triplet(dep, spec.target_triplet()).get_or_throw());
+ }
+
+ std::unordered_set<package_spec> unmet_dependencies = Dependencies::find_unmet_dependencies(paths, first_level_deps_specs, status_db);
if (!unmet_dependencies.empty())
{
System::println(System::color::error, "The build command requires all dependencies to be already installed.");
diff --git a/toolsrc/src/lib.cpp b/toolsrc/src/lib.cpp
index 45b73ee07..3c844ac3f 100644
--- a/toolsrc/src/lib.cpp
+++ b/toolsrc/src/lib.cpp
@@ -209,29 +209,33 @@ static void install_and_write_listfile(const vcpkg_paths& paths, const BinaryPar
// TODO: Refactoring between this function and install_package
std::vector<std::string> vcpkg::get_unmet_package_dependencies(const vcpkg_paths& paths, const package_spec& spec, const StatusParagraphs& status_db)
{
- std::vector<std::unordered_map<std::string, std::string>> pghs;
- {
- const fs::path packages_dir_control_file_path = paths.package_dir(spec) / "CONTROL";
+ const fs::path packages_dir_control_file_path = paths.package_dir(spec) / "CONTROL";
- auto control_contents_maybe = Files::get_contents(packages_dir_control_file_path);
- if (auto control_contents = control_contents_maybe.get())
+ auto control_contents_maybe = Files::get_contents(packages_dir_control_file_path);
+ if (auto control_contents = control_contents_maybe.get())
+ {
+ std::vector<std::unordered_map<std::string, std::string>> pghs;
+ try
+ {
+ pghs = parse_paragraphs(*control_contents);
+ }
+ catch (std::runtime_error)
{
- try
- {
- pghs = parse_paragraphs(*control_contents);
- }
- catch (std::runtime_error)
- {
- }
- Checks::check_exit(pghs.size() == 1, "Invalid control file at %s", packages_dir_control_file_path.string());
- return BinaryParagraph(pghs[0]).depends;
}
+ Checks::check_exit(pghs.size() == 1, "Invalid control file at %s", packages_dir_control_file_path.string());
+ return BinaryParagraph(pghs[0]).depends;
}
+ return get_unmet_package_build_dependencies(paths, spec, status_db);
+}
+
+std::vector<std::string> vcpkg::get_unmet_package_build_dependencies(const vcpkg_paths& paths, const package_spec& spec, const StatusParagraphs& status_db)
+{
const fs::path ports_dir_control_file_path = paths.port_dir(spec) / "CONTROL";
auto control_contents_maybe = Files::get_contents(ports_dir_control_file_path);
if (auto control_contents = control_contents_maybe.get())
{
+ std::vector<std::unordered_map<std::string, std::string>> pghs;
try
{
pghs = parse_paragraphs(*control_contents);
@@ -240,7 +244,7 @@ std::vector<std::string> vcpkg::get_unmet_package_dependencies(const vcpkg_paths
{
}
Checks::check_exit(pghs.size() == 1, "Invalid control file at %s", ports_dir_control_file_path.string());
- return SourceParagraph(pghs[0]).depends;
+ return filter_dependencies(SourceParagraph(pghs[0]).depends, spec.target_triplet());
}
Checks::exit_with_message("Could not find package named %s", spec);
@@ -252,11 +256,11 @@ void vcpkg::install_package(const vcpkg_paths& paths, const BinaryParagraph& bin
spgh.package = binary_paragraph;
spgh.want = want_t::install;
spgh.state = install_state_t::half_installed;
- for (const std::string& dependency : spgh.package.depends)
+ for (auto&& dep : spgh.package.depends)
{
- if (status_db.find_installed(dependency, spgh.package.spec.target_triplet()) == status_db.end())
+ if (status_db.find_installed(dep, spgh.package.spec.target_triplet()) == status_db.end())
{
- std::abort();
+ Checks::unreachable();
}
}
write_update(paths, spgh);
diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp
new file mode 100644
index 000000000..bce1cab0e
--- /dev/null
+++ b/toolsrc/src/tests_dependencies.cpp
@@ -0,0 +1,39 @@
+#include "CppUnitTest.h"
+#include "SourceParagraph.h"
+#include "triplet.h"
+
+#pragma comment(lib,"version")
+#pragma comment(lib,"winhttp")
+
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+
+using namespace vcpkg;
+
+namespace UnitTest1
+{
+ TEST_CLASS(DependencyTests)
+ {
+ public:
+ TEST_METHOD(parse_depends_one)
+ {
+ auto v = expand_qualified_dependencies(parse_depends("libA [windows]"));
+ Assert::AreEqual(size_t(1), v.size());
+ Assert::AreEqual("libA", v[0].name.c_str());
+ Assert::AreEqual("windows", v[0].qualifier.c_str());
+ }
+
+ TEST_METHOD(filter_depends)
+ {
+ auto deps = expand_qualified_dependencies(parse_depends("libA [windows], libB, libC [uwp]"));
+ auto v = filter_dependencies(deps, triplet::X64_WINDOWS);
+ Assert::AreEqual(size_t(2), v.size());
+ Assert::AreEqual("libA", v[0].c_str());
+ Assert::AreEqual("libB", v[1].c_str());
+
+ auto v2 = filter_dependencies(deps, triplet::ARM_UWP);
+ Assert::AreEqual(size_t(2), v.size());
+ Assert::AreEqual("libB", v2[0].c_str());
+ Assert::AreEqual("libC", v2[1].c_str());
+ }
+ };
+}
diff --git a/toolsrc/src/test.cpp b/toolsrc/src/tests_paragraph.cpp
index fc49b362d..b06359b90 100644
--- a/toolsrc/src/test.cpp
+++ b/toolsrc/src/tests_paragraph.cpp
@@ -48,7 +48,7 @@ namespace UnitTest1
Assert::AreEqual("m", pgh.maintainer.c_str());
Assert::AreEqual("d", pgh.description.c_str());
Assert::AreEqual(size_t(1), pgh.depends.size());
- Assert::AreEqual("bd", pgh.depends[0].c_str());
+ Assert::AreEqual("bd", pgh.depends[0].name.c_str());
}
TEST_METHOD(SourceParagraph_Two_Depends)
@@ -60,8 +60,8 @@ namespace UnitTest1
});
Assert::AreEqual(size_t(2), pgh.depends.size());
- Assert::AreEqual("z", pgh.depends[0].c_str());
- Assert::AreEqual("openssl", pgh.depends[1].c_str());
+ Assert::AreEqual("z", pgh.depends[0].name.c_str());
+ Assert::AreEqual("openssl", pgh.depends[1].name.c_str());
}
TEST_METHOD(SourceParagraph_Three_Depends)
@@ -73,17 +73,37 @@ namespace UnitTest1
});
Assert::AreEqual(size_t(3), pgh.depends.size());
- Assert::AreEqual("z", pgh.depends[0].c_str());
- Assert::AreEqual("openssl", pgh.depends[1].c_str());
- Assert::AreEqual("xyz", pgh.depends[2].c_str());
+ Assert::AreEqual("z", pgh.depends[0].name.c_str());
+ Assert::AreEqual("openssl", pgh.depends[1].name.c_str());
+ Assert::AreEqual("xyz", pgh.depends[2].name.c_str());
}
+ TEST_METHOD(SourceParagraph_Construct_Qualified_Depends)
+ {
+ vcpkg::SourceParagraph pgh({
+ { "Source", "zlib" },
+ { "Version", "1.2.8" },
+ { "Build-Depends", "libA [windows], libB [uwp]" }
+ });
+
+ Assert::AreEqual("zlib", pgh.name.c_str());
+ Assert::AreEqual("1.2.8", pgh.version.c_str());
+ Assert::AreEqual("", pgh.maintainer.c_str());
+ Assert::AreEqual("", pgh.description.c_str());
+ Assert::AreEqual(size_t(2), pgh.depends.size());
+ Assert::AreEqual("libA", pgh.depends[0].name.c_str());
+ Assert::AreEqual("windows", pgh.depends[0].qualifier.c_str());
+ Assert::AreEqual("libB", pgh.depends[1].name.c_str());
+ Assert::AreEqual("uwp", pgh.depends[1].qualifier.c_str());
+ }
+
+
TEST_METHOD(BinaryParagraph_Construct_Minimum)
{
vcpkg::BinaryParagraph pgh({
{"Package", "zlib"},
{"Version", "1.2.8"},
- {"Architecture", "a"},
+ {"Architecture", "x86-windows"},
{"Multi-Arch", "same"},
});
@@ -91,7 +111,7 @@ namespace UnitTest1
Assert::AreEqual("1.2.8", pgh.version.c_str());
Assert::AreEqual("", pgh.maintainer.c_str());
Assert::AreEqual("", pgh.description.c_str());
- Assert::AreEqual("a", pgh.spec.target_triplet().canonical_name().c_str());
+ Assert::AreEqual("x86-windows", pgh.spec.target_triplet().canonical_name().c_str());
Assert::AreEqual(size_t(0), pgh.depends.size());
}
@@ -100,7 +120,7 @@ namespace UnitTest1
vcpkg::BinaryParagraph pgh({
{"Package", "s"},
{"Version", "v"},
- {"Architecture", "a"},
+ {"Architecture", "x86-windows"},
{"Multi-Arch", "same"},
{"Maintainer", "m"},
{"Description", "d"},
@@ -119,7 +139,7 @@ namespace UnitTest1
vcpkg::BinaryParagraph pgh({
{"Package", "zlib"},
{"Version", "1.2.8"},
- {"Architecture", "a"},
+ {"Architecture", "x86-windows"},
{"Multi-Arch", "same"},
{"Depends", "a, b, c"},
});
@@ -253,7 +273,7 @@ namespace UnitTest1
vcpkg::BinaryParagraph pgh({
{"Package", "zlib"},
{"Version", "1.2.8"},
- {"Architecture", "a"},
+ {"Architecture", "x86-windows"},
{"Multi-Arch", "same"},
});
ss << pgh;
@@ -262,7 +282,7 @@ namespace UnitTest1
Assert::AreEqual(size_t(4), pghs[0].size());
Assert::AreEqual("zlib", pghs[0]["Package"].c_str());
Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str());
- Assert::AreEqual("a", pghs[0]["Architecture"].c_str());
+ Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str());
Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str());
}
@@ -272,7 +292,7 @@ namespace UnitTest1
vcpkg::BinaryParagraph pgh({
{"Package", "zlib"},
{"Version", "1.2.8"},
- {"Architecture", "a"},
+ {"Architecture", "x86-windows"},
{"Description", "first line\n second line"},
{"Maintainer", "abc <abc@abc.abc>"},
{"Depends", "dep"},
@@ -284,7 +304,7 @@ namespace UnitTest1
Assert::AreEqual(size_t(7), pghs[0].size());
Assert::AreEqual("zlib", pghs[0]["Package"].c_str());
Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str());
- Assert::AreEqual("a", pghs[0]["Architecture"].c_str());
+ Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str());
Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str());
Assert::AreEqual("first line\n second line", pghs[0]["Description"].c_str());
Assert::AreEqual("dep", pghs[0]["Depends"].c_str());
@@ -296,7 +316,7 @@ namespace UnitTest1
vcpkg::BinaryParagraph pgh({
{"Package", "zlib"},
{"Version", "1.2.8"},
- {"Architecture", "a"},
+ {"Architecture", "x86-windows"},
{"Multi-Arch", "same"},
{"Depends", "a, b, c"},
});
diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp
index db6c03480..453ba81fd 100644
--- a/toolsrc/src/vcpkg_Checks.cpp
+++ b/toolsrc/src/vcpkg_Checks.cpp
@@ -8,6 +8,9 @@ namespace vcpkg {namespace Checks
void unreachable()
{
System::println(System::color::error, "Error: Unreachable code was reached");
+#ifndef NDEBUG
+ std::abort();
+#endif
exit(EXIT_FAILURE);
}
diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp
index 54b37cd11..0e45b28dd 100644
--- a/toolsrc/src/vcpkg_Dependencies.cpp
+++ b/toolsrc/src/vcpkg_Dependencies.cpp
@@ -57,11 +57,9 @@ namespace vcpkg { namespace Dependencies
return build_dependency_graph(paths, specs, status_db).find_topological_sort();
}
- std::unordered_set<package_spec> find_unmet_dependencies(const vcpkg_paths& paths, const package_spec& spec, const StatusParagraphs& status_db)
+ std::unordered_set<package_spec> find_unmet_dependencies(const vcpkg_paths& paths, const std::vector<package_spec>& specs, const StatusParagraphs& status_db)
{
- const Graphs::Graph<package_spec> dependency_graph = build_dependency_graph(paths, {spec}, status_db);
- std::unordered_set<package_spec> key_set = Maps::extract_key_set(dependency_graph.adjacency_list());
- key_set.erase(spec);
- return key_set;
+ const Graphs::Graph<package_spec> dependency_graph = build_dependency_graph(paths, specs, status_db);
+ return Maps::extract_key_set(dependency_graph.adjacency_list());
}
}}
diff --git a/toolsrc/src/vcpkglib_helpers.cpp b/toolsrc/src/vcpkglib_helpers.cpp
index 3d14d4b06..61dc4f4cc 100644
--- a/toolsrc/src/vcpkglib_helpers.cpp
+++ b/toolsrc/src/vcpkglib_helpers.cpp
@@ -45,37 +45,4 @@ namespace vcpkg {namespace details
return value;
}
- std::vector<std::string> parse_depends(const std::string& depends_string)
- {
- if (depends_string.empty())
- {
- return {};
- }
-
- std::vector<std::string> out;
-
- size_t cur = 0;
- do
- {
- auto pos = depends_string.find(',', cur);
- if (pos == std::string::npos)
- {
- out.push_back(depends_string.substr(cur));
- break;
- }
- out.push_back(depends_string.substr(cur, pos - cur));
-
- // skip comma and space
- ++pos;
- if (depends_string[pos] == ' ')
- {
- ++pos;
- }
-
- cur = pos;
- }
- while (cur != std::string::npos);
-
- return out;
- }
}}