aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2015-04-04 17:36:30 -0700
committerAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2017-06-10 22:26:31 -0700
commite1b23f5d82571f9232bdbcd67a8540fe26375b31 (patch)
tree1020e1b6004e8b1fa9dd0cb9cd7e7853bcb77071
parent26c2a2fa0dfe79668ad8f5f225c6b575e3832ff3 (diff)
downloadpaludis-cross.tar.gz
paludis-cross.tar.xz
add support for cross-compilingcross
Native cross-compilation is only supported on exheres-0 and paludis-1 capable environments. Mark the distributions as supporting cross-compilation. Use this to enable the functionality. Adjust certain repositories to teach paludis that they cannot be cross-compiled to. Wire up the cross compile host to various helpers in the resolver to allow the host to be queried at various times to filter the package set as appropriate. Add UI to cave to access the cross-compilation support.
-rw-r--r--bash-completion/cave1
-rw-r--r--paludis/distribution.cc3
-rw-r--r--paludis/distribution.hh2
-rw-r--r--paludis/distributions/exherbo.conf1
-rw-r--r--paludis/distributions/gentoo.conf1
-rw-r--r--paludis/filter-fwd.hh2
-rw-r--r--paludis/filter.cc40
-rw-r--r--paludis/filter.hh7
-rw-r--r--paludis/repositories/accounts/accounts_id.cc1
-rw-r--r--paludis/repositories/accounts/installed_accounts_id.cc1
-rw-r--r--paludis/repositories/repository/repository_id.cc1
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_id.cc1
-rw-r--r--paludis/repositories/unpackaged/installed_id.cc1
-rw-r--r--paludis/resolver/allowed_to_remove_helper.cc22
-rw-r--r--paludis/resolver/allowed_to_remove_helper.hh2
-rw-r--r--paludis/resolver/destination_types.se1
-rw-r--r--paludis/resolver/destination_utils-fwd.hh2
-rw-r--r--paludis/resolver/destination_utils.cc50
-rw-r--r--paludis/resolver/find_replacing_helper.cc13
-rw-r--r--paludis/resolver/find_repository_for_helper.cc23
-rw-r--r--paludis/resolver/find_repository_for_helper.hh2
-rw-r--r--paludis/resolver/get_constraints_for_dependent_helper.cc23
-rw-r--r--paludis/resolver/get_constraints_for_dependent_helper.hh2
-rw-r--r--paludis/resolver/get_initial_constraints_for_helper.cc14
-rw-r--r--paludis/resolver/get_initial_constraints_for_helper.hh2
-rw-r--r--paludis/resolver/get_resolvents_for_helper.cc9
-rw-r--r--paludis/resolver/get_use_existing_nothing_helper.cc4
-rw-r--r--paludis/resolver/make_destination_filtered_generator_helper.cc11
-rw-r--r--paludis/resolver/make_destination_filtered_generator_helper.hh2
-rw-r--r--paludis/resolver/remove_if_dependent_helper.cc24
-rw-r--r--paludis/resolver/remove_if_dependent_helper.hh2
-rw-r--r--src/clients/cave/cmd_display_resolution.cc10
-rw-r--r--src/clients/cave/cmd_execute_resolution.cc5
-rw-r--r--src/clients/cave/cmd_fix_linkage.cc28
-rw-r--r--src/clients/cave/cmd_graph_jobs.cc5
-rw-r--r--src/clients/cave/cmd_uninstall.cc5
-rw-r--r--src/clients/cave/resolve_cmdline.cc14
-rw-r--r--src/clients/cave/resolve_cmdline.hh1
-rw-r--r--src/clients/cave/resolve_common.cc16
39 files changed, 339 insertions, 15 deletions
diff --git a/bash-completion/cave b/bash-completion/cave
index a107b57..f06e52a 100644
--- a/bash-completion/cave
+++ b/bash-completion/cave
@@ -127,6 +127,7 @@ __cave_resolve_options="-h --help
-B --no-binaries-for
-/ --install-to-root --no-install-to-root
-2 --chroot-path
+ -4 --cross-host
--dump --no-dump
--dump-restarts --no-dump-restarts
-1 --preserve-world --no-preserve-world
diff --git a/paludis/distribution.cc b/paludis/distribution.cc
index 08dbfb0..0b6485c 100644
--- a/paludis/distribution.cc
+++ b/paludis/distribution.cc
@@ -73,7 +73,8 @@ namespace paludis
n::extra_data_dir() = FSPath(strip_trailing_string(stringify(d->realpath()), ".conf")),
n::fallback_environment() = k.get("fallback_environment"),
n::name() = strip_trailing_string(d->basename(), ".conf"),
- n::paludis_package() = k.get("paludis_package")
+ n::paludis_package() = k.get("paludis_package"),
+ n::supports_cross_compile() = destringify<bool>(k.get("supports_cross_compile"))
))));
}
}
diff --git a/paludis/distribution.hh b/paludis/distribution.hh
index 43dd664..656412c 100644
--- a/paludis/distribution.hh
+++ b/paludis/distribution.hh
@@ -54,6 +54,7 @@ namespace paludis
typedef Name<struct name_fallback_environment> fallback_environment;
typedef Name<struct name_name> name;
typedef Name<struct name_paludis_package> paludis_package;
+ typedef Name<struct name_supports_cross_compile> supports_cross_compile;
}
/**
@@ -77,6 +78,7 @@ namespace paludis
NamedValue<n::fallback_environment, std::string> fallback_environment;
NamedValue<n::name, std::string> name;
NamedValue<n::paludis_package, std::string> paludis_package;
+ NamedValue<n::supports_cross_compile, bool> supports_cross_compile;
};
/**
diff --git a/paludis/distributions/exherbo.conf b/paludis/distributions/exherbo.conf
index cadfbca..dc91dd6 100644
--- a/paludis/distributions/exherbo.conf
+++ b/paludis/distributions/exherbo.conf
@@ -6,4 +6,5 @@ concept_use = Option flag
default_environment = paludis
fallback_environment =
paludis_package = sys-apps/paludis
+supports_cross_compile = true
diff --git a/paludis/distributions/gentoo.conf b/paludis/distributions/gentoo.conf
index 78a65b0..7e97355 100644
--- a/paludis/distributions/gentoo.conf
+++ b/paludis/distributions/gentoo.conf
@@ -6,4 +6,5 @@ concept_use = USE flag
default_environment = paludis
fallback_environment = portage
paludis_package = sys-apps/paludis
+supports_cross_compile = false
diff --git a/paludis/filter-fwd.hh b/paludis/filter-fwd.hh
index 2cbc5df..bc70950 100644
--- a/paludis/filter-fwd.hh
+++ b/paludis/filter-fwd.hh
@@ -46,6 +46,8 @@ namespace paludis
class InstalledAtRoot;
class InstalledAtSlash;
class InstalledAtNotSlash;
+
+ class CrossCompileHost;
}
/**
diff --git a/paludis/filter.cc b/paludis/filter.cc
index ea569ec..fe3e53e 100644
--- a/paludis/filter.cc
+++ b/paludis/filter.cc
@@ -250,6 +250,41 @@ namespace
}
};
+ struct CrossCompileHostHandler :
+ AllFilterHandlerBase
+ {
+ const std::string & host;
+
+ CrossCompileHostHandler(const std::string & h) : host(h)
+ {
+ }
+
+ std::shared_ptr<const RepositoryNameSet>
+ repositories(const Environment * const env, const std::shared_ptr<const RepositoryNameSet> & repos) const override
+ {
+ auto result = std::make_shared<RepositoryNameSet>();
+
+ if (host.empty())
+ for (const auto & repository : *repos)
+ if (auto cross_ompile_host_key = env->fetch_repository(repository)->cross_compile_host_key())
+ continue;
+ else
+ result->insert(repository);
+ else
+ for (const auto & repository : *repos)
+ if (auto cross_compile_host_key = env->fetch_repository(repository)->cross_compile_host_key())
+ if (cross_compile_host_key->parse_value() == host)
+ result->insert(repository);
+
+ return result;
+ }
+
+ std::string as_string() const override
+ {
+ return "cross compiled to " + host;
+ }
+ };
+
struct AndFilterHandler :
FilterHandler
{
@@ -521,6 +556,11 @@ filter::InstalledAtNotSlash::InstalledAtNotSlash() :
{
}
+filter::CrossCompileHost::CrossCompileHost(const std::string & host) :
+ Filter(std::make_shared<CrossCompileHostHandler>(host))
+{
+}
+
filter::And::And(const Filter & f1, const Filter & f2) :
Filter(std::make_shared<AndFilterHandler>(f1, f2))
{
diff --git a/paludis/filter.hh b/paludis/filter.hh
index 14fd195..a39605b 100644
--- a/paludis/filter.hh
+++ b/paludis/filter.hh
@@ -224,6 +224,13 @@ namespace paludis
InstalledAtNotSlash();
};
+ class PALUDIS_VISIBLE CrossCompileHost :
+ public Filter
+ {
+ public:
+ CrossCompileHost(const std::string & host);
+ };
+
/**
* A Filter which accepts only PackageID instances that are accepted by
* two different filters.
diff --git a/paludis/repositories/accounts/accounts_id.cc b/paludis/repositories/accounts/accounts_id.cc
index 2eaac01..c77b483 100644
--- a/paludis/repositories/accounts/accounts_id.cc
+++ b/paludis/repositories/accounts/accounts_id.cc
@@ -58,6 +58,7 @@ namespace
{
behaviours_value->insert("unbinaryable");
behaviours_value->insert("unchrootable");
+ behaviours_value->insert("uncrossable");
}
};
}
diff --git a/paludis/repositories/accounts/installed_accounts_id.cc b/paludis/repositories/accounts/installed_accounts_id.cc
index ccc876c..47107bc 100644
--- a/paludis/repositories/accounts/installed_accounts_id.cc
+++ b/paludis/repositories/accounts/installed_accounts_id.cc
@@ -61,6 +61,7 @@ namespace
behaviours_value->insert("transient");
behaviours_value->insert("used");
behaviours_value->insert("unbinaryable");
+ behaviours_value->insert("uncrossable");
}
};
}
diff --git a/paludis/repositories/repository/repository_id.cc b/paludis/repositories/repository/repository_id.cc
index b883165..17a8c68 100644
--- a/paludis/repositories/repository/repository_id.cc
+++ b/paludis/repositories/repository/repository_id.cc
@@ -51,6 +51,7 @@ namespace
{
behaviours_value->insert("transient");
behaviours_value->insert("used");
+ behaviours_value->insert("uncrossable");
}
};
}
diff --git a/paludis/repositories/unavailable/unavailable_repository_id.cc b/paludis/repositories/unavailable/unavailable_repository_id.cc
index fe514a7..9b1ca74 100644
--- a/paludis/repositories/unavailable/unavailable_repository_id.cc
+++ b/paludis/repositories/unavailable/unavailable_repository_id.cc
@@ -54,6 +54,7 @@ namespace
{
behaviours_value->insert("unbinaryable");
behaviours_value->insert("unchrootable");
+ behaviours_value->insert("uncrossable");
}
};
}
diff --git a/paludis/repositories/unpackaged/installed_id.cc b/paludis/repositories/unpackaged/installed_id.cc
index efb271e..ae8bc74 100644
--- a/paludis/repositories/unpackaged/installed_id.cc
+++ b/paludis/repositories/unpackaged/installed_id.cc
@@ -76,6 +76,7 @@ namespace
run_dependencies_labels(std::make_shared<DependenciesLabelSequence>())
{
behaviours_value->insert("transient");
+ behaviours_value->insert("uncrossable");
build_dependencies_labels->push_back(std::make_shared<AlwaysEnabledDependencyLabel<DependenciesBuildLabelTag> >("build_dependencies"));
run_dependencies_labels->push_back(std::make_shared<AlwaysEnabledDependencyLabel<DependenciesRunLabelTag> >("run_dependencies"));
diff --git a/paludis/resolver/allowed_to_remove_helper.cc b/paludis/resolver/allowed_to_remove_helper.cc
index 8db14c4..25c45bc 100644
--- a/paludis/resolver/allowed_to_remove_helper.cc
+++ b/paludis/resolver/allowed_to_remove_helper.cc
@@ -24,7 +24,11 @@
#include <paludis/resolver/resolution.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
+#include <paludis/metadata_key.hh>
#include <paludis/package_dep_spec_collection.hh>
+#include <paludis/package_id.hh>
+#include <paludis/repository.hh>
using namespace paludis;
using namespace paludis::resolver;
@@ -36,6 +40,7 @@ namespace paludis
{
const Environment * const env;
PackageDepSpecCollection allowed_to_remove_specs;
+ std::string cross_compile_host;
Imp(const Environment * const e) : env(e), allowed_to_remove_specs(nullptr)
{
@@ -56,10 +61,25 @@ AllowedToRemoveHelper::add_allowed_to_remove_spec(const PackageDepSpec & spec)
_imp->allowed_to_remove_specs.insert(spec);
}
+void
+AllowedToRemoveHelper::set_cross_compile_host(const std::string & host)
+{
+ _imp->cross_compile_host = host;
+}
+
bool
AllowedToRemoveHelper::operator()(const std::shared_ptr<const Resolution> & resolution,
const std::shared_ptr<const PackageID> & id) const
{
+ auto cross_compile_host_matches = [this, &id] {
+ auto repository = _imp->env->fetch_repository(id->repository_name());
+ auto cross_compile_host_key = repository->cross_compile_host_key();
+
+ if (_imp->cross_compile_host.empty())
+ return ! cross_compile_host_key;
+ return cross_compile_host_key && cross_compile_host_key->parse_value() == _imp->cross_compile_host;
+ };
+
auto v = make_visitor([&](const DependentReason &) { return true; },
[&](const TargetReason &) { return true; },
[&](const DependencyReason &) { return false; },
@@ -71,7 +91,7 @@ AllowedToRemoveHelper::operator()(const std::shared_ptr<const Resolution> & reso
for (const auto & constraint : *resolution->constraints())
if (constraint->reason()->accept_returning<bool>(v))
- return true;
+ return cross_compile_host_matches();
return _imp->allowed_to_remove_specs.match_any(_imp->env, id, {});
}
diff --git a/paludis/resolver/allowed_to_remove_helper.hh b/paludis/resolver/allowed_to_remove_helper.hh
index abe3f71..714e0f5 100644
--- a/paludis/resolver/allowed_to_remove_helper.hh
+++ b/paludis/resolver/allowed_to_remove_helper.hh
@@ -44,6 +44,8 @@ namespace paludis
void add_allowed_to_remove_spec(const PackageDepSpec &);
+ void set_cross_compile_host(const std::string &);
+
bool operator()(const std::shared_ptr<const Resolution> &,
const std::shared_ptr<const PackageID> &) const;
};
diff --git a/paludis/resolver/destination_types.se b/paludis/resolver/destination_types.se
index e982d3d..e8d5503 100644
--- a/paludis/resolver/destination_types.se
+++ b/paludis/resolver/destination_types.se
@@ -9,6 +9,7 @@ make_enum_DestinationType()
key dt_install_to_slash "Install to the / fs"
key dt_install_to_chroot "Install to the chroot"
key dt_create_binary "Create a binary"
+ key dt_cross_compile "cross compile"
want_destringify
}
diff --git a/paludis/resolver/destination_utils-fwd.hh b/paludis/resolver/destination_utils-fwd.hh
index 012c609..b86d8b2 100644
--- a/paludis/resolver/destination_utils-fwd.hh
+++ b/paludis/resolver/destination_utils-fwd.hh
@@ -35,6 +35,8 @@ namespace paludis
bool can_make_binary_for(const std::shared_ptr<const PackageID> & id) PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE;
bool is_already_binary(const std::shared_ptr<const PackageID> & id) PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE;
bool can_chroot(const std::shared_ptr<const PackageID> & id) PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE;
+ bool can_cross_compile(const std::shared_ptr<const PackageID> & id)
+ PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE;
FilteredGenerator destination_filtered_generator(
const Environment * const,
diff --git a/paludis/resolver/destination_utils.cc b/paludis/resolver/destination_utils.cc
index de25a35..6c3efae 100644
--- a/paludis/resolver/destination_utils.cc
+++ b/paludis/resolver/destination_utils.cc
@@ -60,6 +60,16 @@ paludis::resolver::can_chroot(const std::shared_ptr<const PackageID> & id)
return v->end() == v->find("unchrootable");
}
+bool
+paludis::resolver::can_cross_compile(const std::shared_ptr<const PackageID> & id)
+{
+ if (! id->behaviours_key())
+ return true;
+
+ auto v(id->behaviours_key()->parse_value());
+ return v->end() == v->find("uncrossable");
+}
+
namespace
{
struct BinaryDestinationGeneratorHandler :
@@ -93,6 +103,37 @@ namespace
{
}
};
+
+ struct CrossCompiledGeneratorHandler :
+ AllGeneratorHandlerBase
+ {
+ std::shared_ptr<const RepositoryNameSet>
+ repositories(const Environment * const env,
+ const RepositoryContentMayExcludes &) const override
+ {
+ auto result(std::make_shared<RepositoryNameSet>());
+
+ for (const auto & repository : env->repositories())
+ if (repository->cross_compile_host_key())
+ result->insert(repository->name());
+
+ return result;
+ }
+
+ std::string as_string() const override
+ {
+ return "cross-compiled destination repositories";
+ }
+ };
+
+ struct CrossCompiledDestinationGenerator :
+ Generator
+ {
+ CrossCompiledDestinationGenerator()
+ : Generator(std::make_shared<CrossCompiledGeneratorHandler>())
+ {
+ }
+ };
}
FilteredGenerator
@@ -111,6 +152,9 @@ paludis::resolver::destination_filtered_generator(const Environment * const env,
case dt_create_binary:
return g & BinaryDestinationGenerator();
+ case dt_cross_compile:
+ return g & CrossCompiledDestinationGenerator();
+
case last_dt:
break;
}
@@ -119,8 +163,7 @@ paludis::resolver::destination_filtered_generator(const Environment * const env,
}
Filter
-paludis::resolver::make_destination_type_filter(
- const DestinationType t)
+paludis::resolver::make_destination_type_filter(const DestinationType t)
{
switch (t)
{
@@ -136,6 +179,9 @@ paludis::resolver::make_destination_type_filter(
},
"can be made into a binary");
+ case dt_cross_compile:
+ return filter::All();
+
case last_dt:
break;
}
diff --git a/paludis/resolver/find_replacing_helper.cc b/paludis/resolver/find_replacing_helper.cc
index f1d4cb9..fd9b314 100644
--- a/paludis/resolver/find_replacing_helper.cc
+++ b/paludis/resolver/find_replacing_helper.cc
@@ -78,10 +78,21 @@ FindReplacingHelper::operator()(const std::shared_ptr<const PackageID> & id,
if (repo->installed_root_key())
{
const auto & dest_root = repo->installed_root_key()->parse_value();
+ const auto & dest_host =
+ repo->cross_compile_host_key()
+ ? repo->cross_compile_host_key()->parse_value()
+ : "";
for (const auto & repository : _imp->env->repositories())
- if (repository->installed_root_key() && repository->installed_root_key()->parse_value() == dest_root)
+ {
+ const auto & repo_host =
+ repository->cross_compile_host_key()
+ ? repository->cross_compile_host_key()->parse_value()
+ : "";
+
+ if ((repository->installed_root_key() && repository->installed_root_key()->parse_value() == dest_root) && repo_host == dest_host)
repos.insert(repository->name());
+ }
}
else
repos.insert(repo->name());
diff --git a/paludis/resolver/find_repository_for_helper.cc b/paludis/resolver/find_repository_for_helper.cc
index 18432d8..2d76df1 100644
--- a/paludis/resolver/find_repository_for_helper.cc
+++ b/paludis/resolver/find_repository_for_helper.cc
@@ -45,6 +45,7 @@ namespace paludis
{
const Environment * const env;
std::unique_ptr<const FSPath> chroot_path;
+ std::string cross_compile_host;
Imp(const Environment * const e) :
env(e)
@@ -80,11 +81,15 @@ FindRepositoryForHelper::operator() (
switch (resolution->resolvent().destination_type())
{
case dt_install_to_slash:
- if ((!repository->installed_root_key()) || (repository->installed_root_key()->parse_value() != _imp->env->system_root_key()->parse_value()))
+ if (repository->cross_compile_host_key() || (!repository->installed_root_key()) ||
+ (repository->installed_root_key()->parse_value() != _imp->env->system_root_key()->parse_value()))
continue;
break;
case dt_install_to_chroot:
+ if (repository->cross_compile_host_key())
+ continue;
+
if (_imp->chroot_path) {
if ((!repository->installed_root_key()) || (repository->installed_root_key()->parse_value() != *_imp->chroot_path))
continue;
@@ -100,6 +105,16 @@ FindRepositoryForHelper::operator() (
continue;
break;
+ case dt_cross_compile:
+ if (! repository->cross_compile_host_key())
+ continue;
+
+ if (! _imp->cross_compile_host.empty())
+ if (repository->cross_compile_host_key()->parse_value() != _imp->cross_compile_host)
+ continue;
+
+ break;
+
case last_dt:
break;
}
@@ -135,6 +150,12 @@ FindRepositoryForHelper::set_chroot_path(const FSPath & p)
_imp->chroot_path.reset(new FSPath(p));
}
+void
+FindRepositoryForHelper::set_cross_compile_host(const std::string & target)
+{
+ _imp->cross_compile_host = target;
+}
+
namespace paludis
{
template class Pimp<FindRepositoryForHelper>;
diff --git a/paludis/resolver/find_repository_for_helper.hh b/paludis/resolver/find_repository_for_helper.hh
index 34cb544..8407e2b 100644
--- a/paludis/resolver/find_repository_for_helper.hh
+++ b/paludis/resolver/find_repository_for_helper.hh
@@ -45,6 +45,8 @@ namespace paludis
void set_chroot_path(const FSPath &);
+ void set_cross_compile_host(const std::string &);
+
const std::shared_ptr<const Repository> operator() (
const std::shared_ptr<const Resolution> &,
const ChangesToMakeDecision &) const;
diff --git a/paludis/resolver/get_constraints_for_dependent_helper.cc b/paludis/resolver/get_constraints_for_dependent_helper.cc
index 4e45398..76e768a 100644
--- a/paludis/resolver/get_constraints_for_dependent_helper.cc
+++ b/paludis/resolver/get_constraints_for_dependent_helper.cc
@@ -29,9 +29,12 @@
#include <paludis/util/make_named_values.hh>
#include <paludis/util/stringify.hh>
#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
+#include <paludis/metadata_key.hh>
#include <paludis/package_id.hh>
#include <paludis/package_dep_spec_collection.hh>
#include <paludis/partially_made_package_dep_spec.hh>
+#include <paludis/repository.hh>
#include <paludis/elike_slot_requirement.hh>
#include <paludis/metadata_key.hh>
#include <paludis/slot.hh>
@@ -46,6 +49,7 @@ namespace paludis
{
const Environment * const env;
PackageDepSpecCollection less_restrictive_remove_blockers_specs;
+ std::string cross_compile_host;
Imp(const Environment * const e) : env(e), less_restrictive_remove_blockers_specs(nullptr)
{
@@ -66,11 +70,30 @@ GetConstraintsForDependentHelper::add_less_restrictive_remove_blockers_spec(cons
_imp->less_restrictive_remove_blockers_specs.insert(spec);
}
+void
+GetConstraintsForDependentHelper::set_cross_compile_host(const std::string & host)
+{
+ _imp->cross_compile_host = host;
+}
+
const std::shared_ptr<ConstraintSequence>
GetConstraintsForDependentHelper::operator()(const std::shared_ptr<const Resolution> &,
const std::shared_ptr<const PackageID> & id,
const std::shared_ptr<const DependentPackageIDSequence> & dependent_upon_ids) const
{
+ auto repository = _imp->env->fetch_repository(id->repository_name());
+ auto cross_compile_host_key = repository->cross_compile_host_key();
+ if (_imp->cross_compile_host.empty())
+ {
+ if (cross_compile_host_key)
+ return std::make_shared<ConstraintSequence>();
+ }
+ else
+ {
+ if (! cross_compile_host_key || cross_compile_host_key->parse_value() != _imp->cross_compile_host)
+ return std::make_shared<ConstraintSequence>();
+ }
+
auto result(std::make_shared<ConstraintSequence>());
std::shared_ptr<PackageDepSpec> spec;
diff --git a/paludis/resolver/get_constraints_for_dependent_helper.hh b/paludis/resolver/get_constraints_for_dependent_helper.hh
index b5f30ca..432f56e 100644
--- a/paludis/resolver/get_constraints_for_dependent_helper.hh
+++ b/paludis/resolver/get_constraints_for_dependent_helper.hh
@@ -50,6 +50,8 @@ namespace paludis
void add_less_restrictive_remove_blockers_spec(const PackageDepSpec &);
+ void set_cross_compile_host(const std::string &);
+
const std::shared_ptr<ConstraintSequence> operator()(const std::shared_ptr<const Resolution> &,
const std::shared_ptr<const PackageID> &,
const std::shared_ptr<const DependentPackageIDSequence> &) const;
diff --git a/paludis/resolver/get_initial_constraints_for_helper.cc b/paludis/resolver/get_initial_constraints_for_helper.cc
index a132700..4f823fa 100644
--- a/paludis/resolver/get_initial_constraints_for_helper.cc
+++ b/paludis/resolver/get_initial_constraints_for_helper.cc
@@ -60,6 +60,7 @@ namespace paludis
std::list<PackageDepSpec> without_specs;
int reinstall_scm_days;
+ std::string cross_compile_host;
InitialConstraints initial_constraints;
@@ -132,6 +133,12 @@ GetInitialConstraintsForHelper::set_reinstall_scm_days(const int d)
_imp->reinstall_scm_days = d;
}
+void
+GetInitialConstraintsForHelper::set_cross_compile_host(const std::string & host)
+{
+ _imp->cross_compile_host = host;
+}
+
const std::shared_ptr<Constraints>
GetInitialConstraintsForHelper::operator() (const Resolvent & resolvent) const
{
@@ -186,13 +193,14 @@ namespace
}
bool installed_is_scm_older_than(const Environment * const env,
- const Resolvent & r, const int n)
+ const Resolvent & r,
+ const std::string & host, const int n)
{
Context context("When working out whether '" + stringify(r) + "' has installed SCM packages:");
const std::shared_ptr<const PackageIDSequence> ids =
(*env)[selection::AllVersionsUnsorted(destination_filtered_generator(env, r.destination_type(), generator::Package(r.package())) |
- make_slot_filter(r))];
+ make_slot_filter(r) | filter::CrossCompileHost(host))];
for (const auto & package : *ids)
if (is_scm_older_than(package, n))
@@ -217,7 +225,7 @@ GetInitialConstraintsForHelper::_make_initial_constraints_for(const Resolvent &
auto result(std::make_shared<Constraints>());
if ((-1 != _imp->reinstall_scm_days) &&
- installed_is_scm_older_than(_imp->env, resolvent, _imp->reinstall_scm_days) &&
+ installed_is_scm_older_than(_imp->env, resolvent, _imp->cross_compile_host, _imp->reinstall_scm_days) &&
! use_existing_from_withish(_imp->env, resolvent.package(), _imp->without_specs))
{
result->add(std::make_shared<Constraint>(make_named_values<Constraint>(
diff --git a/paludis/resolver/get_initial_constraints_for_helper.hh b/paludis/resolver/get_initial_constraints_for_helper.hh
index 7e90c85..3a3295d 100644
--- a/paludis/resolver/get_initial_constraints_for_helper.hh
+++ b/paludis/resolver/get_initial_constraints_for_helper.hh
@@ -55,6 +55,8 @@ namespace paludis
void set_reinstall_scm_days(const int);
+ void set_cross_compile_host(const std::string &);
+
const std::shared_ptr<Constraints> operator()(const Resolvent &) const;
};
}
diff --git a/paludis/resolver/get_resolvents_for_helper.cc b/paludis/resolver/get_resolvents_for_helper.cc
index d6df5a3..88ad1f0 100644
--- a/paludis/resolver/get_resolvents_for_helper.cc
+++ b/paludis/resolver/get_resolvents_for_helper.cc
@@ -222,6 +222,12 @@ namespace
}
break;
+ case dt_cross_compile:
+ if (is_run_or_post_dep(env, package_id, dep.sanitised_dependency()))
+ if (can_cross_compile(package_id))
+ return DestinationTypes{dt_cross_compile};
+ return DestinationTypes{ };
+
case dt_install_to_slash:
break;
@@ -274,6 +280,9 @@ namespace
case dt_install_to_slash:
return filter::InstalledAtRoot(env->system_root_key()->parse_value());
+ case dt_cross_compile:
+ return filter::InstalledAtRoot(env->system_root_key()->parse_value());
+
case last_dt:
break;
}
diff --git a/paludis/resolver/get_use_existing_nothing_helper.cc b/paludis/resolver/get_use_existing_nothing_helper.cc
index 1f86e4d..a505d13 100644
--- a/paludis/resolver/get_use_existing_nothing_helper.cc
+++ b/paludis/resolver/get_use_existing_nothing_helper.cc
@@ -136,6 +136,10 @@ namespace
can = &can_chroot;
break;
+ case dt_cross_compile:
+ can = &can_cross_compile;
+ break;
+
case last_dt:
break;
}
diff --git a/paludis/resolver/make_destination_filtered_generator_helper.cc b/paludis/resolver/make_destination_filtered_generator_helper.cc
index 27b9d99..b984846 100644
--- a/paludis/resolver/make_destination_filtered_generator_helper.cc
+++ b/paludis/resolver/make_destination_filtered_generator_helper.cc
@@ -42,6 +42,7 @@ namespace paludis
struct Imp<MakeDestinationFilteredGeneratorHelper>
{
const Environment * const env;
+ std::string cross_compile_host;
Imp(const Environment * const e) : env(e)
{
@@ -56,11 +57,19 @@ MakeDestinationFilteredGeneratorHelper::MakeDestinationFilteredGeneratorHelper(c
MakeDestinationFilteredGeneratorHelper::~MakeDestinationFilteredGeneratorHelper() = default;
+void
+MakeDestinationFilteredGeneratorHelper::set_cross_compile_host(const std::string & host)
+{
+ _imp->cross_compile_host = host;
+}
+
FilteredGenerator
MakeDestinationFilteredGeneratorHelper::operator()(const Generator & g,
const std::shared_ptr<const Resolution> & r) const
{
- return destination_filtered_generator(_imp->env, r->resolvent().destination_type(), g);
+ auto cross_compile_filter = _imp->cross_compile_host.empty() ? Filter(filter::All())
+ : filter::CrossCompileHost(_imp->cross_compile_host);
+ return destination_filtered_generator(_imp->env, r->resolvent().destination_type(), g) | cross_compile_filter;
}
namespace paludis
diff --git a/paludis/resolver/make_destination_filtered_generator_helper.hh b/paludis/resolver/make_destination_filtered_generator_helper.hh
index c68a116..738bd9f 100644
--- a/paludis/resolver/make_destination_filtered_generator_helper.hh
+++ b/paludis/resolver/make_destination_filtered_generator_helper.hh
@@ -42,6 +42,8 @@ namespace paludis
explicit MakeDestinationFilteredGeneratorHelper(const Environment * const);
~MakeDestinationFilteredGeneratorHelper();
+ void set_cross_compile_host(const std::string & host);
+
FilteredGenerator operator()(const Generator &,
const std::shared_ptr<const Resolution> &) const;
};
diff --git a/paludis/resolver/remove_if_dependent_helper.cc b/paludis/resolver/remove_if_dependent_helper.cc
index efe25b9..eed736c 100644
--- a/paludis/resolver/remove_if_dependent_helper.cc
+++ b/paludis/resolver/remove_if_dependent_helper.cc
@@ -24,7 +24,11 @@
#include <paludis/resolver/resolution.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
+#include <paludis/metadata_key.hh>
#include <paludis/package_dep_spec_collection.hh>
+#include <paludis/package_id.hh>
+#include <paludis/repository.hh>
using namespace paludis;
using namespace paludis::resolver;
@@ -36,6 +40,7 @@ namespace paludis
{
const Environment * const env;
PackageDepSpecCollection remove_if_dependent_specs;
+ std::string cross_compile_host;
Imp(const Environment * const e) : env(e), remove_if_dependent_specs(nullptr)
{
@@ -56,9 +61,28 @@ RemoveIfDependentHelper::add_remove_if_dependent_spec(const PackageDepSpec & spe
_imp->remove_if_dependent_specs.insert(spec);
}
+void
+RemoveIfDependentHelper::set_cross_compile_host(const std::string & host)
+{
+ _imp->cross_compile_host = host;
+}
+
bool
RemoveIfDependentHelper::operator()(const std::shared_ptr<const PackageID> & id) const
{
+ auto repository = _imp->env->fetch_repository(id->repository_name());
+ auto cross_compile_host_key = repository->cross_compile_host_key();
+ if (_imp->cross_compile_host.empty())
+ {
+ if (cross_compile_host_key)
+ return false;
+ }
+ else
+ {
+ if (! cross_compile_host_key || cross_compile_host_key->parse_value() != _imp->cross_compile_host)
+ return false;
+ }
+
return _imp->remove_if_dependent_specs.match_any(_imp->env, id, { });
}
diff --git a/paludis/resolver/remove_if_dependent_helper.hh b/paludis/resolver/remove_if_dependent_helper.hh
index e0052a6..44475c5 100644
--- a/paludis/resolver/remove_if_dependent_helper.hh
+++ b/paludis/resolver/remove_if_dependent_helper.hh
@@ -44,6 +44,8 @@ namespace paludis
void add_remove_if_dependent_spec(const PackageDepSpec &);
+ void set_cross_compile_host(const std::string &);
+
bool operator()(const std::shared_ptr<const PackageID> &) const;
};
}
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index fb885e9..8efeb61 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -364,6 +364,10 @@ namespace
result << ", creating a binary";
break;
+ case dt_cross_compile:
+ result << ", cross compiling";
+ break;
+
case last_dt:
break;
}
@@ -1165,6 +1169,12 @@ namespace
++maybe_totals->binary_installs_count;
continue;
+ case dt_cross_compile:
+ c = c::pink().colour_string();
+ if (maybe_totals)
+ ++maybe_totals->installs_ct_count.insert(std::make_pair(decision.change_type(), 0)).first->second;
+ continue;
+
case last_dt:
break;
}
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc
index 101572b..5cccb22 100644
--- a/src/clients/cave/cmd_execute_resolution.cc
+++ b/src/clients/cave/cmd_execute_resolution.cc
@@ -864,6 +864,11 @@ namespace
action_string = "create binary in ::" + stringify(install_item.destination_repository_name());
break;
+ case dt_cross_compile:
+ destination_string = "cross compiling";
+ action_string = "cross compile";
+ break;
+
case last_dt:
break;
}
diff --git a/src/clients/cave/cmd_fix_linkage.cc b/src/clients/cave/cmd_fix_linkage.cc
index f070225..7097694 100644
--- a/src/clients/cave/cmd_fix_linkage.cc
+++ b/src/clients/cave/cmd_fix_linkage.cc
@@ -32,12 +32,14 @@
#include <paludis/package_id.hh>
#include <paludis/name.hh>
#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/metadata_key.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/version_operator.hh>
#include <paludis/version_requirements.hh>
#include <paludis/partially_made_package_dep_spec.hh>
+#include <paludis/repository.hh>
#include <paludis/slot.hh>
#include <iostream>
@@ -199,6 +201,30 @@ FixLinkageCommand::run(const std::shared_ptr<Environment> & env,
{
cout << endl;
+ auto repository = env->fetch_repository(package->repository_name());
+ auto cross_compile_host = repository->cross_compile_host_key();
+
+ if (! (resolve_cmdline.resolution_options.a_cross_host.specified()
+ ? (cross_compile_host && cross_compile_host->parse_value() == resolve_cmdline.resolution_options.a_cross_host.argument())
+ : !cross_compile_host))
+ {
+ cout << endl;
+
+ if (cross_compile_host)
+ cout << "The following broken files are owned by a foreign cross-compiled target ("
+ << stringify(package->name()) << " x " << stringify(cross_compile_host->parse_value()) << "):";
+ else
+ cout << "The following broken files are owned by the default target:";
+
+ cout << endl;
+
+ for (const auto & file : finder->broken_files(package))
+ cout << " " << file << " (requires " << join(finder->begin_missing_requirements(package, file),
+ finder->end_missing_requirements(package, file), " ") << ")"
+ << endl;
+ continue;
+ }
+
cout << "* " << *package << endl;
std::set<FSPath, FSPathComparator> broken_files;
@@ -239,6 +265,8 @@ FixLinkageCommand::run(const std::shared_ptr<Environment> & env,
}
}
+ if (targets->empty())
+ return 0;
return resolve_common(env, resolve_cmdline.resolution_options, resolve_cmdline.execution_options, resolve_cmdline.display_options, resolve_cmdline.graph_jobs_options,
resolve_cmdline.program_options, nullptr, targets, nullptr, false);
}
diff --git a/src/clients/cave/cmd_graph_jobs.cc b/src/clients/cave/cmd_graph_jobs.cc
index 351bbe4..1d6b0c2 100644
--- a/src/clients/cave/cmd_graph_jobs.cc
+++ b/src/clients/cave/cmd_graph_jobs.cc
@@ -132,6 +132,11 @@ namespace
output_stream << "fillcolor=steelblue, ";
break;
+ case dt_cross_compile:
+ output_stream << "shape=doublehexagon, ";
+ output_stream << "fillcolor=deeppink, ";
+ break;
+
case last_dt:
break;
}
diff --git a/src/clients/cave/cmd_uninstall.cc b/src/clients/cave/cmd_uninstall.cc
index de907f0..6ba716e 100644
--- a/src/clients/cave/cmd_uninstall.cc
+++ b/src/clients/cave/cmd_uninstall.cc
@@ -135,7 +135,10 @@ UninstallCommand::run(
p != p_end ; ++p)
{
PackageDepSpec spec(parse_spec_with_nice_error(*p, env.get(), { updso_allow_wildcards }, filter::All()));
- const auto ids((*env)[selection::AllVersionsSorted(generator::Matches(spec, nullptr, { }) | filter::SupportsAction<UninstallAction>())]);
+ const std::string & cross_host = cmdline.resolution_options->a_cross_host.specified() ? cmdline.resolution_options->a_cross_host.argument() : "";
+ const auto ids =
+ (*env)[selection::AllVersionsSorted(generator::Matches(spec, nullptr, {}) | filter::SupportsAction<UninstallAction>() | filter::CrossCompileHost(cross_host))];
+
if (ids->empty())
nothing_matching_error(env.get(), *p, filter::SupportsAction<UninstallAction>());
else if ((! cmdline.a_all_versions.specified()) && has_multiple_versions(ids))
diff --git a/src/clients/cave/resolve_cmdline.cc b/src/clients/cave/resolve_cmdline.cc
index 8a924a9..42bf4e8 100644
--- a/src/clients/cave/resolve_cmdline.cc
+++ b/src/clients/cave/resolve_cmdline.cc
@@ -19,11 +19,13 @@
#include "resolve_cmdline.hh"
#include <paludis/args/do_help.hh>
+#include <paludis/distribution.hh>
#include <paludis/repository.hh>
#include <paludis/environment.hh>
#include <paludis/util/map.hh>
#include <paludis/util/log.hh>
#include <paludis/repository_factory.hh>
+#include <iostream>
#include <memory>
using namespace paludis;
@@ -269,8 +271,10 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
("auto", 'a', "'install', or 'chroot' if the preferred root is not /")
("install", 'i', "Install targets to /")
("binaries", 'b', "Create binary packages for targets")
- ("chroot", 'c', "Install targets to a chroot"),
+ ("chroot", 'c', "Install targets to a chroot")
+ ("cross-compile", 'x', "cross compile package (Exherbo only)"),
"auto"),
+ a_cross_host(&g_destination_options, "cross-host", '4', "Specify which cross host to use"),
a_make_dependencies(&g_destination_options, "make-dependencies", 'M', "Specify what to do with dependencies of "
"targets. Only useful when '--make' is not set to 'install', since dependencies on / are considered "
"specially.",
@@ -522,7 +526,13 @@ ResolveCommandLineResolutionOptions::apply_shortcuts()
}
void
-ResolveCommandLineResolutionOptions::verify(const std::shared_ptr<const Environment> &)
+ResolveCommandLineResolutionOptions::verify(const std::shared_ptr<const Environment> & env)
{
+ if (a_make.specified() && a_make.argument() == "cross-compile" &&
+ !DistributionData::get_instance()->distribution_from_string(env->distribution())->supports_cross_compile())
+ {
+ std::cerr << env->distribution() << " does not support cross compilation" << std::endl;
+ ::exit(EXIT_FAILURE);
+ }
}
diff --git a/src/clients/cave/resolve_cmdline.hh b/src/clients/cave/resolve_cmdline.hh
index 4edaf22..ec17f30 100644
--- a/src/clients/cave/resolve_cmdline.hh
+++ b/src/clients/cave/resolve_cmdline.hh
@@ -99,6 +99,7 @@ namespace paludis
args::ArgsGroup g_destination_options;
args::EnumArg a_make;
+ args::StringArg a_cross_host;
args::EnumArg a_make_dependencies;
args::StringSetArg a_via_binary;
args::EnumArg a_dependencies_to_slash;
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index 30c9d76..b80de62 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -663,6 +663,8 @@ namespace
return dt_install_to_slash;
else if (arg.argument() == "chroot")
return dt_install_to_chroot;
+ else if (arg.argument() == "cross-compile")
+ return dt_cross_compile;
else
throw args::DoHelp("Don't understand argument '" + arg.argument() + "' to '--"
+ arg.long_name() + "'");
@@ -771,6 +773,8 @@ paludis::cave::resolve_common(
allow_choice_changes_helper.set_allow_choice_changes(! resolution_options.a_no_override_flags.specified());
AllowedToRemoveHelper allowed_to_remove_helper(env.get());
+ if (resolution_options.a_cross_host.specified())
+ allowed_to_remove_helper.set_cross_compile_host(resolution_options.a_cross_host.argument());
for (const auto & spec : resolution_options.a_permit_uninstall.args())
allowed_to_remove_helper.add_allowed_to_remove_spec(parse_spec_with_nice_error(spec, env.get(), {updso_allow_wildcards}, filter::All()));
@@ -805,8 +809,12 @@ paludis::cave::resolve_common(
FindRepositoryForHelper find_repository_for_helper(env.get());
if (resolution_options.a_chroot_path.specified())
find_repository_for_helper.set_chroot_path(FSPath(resolution_options.a_chroot_path.argument()));
+ if (resolution_options.a_cross_host.specified())
+ find_repository_for_helper.set_cross_compile_host(resolution_options.a_cross_host.argument());
GetConstraintsForDependentHelper get_constraints_for_dependent_helper(env.get());
+ if (resolution_options.a_cross_host.specified())
+ get_constraints_for_dependent_helper.set_cross_compile_host(resolution_options.a_cross_host.argument());
for (const auto & spec : resolution_options.a_less_restrictive_remove_blockers.args())
get_constraints_for_dependent_helper.add_less_restrictive_remove_blockers_spec(parse_spec_with_nice_error(spec, env.get(), {updso_allow_wildcards}, filter::All()));
@@ -823,12 +831,12 @@ paludis::cave::resolve_common(
get_destination_types_for_error_helper.set_target_destination_type(destination_type_from_arg(env.get(), resolution_options.a_make));
GetInitialConstraintsForHelper get_initial_constraints_for_helper(env.get());
+ if (resolution_options.a_cross_host.specified())
+ get_initial_constraints_for_helper.set_cross_compile_host(resolution_options.a_cross_host.argument());
for (const auto & spec : resolution_options.a_without.args())
get_initial_constraints_for_helper.add_without_spec(parse_spec_with_nice_error(spec, env.get(), {updso_allow_wildcards}, filter::All()));
-
for (const auto & spec : resolution_options.a_preset.args())
get_initial_constraints_for_helper.add_preset_spec(parse_spec_with_nice_error(spec, env.get(), {updso_allow_wildcards}, filter::All()), nullptr);
-
get_initial_constraints_for_helper.set_reinstall_scm_days(reinstall_scm_days(resolution_options));
RemoveHiddenHelper remove_hidden_helper(env.get());
@@ -930,6 +938,8 @@ paludis::cave::resolve_common(
get_use_existing_nothing_helper.set_use_existing_for_set_targets(use_existing_from_arg(resolution_options.a_keep_targets, true));
MakeDestinationFilteredGeneratorHelper make_destination_filtered_generator_helper(env.get());
+ if (resolution_options.a_cross_host.specified())
+ make_destination_filtered_generator_helper.set_cross_compile_host(resolution_options.a_cross_host.argument());
MakeOriginFilteredGeneratorHelper make_origin_filtered_generator_helper(env.get());
make_origin_filtered_generator_helper.set_making_binaries(
@@ -963,6 +973,8 @@ paludis::cave::resolve_common(
nullptr, {}))]);
RemoveIfDependentHelper remove_if_dependent_helper(env.get());
+ if (resolution_options.a_cross_host.specified())
+ remove_if_dependent_helper.set_cross_compile_host(resolution_options.a_cross_host.argument());
for (const auto & spec : resolution_options.a_remove_if_dependent.args())
remove_if_dependent_helper.add_remove_if_dependent_spec(parse_spec_with_nice_error(spec, env.get(), {updso_allow_wildcards}, filter::All()));