diff --git a/build/files.c b/build/files.c index dcc772e09c..f75edc3b5b 100644 --- a/build/files.c +++ b/build/files.c @@ -60,6 +60,17 @@ #define DEBUG_ID_DIR "/usr/lib/debug/.build-id" #define DEBUG_DWZ_DIR "/usr/lib/debug/.dwz" +#undef HASHTYPE +#undef HTKEYTYPE +#undef HTDATATYPE +#define HASHTYPE fileRenameHash +#define HTKEYTYPE const char * +#define HTDATATYPE const char * +#include "lib/rpmhash.C" +#undef HASHTYPE +#undef HTKEYTYPE +#undef HTDATATYPE + /** */ enum specfFlags_e { @@ -1022,19 +1033,28 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) } /* Adjust paths if needed */ - if (!isSrc && pkg->removePostfixes) - for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { - char * cpiopath = flp->cpioPath; - - for (ARGV_const_t postfix_p = pkg->removePostfixes; *postfix_p; postfix_p++) { - int len = strlen(*postfix_p); - int plen = strlen(cpiopath); - if (len <= plen && !strncmp(cpiopath+plen-len, *postfix_p, len)) { - cpiopath[plen-len] = '\0'; - if (plen-len > 0 && cpiopath[plen-len-1] == '/') { - cpiopath[plen-len-1] = '\0'; + if (!isSrc && pkg->removePostfixes) { + pkg->fileRenameMap = fileRenameHashCreate(fl->files.used, + rstrhash, strcmp, + (fileRenameHashFreeKey)rfree, (fileRenameHashFreeData)rfree); + for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) { + char * cpiopath = flp->cpioPath; + char * cpiopath_orig = xstrdup(cpiopath); + + for (ARGV_const_t postfix_p = pkg->removePostfixes; *postfix_p; postfix_p++) { + int len = strlen(*postfix_p); + int plen = strlen(cpiopath); + if (len <= plen && !strncmp(cpiopath+plen-len, *postfix_p, len)) { + cpiopath[plen-len] = '\0'; + if (plen-len > 0 && cpiopath[plen-len-1] == '/') { + cpiopath[plen-len-1] = '\0'; + } } } + if (strcmp(cpiopath_orig, cpiopath)) + fileRenameHashAddEntry(pkg->fileRenameMap, xstrdup(cpiopath), cpiopath_orig); + else + _free(cpiopath_orig); } } @@ -1100,7 +1120,11 @@ static void genCpioListAndHeader(FileList fl, Package pkg, int isSrc) } /* Skip files that were marked with %exclude. */ - if (flp->flags & RPMFILE_EXCLUDE) continue; + if (flp->flags & RPMFILE_EXCLUDE) + { + argvAdd(&pkg->fileExcludeList, flp->cpioPath); + continue; + } /* Collect on-disk paths for archive creation */ pkg->dpaths[npaths++] = xstrdup(flp->diskPath); @@ -2813,9 +2837,21 @@ static void filterDebuginfoPackage(rpmSpec spec, Package pkg, int namel = strlen(name); /* strip trailing .debug like in find-debuginfo.sh */ - namel = strlen(name); if (namel > 6 && !strcmp(name + namel - 6, ".debug")) namel -= 6; + + /* fileRenameMap doesn't necessarily have to be initialized */ + if (pkg->fileRenameMap) { + const char **names = NULL; + int namec = 0; + fileRenameHashGetEntry(pkg->fileRenameMap, name, &names, &namec, NULL); + if (namec) { + if (namec > 1) + rpmlog(RPMLOG_WARNING, _("%s was mapped to multiple filenames"), name); + name = *names; + namel = strlen(name); + } + } /* generate path */ rasprintf(&path, "%s%s%.*s%s.debug", buildroot, DEBUG_LIB_DIR, namel, name, uniquearch); @@ -2848,6 +2884,21 @@ static void filterDebuginfoPackage(rpmSpec spec, Package pkg, } path = _free(path); } + /* Exclude debug files for files which were excluded in respective non-debug package */ + for (ARGV_const_t excl = pkg->fileExcludeList; excl && *excl; excl++) { + const char *name = *excl; + + /* generate path */ + rasprintf(&path, "%s%s%s%s.debug", buildroot, DEBUG_LIB_DIR, name, uniquearch); + /* Exclude only debuginfo files which actually exist */ + if (access(path, F_OK) == 0) { + char *line = NULL; + rasprintf(&line, "%%exclude %s", path + buildrootlen); + argvAdd(&files, line); + _free(line); + } + path = _free(path); + } /* add collected directories to file list */ if (dirs) { diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h index 46d967606b..c294d5ee27 100644 --- a/build/rpmbuild_internal.h +++ b/build/rpmbuild_internal.h @@ -6,6 +6,17 @@ #include #include "build/rpmbuild_misc.h" +#undef HASHTYPE +#undef HTKEYTYPE +#undef HTDATATYPE +#define HASHTYPE fileRenameHash +#define HTKEYTYPE const char * +#define HTDATATYPE const char * +#include "lib/rpmhash.H" +#undef HASHTYPE +#undef HTKEYTYPE +#undef HTDATATYPE + struct TriggerFileEntry { int index; char * fileName; @@ -117,7 +128,9 @@ struct Package_s { ARGV_t fileFile; ARGV_t fileList; /* If NULL, package will not be written */ + ARGV_t fileExcludeList; ARGV_t removePostfixes; + fileRenameHash fileRenameMap; ARGV_t policyList; Package next; diff --git a/build/spec.c b/build/spec.c index b72d3571b9..17a9b7c5a5 100644 --- a/build/spec.c +++ b/build/spec.c @@ -110,8 +110,10 @@ Package newPackage(const char *name, rpmstrPool pool, Package *pkglist) p->autoProv = 1; p->autoReq = 1; p->fileList = NULL; + p->fileExcludeList = NULL; p->fileFile = NULL; p->policyList = NULL; + p->fileRenameMap = NULL; p->pool = rpmstrPoolLink(pool); p->dpaths = NULL; @@ -152,9 +154,11 @@ static Package freePackage(Package pkg) } pkg->fileList = argvFree(pkg->fileList); + pkg->fileExcludeList = argvFree(pkg->fileExcludeList); pkg->fileFile = argvFree(pkg->fileFile); pkg->policyList = argvFree(pkg->policyList); pkg->removePostfixes = argvFree(pkg->removePostfixes); + pkg->fileRenameMap = fileRenameHashFree(pkg->fileRenameMap); pkg->cpioList = rpmfilesFree(pkg->cpioList); pkg->dpaths = argvFree(pkg->dpaths);