build/interdep.c: initial revision

This commit is contained in:
Alexey Tourbin 2011-01-10 13:02:49 +03:00
parent f0be1f05f3
commit 2c673900ce
4 changed files with 138 additions and 3 deletions

View File

@ -12,12 +12,12 @@ LIBS =
pkgincdir = $(pkgincludedir)
pkginc_HEADERS = rpmbuild.h rpmspec.h
noinst_HEADERS = buildio.h checkFiles.h
noinst_HEADERS = buildio.h checkFiles.h interdep.h
lib_LTLIBRARIES = librpmbuild.la
librpmbuild_la_SOURCES = \
build.c checkFiles.c expression.c files.c misc.c names.c pack.c \
parseBuildInstallClean.c parseChangelog.c parseDescription.c \
build.c checkFiles.c expression.c files.c interdep.c misc.c names.c \
pack.c parseBuildInstallClean.c parseChangelog.c parseDescription.c \
parseFiles.c parsePreamble.c parsePrep.c parseReqs.c parseScript.c \
parseSpec.c poptBT.c reqprov.c spec.c
librpmbuild_la_LDFLAGS = -release @VERSION@.1

View File

@ -2909,6 +2909,7 @@ static void printDeps(Header h)
versions = hfd(versions, dvt);
}
#include "interdep.h"
#include "checkFiles.h"
int processBinaryFiles(Spec spec, int installSpecialDoc, int test)
@ -2939,6 +2940,9 @@ int processBinaryFiles(Spec spec, int installSpecialDoc, int test)
if (rc) break;
}
if (rc == 0)
rc = processInterdep(spec);
if (rc == 0)
rc = checkFiles(spec);

124
build/interdep.c Normal file
View File

@ -0,0 +1,124 @@
/*
* interdep.c - inter-package analysis and optimizations based on
* strict dependencies between subpackages (Requires: N = [E:]V-R).
*
* Written by Alexey Tourbin <at@altlinux.org>.
* License: GPLv2+.
*/
#include "system.h"
#include "rpmbuild.h"
#include "interdep.h"
static
const char *skipPrefixDash(const char *str, const char *prefix)
{
int len = strlen(prefix);
if (strncmp(str, prefix, len))
return NULL;
if (str[len] != '-')
return NULL;
return str + len + 1;
}
struct Req {
int c;
struct Pair {
Package pkg1;
Package pkg2;
} *v;
};
static
int Requires(struct Req *r, Package pkg1, Package pkg2)
{
int i;
for (i = 0; i < r->c; i++)
if (pkg1 == r->v[i].pkg1 && pkg2 == r->v[i].pkg2)
return 1;
return 0;
}
static
void addRequires(struct Req *r, Package pkg1, Package pkg2)
{
if (Requires(r, pkg1, pkg2))
return;
AUTO_REALLOC(r->v, r->c, 8);
r->v[r->c++] = (struct Pair) { pkg1, pkg2 };
}
static
void makeReq1(struct Req *r, Package pkg1, Package pkg2)
{
int c = 0;
const char **reqNv = NULL;
const char **reqVv = NULL;
const int *reqFv = NULL;
const HGE_t hge = (HGE_t)headerGetEntryMinMemory;
int ok =
hge(pkg1->header, RPMTAG_REQUIRENAME, NULL, (void **) &reqNv, &c) &&
hge(pkg1->header, RPMTAG_REQUIREVERSION, NULL, (void **) &reqVv, NULL) &&
hge(pkg1->header, RPMTAG_REQUIREFLAGS, NULL, (void **) &reqFv, NULL);
if (!ok)
return;
const char *provN, *provV, *provR;
headerNVR(pkg2->header, &provN, &provV, &provR);
int i;
for (i = 0; i < c; i++) {
if (strcmp(reqNv[i], provN))
continue;
if ((reqFv[i] & RPMSENSE_SENSEMASK) != RPMSENSE_EQUAL)
continue;
const char *reqVR = reqVv[i];
if (*reqVR == '\0')
continue;
const char *reqR = skipPrefixDash(reqVR, provV);
if (reqR == NULL) {
// XXX handle epoch properly?
const char *colon = strchr(reqVR, ':');
if (colon)
reqR = skipPrefixDash(colon + 1, provV);
}
if (reqR == NULL)
continue;
if (strcmp(reqR, provR))
continue;
addRequires(r, pkg1, pkg2);
break;
}
const HFD_t hfd = (HFD_t) headerFreeData;
reqNv = hfd(reqNv, RPM_STRING_ARRAY_TYPE);
reqVv = hfd(reqVv, RPM_STRING_ARRAY_TYPE);
}
static
struct Req *makeRequires(Spec spec)
{
struct Req *r = xmalloc(sizeof *r);
r->c = 0;
r->v = NULL;
Package pkg1, pkg2;
for (pkg1 = spec->packages; pkg1; pkg1 = pkg1->next)
for (pkg2 = pkg1->next; pkg2; pkg2 = pkg2->next) {
makeReq1(r, pkg1, pkg2);
makeReq1(r, pkg2, pkg1);
}
return r;
}
static
struct Req *freeRequires(struct Req *r)
{
r->v = _free(r->v);
return _free(r);
}
int processInterdep(Spec spec)
{
struct Req *r = makeRequires(spec);
r = freeRequires(r);
return 0;
}
// ex: set ts=8 sts=4 sw=4 noet:

7
build/interdep.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef INTERDEP_H
#define INTERDEP_H
/* Perform inter-package analysis and optimizations. */
int processInterdep(Spec spec);
#endif