ENDIF (DEFINED INCLUDE)
MESSAGE (STATUS "Header files will be installed in ${INCLUDE_INSTALL_DIR}")
SET (BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
+IF (NOT MAN_INSTALL_DIR)
SET (MAN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/man")
IF (IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/man" AND NOT IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/share/man")
SET (MAN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/man")
ENDIF (IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/man" AND NOT IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/share/man")
+ENDIF (NOT MAN_INSTALL_DIR)
MESSAGE(STATUS "Man pages will be installed in ${MAN_INSTALL_DIR}")
+IF (NOT PKGCONFIG_INSTALL_DIR)
+ SET (PKGCONFIG_INSTALL_DIR ${LIB_INSTALL_DIR}/pkgconfig)
+ENDIF (NOT PKGCONFIG_INSTALL_DIR)
####################################################################
# CONFIGURATION #
####################################################################
ENDIF (ENABLE_ARCHREPO)
FIND_PACKAGE (EXPAT REQUIRED)
+INCLUDE_DIRECTORIES (${EXPAT_INCLUDE_DIRS})
FIND_PACKAGE (ZLIB REQUIRED)
IF (ENABLE_LZMA_COMPRESSION)
FIND_PACKAGE (LZMA REQUIRED)
IF (DB_LIBRARY)
SET (RPMDB_LIBRARY ${DB_LIBRARY} ${RPMDB_LIBRARY})
ENDIF (DB_LIBRARY)
+ IF (DB_INCLUDE_DIR)
+ INCLUDE_DIRECTORIES (${DB_INCLUDE_DIR})
+ ENDIF (DB_INCLUDE_DIR)
ENDIF (NOT HAVE_RPM_DB_H)
INCLUDE (CheckLibraryExists)
CHECK_LIBRARY_EXISTS(rpmio pgpDigGetParams "" HAVE_PGPDIGGETPARAMS)
MACRO (PCFILE)
MESSAGE (STATUS "Writing pkg-config file...")
CONFIGURE_FILE (${CMAKE_SOURCE_DIR}/libsolv.pc.in ${CMAKE_BINARY_DIR}/libsolv.pc @ONLY)
- INSTALL( FILES ${CMAKE_BINARY_DIR}/libsolv.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
+ INSTALL( FILES ${CMAKE_BINARY_DIR}/libsolv.pc DESTINATION ${PKGCONFIG_INSTALL_DIR} )
ENDMACRO (PCFILE)
SPECFILE ()
This file contains the major changes between
libsolv versions:
+Version 0.6.25
+- new features:
+ * new SOLVER_FLAG_STRONG_RECOMMENDS flag
+ * new SOLVER_FLAG_INSTALL_ALSO_UPDATES flag
+ * new matchesdep() method in bindings
+ * SOLVABLE_NAME selects nevr matching for
+ pool_whatmatchesdep and solvable_matchesdep
+
Version 0.6.24
- new features:
* new SOLVER_FLAG_FOCUS_BEST flag
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "24")
+SET(LIBSOLV_PATCH "25")
}
#endif
+ Repo *createshadow(const char *name) {
+ Repo *repo = repo_create($self->pool, name);
+ if ($self->idarraysize) {
+ repo_reserve_ids(repo, 0, $self->idarraysize);
+ memcpy(repo->idarraydata, $self->idarraydata, sizeof(Id) * $self->idarraysize);
+ repo->idarraysize = $self->idarraysize;
+ }
+ repo->start = $self->start;
+ repo->end = $self->end;
+ repo->nsolvables = $self->nsolvables;
+ return repo;
+ }
+
+ void moveshadow(Queue q) {
+ Pool *pool = $self->pool;
+ int i;
+ for (i = 0; i < q.count; i++) {
+ Solvable *s;
+ Id p = q.elements[i];
+ if (p < $self->start || p >= $self->end)
+ continue;
+ s = pool->solvables + p;
+ if ($self->idarraysize != s->repo->idarraysize)
+ continue;
+ s->repo = $self;
+ }
+ }
+
#if defined(SWIGTCL)
%rename("==") __eq__;
#endif
int evrcmp(XSolvable *s2) {
return pool_evrcmp($self->pool, $self->pool->solvables[$self->id].evr, s2->pool->solvables[s2->id].evr, EVRCMP_COMPARE);
}
+#ifdef SWIGRUBY
+ %rename("matchesdep?") matchesdep;
+#endif
+ bool matchesdep(Id keyname, DepId id, Id marker = -1) {
+ return solvable_matchesdep($self->pool->solvables + $self->id, keyname, id, marker);
+ }
#if defined(SWIGTCL)
%rename("==") __eq__;
static const int SOLVER_FLAG_YUM_OBSOLETES = SOLVER_FLAG_YUM_OBSOLETES;
static const int SOLVER_FLAG_NEED_UPDATEPROVIDE = SOLVER_FLAG_NEED_UPDATEPROVIDE;
static const int SOLVER_FLAG_FOCUS_BEST = SOLVER_FLAG_FOCUS_BEST;
+ static const int SOLVER_FLAG_STRONG_RECOMMENDS = SOLVER_FLAG_STRONG_RECOMMENDS;
+ static const int SOLVER_FLAG_INSTALL_ALSO_UPDATES = SOLVER_FLAG_INSTALL_ALSO_UPDATES;
static const int SOLVER_REASON_UNRELATED = SOLVER_REASON_UNRELATED;
static const int SOLVER_REASON_UNIT_RULE = SOLVER_REASON_UNIT_RULE;
bool write_testcase(const char *dir) {
return testcase_write($self, dir, TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS, 0, 0);
}
+
+ Queue raw_decisions(int filter=0) {
+ Queue q;
+ queue_init(&q);
+ solver_get_decisionqueue($self, &q);
+ if (filter) {
+ int i, j;
+ for (i = j = 0; i < q.count; i++)
+ if ((filter > 0 && q.elements[i] > 1) ||
+ (filter < 0 && q.elements[i] < 0))
+ q.elements[j++] = q.elements[i];
+ queue_truncate(&q, j);
+ }
+ return q;
+ }
}
%extend Transaction {
.\" Title: Libsolv-Bindings
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 05/03/2016
+.\" Date: 12/14/2016
.\" Manual: LIBSOLV
.\" Source: libsolv
.\" Language: English
.\"
-.TH "LIBSOLV\-BINDINGS" "3" "05/03/2016" "libsolv" "LIBSOLV"
+.TH "LIBSOLV\-BINDINGS" "3" "12/14/2016" "libsolv" "LIBSOLV"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.nf
\fBbool identical(Solvable *\fR\fIother\fR\fB)\fR
\fI$solvable\fR\fB\->identical(\fR\fI$other\fR\fB)\fR
-\fI$solvable\fR\fB\&.identical(\fR\fIother\fR\fB)\fR
-\fI$solvable\fR\fB\&.identical?(\fR\fIother\fR\fB)\fR
+\fIsolvable\fR\fB\&.identical(\fR\fIother\fR\fB)\fR
+\fIsolvable\fR\fB\&.identical?(\fR\fIother\fR\fB)\fR
.fi
.if n \{\
.RE
.\}
.nf
\fBint evrcmp(Solvable *\fR\fIother\fR\fB)\fR
-\fI$solvable\fR\fB\->evrcmp(\fR\fIother\fR\fB)\fR
-\fI$solvable\fR\fB\&.evrcmp(\fR\fIother\fR\fB)\fR
-\fI$solvable\fR\fB\&.evrcmp(\fR\fIother\fR\fB)\fR
+\fI$solvable\fR\fB\->evrcmp(\fR\fI$other\fR\fB)\fR
+\fIsolvable\fR\fB\&.evrcmp(\fR\fIother\fR\fB)\fR
+\fIsolvable\fR\fB\&.evrcmp(\fR\fIother\fR\fB)\fR
.fi
.if n \{\
.RE
.RS 4
.\}
.nf
+\fBint matchesdep(Id\fR \fIkeyname\fR\fB, DepId\fR \fIid\fR\fB, Id\fR \fImarker\fR \fB= \-1)\fR
+\fI$solvable\fR\fB\->matchesdep(\fR\fI$keyname\fR\fB,\fR \fI$dep\fR\fB)\fR
+\fIsolvable\fR\fB\&.matchesdep(\fR\fIkeyname\fR\fB,\fR \fIdep\fR\fB)\fR
+\fIsolvable\fR\fB\&.matchesdep?(\fR\fIkeyname\fR\fB,\fR \fIdep\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Return true if the dependencies stored in keyname match the specified dependeny\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
\fBSelection Selection(int\fR \fIsetflags\fR \fB= 0)\fR
my \fI$sel\fR \fB=\fR \fI$solvable\fR\fB\->Selection()\fR;
\fIsel\fR \fB=\fR \fIsolvable\fR\fB\&.Selection()\fR
If multiple packages obsolete an installed package, the solver checks the provides of every such package and ignores all packages that do not provide the installed package name\&. Thus, you can have an official update candidate that provides the old name, and other packages that also obsolete the package but are not considered for updating\&. If you cannot use this feature, you can turn it off by setting this flag\&.
.RE
.PP
+\fBSOLVER_FLAG_NEED_UPDATEPROVIDE\fR
+.RS 4
+This is somewhat the opposite of SOLVER_FLAG_NO_UPDATEPROVIDE: Only packages that provied the installed package names are considered for updating\&.
+.RE
+.PP
\fBSOLVER_FLAG_SPLITPROVIDES\fR
.RS 4
Make the solver aware of special provides of the form \(lq<packagename>:<path>\(rq used in SUSE systems to support package splits\&.
.PP
\fBSOLVER_FLAG_FOCUS_INSTALLED\fR
.RS 4
-Resolve installed packages before resolving the given job\&. Setting this flag means that the solver will prefer picking a package version that fits the other installed packages over updating installed packages\&.
+Resolve installed packages before resolving the given jobs\&. Setting this flag means that the solver will prefer picking a package version that fits the other installed packages over updating installed packages\&.
+.RE
+.PP
+\fBSOLVER_FLAG_FOCUS_BEST\fR
+.RS 4
+First resolve the given jobs, then the dependencies of the resulting packages, then resolve all already installed packages\&. This will result in more packages being updated as when the flag is not used\&.
+.RE
+.PP
+\fBSOLVER_FLAG_INSTALL_ALSO_UPDATES\fR
+.RS 4
+Update the package if a job is already fulfilled by an installed package\&.
+.RE
+.PP
+\fBSOLVER_FLAG_YUM_OBSOLETES\fR
+.RS 4
+Turn on yum\-like package split handling\&. See the yum documentation for more details\&.
+.RE
+.PP
+\fBSOLVER_FLAG_URPM_REORDER\fR
+.RS 4
+Turn on urpm like package reordering for kernel packages\&. See the urpm documentation for more details\&.
.RE
.sp
Basic rule types:
bool identical(Solvable *other)
$solvable->identical($other)
- $solvable.identical(other)
- $solvable.identical?(other)
+ solvable.identical(other)
+ solvable.identical?(other)
Return true if the two solvables are identical.
int evrcmp(Solvable *other)
- $solvable->evrcmp(other)
- $solvable.evrcmp(other)
- $solvable.evrcmp(other)
+ $solvable->evrcmp($other)
+ solvable.evrcmp(other)
+ solvable.evrcmp(other)
Returns -1 if the epoch/version/release of the solvable is less than the
one from the other solvable, 1 if it is greater, and 0 if they are equal.
Note that "equal" does not mean that the evr is identical.
+ int matchesdep(Id keyname, DepId id, Id marker = -1)
+ $solvable->matchesdep($keyname, $dep)
+ solvable.matchesdep(keyname, dep)
+ solvable.matchesdep?(keyname, dep)
+
+Return true if the dependencies stored in keyname match the specified dependeny.
+
Selection Selection(int setflags = 0)
my $sel = $solvable->Selection();
sel = solvable.Selection()
updating. If you cannot use this feature, you can turn it off
by setting this flag.
+*SOLVER_FLAG_NEED_UPDATEPROVIDE*::
+This is somewhat the opposite of SOLVER_FLAG_NO_UPDATEPROVIDE: Only
+packages that provied the installed package names are considered
+for updating.
+
*SOLVER_FLAG_SPLITPROVIDES*::
Make the solver aware of special provides of the form
``<packagename>:<path>'' used in SUSE systems to support package
in no longer working packages in case they are orphaned.
*SOLVER_FLAG_FOCUS_INSTALLED*::
-Resolve installed packages before resolving the given job.
+Resolve installed packages before resolving the given jobs.
Setting this flag means that the solver will prefer picking
a package version that fits the other installed packages
over updating installed packages.
+*SOLVER_FLAG_FOCUS_BEST*::
+First resolve the given jobs, then the dependencies of the
+resulting packages, then resolve all already installed
+packages. This will result in more packages being updated
+as when the flag is not used.
+
+*SOLVER_FLAG_INSTALL_ALSO_UPDATES*::
+Update the package if a job is already fulfilled by an installed
+package.
+
+*SOLVER_FLAG_YUM_OBSOLETES*::
+Turn on yum-like package split handling. See the yum documentation
+for more details.
+
+*SOLVER_FLAG_URPM_REORDER*::
+Turn on urpm like package reordering for kernel packages. See
+the urpm documentation for more details.
+
+
+
Basic rule types:
*SOLVER_RULE_UNKNOWN*::
#if defined(ENABLE_DEBIAN) && defined(DEBIAN)
#include "repo_deb.h"
#endif
+#ifdef SUSE
+#include "repo_autopattern.h"
+#endif
+
#include "repoinfo.h"
#include "repoinfo_cache.h"
#if defined(ENABLE_DEBIAN) && defined(DEBIAN)
r = read_installed_debian(cinfo);
#endif
+#ifdef SUSE
+ repo_add_autopattern(cinfo->repo, 0);
+#endif
pool_set_installed(pool, cinfo->repo);
return r;
}
if ((!cinfo->autorefresh || cinfo->metadata_expire) && usecachedrepo(cinfo, 0, 0))
{
+#ifdef SUSE
+ repo_add_autopattern(cinfo->repo, 0);
+#endif
printf("repo '%s':", cinfo->alias);
printf(" cached\n");
continue;
cinfo->repo = 0;
break;
}
+#ifdef SUSE
+ if (cinfo->repo)
+ repo_add_autopattern(cinfo->repo, 0);
+#endif
}
if (sigpool)
pool_free(sigpool);
#ifdef SUSE
static void
-add_autopackages(Pool *pool)
-{
- int i;
- Repo *repo;
- FOR_REPOS(i, repo)
- repo_add_autopattern(repo, 0);
-}
-#endif
-
-#ifdef SUSE
-static void
showdiskusagechanges(Transaction *trans)
{
DUChanges duc[4];
commandlinepkgs[i] = p;
}
if (commandlinerepo)
- repo_internalize(commandlinerepo);
+ {
+ repo_internalize(commandlinerepo);
+#ifdef SUSE
+ repo_add_autopattern(commandlinerepo, 0);
+#endif
+ }
}
#if defined(ENABLE_RPMDB)
if (pool->disttype == DISTTYPE_RPM)
addfileprovides(pool);
#endif
-#ifdef SUSE
- add_autopackages(pool);
-#endif
pool_createwhatprovides(pool);
if (keyname)
{
if (!fn[i])
continue;
- if (!*dn[i])
+ did = repodata_str2dir(data, dn[i], 1);
+ if (!did)
{
- Solvable *s = data->repo->pool->solvables + handle;
+ Solvable *s = data->repo->pool->solvables + handle;
if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
did = repodata_str2dir(data, "/usr/src", 1);
else
continue; /* work around rpm bug */
}
- else
- did = repodata_str2dir(data, dn[i], 1);
repodata_add_dirnumnum(data, handle, SOLVABLE_DISKUSAGE, did, fkb[i], fn[i]);
}
solv_free(fn);
static inline Id
copydir(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache)
{
- if (cache && cache[did & 255] == did)
+ if (cache && did && cache[did & 255] == did)
return cache[(did & 255) + 256];
return copydir_complex(pool, data, fromdata, did, cache);
}
static Id
copydir_complex(Pool *pool, Repodata *data, Repodata *fromdata, Id did, Id *cache)
{
- Id parent = dirpool_parent(&fromdata->dirpool, did);
- Id compid = dirpool_compid(&fromdata->dirpool, did);
+ Id parent, compid;
+ if (!did)
+ {
+ /* make sure that the dirpool has an entry */
+ if (!data->dirpool.ndirs)
+ dirpool_add_dir(&data->dirpool, 0, 0, 1);
+ return 0;
+ }
+ parent = dirpool_parent(&fromdata->dirpool, did);
+ compid = dirpool_compid(&fromdata->dirpool, did);
if (parent)
parent = copydir(pool, data, fromdata, parent, cache);
if (data->localpool || fromdata->localpool)
{ SOLVER_FLAG_NEED_UPDATEPROVIDE, "needupdateprovide", 0 },
{ SOLVER_FLAG_URPM_REORDER, "urpmreorder", 0 },
{ SOLVER_FLAG_FOCUS_BEST, "focusbest", 0 },
+ { SOLVER_FLAG_STRONG_RECOMMENDS, "strongrecommends", 0 },
+ { SOLVER_FLAG_INSTALL_ALSO_UPDATES, "installalsoupdates", 0 },
{ 0, 0, 0 }
};
-------------------------------------------------------------------
+Tue Feb 7 13:13:01 CET 2017 - mls@suse.de
+
+- add SOLVABLE_NAME hack for pool_whatmatchesdep and
+ solvable_matchesdep
+- add SOLVER_FLAG_STRONG_RECOMMENDS option
+- add SOLVER_FLAG_INSTALL_ALSO_UPDATES option
+- do not special case release-less provides in sort_by_common_dep
+- solver_problemruleinfo2str: return reason why a package is not
+ installable
+- guard against dirpool_add_dir being called with an illegal
+ component id
+- reject solv files with bad directories
+- bump version to 0.6.25
+
+-------------------------------------------------------------------
Thu Nov 10 15:09:25 CET 2016 - mls@suse.de
- make testcase_str2solvid work with ignored packages
Id
dirpool_add_dir(Dirpool *dp, Id parent, Id comp, int create)
{
- Id did, d, ds, *dirtraverse;
+ Id did, d, ds;
if (!dp->ndirs)
{
dp->dirs[0] = 0;
dp->dirs[1] = 1; /* "" */
}
+ if (comp <= 0)
+ return 0;
if (parent == 0 && comp == 1)
return 1;
if (!dp->dirtraverse)
dirpool_make_dirtraverse(dp);
/* check all entries with this parent if we
* already have this component */
- dirtraverse = dp->dirtraverse;
- ds = dirtraverse[parent];
+ ds = dp->dirtraverse[parent];
while (ds)
{
/* ds: first component in this block
return 0;
a = aa[2] < 0 ? -aa[2] : aa[2];
b = bb[2] < 0 ? -bb[2] : bb[2];
- if (pool->disttype != DISTTYPE_DEB && a != b)
- {
- /* treat release-less versions different */
- const char *as = pool_id2str(pool, a);
- const char *bs = pool_id2str(pool, b);
- if (strchr(as, '-'))
- {
- if (!strchr(bs, '-'))
- return -2;
- }
- else
- {
- if (strchr(bs, '-'))
- return 2;
- }
- }
- r = pool_evrcmp(pool, b, a, EVRCMP_COMPARE);
+ r = pool_evrcmp(pool, b, a, pool->disttype != DISTTYPE_DEB ? EVRCMP_MATCH_RELEASE : EVRCMP_COMPARE);
if (!r && (aa[2] < 0 || bb[2] < 0))
{
if (bb[2] >= 0)
if (aa[2] >= 0)
return -1;
}
- if (r)
- return r < 0 ? -1 : 1;
- return 0;
+ return r;
}
/* common end of sort_by_srcversion and sort_by_common_dep */
/* public (i.e. not inlined) version of pool_match_flags_evr */
int
-pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, int evr)
+pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, Id evr)
{
return pool_match_flags_evr(pool, pflags, pevr, flags, evr);
}
int i;
queue_empty(q);
+ if (keyname == SOLVABLE_NAME)
+ {
+ Id pp;
+ FOR_PROVIDES(p, pp, dep)
+ if (pool_match_dep(pool, p, dep))
+ queue_push(q, p);
+ return;
+ }
queue_init(&qq);
FOR_POOL_SOLVABLES(p)
{
void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);
-int pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, int evr);
+int pool_intersect_evrs(Pool *pool, int pflags, Id pevr, int flags, Id evr);
int pool_match_dep(Pool *pool, Id d1, Id d2);
/* semi private, used in pool_match_nevr */
{
Pool *pool = solv->pool;
char *s;
+ Solvable *ss;
switch (type)
{
case SOLVER_RULE_DISTUPGRADE:
return pool_tmpjoin(pool, "cannot install the best update candidate for package ", pool_solvid2str(pool, source), 0);
return "cannot install the best candidate for the job";
case SOLVER_RULE_PKG_NOT_INSTALLABLE:
+ ss = pool->solvables + source;
+ if (pool_disabled_solvable(pool, ss))
+ return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is disabled");
+ if (ss->arch && ss->arch != ARCH_SRC && ss->arch != ARCH_NOSRC &&
+ pool->id2arch && (ss->arch > pool->lastarch || !pool->id2arch[ss->arch]))
+ return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " does not have a compatible architecture");
return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is not installable");
case SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP:
s = pool_tmpjoin(pool, "nothing provides ", pool_dep2str(pool, dep), 0);
{
id = read_id(&data, i + numid);
if (id >= numid)
- data.dirpool.dirs[i] = -(id - numid);
- else if (idmap)
- data.dirpool.dirs[i] = idmap[id];
- else
- data.dirpool.dirs[i] = id;
+ {
+ data.dirpool.dirs[i++] = -(id - numid);
+ if (i >= numdir)
+ {
+ data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "last dir entry is not a component");
+ break;
+ }
+ id = read_id(&data, numid);
+ }
+ if (idmap)
+ id = idmap[id];
+ data.dirpool.dirs[i] = id;
+ if (id <= 0)
+ data.error = pool_error(pool, SOLV_ERROR_CORRUPT, "bad dir component");
}
}
dirmap[n++] = sib;
}
+ /* check if our block has some content */
+ if (parent == n)
+ return n - 1; /* nope, drop parent id again */
+
/* now go through all the siblings we just added and
* do recursive calls on them */
lastn = n;
#endif
const char *dire;
- parent = 0;
if (!*dir)
- return 0;
+ return data->dirpool.ndirs ? 0 : dirpool_add_dir(&data->dirpool, 0, 0, create);
while (*dir == '/' && dir[1] == '/')
dir++;
if (*dir == '/' && !dir[1])
- {
- if (data->dirpool.ndirs)
- return 1;
- return dirpool_add_dir(&data->dirpool, 0, 1, create);
- }
+ return data->dirpool.ndirs ? 1 : dirpool_add_dir(&data->dirpool, 0, 1, create);
+ parent = 0;
#ifdef DIRCACHE_SIZE
dirs = dir;
if (data->dircache)
x = a->p - b->p;
if (x)
- return x; /* p differs */
+ return x; /* p differs */
/* identical p */
- if (a->d == 0 && b->d == 0)
- return a->w2 - b->w2; /* assertion: return w2 diff */
+ if (a->d == 0 && b->d == 0) /* both assertions or binary */
+ return a->w2 - b->w2;
- if (a->d == 0) /* a is assertion, b not */
+ if (a->d == 0) /* a is assertion or binary, b not */
{
x = a->w2 - pool->whatprovidesdata[b->d];
return x ? x : -1;
}
- if (b->d == 0) /* b is assertion, a not */
+ if (b->d == 0) /* b is assertion or binary, a not */
{
x = pool->whatprovidesdata[a->d] - b->w2;
return x ? x : 1;
}
+ if (a->d == b->d)
+ return 0;
+
/* compare whatprovidesdata */
ad = pool->whatprovidesdata + a->d;
bd = pool->whatprovidesdata + b->d;
int i, j;
Rule *ir, *jr;
- if (solv->nrules <= 2) /* nothing to unify */
+ if (solv->nrules <= 2) /* nothing to unify */
return;
+ if (solv->recommendsruleq)
+ {
+ /* mis-use n2 as recommends rule marker */
+ for (i = 1, ir = solv->rules + i; i < solv->nrules; i++, ir++)
+ ir->n2 = 0;
+ for (i = 0; i < solv->recommendsruleq->count; i++)
+ solv->rules[solv->recommendsruleq->elements[i]].n2 = 1;
+ }
+
/* sort rules first */
solv_sort(solv->rules + 1, solv->nrules - 1, sizeof(Rule), unifyrules_sortcmp, solv->pool);
- /* prune rules
- * i = unpruned
- * j = pruned
- */
+ /* prune rules */
jr = 0;
for (i = j = 1, ir = solv->rules + i; i < solv->nrules; i++, ir++)
{
if (jr && !unifyrules_sortcmp(ir, jr, pool))
- continue; /* prune! */
- jr = solv->rules + j++; /* keep! */
+ {
+ jr->n2 &= ir->n2; /* bitwise-and recommends marker */
+ continue; /* prune! */
+ }
+ jr = solv->rules + j++; /* keep! */
if (ir != jr)
*jr = *ir;
}
POOL_DEBUG(SOLV_DEBUG_STATS, "pruned rules from %d to %d\n", solv->nrules, j);
/* adapt rule buffer */
- solv->nrules = j;
- solv->rules = solv_extend_resize(solv->rules, solv->nrules, sizeof(Rule), RULES_BLOCK);
+ solver_shrinkrules(solv, j);
+
+ if (solv->recommendsruleq)
+ {
+ /* rebuild recommendsruleq */
+ queue_empty(solv->recommendsruleq);
+ for (i = 1, ir = solv->rules + i; i < solv->nrules; i++, ir++)
+ if (ir->n2)
+ {
+ ir->n2 = 0;
+ queue_push(solv->recommendsruleq, i);
+ }
+ }
/*
* debug: log rule statistics
* the work for unifyrules a bit easier */
if (!solv->pkgrules_end) /* we add pkg rules */
{
- r = solv->rules + solv->nrules - 1;
+ r = solv->rules + solv->lastpkgrule;
if (d)
{
Id *dp;
if (p == -p2)
return 0; /* rule is self-fulfilling */
}
+ solv->lastpkgrule = solv->nrules;
}
solv->rules = solv_extend(solv->rules, solv->nrules, 1, sizeof(Rule), RULES_BLOCK);
{
solv->nrules = nrules;
solv->rules = solv_extend_resize(solv->rules, solv->nrules, sizeof(Rule), RULES_BLOCK);
+ solv->lastpkgrule = 0;
}
/******************************************************************************
if (!dp[j])
continue;
}
+ if (type == SOLVER_RULE_PKG_RECOMMENDS && !*dp)
+ continue;
/* check if the rule contains both p and -p */
for (j = 0; dp[j] != 0; j++)
if (dp[j] == p)
break;
if (dp[j])
continue;
- addpkgrule(solv, -p, 0, dp - pool->whatprovidesdata, SOLVER_RULE_PKG_REQUIRES, dep);
+ addpkgrule(solv, -p, 0, dp - pool->whatprovidesdata, type, dep);
/* push all non-visited providers on the work queue */
if (m)
for (; *dp; dp++)
}
}
+ if (s->recommends && solv->strongrecommends)
+ {
+ int start = solv->nrules;
+ solv->lastpkgrule = 0;
+ reqp = s->repo->idarraydata + s->recommends;
+ while ((req = *reqp++) != 0) /* go through all recommends */
+ {
+#ifdef ENABLE_COMPLEX_DEPS
+ if (pool_is_complex_dep(pool, req))
+ {
+ /* we have AND/COND deps, normalize */
+ add_complex_deprules(solv, n, req, SOLVER_RULE_PKG_RECOMMENDS, dontfix, &workq, m);
+ continue;
+ }
+#endif
+ dp = pool_whatprovides_ptr(pool, req);
+ if (*dp == SYSTEMSOLVABLE || !*dp) /* always installed or not installable */
+ continue;
+ for (i = 0; dp[i] != 0; i++)
+ if (n == dp[i])
+ break;
+ if (dp[i])
+ continue; /* provided by itself, no need to add rule */
+ addpkgrule(solv, -n, 0, dp - pool->whatprovidesdata, SOLVER_RULE_PKG_RECOMMENDS, req);
+ if (m)
+ for (; *dp; dp++)
+ if (!MAPTST(m, *dp))
+ queue_push(&workq, *dp);
+ }
+ if (!solv->ruleinfoq && start < solv->nrules)
+ {
+ if (!solv->recommendsruleq)
+ {
+ solv->recommendsruleq = solv_calloc(1, sizeof(Queue));
+ queue_init(solv->recommendsruleq);
+ }
+ for (i = start; i < solv->nrules; i++)
+ queue_push(solv->recommendsruleq, i);
+ solv->lastpkgrule = 0;
+ }
+ }
+
/* that's all we check for src packages */
if (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
continue;
SOLVER_RULE_PKG_OBSOLETES,
SOLVER_RULE_PKG_IMPLICIT_OBSOLETES,
SOLVER_RULE_PKG_INSTALLED_OBSOLETES,
+ SOLVER_RULE_PKG_RECOMMENDS,
SOLVER_RULE_UPDATE = 0x200,
SOLVER_RULE_FEATURE = 0x300,
SOLVER_RULE_JOB = 0x400,
int i;
Pool *pool = s->repo->pool;
Queue q;
+
+ if (keyname == SOLVABLE_NAME)
+ return pool_match_nevr(pool, s, dep) ? 1 : 0; /* nevr match hack */
queue_init(&q);
solvable_lookup_deparray(s, keyname, &q, marker);
for (i = 0; i < q.count; i++)
queuep_free(&solv->suggestscplxq);
queuep_free(&solv->brokenorphanrules);
queuep_free(&solv->favorq);
+ queuep_free(&solv->recommendsruleq);
map_free(&solv->recommendsmap);
map_free(&solv->suggestsmap);
return solv->needupdateprovide;
case SOLVER_FLAG_URPM_REORDER:
return solv->urpmreorder;
+ case SOLVER_FLAG_STRONG_RECOMMENDS:
+ return solv->strongrecommends;
+ case SOLVER_FLAG_INSTALL_ALSO_UPDATES:
+ return solv->install_also_updates;
default:
break;
}
case SOLVER_FLAG_URPM_REORDER:
solv->urpmreorder = value;
break;
+ case SOLVER_FLAG_STRONG_RECOMMENDS:
+ solv->strongrecommends = value;
+ break;
+ case SOLVER_FLAG_INSTALL_ALSO_UPDATES:
+ solv->install_also_updates = value;
+ break;
default:
break;
}
continue;
/* prune to installed if not updating */
if (dq->count > 1 && solv->installed && !solv->updatemap_all &&
+ !solv->install_also_updates &&
!(solv->job.elements[solv->ruletojob.elements[i - solv->jobrules]] & SOLVER_ORUPDATE))
{
- int j, k;
- for (j = k = 0; j < dq->count; j++)
+ int j = dq->count, k;
+ if (solv->updatemap.size)
{
- Solvable *s = pool->solvables + dq->elements[j];
- if (s->repo == solv->installed)
- {
- dq->elements[k++] = dq->elements[j];
- if (solv->updatemap.size && MAPTST(&solv->updatemap, dq->elements[j] - solv->installed->start))
- {
- k = 0; /* package wants to be updated, do not prune */
- break;
- }
- }
+ /* do not prune if an installed package wants to be updated */
+ for (j = 0; j < dq->count; j++)
+ if (pool->solvables[dq->elements[j]].repo == solv->installed
+ && MAPTST(&solv->updatemap, dq->elements[j] - solv->installed->start))
+ break;
+ }
+ if (j == dq->count)
+ {
+ for (j = k = 0; j < dq->count; j++)
+ if (pool->solvables[dq->elements[j]].repo == solv->installed)
+ dq->elements[k++] = dq->elements[j];
+ if (k)
+ dq->count = k;
}
- if (k)
- dq->count = k;
}
olevel = level;
level = selectandinstall(solv, level, dq, disablerules, i, SOLVER_REASON_RESOLVE_JOB);
if (solv->nrules != initialnrules)
solver_shrinkrules(solv, initialnrules);
solv->nrules = initialnrules;
+ solv->lastpkgrule = 0;
solv->pkgrules_end = 0;
if (installed)
if (solv->nrules > initialnrules)
solver_unifyrules(solv); /* remove duplicate pkg rules */
solv->pkgrules_end = solv->nrules; /* mark end of pkg rules */
+ solv->lastpkgrule = 0;
if (solv->nrules > initialnrules)
addedmap2deduceq(solv, &addedmap); /* so that we can recreate the addedmap */
POOL_DEBUG(SOLV_DEBUG_STATS, "overall rule memory used: %d K\n", solv->nrules * (int)sizeof(Rule) / 1024);
/* create weak map */
- if (solv->weakruleq.count)
+ if (solv->weakruleq.count || solv->recommendsruleq)
{
map_grow(&solv->weakrulemap, solv->nrules);
for (i = 0; i < solv->weakruleq.count; i++)
p = solv->weakruleq.elements[i];
MAPSET(&solv->weakrulemap, p);
}
+ if (solv->recommendsruleq)
+ {
+ for (i = 0; i < solv->recommendsruleq->count; i++)
+ {
+ p = solv->recommendsruleq->elements[i];
+ MAPSET(&solv->weakrulemap, p);
+ }
+ }
}
/* enable cleandepsmap creation if we have updatepkgs */
*/
Rule *rules; /* all rules */
Id nrules; /* [Offset] index of the last rule */
+ Id lastpkgrule; /* last package rule we added */
Queue ruleassertions; /* Queue of all assertion rules */
int focus_best; /* true: resolve job dependencies first */
int do_yum_obsoletes; /* true: add special yumobs rules */
int urpmreorder; /* true: do special urpm package reordering */
+ int strongrecommends; /* true: create weak rules for recommends */
+ int install_also_updates; /* true: do not prune install job rules to installed packages */
Map dupmap; /* dup these packages*/
int dupmap_all; /* dup all packages */
int installedpos; /* for resolve_installed */
int do_extra_reordering; /* reorder for future installed packages */
+
+ Queue *recommendsruleq; /* pkg rules comming from recommends */
#endif /* LIBSOLV_INTERNAL */
};
#define SOLVER_FLAG_NEED_UPDATEPROVIDE 22
#define SOLVER_FLAG_URPM_REORDER 23
#define SOLVER_FLAG_FOCUS_BEST 24
+#define SOLVER_FLAG_STRONG_RECOMMENDS 25
+#define SOLVER_FLAG_INSTALL_ALSO_UPDATES 26
#define GET_USERINSTALLED_NAMES (1 << 0) /* package names instead of ids */
#define GET_USERINSTALLED_INVERTED (1 << 1) /* autoinstalled */
Offset
repo_fix_conflicts(Repo *repo, Offset conflicts)
{
- char buf[1024], *p, *dep;
+ char buf[1024], *dep;
Pool *pool = repo->pool;
Id id;
int i;
if (ISRELDEP(id))
continue;
dep = (char *)pool_id2str(pool, id);
- if (!strncmp(dep, "otherproviders(", 15) && strlen(dep) < sizeof(buf) - 2)
+ if (!strncmp(dep, "otherproviders(", 15) && dep[15] && strlen(dep) < sizeof(buf) - 2)
{
strcpy(buf, dep + 15);
- if ((p = strchr(buf, ')')) != 0)
- *p = 0;
+ buf[strlen(buf) - 1] = 0;
id = pool_str2id(pool, buf, 1);
id = pool_rel2id(pool, NAMESPACE_OTHERPROVIDERS, id, REL_NAMESPACE, 1);
repo->idarraydata[i] = id;