FOREACH (VAR
ENABLE_RPMDB ENABLE_RPMPKG ENABLE_PUBKEY ENABLE_RPMMD ENABLE_RPMDB_BYRPMHEADER
- ENABLE_SUSEREPO ENABLE_COMPS
+ ENABLE_SUSEREPO ENABLE_COMPS ENABLE_TESTCASE_HELIXREPO
ENABLE_HELIXREPO ENABLE_MDKREPO ENABLE_ARCHREPO ENABLE_DEBIAN ENABLE_HAIKU
ENABLE_ZLIB_COMPRESSION ENABLE_LZMA_COMPRESSION ENABLE_BZIP2_COMPRESSION
ENABLE_PGPVRFY ENABLE_APPDATA)
This file contains the major changes between
libsolv versions:
+Version 0.6.28
+- new features:
+ * new pool_best_solvables() function
+
Version 0.6.27
- new features:
* allow building with libxml2 instead of libexpat
SET(LIBSOLV_MAJOR "0")
SET(LIBSOLV_MINOR "6")
-SET(LIBSOLV_PATCH "27")
+SET(LIBSOLV_PATCH "28")
IF (${PYTHON_VERSION_MAJOR} GREATER 2)
SET (SWIG_PY_FLAGS -DPYTHON3=1)
ENDIF (${PYTHON_VERSION_MAJOR} GREATER 2)
+SET (SWIG_PY_FLAGS ${SWIG_PY_FLAGS} -DSWIG_PYTHON_LEGACY_BOOL=1)
MESSAGE (STATUS "Python executable: ${PYTHON_EXECUTABLE}")
MESSAGE (STATUS "Python installation dir: ${PYTHON_INSTALL_DIR}")
EXECUTE_PROCESS(COMMAND ${PYTHON3_EXECUTABLE} -c "from sys import stdout; from distutils import sysconfig; stdout.write(sysconfig.get_python_lib(True))" OUTPUT_VARIABLE PYTHON3_INSTALL_DIR)
EXECUTE_PROCESS(COMMAND ${PYTHON3_EXECUTABLE} -c "from sys import stdout; from distutils import sysconfig; stdout.write(sysconfig.get_python_inc())" OUTPUT_VARIABLE PYTHON3_INCLUDE_DIR)
+SET (SWIG_PY3_FLAGS -DPYTHON3=1)
+SET (SWIG_PY3_FLAGS ${SWIG_PY3_FLAGS} -DSWIG_PYTHON_LEGACY_BOOL=1)
+
MESSAGE (STATUS "Python3 executable: ${PYTHON3_EXECUTABLE}")
MESSAGE (STATUS "Python3 installation dir: ${PYTHON3_INSTALL_DIR}")
MESSAGE (STATUS "Python3 include path: ${PYTHON3_INCLUDE_DIR}")
ADD_CUSTOM_COMMAND (
OUTPUT solv_python.c
- COMMAND ${SWIG_EXECUTABLE} ${SWIG_FLAGS} -python -DPYTHON3=1 -I${CMAKE_SOURCE_DIR}/src -o solv_python.c ${CMAKE_SOURCE_DIR}/bindings/solv.i
+ COMMAND ${SWIG_EXECUTABLE} ${SWIG_FLAGS} -python ${SWIG_PY3_FLAGS} -I${CMAKE_SOURCE_DIR}/src -o solv_python.c ${CMAKE_SOURCE_DIR}/bindings/solv.i
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_SOURCE_DIR}/bindings/solv.i
)
#if defined(SWIGPERL)
-/* work around a swig bug */
+/* work around a swig bug for swig versions < 2.0.5 */
+#if SWIG_VERSION < 0x020005
%{
#undef SWIG_CALLXS
#ifdef PERL_OBJECT
# endif
#endif
%}
+#endif
%define perliter(class)
#ifdef SWIGPERL
perliter(solv::Pool_repo_iterator)
#endif
- %newobject __next__;
Repo *__next__() {
Pool *pool = $self->pool;
if ($self->id >= pool->nrepos)
void each() {
Repo *n;
while ((n = Pool_repo_iterator___next__($self)) != 0) {
- rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_Repo, SWIG_POINTER_OWN | 0));
+ rb_yield(SWIG_NewPointerObj(SWIG_as_voidptr(n), SWIGTYPE_p_Repo, 0 | 0));
}
}
#endif
const char *lookup_location(unsigned int *OUTPUT) {
return solvable_lookup_location($self->pool->solvables + $self->id, OUTPUT);
}
+ const char *lookup_sourcepkg() {
+ return solvable_lookup_sourcepkg($self->pool->solvables + $self->id);
+ }
%newobject Dataiterator;
Dataiterator *Dataiterator(Id key, const char *match = 0, int flags = 0) {
return new_Dataiterator($self->pool, 0, $self->id, key, match, flags);
if (buf)
repodata_set_bin_checksum(repo_id2repodata($self->repo, $self->id), solvid, keyname, solv_chksum_get_type(chksum), buf);
}
+ void set_sourcepkg(Id solvid, const char *sourcepkg) {
+ repodata_set_sourcepkg(repo_id2repodata($self->repo, $self->id), solvid, sourcepkg);
+ }
const char *lookup_str(Id solvid, Id keyname) {
return repodata_lookup_str(repo_id2repodata($self->repo, $self->id), solvid, keyname);
}
.RS 4
.\}
.nf
+\fBconst char *lookup_sourcepkg()\fR;
+my \fR\fI$sourcepkg\fR\fB =\fR \fI$solvable\fR\fB\->lookup_sourcepkg()\fR;
+\fIsourcepkg\fR\fB \fB=\fR \fIsolvable\fR\fB\&.lookup_sourcepkg()\fR
+\fIsourcepkg\fR\fB \fB=\fR \fIsolvable\fR\fB\&.lookup_sourcepkg()\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Return a sourcepkg name associated with solvable\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
\fBDataiterator Dataiterator(Id\fR \fIkeyname\fR\fB, const char *\fR\fImatch\fR \fB= 0, int\fR \fIflags\fR \fB= 0)\fR
my \fI$di\fR \fB=\fR \fI$solvable\fR\fB\->Dataiterator(\fR\fI$keyname\fR\fB,\fR \fI$match\fR\fB,\fR \fI$flags\fR\fB)\fR;
\fIdi\fR \fB=\fR \fIsolvable\fR\fB\&.Dataiterator(\fR\fIkeyname\fR\fB,\fR \fImatch\fR\fB,\fR \fIflags\fR\fB)\fR
.RS 4
.\}
.nf
+\fBvoid set_sourcepkg(Id\fR \fIsolvid\fR\fB, const char *\fR\fIsourcepkg\fR\fB)\fR;
+\fI$data\fR\fB\->set_sourcepkg(\fR\fI$solvid\fR\fB, \fI$sourcepkg\fR\fB)\fR;
+\fIdata\fR\fB\&.set_sourcepkg(\fR\fIsolvid\fR\fB,\fR \fIsourcepkg\fR\fB)\fR
+\fIdata\fR\fB\&.set_sourcepkg(\fR\fIsolvid\fR\fB,\fR \fIsourcepkg\fR\fB)\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
\fBvoid add_idarray(Id\fR \fIsolvid\fR\fB, Id\fR \fIkeyname\fR\fB, DepId\fR \fIid\fR\fB)\fR;
\fI$data\fR\fB\->add_idarray(\fR\fI$solvid\fR\fB,\fR \fI$keyname\fR\fB,\fR \fI$id\fR\fB)\fR;
\fIdata\fR\fB\&.add_idarray(\fR\fIsolvid\fR\fB,\fR \fIkeyname\fR\fB,\fR \fIid\fR\fB)\fR
media number for multi-part repositories (e.g. repositories
spawning multiple DVDs).
+ const char *lookup_sourcepkg();
+ my $sourcepkg = $solvable->lookup_sourcepkg();
+ sourcepkg = solvable.lookup_sourcepkg()
+ sourcepkg = solvable.lookup_sourcepkg()
+
+Return a sourcepkg name associated with solvable.
+
Dataiterator Dataiterator(Id keyname, const char *match = 0, int flags = 0)
my $di = $solvable->Dataiterator($keyname, $match, $flags);
di = solvable.Dataiterator(keyname, match, flags)
data.set_checksum(solvid, keyname, chksum)
data.set_checksum(solvid, keyname, chksum)
+ void set_sourcepkg(Id solvid, const char *sourcepkg);
+ $data.set_sourcepkg($solvid, $sourcepkg);
+ data.set_sourcepkg(solvid, sourcepkg)
+ data.set_sourcepkg(solvid, sourcepkg)
+
void add_idarray(Id solvid, Id keyname, DepId id);
$data->add_idarray($solvid, $keyname, $id);
data.add_idarray(solvid, keyname, id)
sub add_exts {
my ($self) = @_;
my $repodata = $self->{handle}->add_repodata(0);
+ $repodata->extend_to_repo();
$self->add_ext($repodata, 'deltainfo', 'DL');
$self->add_ext($repodata, 'filelists', 'FL');
$repodata->internalize();
def add_exts(self):
repodata = self.handle.add_repodata(0)
+ repodata.extend_to_repo()
self.add_ext(repodata, 'deltainfo', 'DL')
self.add_ext(repodata, 'filelists', 'FL')
repodata.internalize()
def add_exts
repodata = @handle.add_repodata(0)
+ repodata.extend_to_repo()
add_ext(repodata, 'deltainfo', 'DL')
add_ext(repodata, 'filelists', 'FL')
repodata.internalize()
return 1;
}
+static void
+mdk_add_ext(Repo *repo, Repodata *data, const char *what, const char *ext, const char *filename, Id chksumtype, const unsigned char *chksum)
+{
+ Id handle = repodata_new_handle(data);
+ /* we mis-use the repomd ids here... need something generic in the future */
+ repodata_set_poolstr(data, handle, REPOSITORY_REPOMD_TYPE, what);
+ repodata_set_str(data, handle, REPOSITORY_REPOMD_LOCATION, filename);
+ repodata_set_bin_checksum(data, handle, REPOSITORY_REPOMD_CHECKSUM, chksumtype, chksum);
+ add_ext_keys(data, handle, ext);
+ repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
+}
+
int
mdk_load(struct repoinfo *cinfo, Pool **sigpoolp)
{
/* setup on-demand loading of filelist data */
if (mdk_find(md5sums, "files.xml.lzma", md5))
{
- Id handle = repodata_new_handle(data);
- /* we mis-use the repomd ids here... need something generic in the future */
- repodata_set_poolstr(data, handle, REPOSITORY_REPOMD_TYPE, "filelists");
- repodata_set_str(data, handle, REPOSITORY_REPOMD_LOCATION, "media_info/files.xml.lzma");
- repodata_set_bin_checksum(data, handle, REPOSITORY_REPOMD_CHECKSUM, REPOKEY_TYPE_MD5, md5);
- add_ext_keys(data, handle, "FL");
- repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle);
+ repodata_extend_block(data, repo->start, repo->end - repo->start);
+ mdk_add_ext(repo, data, "filelists", "FL", "media_info/files.xml.lzma", REPOKEY_TYPE_MD5, md5);
}
solv_free(md5sums);
repodata_internalize(data);
}
#endif
data = repo_add_repodata(repo, 0);
+ repodata_extend_block(data, repo->start, repo->end - repo->start);
repomd_add_ext(repo, data, "deltainfo", "DL");
repomd_add_ext(repo, data, "filelists", "FL");
repodata_internalize(data);
return filename;
}
-void
+static void
susetags_add_ext(Repo *repo, Repodata *data)
{
Pool *pool = repo->pool;
#endif
repo_internalize(repo);
data = repo_add_repodata(repo, 0);
+ repodata_extend_block(data, repo->start, repo->end - repo->start);
susetags_add_ext(repo, data);
repodata_internalize(data);
writecachedrepo(cinfo, 0, 0);
proc repo_repomd_add_exts {selfName} {
upvar $selfName self
set repodata [$self(handle) add_repodata 0]
+ $repodata extend_to_repo
repo_repomd_add_ext self $repodata "filelists" "FL"
$repodata internalize
}
proc repo_susetags_add_exts {selfName} {
upvar $selfName self
set repodata [$self(handle) add_repodata 0]
+ $repodata extend_to_repo
repo_susetags_add_ext self $repodata "packages.FL" "FL"
repo_susetags_add_ext self $repodata "packages.FL.gz" "FL"
$repodata internalize
SET_TARGET_PROPERTIES(libsolvext PROPERTIES INSTALL_NAME_DIR ${LIB_INSTALL_DIR})
INSTALL (FILES ${libsolvext_HEADERS} DESTINATION "${INCLUDE_INSTALL_DIR}/solv")
-INSTALL (TARGETS libsolvext LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
+INSTALL (TARGETS libsolvext LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} RUNTIME DESTINATION bin)
IF (ENABLE_STATIC AND NOT DISABLE_SHARED)
ADD_LIBRARY (libsolvext_static STATIC ${libsolvext_SRCS})
for (o = 0; o < i; o++, d += 8)
{
unsigned int x = d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3];
- r[o] = (unsigned long long)x << 32 | (d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7]);
+ r[o] = (unsigned long long)x << 32 | (unsigned int)(d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7]);
}
return r;
}
return 0;
d = h->dp + o;
i = d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3];
- return (unsigned long long)i << 32 | (d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7]);
+ return (unsigned long long)i << 32 | (unsigned int)(d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7]);
}
static unsigned int *
#include "testcase.h"
#include "selection.h"
#include "solv_xfopen.h"
+#if ENABLE_TESTCASE_HELIXREPO
+#include "ext/repo_helix.h"
+#endif
#define DISABLE_JOIN2
#include "tools_util.h"
#ifdef ENABLE_COMPLEX_DEPS
"complex_deps",
#endif
+#if ENABLE_TESTCASE_HELIXREPO
+ "testcase_helixrepo",
+#endif
0
};
strqueue_push(&sq, cmd);
}
- if (resultflags)
+ if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) != 0)
{
char *result;
cmd = 0;
int ngenid = 0;
Queue autoinstq;
+ if (resultp)
+ *resultp = 0;
+ if (resultflagsp)
+ *resultflagsp = 0;
if (!fp && !(fp = fopen(testcase, "r")))
{
pool_debug(pool, SOLV_ERROR, "testcase_read: could not open '%s'\n", testcase);
repo_add_solv(repo, rfp, 0);
fclose(rfp);
}
-#if 0
+#if ENABLE_TESTCASE_HELIXREPO
else if (!strcmp(repotype, "helix"))
{
- extern int repo_add_helix(Repo *repo, FILE *fp, int flags);
repo_add_helix(repo, rfp, 0);
fclose(rfp);
}
if (resultflagsp)
*resultflagsp = resultflags;
}
- else if (!strcmp(pieces[0], "nextjob") && npieces == 1)
+ else if (!strcmp(pieces[0], "nextjob"))
{
+ if (npieces == 2 && resultflagsp && !strcmp(pieces[1], "reusesolver"))
+ *resultflagsp |= TESTCASE_RESULT_REUSE_SOLVER;
break;
}
else if (!strcmp(pieces[0], "disable") && npieces == 3)
#define TESTCASE_RESULT_GENID (1 << 7)
#define TESTCASE_RESULT_REASON (1 << 8)
+/* reuse solver hack, testsolv use only */
+#define TESTCASE_RESULT_REUSE_SOLVER (1 << 31)
+
extern Id testcase_str2dep(Pool *pool, const char *s);
extern const char *testcase_dep2str(Pool *pool, Id id);
extern const char *testcase_repoid2str(Pool *pool, Id repoid);
-------------------------------------------------------------------
+Fri Jun 30 16:37:31 CEST 2017 - mls@suse.de
+
+- make peace with newer perl versions
+- fix memory leak in bindings
+- add pool_best_solvables() function
+- fix 64bit integer parsing from RPM headers
+- bump version to 0.6.28
+
+-------------------------------------------------------------------
+Sun May 28 13:32:15 UTC 2017 - ngompa13@gmail.com
+
+- Enable complex/rich dependencies for CentOS/RHEL 7, matching how
+ libsolv is configured there.
+
+-------------------------------------------------------------------
+Thu May 11 12:41:07 UTC 2017 - ngompa13@gmail.com
+
+- Disable bzip2 and xz/lzma compression support for SLE <= 12
+
+-------------------------------------------------------------------
+Mon May 8 13:15:09 UTC 2017 - ngompa13@gmail.com
+
+- Enable bzip2 and xz/lzma compression support
+- Enable complex/rich dependencies on distributions with RPM 4.13+
+- Simplified CentOS/RHEL conditionals
+- Added Mageia conditionals
+- Fixed a few spec portability issues
+
+-------------------------------------------------------------------
Tue Apr 25 14:11:05 CEST 2017 - mls@suse.de
- change queue resize code to use adaptive chunk sizes
%bcond_without ruby_binding
%bcond_with zypp
+%if 0%{?leap_version} >= 420300 || 0%{?sle_version} >= 120300 || 0%{?suse_version} >= 1330 || !0%{?suse_version}
+%bcond_without bz2
+%bcond_without xz
+%else
+%bcond_with bz2
+%bcond_with xz
+%endif
+
+%if 0%{?fedora} || 0%{?rhel} >= 7 || 0%{?mageia} >= 6 || 0%{?suse_version} >= 1330
+%bcond_without richdeps
+%else
+%bcond_with richdeps
+%endif
+
%if 0%{?mandriva_version}
# force this version on mandriva
BuildRequires: libneon0.26-devel
%endif
-%if 0%{?fedora_version} || 0%{?rhel_version} >= 600 || 0%{?centos_version} >= 600
+%if 0%{?fedora} || 0%{?rhel} >= 6 || 0%{?mageia}
BuildRequires: db-devel
%endif
BuildRequires: libxml2-devel
%if 0%{?suse_version} && 0%{?suse_version} < 1100
BuildRequires: graphviz
%endif
-%if 0%{?suse_version} > 1020
+%if 0%{?suse_version} > 1020 || 0%{?fedora} || 0%{?mageia}
BuildRequires: fdupes
%endif
BuildRequires: cmake
%if %{with perl_binding}
BuildRequires: perl
-%if 0%{?fedora_version} || 0%{?rhel_version} >= 600 || 0%{?centos_version} >= 600
+%if 0%{?fedora} || 0%{?rhel} >= 6 || 0%{?mageia}
BuildRequires: perl-devel
%endif
BuildRequires: swig
%endif
+
%if %{with ruby_binding}
%global ruby_vendorarch %(ruby -r rbconfig -e "puts RbConfig::CONFIG['vendorarchdir'].nil? ? RbConfig::CONFIG['sitearchdir'] : RbConfig::CONFIG['vendorarchdir']")
BuildRequires: ruby
BuildRequires: ruby-devel
BuildRequires: swig
%endif
+
%if %{with python_binding}
%global python_sitearch %(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))")
BuildRequires: python-devel
BuildRequires: swig
%endif
+
%if %{with python3_binding}
%global python3_sitearch %(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))")
BuildRequires: python3-devel
%endif
+%if %{with bz2}
+%if 0%{?suse_version}
+BuildRequires: libbz2-devel
+%else
+BuildRequires: bzip2-devel
+%endif
+%endif
+
+%if %{with xz}
+BuildRequires: xz-devel
+%endif
+
+
Summary: A new approach to package dependency solving
License: BSD-3-Clause
Group: Development/Libraries/C and C++
Summary: Applications demoing the libsolv library
Group: System/Management
Requires: curl
-%if 0%{?fedora_version} || 0%{?rhel_version} >= 600 || 0%{?centos_version} >= 600
+%if 0%{?fedora} || 0%{?rhel} >= 6 || 0%{?mageia}
Requires: gnupg2
%endif
%if 0%{?suse_version}
export CXXFLAGS="$CFLAGS"
CMAKE_FLAGS=
-%if 0%{?fedora_version} || 0%{?rhel_version} >= 600 || 0%{?centos_version} >= 600
-CMAKE_FLAGS="-DFEDORA=1"
+%if 0%{?fedora} || 0%{?rhel} >= 6
+CMAKE_FLAGS="-DFEDORA=1 -DENABLE_APPDATA=1 -DENABLE_COMPS=1"
+%endif
+%if 0%{?mageia}
+CMAKE_FLAGS="-DMAGEIA=1 -DENABLE_APPDATA=1 -DENABLE_COMPS=1"
%endif
%if 0%{?suse_version}
CMAKE_FLAGS="-DSUSE=1 -DENABLE_APPDATA=1 -DENABLE_COMPS=1"
%{?with_python_binding:-DENABLE_PYTHON=1} \
%{?with_python3_binding:-DENABLE_PYTHON3=1} \
%{?with_ruby_binding:-DENABLE_RUBY=1} \
+ %{?with_bz2:-DENABLE_BZIP2_COMPRESSION=1} \
+ %{?with_xz:-DENABLE_LZMA_COMPRESSION=1} \
+ %{?with_richdeps:-DENABLE_COMPLEX_DEPS=1} \
%{?with_zypp:-DENABLE_SUSEREPO=1 -DENABLE_HELIXREPO=1} \
-DUSE_VENDORDIRS=1 \
-DCMAKE_SKIP_RPATH=1
-make %{?jobs:-j %jobs}
+make %{?_smp_mflags}
%install
make DESTDIR=$RPM_BUILD_ROOT install
SET_TARGET_PROPERTIES(libsolv PROPERTIES INSTALL_NAME_DIR ${LIB_INSTALL_DIR})
INSTALL (FILES ${libsolv_HEADERS} DESTINATION "${INCLUDE_INSTALL_DIR}/solv")
-INSTALL (TARGETS libsolv LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
+INSTALL (TARGETS libsolv LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} RUNTIME DESTINATION bin)
IF (ENABLE_STATIC AND NOT DISABLE_SHARED)
ADD_LIBRARY (libsolv_static STATIC ${libsolv_SRCS})
local:
*;
};
+
+SOLV_1.1 {
+ pool_best_solvables;
+} SOLV_1.0;
}
}
+void
+pool_best_solvables(Pool *pool, Queue *plist, int flags)
+{
+ if (plist->count > 1)
+ prune_to_highest_prio(pool, plist);
+ if (plist->count > 1)
+ prune_to_best_arch(pool, plist);
+ if (plist->count > 1)
+ prune_to_best_version(pool, plist);
+ if (plist->count > 1)
+ {
+ dislike_old_versions(pool, plist);
+ sort_by_common_dep(pool, plist);
+ }
+}
+
/* check if there is an illegal architecture change if
* installed solvable s1 is replaced by s2 */
extern void policy_create_obsolete_index(Solver *solv);
+extern void pool_best_solvables(Pool *pool, Queue *plist, int flags);
+
/* internal, do not use */
extern void prune_to_best_version(Pool *pool, Queue *plist);
extern void policy_prefer_favored(Solver *solv, Queue *plist);
"ia64", "ia64:i686:i586:i486:i386",
"armv7hnl", "armv7hnl:armv7hl:armv6hl",
"armv7hl", "armv7hl:armv6hl",
- "armv7l", "armv7l:armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
- "armv6l", "armv6l:armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
- "armv5tejl", "armv5tejl:armv5tel:armv5l:armv4tl:armv4l:armv3l",
- "armv5tel", "armv5tel:armv5l:armv4tl:armv4l:armv3l",
- "armv5tl", "armv5l:armv4tl:armv4l:armv3l",
+ "armv7l", "armv7l:armv6l:armv5tejl:armv5tel:armv5tl:armv5l:armv4tl:armv4l:armv3l",
+ "armv6l", "armv6l:armv5tejl:armv5tel:armv5tl:armv5l:armv4tl:armv4l:armv3l",
+ "armv5tejl", "armv5tejl:armv5tel:armv5tl:armv5l:armv4tl:armv4l:armv3l",
+ "armv5tel", "armv5tel:armv5tl:armv5l:armv4tl:armv4l:armv3l",
+ "armv5tl", "armv5tl:armv5l:armv4tl:armv4l:armv3l",
"armv5l", "armv5l:armv4tl:armv4l:armv3l",
"armv4tl", "armv4tl:armv4l:armv3l",
"armv4l", "armv4l:armv3l",
* for further information
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
/* we need FNM_CASEFOLD */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <fnmatch.h>
#include "pool.h"
enabledisablelearntrules(solv);
}
+static inline int
+queue_contains(Queue *q, Id id)
+{
+ int i;
+ for (i = 0; i < q->count; i++)
+ if (q->elements[i] == id)
+ return 1;
+ return 0;
+}
+
+static void
+disable_recommendsrules(Solver *solv, Queue *weakq)
+{
+ Pool *pool = solv->pool;
+ int i;
+ for (i = 0; i < weakq->count; i++)
+ {
+ Rule *r;
+ if (!queue_contains(solv->recommendsruleq, weakq->elements[i]))
+ continue;
+ r = solv->rules + weakq->elements[i];
+ if (r->d >= 0)
+ {
+ POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "disabling ");
+ solver_printruleclass(solv, SOLV_DEBUG_UNSOLVABLE, r);
+ solver_disablerule(solv, r);
+ }
+ }
+}
/*-------------------------------------------------------------------
*
*/
static void
-analyze_unsolvable_rule(Solver *solv, Rule *r, Id *lastweakp, Map *rseen)
+analyze_unsolvable_rule(Solver *solv, Rule *r, Queue *weakq, Map *rseen)
{
Pool *pool = solv->pool;
int i;
MAPSET(rseen, why - solv->learntrules);
for (i = solv->learnt_why.elements[why - solv->learntrules]; solv->learnt_pool.elements[i]; i++)
if (solv->learnt_pool.elements[i] > 0)
- analyze_unsolvable_rule(solv, solv->rules + solv->learnt_pool.elements[i], lastweakp, rseen);
+ analyze_unsolvable_rule(solv, solv->rules + solv->learnt_pool.elements[i], weakq, rseen);
return;
}
- if (solv->weakrulemap.size && MAPTST(&solv->weakrulemap, why))
- if (!*lastweakp || why > *lastweakp)
- *lastweakp = why;
+ if (solv->weakrulemap.size && MAPTST(&solv->weakrulemap, why) && weakq)
+ queue_push(weakq, why);
/* do not add pkg rules to problem */
if (why < solv->pkgrules_end)
return;
Rule *r;
Map involved; /* global to speed things up? */
Map rseen;
+ Queue weakq;
Id pp, v, vv, why;
int i, idx;
Id *decisionmap = solv->decisionmap;
int oldproblemcount;
int oldlearntpoolcount;
- Id lastweak;
int record_proof = 1;
POOL_DEBUG(SOLV_DEBUG_UNSOLVABLE, "ANALYZE UNSOLVABLE ----------------------\n");
r = cr;
map_init(&involved, pool->nsolvables);
map_init(&rseen, solv->learntrules ? solv->nrules - solv->learntrules : 0);
+ queue_init(&weakq);
if (record_proof)
queue_push(&solv->learnt_pool, r - solv->rules);
- lastweak = 0;
- analyze_unsolvable_rule(solv, r, &lastweak, &rseen);
+ analyze_unsolvable_rule(solv, r, &weakq, &rseen);
FOR_RULELITERALS(v, pp, r)
{
if (DECISIONMAP_TRUE(v)) /* the one true literal */
if (record_proof)
queue_push(&solv->learnt_pool, why);
r = solv->rules + why;
- analyze_unsolvable_rule(solv, r, &lastweak, &rseen);
+ analyze_unsolvable_rule(solv, r, &weakq, &rseen);
FOR_RULELITERALS(v, pp, r)
{
if (DECISIONMAP_TRUE(v)) /* the one true literal */
map_free(&rseen);
queue_push(&solv->problems, 0); /* mark end of this problem */
- if (lastweak)
+ if (weakq.count)
{
- /* disable last weak rule */
+ Id lastweak;
+ /* revert problems */
solv->problems.count = oldproblemcount;
solv->learnt_pool.count = oldlearntpoolcount;
+ /* find last weak */
+ lastweak = 0;
+ for (i = 0; i < weakq.count; i++)
+ if (weakq.elements[i] > lastweak)
+ lastweak = weakq.elements[i];
+ if (lastweak < solv->pkgrules_end && solv->strongrecommends && solv->recommendsruleq && queue_contains(solv->recommendsruleq, lastweak))
+ {
+ disable_recommendsrules(solv, &weakq);
+ queue_free(&weakq);
+ solver_reset(solv);
+ return 0;
+ }
+ queue_free(&weakq);
if (lastweak >= solv->jobrules && lastweak < solv->jobrules_end)
v = -(solv->ruletojob.elements[lastweak - solv->jobrules] + 1);
else
solver_reset(solv);
return 0;
}
+ queue_free(&weakq);
if (solv->allowuninstall || solv->allowuninstall_all || solv->allowuninstallmap.size)
if (autouninstall(solv, solv->problems.elements + oldproblemcount + 1) != 0)
see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
*/
-#if defined(__GLIBC__) && (defined(HAVE_QSORT_R) || defined(HAVE___QSORT_R))
+#if (defined(__GLIBC__) || defined(__NEWLIB__)) && (defined(HAVE_QSORT_R) || defined(HAVE___QSORT_R))
void
solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
--- /dev/null
+repo system 0 testtags <inline>
+#>=Pkg: X 1 1 x86_64
+repo available 0 testtags <inline>
+#>=Pkg: A 1 1 x86_64
+#>=Req: X
+#>=Pkg: B 1 1 x86_64
+job install name A
+result transaction,problems,rules <inline>
+#>install A-1-1.x86_64@available
+#>install X-1-1.x86_64@system
+#>rule job 300db6ce502dde94261e267a8c535441 A-1-1.x86_64@available
+#>rule pkg 11c27e407a56aad27bd6b3eadc17374b X-1-1.x86_64@system
+#>rule pkg 11c27e407a56aad27bd6b3eadc17374b -A-1-1.x86_64@available
+nextjob reusesolver
+job install name B
+result transaction,problems,rules <inline>
+#>install B-1-1.x86_64@available
+#>rule job ad168c1819736b8aa6f507ab075b3494 B-1-1.x86_64@available
+#>rule pkg 11c27e407a56aad27bd6b3eadc17374b X-1-1.x86_64@system
+#>rule pkg 11c27e407a56aad27bd6b3eadc17374b -A-1-1.x86_64@available
--- /dev/null
+#
+# A recommends B and B recommends C
+#
+# With strongrecommends, we get the following
+# rules:
+# A -> B
+# B -> C
+# after pkg rules sorting, this will be (-B is less than -A)
+# B -> C (weak)
+# A -> B (weak)
+# If just the last weak rule is broken, only A will be
+# installed but but B. So the code now breaks all weak
+# recommends rules.
+repo system 0 testtags <inline>
+#>=Pkg: X 1 1 noarch
+#>=Con: C
+repo available 0 testtags <inline>
+#>=Pkg: A 1 2 noarch
+#>=Rec: B
+#>=Pkg: B 1 1 noarch
+#>=Rec: C
+#>=Pkg: C 1 1 noarch
+system i686 rpm system
+solverflags strongrecommends
+job install name A
+result transaction,problems <inline>
+#>install A-1-2.noarch@available
+#>install B-1-1.noarch@available
--- /dev/null
+# test strong recommends
+#
+# with normal recommends, the solver will
+# not backtrack to fulfill them.
+#
+repo system 0 testtags <inline>
+#>=Pkg: A 1 1 noarch
+#>=Con: C
+#>=Pkg: A2 1 1 noarch
+#>=Con: C2
+repo available 0 testtags <inline>
+#>=Pkg: A 1 2 noarch
+#>=Pkg: B 1 1 noarch
+#>=Rec: C
+#>=Pkg: C 1 1 noarch
+#>=Pkg: B2 1 1 noarch
+#>=Rec: C2
+#>=Pkg: C2 1 1 noarch
+system i686 rpm system
+solverflags strongrecommends
+job install name B
+job install name B2
+result transaction,problems <inline>
+#>install B-1-1.noarch@available
+#>install B2-1-1.noarch@available
+#>install C-1-1.noarch@available
+#>upgrade A-1-1.noarch@system A-1-2.noarch@available
Pool *pool;
Queue job;
Queue solq;
- Solver *solv;
+ Solver *solv, *reusesolv = 0;
char *result = 0;
int resultflags = 0;
int debuglevel = 0;
pool_free(pool);
exit(resultflags == 77 ? 77 : 1);
}
-
+ if (reusesolv)
+ {
+ solver_free(solv);
+ solv = reusesolv;
+ reusesolv = 0;
+ }
if (!multijob && !feof(fp))
multijob = 1;
solver_solve(solv, &job);
solv->solution_callback = 0;
solv->solution_callback_data = 0;
- if (!resultflags)
- resultflags = TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
+ if ((resultflags & ~TESTCASE_RESULT_REUSE_SOLVER) == 0)
+ resultflags |= TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
myresult = testcase_solverresult(solv, resultflags);
if (rescallback && reportsolutiondata.result)
{
}
}
queue_free(&job);
- solver_free(solv);
+ if ((resultflags & TESTCASE_RESULT_REUSE_SOLVER) != 0 && !feof(fp))
+ reusesolv = solv;
+ else
+ solver_free(solv);
}
+ if (reusesolv)
+ solver_free(reusesolv);
pool_free(pool);
fclose(fp);
}