From da3af5788be55bca0ab93e911ec817063df61605 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 25 Jun 2017 13:17:18 +0200 Subject: [PATCH] Add support for debugsource and debuginfo subpackages - find-debuginfo-untangle-unique-build-options.patch - debugsrc-and-sub-debuginfo-packages.patch --- debugsrc-and-sub-debuginfo-packages.patch | 647 ++++++++++++++++++ ...uginfo-untangle-unique-build-options.patch | 167 +++++ rpm.spec | 11 +- 3 files changed, 824 insertions(+), 1 deletion(-) create mode 100644 debugsrc-and-sub-debuginfo-packages.patch create mode 100644 find-debuginfo-untangle-unique-build-options.patch diff --git a/debugsrc-and-sub-debuginfo-packages.patch b/debugsrc-and-sub-debuginfo-packages.patch new file mode 100644 index 0000000..b60cb53 --- /dev/null +++ b/debugsrc-and-sub-debuginfo-packages.patch @@ -0,0 +1,647 @@ +commit 538cecf0f1fe127dc416afce7a7ee6f94fdb1ad7 +Author: Michael Schroeder +Date: Tue Mar 28 14:21:40 2017 +0200 + + Support debugsource subpackages + + This can be enabled by setting the _debugsource_packages macro. + +diff --git a/macros.in b/macros.in +index 0ddde29..007b8d4 100644 +--- a/macros.in ++++ b/macros.in +@@ -183,13 +183,12 @@ + %{?_unique_debug_srcs:--unique-debug-src-base "%{name}-%{VERSION}-%{RELEASE}.%{_arch}"} \\\ + %{?_find_debuginfo_dwz_opts} \\\ + %{?_find_debuginfo_opts} \\\ ++ %{?_debugsource_packages:-S debugsourcefiles.list} \\\ + "%{_builddir}/%{?buildsubdir}"\ + %{nil} + + # Template for debug information sub-package. +-%debug_package \ +-%ifnarch noarch\ +-%global __debug_package 1\ ++%_debuginfo_template \ + %package debuginfo\ + Summary: Debug information for package %{name}\ + Group: Development/Debug\ +@@ -201,6 +200,26 @@ Debug information is useful when developing applications that use this\ + package or when debugging this package.\ + %files debuginfo -f debugfiles.list\ + %defattr(-,root,root)\ ++%{nil} ++ ++%_debugsource_template \ ++%package debugsource\ ++Summary: Debug sources for package %{name}\ ++Group: Development/Debug\ ++AutoReqProv: 0\ ++%description debugsource\ ++This package provides debug sources for package %{name}.\ ++Debug sources are useful when developing applications that use this\ ++package or when debugging this package.\ ++%files debugsource -f debugsourcefiles.list\ ++%defattr(-,root,root)\ ++%{nil} ++ ++%debug_package \ ++%ifnarch noarch\ ++%global __debug_package 1\ ++%_debuginfo_template\ ++%{?_debugsource_packages:%_debugsource_template}\ + %endif\ + %{nil} + +@@ -527,6 +546,9 @@ package or when debugging this package.\ + # directory under /usr/debug/src as --. + %_unique_debug_srcs 1 + ++# Whether rpm should put debug source files into its own subpackage ++#%_debugsource_packages 1 ++ + # + # Use internal dependency generator rather than external helpers? + %_use_internal_dependency_generator 1 +diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh +index 1ebc159..aaf4c75 100755 +--- a/scripts/find-debuginfo.sh ++++ b/scripts/find-debuginfo.sh +@@ -4,6 +4,7 @@ + # + # Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] [-i] [-n] + # [-o debugfiles.list] ++# [-S debugsourcefiles.list] + # [--run-dwz] [--dwz-low-mem-die-limit N] + # [--dwz-max-die-limit N] + # [--build-id-seed VERSION-RELEASE] +@@ -79,6 +80,7 @@ n_jobs=1 + + BUILDDIR=. + out=debugfiles.list ++srcout= + nout=0 + while [ $# -gt 0 ]; do + case "$1" in +@@ -147,6 +149,10 @@ while [ $# -gt 0 ]; do + -j*) + n_jobs=${1#-j} + ;; ++ -S) ++ srcout=$2 ++ shift ++ ;; + *) + BUILDDIR=$1 + shift +@@ -512,10 +518,19 @@ if [ -d "${RPM_BUILD_ROOT}/usr/lib" -o -d "${RPM_BUILD_ROOT}/usr/src" ]; then + + (cd "${RPM_BUILD_ROOT}/usr" + test ! -d lib/debug || find lib/debug ! -type d +- test ! -d src/debug || find src/debug -mindepth 1 -maxdepth 1 ++ test ! -d src/debug -o -n "$srcout" || find src/debug -mindepth 1 -maxdepth 1 + ) | sed 's,^,/usr/,' >> "$LISTFILE" + fi + ++if [ -n "$srcout" ]; then ++ > "$srcout" ++ if [ -d "${RPM_BUILD_ROOT}/usr/src/debug" ]; then ++ (cd "${RPM_BUILD_ROOT}/usr" ++ find src/debug -mindepth 1 -maxdepth 1 ++ ) | sed 's,^,/usr/,' >> "$srcout" ++ fi ++fi ++ + # Append to $1 only the lines from stdin not already in the file. + append_uniq() + { + +commit 980749fdce055254ca92ee7e2595b16750b699a2 +Author: Michael Schroeder +Date: Fri Mar 24 15:35:23 2017 +0100 + + Support debuginfo subpackages + + We do this by filtering the debuginfo files generated by find-debuginfo.sh + with the files from the (sub)packages. + + This commit is heavily based on a patch by Richard Biener. + +diff --git a/build/files.c b/build/files.c +index f58569e..e3fc8d6 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -40,6 +40,16 @@ + #define SKIPWHITE(_x) {while(*(_x) && (risspace(*_x) || *(_x) == ',')) (_x)++;} + #define SKIPNONWHITE(_x){while(*(_x) &&!(risspace(*_x) || *(_x) == ',')) (_x)++;} + ++/* the following defines must be in sync with the equally hardcoded paths from ++ * scripts/find-debuginfo.sh ++ */ ++#define BUILD_ID_DIR "/usr/lib/.build-id" ++#define DEBUG_SRC_DIR "/usr/src/debug" ++#define DEBUG_LIB_DIR "/usr/lib/debug" ++#define DEBUG_LIB_PREFIX "/usr/lib/debug/" ++#define DEBUG_ID_DIR "/usr/lib/debug/.build-id" ++#define DEBUG_DWZ_DIR "/usr/lib/debug/.dwz" ++ + /** + */ + enum specfFlags_e { +@@ -1738,9 +1748,8 @@ static int generateBuildIDs(FileList fl) + if (lstat(flp->diskPath, &sbuf) == 0 && S_ISREG (sbuf.st_mode)) { + /* We determine whether this is a main or + debug ELF based on path. */ +- #define DEBUGPATH "/usr/lib/debug/" + int isDbg = strncmp (flp->cpioPath, +- DEBUGPATH, strlen (DEBUGPATH)) == 0; ++ DEBUG_LIB_PREFIX, strlen (DEBUG_LIB_PREFIX)) == 0; + + /* For the main package files mimic what find-debuginfo.sh does. + Only check build-ids for executable files. Debug files are +@@ -1833,8 +1842,6 @@ static int generateBuildIDs(FileList fl) + if (rc == 0) { + char *attrstr; + /* Add .build-id directories to hold the subdirs/symlinks. */ +- #define BUILD_ID_DIR "/usr/lib/.build-id" +- #define DEBUG_ID_DIR "/usr/lib/debug/.build-id" + + mainiddir = rpmGetPath(fl->buildRoot, BUILD_ID_DIR, NULL); + debugiddir = rpmGetPath(fl->buildRoot, DEBUG_ID_DIR, NULL); +@@ -1898,8 +1905,8 @@ static int generateBuildIDs(FileList fl) + /* Don't add anything more when an error occured. But do + cleanup. */ + if (rc == 0) { +- int isDbg = strncmp (paths[i], DEBUGPATH, +- strlen (DEBUGPATH)) == 0; ++ int isDbg = strncmp (paths[i], DEBUG_LIB_PREFIX, ++ strlen (DEBUG_LIB_PREFIX)) == 0; + + char *buildidsubdir; + char subdir[4]; +@@ -2001,7 +2008,7 @@ static int generateBuildIDs(FileList fl) + which don't end in ".debug". */ + int pathlen = strlen(paths[i]); + int debuglen = strlen(".debug"); +- int prefixlen = strlen("/usr/lib/debug"); ++ int prefixlen = strlen(DEBUG_LIB_DIR); + int vralen = vra == NULL ? 0 : strlen(vra); + if (pathlen > prefixlen + debuglen + vralen + && strcmp ((paths[i] + pathlen - debuglen), +@@ -2659,24 +2666,273 @@ exit: + return rc; + } + ++static rpmTag copyTagsFromMainDebug[] = { ++ RPMTAG_ARCH, ++ RPMTAG_SUMMARY, ++ RPMTAG_DESCRIPTION, ++ RPMTAG_GROUP, ++ /* see addTargets */ ++ RPMTAG_OS, ++ RPMTAG_PLATFORM, ++ RPMTAG_OPTFLAGS, ++}; ++ ++/* this is a hack: patch the summary and the description to include ++ * the correct package name */ ++static void patchDebugPackageString(Package dbg, rpmTag tag, Package pkg, Package mainpkg) ++{ ++ const char *oldname, *newname, *old; ++ char *oldsubst = NULL, *newsubst = NULL, *p; ++ oldname = headerGetString(mainpkg->header, RPMTAG_NAME); ++ newname = headerGetString(pkg->header, RPMTAG_NAME); ++ rasprintf(&oldsubst, "package %s", oldname); ++ rasprintf(&newsubst, "package %s", newname); ++ old = headerGetString(dbg->header, tag); ++ p = old ? strstr(old, oldsubst) : NULL; ++ if (p) { ++ char *new = NULL; ++ rasprintf(&new, "%.*s%s%s", (int)(p - old), old, newsubst, p + strlen(oldsubst)); ++ headerDel(dbg->header, tag); ++ headerPutString(dbg->header, tag, new); ++ _free(new); ++ } ++ _free(oldsubst); ++ _free(newsubst); ++} ++ ++/* create a new debuginfo subpackage for package pkg from the ++ * main debuginfo package */ ++static Package cloneDebuginfoPackage(rpmSpec spec, Package pkg, Package maindbg) ++{ ++ const char *name = headerGetString(pkg->header, RPMTAG_NAME); ++ char *dbgname = NULL; ++ Package dbg; ++ ++ rasprintf(&dbgname, "%s-%s", name, "debuginfo"); ++ dbg = newPackage(dbgname, spec->pool, &spec->packages); ++ headerPutString(dbg->header, RPMTAG_NAME, dbgname); ++ copyInheritedTags(dbg->header, pkg->header); ++ headerDel(dbg->header, RPMTAG_GROUP); ++ headerCopyTags(maindbg->header, dbg->header, copyTagsFromMainDebug); ++ dbg->autoReq = maindbg->autoReq; ++ dbg->autoProv = maindbg->autoProv; ++ ++ /* patch summary and description strings */ ++ patchDebugPackageString(dbg, RPMTAG_SUMMARY, pkg, spec->packages); ++ patchDebugPackageString(dbg, RPMTAG_DESCRIPTION, pkg, spec->packages); ++ ++ /* Add self-provides (normally done by addTargets) */ ++ addPackageProvides(dbg); ++ dbg->ds = rpmdsThis(dbg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL); ++ ++ _free(dbgname); ++ return dbg; ++} ++ ++/* add a directory to the file list */ ++static void argvAddDir(ARGV_t *filesp, const char *dir) ++{ ++ char *line = NULL; ++ rasprintf(&line, "%%dir %s", dir); ++ argvAdd(filesp, line); ++ _free(line); ++} ++ ++/* collect the debug files for package pkg and put them into ++ * a (possibly new) debuginfo subpackage */ ++static void filterDebuginfoPackage(rpmSpec spec, Package pkg, ++ Package maindbg, char *buildroot, char *uniquearch) ++{ ++ rpmfi fi; ++ ARGV_t files = NULL; ++ Package dbg = NULL; ++ char *path = NULL; ++ size_t buildrootlen = strlen(buildroot); ++ ++ /* ignore noarch subpackages */ ++ if (rstreq(headerGetString(pkg->header, RPMTAG_ARCH), "noarch")) ++ return; ++ ++ if (!uniquearch) ++ uniquearch = ""; ++ ++ fi = rpmfilesIter(pkg->cpioList, RPMFI_ITER_FWD); ++ /* Check if the current package has files with debug info ++ and add them to the file list */ ++ fi = rpmfiInit(fi, 0); ++ while (rpmfiNext(fi) >= 0) { ++ const char *name = rpmfiFN(fi); ++ 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; ++ ++ /* generate path */ ++ rasprintf(&path, "%s%s%.*s%s.debug", buildroot, DEBUG_LIB_DIR, namel, name, uniquearch); ++ ++ /* If that file exists we have debug information for it */ ++ if (access(path, F_OK) == 0) { ++ /* Append the file list preamble */ ++ if (!files) { ++ argvAdd(&files, "%defattr(-,root,root)"); ++ argvAddDir(&files, DEBUG_LIB_DIR); ++ } ++ /* Add the files main debug-info file */ ++ argvAdd(&files, path + buildrootlen); ++ } ++ path = _free(path); ++ } ++ ++ if (files) { ++ /* we have collected some files. Now put them in a debuginfo ++ * package. If this is not the main package, clone the main ++ * debuginfo package */ ++ if (pkg == spec->packages) ++ maindbg->fileList = files; ++ else { ++ Package dbg = cloneDebuginfoPackage(spec, pkg, maindbg); ++ dbg->fileList = files; ++ } ++ } ++} ++ ++/* add the debug dwz files to package pkg. ++ * return 1 if something was added, 0 otherwise. */ ++static int addDebugDwz(Package pkg, char *buildroot) ++{ ++ int ret = 0; ++ char *path = NULL; ++ struct stat sbuf; ++ ++ rasprintf(&path, "%s%s", buildroot, DEBUG_DWZ_DIR); ++ if (lstat(path, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)) { ++ if (!pkg->fileList) { ++ argvAdd(&pkg->fileList, "%defattr(-,root,root)"); ++ argvAddDir(&pkg->fileList, DEBUG_LIB_DIR); ++ } ++ argvAdd(&pkg->fileList, DEBUG_DWZ_DIR); ++ ret = 1; ++ } ++ path = _free(path); ++ return ret; ++} ++ ++/* add the debug source files to package pkg. ++ * return 1 if something was added, 0 otherwise. */ ++static int addDebugSrc(Package pkg, char *buildroot) ++{ ++ int ret = 0; ++ char *path = NULL; ++ DIR *d; ++ struct dirent *de; ++ ++ /* not needed if we have an extra debugsource subpackage */ ++ if (rpmExpandNumeric("%{?_debugsource_packages}")) ++ return 0; ++ ++ rasprintf(&path, "%s%s", buildroot, DEBUG_SRC_DIR); ++ d = opendir(path); ++ path = _free(path); ++ if (d) { ++ while ((de = readdir(d)) != NULL) { ++ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) ++ continue; ++ rasprintf(&path, "%s/%s", DEBUG_SRC_DIR, de->d_name); ++ if (!pkg->fileList) ++ argvAdd(&pkg->fileList, "%defattr(-,root,root)"); ++ argvAdd(&pkg->fileList, path); ++ path = _free(path); ++ ret = 1; ++ } ++ closedir(d); ++ } ++ return ret; ++} ++ ++/* find the main debuginfo package. We do this simply by ++ * searching for a package with the right name. */ ++static Package findDebuginfoPackage(rpmSpec spec) ++{ ++ Package pkg = NULL; ++ if (lookupPackage(spec, "debuginfo", PART_SUBNAME, &pkg)) ++ return NULL; ++ return pkg && pkg->fileList ? pkg : NULL; ++} ++ ++/* add a requires for package "to" into package "from". */ ++static void addPackageRequires(Package from, Package to) ++{ ++ const char *name; ++ char *evr, *isaprov; ++ name = headerGetString(to->header, RPMTAG_NAME); ++ evr = headerGetAsString(to->header, RPMTAG_EVR); ++ isaprov = rpmExpand(name, "%{?_isa}", NULL); ++ addReqProv(from, RPMTAG_REQUIRENAME, isaprov, evr, RPMSENSE_EQUAL, 0); ++ free(isaprov); ++ free(evr); ++} ++ + rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + int installSpecialDoc, int test) + { + Package pkg; + rpmRC rc = RPMRC_OK; ++ char *buildroot; ++ char *uniquearch = NULL; ++ Package maindbg = NULL; /* the (existing) main debuginfo package */ ++ Package deplink = NULL; /* create requires to this package */ + + #if HAVE_LIBDW + elf_version (EV_CURRENT); + #endif + check_fileList = newStringBuf(); + genSourceRpmName(spec); ++ buildroot = rpmGenPath(spec->rootDir, spec->buildRoot, NULL); + ++ if (rpmExpandNumeric("%{?_debuginfo_subpackages}")) { ++ maindbg = findDebuginfoPackage(spec); ++ if (maindbg) { ++ /* move debuginfo package to back */ ++ if (maindbg->next) { ++ Package *pp; ++ /* dequeue */ ++ for (pp = &spec->packages; *pp != maindbg; pp = &(*pp)->next) ++ ; ++ *pp = maindbg->next; ++ maindbg->next = 0; ++ /* enqueue at tail */ ++ for (; *pp; pp = &(*pp)->next) ++ ; ++ *pp = maindbg; ++ } ++ /* delete unsplit file list, we will re-add files back later */ ++ maindbg->fileFile = argvFree(maindbg->fileFile); ++ maindbg->fileList = argvFree(maindbg->fileList); ++ if (rpmExpandNumeric("%{?_unique_debug_names}")) ++ uniquearch = rpmExpand("-%{VERSION}-%{RELEASE}.%{_arch}", NULL); ++ } ++ } ++ + for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { + char *nvr; + const char *a; + int header_color; + int arch_color; + ++ if (pkg == maindbg) { ++ /* if there is just one debuginfo package, we put our extra stuff ++ * in it. Otherwise we put it in the main debug package */ ++ Package extradbg = !maindbg->fileList && maindbg->next && !maindbg->next->next ? ++ maindbg->next : maindbg; ++ if (addDebugDwz(extradbg, buildroot)) ++ deplink = extradbg; ++ if (addDebugSrc(extradbg, buildroot)) ++ deplink = extradbg; ++ maindbg = NULL; /* all normal packages processed */ ++ } ++ + if (pkg->fileList == NULL) + continue; + +@@ -2685,9 +2941,16 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + nvr = headerGetAsString(pkg->header, RPMTAG_NVRA); + rpmlog(RPMLOG_NOTICE, _("Processing files: %s\n"), nvr); + free(nvr); +- +- if ((rc = processPackageFiles(spec, pkgFlags, pkg, installSpecialDoc, test)) != RPMRC_OK || +- (rc = rpmfcGenerateDepends(spec, pkg)) != RPMRC_OK) ++ ++ if ((rc = processPackageFiles(spec, pkgFlags, pkg, installSpecialDoc, test)) != RPMRC_OK) ++ goto exit; ++ ++ if (maindbg) ++ filterDebuginfoPackage(spec, pkg, maindbg, buildroot, uniquearch); ++ else if (deplink && pkg != deplink) ++ addPackageRequires(pkg, deplink); ++ ++ if ((rc = rpmfcGenerateDepends(spec, pkg)) != RPMRC_OK) + goto exit; + + a = headerGetString(pkg->header, RPMTAG_ARCH); +@@ -2722,6 +2985,8 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags, + } + exit: + check_fileList = freeStringBuf(check_fileList); ++ _free(buildroot); ++ _free(uniquearch); + + return rc; + } +diff --git a/build/parsePreamble.c b/build/parsePreamble.c +index 6d25f4c..5715d25 100644 +--- a/build/parsePreamble.c ++++ b/build/parsePreamble.c +@@ -544,6 +544,13 @@ static void fillOutMainPackage(Header h) + + /** + */ ++void copyInheritedTags(Header h, Header fromh) ++{ ++ headerCopyTags(fromh, h, (rpmTagVal *)copyTagsDuringParse); ++} ++ ++/** ++ */ + static rpmRC readIcon(Header h, const char * file) + { + char *fn = NULL; +@@ -1197,8 +1204,7 @@ int parsePreamble(rpmSpec spec, int initialPackage) + } + + if (pkg != spec->packages) { +- headerCopyTags(spec->packages->header, pkg->header, +- (rpmTagVal *)copyTagsDuringParse); ++ copyInheritedTags(pkg->header, spec->packages->header); + } + + if (checkForRequired(pkg->header, NVR)) { +diff --git a/build/parseSpec.c b/build/parseSpec.c +index 2928e85..d0c42a4 100644 +--- a/build/parseSpec.c ++++ b/build/parseSpec.c +@@ -572,7 +572,7 @@ static void initSourceHeader(rpmSpec spec) + } + + /* Add extra provides to package. */ +-static void addPackageProvides(Package pkg) ++void addPackageProvides(Package pkg) + { + const char *arch, *name; + char *evr, *isaprov; +diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h +index 948dc31..46d9676 100644 +--- a/build/rpmbuild_internal.h ++++ b/build/rpmbuild_internal.h +@@ -442,6 +442,13 @@ + + + /** \ingroup rpmbuild ++ * Add self-provides to package. ++ * @param pkg package ++ */ ++RPM_GNUC_INTERNAL ++void addPackageProvides(Package pkg); ++ ++/** \ingroup rpmbuild + * Add rpmlib feature dependency. + * @param pkg package + * @param feature rpm feature name (i.e. "rpmlib(Foo)" for feature Foo) +@@ -463,6 +470,16 @@ int rpmlibNeedsFeature(Package pkg, const char * feature, const char * featureEV + + RPM_GNUC_INTERNAL + rpmRC checkForEncoding(Header h, int addtag); ++ ++ ++/** \ingroup rpmbuild ++ * Copy tags inherited by subpackages from the source header to the target header ++ * @param h target header ++ * @param fromh source header ++ */ ++RPM_GNUC_INTERNAL ++void copyInheritedTags(Header h, Header fromh); ++ + #ifdef __cplusplus + } + #endif +diff --git a/macros.in b/macros.in +index 007b8d4..cb65f4f 100644 +--- a/macros.in ++++ b/macros.in +@@ -549,6 +549,9 @@ package or when debugging this package.\ + # Whether rpm should put debug source files into its own subpackage + #%_debugsource_packages 1 + ++# Whether rpm should create extra debuginfo packages for each subpackage ++#%_debuginfo_subpackages 1 ++ + # + # Use internal dependency generator rather than external helpers? + %_use_internal_dependency_generator 1 + +commit a517554e36666f58724620347a4b8224471d2225 +Author: Michael Schroeder +Date: Wed Mar 29 14:55:10 2017 +0200 + + Also add directories to split debuginfo packages + + This gets rid of the last difference between debuginfo subpackages + and normal debuginfo packages. + +diff --git a/build/files.c b/build/files.c +index e3fc8d6..5022069 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -2745,8 +2745,9 @@ static void filterDebuginfoPackage(rpmSpec spec, Package pkg, + { + rpmfi fi; + ARGV_t files = NULL; +- Package dbg = NULL; +- char *path = NULL; ++ ARGV_t dirs = NULL; ++ int lastdiridx = -1, dirsadded; ++ char *path = NULL, *p, *pmin; + size_t buildrootlen = strlen(buildroot); + + /* ignore noarch subpackages */ +@@ -2779,12 +2780,37 @@ static void filterDebuginfoPackage(rpmSpec spec, Package pkg, + argvAdd(&files, "%defattr(-,root,root)"); + argvAddDir(&files, DEBUG_LIB_DIR); + } ++ + /* Add the files main debug-info file */ + argvAdd(&files, path + buildrootlen); ++ ++ /* Add the dir(s) */ ++ dirsadded = 0; ++ pmin = path + buildrootlen + strlen(DEBUG_LIB_DIR); ++ while ((p = strrchr(path + buildrootlen, '/')) != NULL && p > pmin) { ++ *p = 0; ++ if (lastdiridx >= 0 && !strcmp(dirs[lastdiridx], path + buildrootlen)) ++ break; /* already added this one */ ++ argvAdd(&dirs, path + buildrootlen); ++ dirsadded++; ++ } ++ if (dirsadded) ++ lastdiridx = argvCount(dirs) - dirsadded; /* remember longest dir */ + } + path = _free(path); + } + ++ /* add collected directories to file list */ ++ if (dirs) { ++ int i; ++ argvSort(dirs, NULL); ++ for (i = 0; dirs[i]; i++) { ++ if (!i || strcmp(dirs[i], dirs[i - 1]) != 0) ++ argvAddDir(&files, dirs[i]); ++ } ++ dirs = argvFree(dirs); ++ } ++ + if (files) { + /* we have collected some files. Now put them in a debuginfo + * package. If this is not the main package, clone the main diff --git a/find-debuginfo-untangle-unique-build-options.patch b/find-debuginfo-untangle-unique-build-options.patch new file mode 100644 index 0000000..c0e06ad --- /dev/null +++ b/find-debuginfo-untangle-unique-build-options.patch @@ -0,0 +1,167 @@ +commit 4842adfd91c3b37744c66d9f01c0112468fdbf37 +Author: Michael Schroeder +Date: Tue Mar 28 14:20:50 2017 +0200 + + Untangle unique build options in find-debuginfo.sh + + Rename --ver-rel option to --build-id-seed, so that it reflects what + it does, not how it is used. + + Remove implcit usage of the old --ver-rel option for --unique-debug-arch + and --unique-debug-src-base, instead already call find-debuginfo.sh with + the version included. + + Rename --unique-debug-arch to --unique-debug-suffix because it now + also contains the package version. + +diff --git a/macros.in b/macros.in +index 7656c06..0ddde29 100644 +--- a/macros.in ++++ b/macros.in +@@ -172,7 +172,18 @@ + # the script. See the script for details. + # + %__debug_install_post \ +- %{_rpmconfigdir}/find-debuginfo.sh %{?_smp_mflags} %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_no_recompute_build_ids:-n} %{?_include_minidebuginfo:-m} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{VERSION}-%{RELEASE}"} %{?_unique_debug_names:--unique-debug-arch "%{_arch}"} %{?_unique_debug_srcs:--unique-debug-src-base "%{name}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ ++ %{_rpmconfigdir}/find-debuginfo.sh \\\ ++ %{?_smp_mflags} \\\ ++ %{?_missing_build_ids_terminate_build:--strict-build-id} \\\ ++ %{?_no_recompute_build_ids:-n} \\\ ++ %{?_include_minidebuginfo:-m} \\\ ++ %{?_include_gdb_index:-i} \\\ ++ %{?_unique_build_ids:--build-id-seed "%{VERSION}-%{RELEASE}"} \\\ ++ %{?_unique_debug_names:--unique-debug-suffix "-%{VERSION}-%{RELEASE}.%{_arch}"} \\\ ++ %{?_unique_debug_srcs:--unique-debug-src-base "%{name}-%{VERSION}-%{RELEASE}.%{_arch}"} \\\ ++ %{?_find_debuginfo_dwz_opts} \\\ ++ %{?_find_debuginfo_opts} \\\ ++ "%{_builddir}/%{?buildsubdir}"\ + %{nil} + + # Template for debug information sub-package. +diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh +index 8effac8..1ebc159 100755 +--- a/scripts/find-debuginfo.sh ++++ b/scripts/find-debuginfo.sh +@@ -6,7 +6,7 @@ + # [-o debugfiles.list] + # [--run-dwz] [--dwz-low-mem-die-limit N] + # [--dwz-max-die-limit N] +-# [--ver-rel VERSION-RELEASE] ++# [--build-id-seed VERSION-RELEASE] + # [[-l filelist]... [-p 'pattern'] -o debuginfo.list] + # [builddir] + # +@@ -30,7 +30,7 @@ + # if available, and --dwz-low-mem-die-limit and --dwz-max-die-limit + # provide detailed limits. See dwz(1) -l and -L option for details. + # +-# If --ver-rel VERSION-RELEASE is given then debugedit is called to ++# If --build-id-seed VERSION-RELEASE is given then debugedit is called to + # update the build-ids it finds adding the VERSION-RELEASE string as + # seed to recalculate the build-id hash. This makes sure the + # build-ids in the ELF files are unique between versions and releases +@@ -65,11 +65,11 @@ run_dwz=false + dwz_low_mem_die_limit= + dwz_max_die_limit= + +-# Version and release of the spec. Given by --ver-rel +-ver_rel= ++# build id seed given by the --build-id-seed option ++build_id_seed= + + # Arch given by --unique-debug-arch +-unique_debug_arch= ++unique_debug_suffix= + + # Base given by --unique-debug-src-base + unique_debug_src_base= +@@ -96,12 +96,12 @@ while [ $# -gt 0 ]; do + dwz_max_die_limit=$2 + shift + ;; +- --ver-rel) +- ver_rel=$2 ++ --build-id-seed) ++ build_id_seed=$2 + shift + ;; +- --unique-debug-arch) +- unique_debug_arch=$2 ++ --unique-debug-suffix) ++ unique_debug_suffix=$2 + shift + ;; + --unique-debug-src-base) +@@ -156,18 +156,8 @@ while [ $# -gt 0 ]; do + shift + done + +-if test -z "$ver_rel" -a -n "$unique_debug_arch"; then +- echo >&2 "*** ERROR: --unique-debug-arch (${unique_debug_arch}) needs --ver-rel (${ver_rel})" +- exit 2 +-fi +- +-if test -z "$unique_debug_arch" -a -n "$unique_debug_src_base"; then +- echo >&2 "*** ERROR: --unique-debug-src-base (${unique_debug_src_base}) needs --unique-debug-arch (${unique_debug_arch})" +- exit 2 +-fi +- +-if test -n "$ver_rel" -a "$no_recompute_build_id" = "true"; then +- echo >&2 "*** ERROR: --ver-rel (unique build-ids) and -n (do not recompute build-id cannot be used together" ++if test -n "$build_id_seed" -a "$no_recompute_build_id" = "true"; then ++ echo >&2 "*** ERROR: --build-id-seed (unique build-ids) and -n (do not recompute build-id) cannot be used together" + exit 2 + fi + +@@ -278,12 +268,7 @@ debug_link() + get_debugfn() + { + dn=$(dirname "${1#$RPM_BUILD_ROOT}") +- if test -n "${unique_debug_arch}"; then +- bn=$(basename "$1" .debug)-${ver_rel}.${unique_debug_arch}.debug +- else +- bn=$(basename "$1" .debug).debug +- fi +- ++ bn=$(basename "$1" .debug)${unique_debug_suffix}.debug + debugdn=${debugdir}${dn} + debugfn=${debugdn}/${bn} + } +@@ -310,23 +310,21 @@ + [ -f "${debugfn}" ] && return + + echo "extracting debug info from $f" +- build_id_seed= +- if [ ! -z "$ver_rel" ]; then +- build_id_seed="--build-id-seed=$ver_rel" +- fi + # See also cpio SOURCEFILE copy. Directories must match up. + debug_base_name="$RPM_BUILD_DIR" + debug_dest_name="/usr/src/debug" + if [ ! -z "$unique_debug_src_base" ]; then + debug_base_name="$BUILDDIR" +- debug_dest_name="/usr/src/debug/${unique_debug_src_base}-${ver_rel}.${unique_debug_arch}" ++ debug_dest_name="/usr/src/debug/${unique_debug_src_base}" + fi + no_recompute= + if [ "$no_recompute_build_id" = "true" ]; then + no_recompute="-n" + fi +- id=$(${lib_rpm_dir}/debugedit -b $debug_base_name -d $debug_dest_name \ +- $no_recompute -i $build_id_seed -l "$SOURCEFILE" "$f") || exit ++ id=$(${lib_rpm_dir}/debugedit -b "$debug_base_name" -d "$debug_dest_name" \ ++ $no_recompute -i \ ++ ${build_id_seed:+--build-id-seed="$build_id_seed"} \ ++ -l "$SOURCEFILE" "$f") || exit + if [ -z "$id" ]; then + echo >&2 "*** ${strict_error}: No build ID note found in $f" + $strict && exit 2 +@@ -509,7 +492,7 @@ if [ -s "$SOURCEFILE" ]; then + debug_dest_name="/usr/src/debug" + if [ ! -z "$unique_debug_src_base" ]; then + debug_base_name="$BUILDDIR" +- debug_dest_name="/usr/src/debug/${unique_debug_src_base}-${ver_rel}.${unique_debug_arch}" ++ debug_dest_name="/usr/src/debug/${unique_debug_src_base}" + fi + + mkdir -p "${RPM_BUILD_ROOT}${debug_dest_name}" diff --git a/rpm.spec b/rpm.spec index 560c7d0..e74d299 100644 --- a/rpm.spec +++ b/rpm.spec @@ -33,7 +33,7 @@ Summary: The RPM package management system Name: rpm Version: %{rpmver} -Release: %{?snapver:0.%{snapver}.}24%{?dist} +Release: %{?snapver:0.%{snapver}.}25%{?dist} Group: System Environment/Base Url: http://www.rpm.org/ Source0: http://ftp.rpm.org/releases/%{srcdir}/%{name}-%{srcver}.tar.bz2 @@ -97,6 +97,10 @@ Patch280: rpm-4.13.x-writable-tmp-dir.patch Patch281: find-debuginfo-split-traversal-and-extraction.patch Patch282: find-debuginfo-process-files-in-parallel.patch +# Support debugsource and debuginfo subpackages +Patch285: find-debuginfo-untangle-unique-build-options.patch +Patch286: debugsrc-and-sub-debuginfo-packages.patch + # OpenSSL backend Patch300: 0001-Add-OpenSSL-support-for-digest-and-signatures.patch @@ -598,6 +602,11 @@ exit 0 %doc doc/librpm/html/* %changelog +* Sun Jun 25 2017 Mark Wielaard - 4.13.0.1-25 +- Add support for debugsource and debuginfo subpackages + - find-debuginfo-untangle-unique-build-options.patch + - debugsrc-and-sub-debuginfo-packages.patch + * Fri Jun 23 2017 Mark Wielaard - 4.13.0.1-24 - Backport parallel debuginfo processing.