teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone

Blame debugsrc-and-sub-debuginfo-packages.patch

Mark Wielaard da3af5
commit 538cecf0f1fe127dc416afce7a7ee6f94fdb1ad7
Mark Wielaard da3af5
Author: Michael Schroeder <mls@suse.de>
Mark Wielaard da3af5
Date:   Tue Mar 28 14:21:40 2017 +0200
Mark Wielaard da3af5
Mark Wielaard da3af5
    Support debugsource subpackages
Mark Wielaard da3af5
    
Mark Wielaard da3af5
    This can be enabled by setting the _debugsource_packages macro.
Mark Wielaard da3af5
Mark Wielaard da3af5
diff --git a/macros.in b/macros.in
Mark Wielaard da3af5
index 0ddde29..007b8d4 100644
Mark Wielaard da3af5
--- a/macros.in
Mark Wielaard da3af5
+++ b/macros.in
Mark Wielaard da3af5
@@ -183,13 +183,12 @@
Mark Wielaard da3af5
     %{?_unique_debug_srcs:--unique-debug-src-base "%{name}-%{VERSION}-%{RELEASE}.%{_arch}"} \\\
Mark Wielaard da3af5
     %{?_find_debuginfo_dwz_opts} \\\
Mark Wielaard da3af5
     %{?_find_debuginfo_opts} \\\
Mark Wielaard da3af5
+    %{?_debugsource_packages:-S debugsourcefiles.list} \\\
Mark Wielaard da3af5
     "%{_builddir}/%{?buildsubdir}"\
Mark Wielaard da3af5
 %{nil}
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 #	Template for debug information sub-package.
Mark Wielaard da3af5
-%debug_package \
Mark Wielaard da3af5
-%ifnarch noarch\
Mark Wielaard da3af5
-%global __debug_package 1\
Mark Wielaard da3af5
+%_debuginfo_template \
Mark Wielaard da3af5
 %package debuginfo\
Mark Wielaard da3af5
 Summary: Debug information for package %{name}\
Mark Wielaard da3af5
 Group: Development/Debug\
Mark Wielaard da3af5
@@ -201,6 +200,26 @@ Debug information is useful when developing applications that use this\
Mark Wielaard da3af5
 package or when debugging this package.\
Mark Wielaard da3af5
 %files debuginfo -f debugfiles.list\
Mark Wielaard da3af5
 %defattr(-,root,root)\
Mark Wielaard da3af5
+%{nil}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+%_debugsource_template \
Mark Wielaard da3af5
+%package debugsource\
Mark Wielaard da3af5
+Summary: Debug sources for package %{name}\
Mark Wielaard da3af5
+Group: Development/Debug\
Mark Wielaard da3af5
+AutoReqProv: 0\
Mark Wielaard da3af5
+%description debugsource\
Mark Wielaard da3af5
+This package provides debug sources for package %{name}.\
Mark Wielaard da3af5
+Debug sources are useful when developing applications that use this\
Mark Wielaard da3af5
+package or when debugging this package.\
Mark Wielaard da3af5
+%files debugsource -f debugsourcefiles.list\
Mark Wielaard da3af5
+%defattr(-,root,root)\
Mark Wielaard da3af5
+%{nil}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+%debug_package \
Mark Wielaard da3af5
+%ifnarch noarch\
Mark Wielaard da3af5
+%global __debug_package 1\
Mark Wielaard da3af5
+%_debuginfo_template\
Mark Wielaard da3af5
+%{?_debugsource_packages:%_debugsource_template}\
Mark Wielaard da3af5
 %endif\
Mark Wielaard da3af5
 %{nil}
Mark Wielaard da3af5
 
Mark Wielaard da3af5
@@ -527,6 +546,9 @@ package or when debugging this package.\
Mark Wielaard da3af5
 # directory under /usr/debug/src as <name>-<ver>-<rel>.<arch>
Mark Wielaard da3af5
 %_unique_debug_srcs	1
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+# Whether rpm should put debug source files into its own subpackage
Mark Wielaard da3af5
+#%_debugsource_packages	1
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 #
Mark Wielaard da3af5
 # Use internal dependency generator rather than external helpers?
Mark Wielaard da3af5
 %_use_internal_dependency_generator	1
Mark Wielaard da3af5
diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
Mark Wielaard da3af5
index 1ebc159..aaf4c75 100755
Mark Wielaard da3af5
--- a/scripts/find-debuginfo.sh
Mark Wielaard da3af5
+++ b/scripts/find-debuginfo.sh
Mark Wielaard da3af5
@@ -4,6 +4,7 @@
Mark Wielaard da3af5
 #
Mark Wielaard da3af5
 # Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] [-i] [-n]
Mark Wielaard da3af5
 #	 		   [-o debugfiles.list]
Mark Wielaard da3af5
+#	 		   [-S debugsourcefiles.list]
Mark Wielaard da3af5
 #			   [--run-dwz] [--dwz-low-mem-die-limit N]
Mark Wielaard da3af5
 #			   [--dwz-max-die-limit N]
Mark Wielaard da3af5
 #			   [--build-id-seed VERSION-RELEASE]
Mark Wielaard da3af5
@@ -79,6 +80,7 @@ n_jobs=1
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 BUILDDIR=.
Mark Wielaard da3af5
 out=debugfiles.list
Mark Wielaard da3af5
+srcout=
Mark Wielaard da3af5
 nout=0
Mark Wielaard da3af5
 while [ $# -gt 0 ]; do
Mark Wielaard da3af5
   case "$1" in
Mark Wielaard da3af5
@@ -147,6 +149,10 @@ while [ $# -gt 0 ]; do
Mark Wielaard da3af5
   -j*)
Mark Wielaard da3af5
     n_jobs=${1#-j}
Mark Wielaard da3af5
     ;;
Mark Wielaard da3af5
+  -S)
Mark Wielaard da3af5
+    srcout=$2
Mark Wielaard da3af5
+    shift
Mark Wielaard da3af5
+    ;;
Mark Wielaard da3af5
   *)
Mark Wielaard da3af5
     BUILDDIR=$1
Mark Wielaard da3af5
     shift
Mark Wielaard da3af5
@@ -512,10 +518,19 @@ if [ -d "${RPM_BUILD_ROOT}/usr/lib" -o -d "${RPM_BUILD_ROOT}/usr/src" ]; then
Mark Wielaard da3af5
 
Mark Wielaard da3af5
   (cd "${RPM_BUILD_ROOT}/usr"
Mark Wielaard da3af5
    test ! -d lib/debug || find lib/debug ! -type d
Mark Wielaard da3af5
-   test ! -d src/debug || find src/debug -mindepth 1 -maxdepth 1
Mark Wielaard da3af5
+   test ! -d src/debug -o -n "$srcout" || find src/debug -mindepth 1 -maxdepth 1
Mark Wielaard da3af5
   ) | sed 's,^,/usr/,' >> "$LISTFILE"
Mark Wielaard da3af5
 fi
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+if [ -n "$srcout" ]; then
Mark Wielaard da3af5
+  > "$srcout"
Mark Wielaard da3af5
+  if [ -d "${RPM_BUILD_ROOT}/usr/src/debug" ]; then
Mark Wielaard da3af5
+    (cd "${RPM_BUILD_ROOT}/usr"
Mark Wielaard da3af5
+     find src/debug -mindepth 1 -maxdepth 1
Mark Wielaard da3af5
+    ) | sed 's,^,/usr/,' >> "$srcout"
Mark Wielaard da3af5
+  fi
Mark Wielaard da3af5
+fi
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 # Append to $1 only the lines from stdin not already in the file.
Mark Wielaard da3af5
 append_uniq()
Mark Wielaard da3af5
 {
Mark Wielaard da3af5
Mark Wielaard da3af5
commit 980749fdce055254ca92ee7e2595b16750b699a2
Mark Wielaard da3af5
Author: Michael Schroeder <mls@suse.de>
Mark Wielaard da3af5
Date:   Fri Mar 24 15:35:23 2017 +0100
Mark Wielaard da3af5
Mark Wielaard da3af5
    Support debuginfo subpackages
Mark Wielaard da3af5
    
Mark Wielaard da3af5
    We do this by filtering the debuginfo files generated by find-debuginfo.sh
Mark Wielaard da3af5
    with the files from the (sub)packages.
Mark Wielaard da3af5
    
Mark Wielaard da3af5
    This commit is heavily based on a patch by Richard Biener.
Mark Wielaard da3af5
Mark Wielaard da3af5
diff --git a/build/files.c b/build/files.c
Mark Wielaard da3af5
index f58569e..e3fc8d6 100644
Mark Wielaard da3af5
--- a/build/files.c
Mark Wielaard da3af5
+++ b/build/files.c
Mark Wielaard da3af5
@@ -40,6 +40,16 @@
Mark Wielaard da3af5
 #define	SKIPWHITE(_x)	{while(*(_x) && (risspace(*_x) || *(_x) == ',')) (_x)++;}
Mark Wielaard da3af5
 #define	SKIPNONWHITE(_x){while(*(_x) &&!(risspace(*_x) || *(_x) == ',')) (_x)++;}
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+/* the following defines must be in sync with the equally hardcoded paths from
Mark Wielaard da3af5
+ * scripts/find-debuginfo.sh
Mark Wielaard da3af5
+ */
Mark Wielaard da3af5
+#define BUILD_ID_DIR		"/usr/lib/.build-id"
Mark Wielaard da3af5
+#define DEBUG_SRC_DIR		"/usr/src/debug"
Mark Wielaard da3af5
+#define DEBUG_LIB_DIR		"/usr/lib/debug"
Mark Wielaard da3af5
+#define DEBUG_LIB_PREFIX	"/usr/lib/debug/"
Mark Wielaard da3af5
+#define DEBUG_ID_DIR		"/usr/lib/debug/.build-id"
Mark Wielaard da3af5
+#define DEBUG_DWZ_DIR 		"/usr/lib/debug/.dwz"
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 /**
Mark Wielaard da3af5
  */
Mark Wielaard da3af5
 enum specfFlags_e {
Mark Wielaard da3af5
@@ -1738,9 +1748,8 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard da3af5
 	if (lstat(flp->diskPath, &sbuf) == 0 && S_ISREG (sbuf.st_mode)) {
Mark Wielaard da3af5
 	    /* We determine whether this is a main or
Mark Wielaard da3af5
 	       debug ELF based on path.  */
Mark Wielaard da3af5
-	    #define DEBUGPATH "/usr/lib/debug/"
Mark Wielaard da3af5
 	    int isDbg = strncmp (flp->cpioPath,
Mark Wielaard da3af5
-				 DEBUGPATH, strlen (DEBUGPATH)) == 0;
Mark Wielaard da3af5
+				 DEBUG_LIB_PREFIX, strlen (DEBUG_LIB_PREFIX)) == 0;
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 	    /* For the main package files mimic what find-debuginfo.sh does.
Mark Wielaard da3af5
 	       Only check build-ids for executable files. Debug files are
Mark Wielaard da3af5
@@ -1833,8 +1842,6 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard da3af5
 	if (rc == 0) {
Mark Wielaard da3af5
 	    char *attrstr;
Mark Wielaard da3af5
 	    /* Add .build-id directories to hold the subdirs/symlinks.  */
Mark Wielaard da3af5
-            #define BUILD_ID_DIR "/usr/lib/.build-id"
Mark Wielaard da3af5
-            #define DEBUG_ID_DIR "/usr/lib/debug/.build-id"
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 	    mainiddir = rpmGetPath(fl->buildRoot, BUILD_ID_DIR, NULL);
Mark Wielaard da3af5
 	    debugiddir = rpmGetPath(fl->buildRoot, DEBUG_ID_DIR, NULL);
Mark Wielaard da3af5
@@ -1898,8 +1905,8 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard da3af5
 	    /* Don't add anything more when an error occured. But do
Mark Wielaard da3af5
 	       cleanup.  */
Mark Wielaard da3af5
 	    if (rc == 0) {
Mark Wielaard da3af5
-		int isDbg = strncmp (paths[i], DEBUGPATH,
Mark Wielaard da3af5
-				     strlen (DEBUGPATH)) == 0;
Mark Wielaard da3af5
+		int isDbg = strncmp (paths[i], DEBUG_LIB_PREFIX,
Mark Wielaard da3af5
+				     strlen (DEBUG_LIB_PREFIX)) == 0;
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 		char *buildidsubdir;
Mark Wielaard da3af5
 		char subdir[4];
Mark Wielaard da3af5
@@ -2001,7 +2008,7 @@ static int generateBuildIDs(FileList fl)
Mark Wielaard da3af5
 			       which don't end in ".debug". */
Mark Wielaard da3af5
 			    int pathlen = strlen(paths[i]);
Mark Wielaard da3af5
 			    int debuglen = strlen(".debug");
Mark Wielaard da3af5
-			    int prefixlen = strlen("/usr/lib/debug");
Mark Wielaard da3af5
+			    int prefixlen = strlen(DEBUG_LIB_DIR);
Mark Wielaard da3af5
 			    int vralen = vra == NULL ? 0 : strlen(vra);
Mark Wielaard da3af5
 			    if (pathlen > prefixlen + debuglen + vralen
Mark Wielaard da3af5
 				&& strcmp ((paths[i] + pathlen - debuglen),
Mark Wielaard da3af5
@@ -2659,24 +2666,273 @@ exit:
Mark Wielaard da3af5
     return rc;
Mark Wielaard da3af5
 }
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+static rpmTag copyTagsFromMainDebug[] = {
Mark Wielaard da3af5
+    RPMTAG_ARCH,
Mark Wielaard da3af5
+    RPMTAG_SUMMARY,
Mark Wielaard da3af5
+    RPMTAG_DESCRIPTION,
Mark Wielaard da3af5
+    RPMTAG_GROUP,
Mark Wielaard da3af5
+    /* see addTargets */
Mark Wielaard da3af5
+    RPMTAG_OS,
Mark Wielaard da3af5
+    RPMTAG_PLATFORM,
Mark Wielaard da3af5
+    RPMTAG_OPTFLAGS,
Mark Wielaard da3af5
+};
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* this is a hack: patch the summary and the description to include
Mark Wielaard da3af5
+ * the correct package name */
Mark Wielaard da3af5
+static void patchDebugPackageString(Package dbg, rpmTag tag, Package pkg, Package mainpkg)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    const char *oldname, *newname, *old;
Mark Wielaard da3af5
+    char *oldsubst = NULL, *newsubst = NULL, *p;
Mark Wielaard da3af5
+    oldname = headerGetString(mainpkg->header, RPMTAG_NAME);
Mark Wielaard da3af5
+    newname = headerGetString(pkg->header, RPMTAG_NAME);
Mark Wielaard da3af5
+    rasprintf(&oldsubst, "package %s", oldname);
Mark Wielaard da3af5
+    rasprintf(&newsubst, "package %s", newname);
Mark Wielaard da3af5
+    old = headerGetString(dbg->header, tag);
Mark Wielaard da3af5
+    p = old ? strstr(old, oldsubst) : NULL;
Mark Wielaard da3af5
+    if (p) {
Mark Wielaard da3af5
+	char *new = NULL;
Mark Wielaard da3af5
+	rasprintf(&new, "%.*s%s%s", (int)(p - old), old, newsubst, p + strlen(oldsubst));
Mark Wielaard da3af5
+	headerDel(dbg->header, tag);
Mark Wielaard da3af5
+	headerPutString(dbg->header, tag, new);
Mark Wielaard da3af5
+	_free(new);
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+    _free(oldsubst);
Mark Wielaard da3af5
+    _free(newsubst);
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* create a new debuginfo subpackage for package pkg from the
Mark Wielaard da3af5
+ * main debuginfo package */
Mark Wielaard da3af5
+static Package cloneDebuginfoPackage(rpmSpec spec, Package pkg, Package maindbg)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    const char *name = headerGetString(pkg->header, RPMTAG_NAME);
Mark Wielaard da3af5
+    char *dbgname = NULL;
Mark Wielaard da3af5
+    Package dbg;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    rasprintf(&dbgname, "%s-%s", name, "debuginfo");
Mark Wielaard da3af5
+    dbg = newPackage(dbgname, spec->pool, &spec->packages);
Mark Wielaard da3af5
+    headerPutString(dbg->header, RPMTAG_NAME, dbgname);
Mark Wielaard da3af5
+    copyInheritedTags(dbg->header, pkg->header);
Mark Wielaard da3af5
+    headerDel(dbg->header, RPMTAG_GROUP);
Mark Wielaard da3af5
+    headerCopyTags(maindbg->header, dbg->header, copyTagsFromMainDebug);
Mark Wielaard da3af5
+    dbg->autoReq = maindbg->autoReq;
Mark Wielaard da3af5
+    dbg->autoProv = maindbg->autoProv;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    /* patch summary and description strings */
Mark Wielaard da3af5
+    patchDebugPackageString(dbg, RPMTAG_SUMMARY, pkg, spec->packages);
Mark Wielaard da3af5
+    patchDebugPackageString(dbg, RPMTAG_DESCRIPTION, pkg, spec->packages);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    /* Add self-provides (normally done by addTargets) */
Mark Wielaard da3af5
+    addPackageProvides(dbg);
Mark Wielaard da3af5
+    dbg->ds = rpmdsThis(dbg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    _free(dbgname);
Mark Wielaard da3af5
+    return dbg;
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* add a directory to the file list */
Mark Wielaard da3af5
+static void argvAddDir(ARGV_t *filesp, const char *dir)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    char *line = NULL;
Mark Wielaard da3af5
+    rasprintf(&line, "%%dir %s", dir);
Mark Wielaard da3af5
+    argvAdd(filesp, line);
Mark Wielaard da3af5
+    _free(line);
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* collect the debug files for package pkg and put them into
Mark Wielaard da3af5
+ * a (possibly new) debuginfo subpackage */
Mark Wielaard da3af5
+static void filterDebuginfoPackage(rpmSpec spec, Package pkg,
Mark Wielaard da3af5
+		Package maindbg, char *buildroot, char *uniquearch)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    rpmfi fi;
Mark Wielaard da3af5
+    ARGV_t files = NULL;
Mark Wielaard da3af5
+    Package dbg = NULL;
Mark Wielaard da3af5
+    char *path = NULL;
Mark Wielaard da3af5
+    size_t buildrootlen = strlen(buildroot);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    /* ignore noarch subpackages */
Mark Wielaard da3af5
+    if (rstreq(headerGetString(pkg->header, RPMTAG_ARCH), "noarch"))
Mark Wielaard da3af5
+	return;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    if (!uniquearch)
Mark Wielaard da3af5
+	uniquearch = "";
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    fi = rpmfilesIter(pkg->cpioList, RPMFI_ITER_FWD);
Mark Wielaard da3af5
+    /* Check if the current package has files with debug info
Mark Wielaard da3af5
+       and add them to the file list */
Mark Wielaard da3af5
+    fi = rpmfiInit(fi, 0);
Mark Wielaard da3af5
+    while (rpmfiNext(fi) >= 0) {
Mark Wielaard da3af5
+	const char *name = rpmfiFN(fi);
Mark Wielaard da3af5
+	int namel = strlen(name);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+	/* strip trailing .debug like in find-debuginfo.sh */
Mark Wielaard da3af5
+	namel = strlen(name);
Mark Wielaard da3af5
+	if (namel > 6 && !strcmp(name + namel - 6, ".debug"))
Mark Wielaard da3af5
+	    namel -= 6;
Mark Wielaard da3af5
+	
Mark Wielaard da3af5
+	/* generate path */
Mark Wielaard da3af5
+	rasprintf(&path, "%s%s%.*s%s.debug", buildroot, DEBUG_LIB_DIR, namel, name, uniquearch);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+	/* If that file exists we have debug information for it */
Mark Wielaard da3af5
+	if (access(path, F_OK) == 0) {
Mark Wielaard da3af5
+	    /* Append the file list preamble */
Mark Wielaard da3af5
+	    if (!files) {
Mark Wielaard da3af5
+		argvAdd(&files, "%defattr(-,root,root)");
Mark Wielaard da3af5
+		argvAddDir(&files, DEBUG_LIB_DIR);
Mark Wielaard da3af5
+	    }
Mark Wielaard da3af5
+	    /* Add the files main debug-info file */
Mark Wielaard da3af5
+	    argvAdd(&files, path + buildrootlen);
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+	path = _free(path);
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    if (files) {
Mark Wielaard da3af5
+	/* we have collected some files. Now put them in a debuginfo
Mark Wielaard da3af5
+         * package. If this is not the main package, clone the main
Mark Wielaard da3af5
+         * debuginfo package */
Mark Wielaard da3af5
+	if (pkg == spec->packages)
Mark Wielaard da3af5
+	    maindbg->fileList = files;
Mark Wielaard da3af5
+	else {
Mark Wielaard da3af5
+	    Package dbg = cloneDebuginfoPackage(spec, pkg, maindbg);
Mark Wielaard da3af5
+	    dbg->fileList = files;
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* add the debug dwz files to package pkg.
Mark Wielaard da3af5
+ * return 1 if something was added, 0 otherwise. */
Mark Wielaard da3af5
+static int addDebugDwz(Package pkg, char *buildroot)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    int ret = 0;
Mark Wielaard da3af5
+    char *path = NULL;
Mark Wielaard da3af5
+    struct stat sbuf;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    rasprintf(&path, "%s%s", buildroot, DEBUG_DWZ_DIR);
Mark Wielaard da3af5
+    if (lstat(path, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)) {
Mark Wielaard da3af5
+	if (!pkg->fileList) {
Mark Wielaard da3af5
+	    argvAdd(&pkg->fileList, "%defattr(-,root,root)");
Mark Wielaard da3af5
+	    argvAddDir(&pkg->fileList, DEBUG_LIB_DIR);
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+	argvAdd(&pkg->fileList, DEBUG_DWZ_DIR);
Mark Wielaard da3af5
+	ret = 1;
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+    path = _free(path);
Mark Wielaard da3af5
+    return ret;
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* add the debug source files to package pkg.
Mark Wielaard da3af5
+ * return 1 if something was added, 0 otherwise. */
Mark Wielaard da3af5
+static int addDebugSrc(Package pkg, char *buildroot)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    int ret = 0;
Mark Wielaard da3af5
+    char *path = NULL;
Mark Wielaard da3af5
+    DIR *d;
Mark Wielaard da3af5
+    struct dirent *de;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    /* not needed if we have an extra debugsource subpackage */
Mark Wielaard da3af5
+    if (rpmExpandNumeric("%{?_debugsource_packages}"))
Mark Wielaard da3af5
+	return 0;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+    rasprintf(&path, "%s%s", buildroot, DEBUG_SRC_DIR);
Mark Wielaard da3af5
+    d = opendir(path);
Mark Wielaard da3af5
+    path = _free(path);
Mark Wielaard da3af5
+    if (d) {
Mark Wielaard da3af5
+	while ((de = readdir(d)) != NULL) {
Mark Wielaard da3af5
+	    if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
Mark Wielaard da3af5
+		continue;
Mark Wielaard da3af5
+	    rasprintf(&path, "%s/%s", DEBUG_SRC_DIR, de->d_name);
Mark Wielaard da3af5
+	    if (!pkg->fileList)
Mark Wielaard da3af5
+		argvAdd(&pkg->fileList, "%defattr(-,root,root)");
Mark Wielaard da3af5
+	    argvAdd(&pkg->fileList, path);
Mark Wielaard da3af5
+	    path = _free(path);
Mark Wielaard da3af5
+	    ret = 1;
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+	closedir(d);
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+    return ret;
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* find the main debuginfo package. We do this simply by
Mark Wielaard da3af5
+ * searching for a package with the right name. */
Mark Wielaard da3af5
+static Package findDebuginfoPackage(rpmSpec spec)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    Package pkg = NULL;
Mark Wielaard da3af5
+    if (lookupPackage(spec, "debuginfo", PART_SUBNAME, &pkg))
Mark Wielaard da3af5
+	return NULL;
Mark Wielaard da3af5
+    return pkg && pkg->fileList ? pkg : NULL;
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/* add a requires for package "to" into package "from". */
Mark Wielaard da3af5
+static void addPackageRequires(Package from, Package to)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    const char *name;
Mark Wielaard da3af5
+    char *evr, *isaprov;
Mark Wielaard da3af5
+    name = headerGetString(to->header, RPMTAG_NAME);
Mark Wielaard da3af5
+    evr = headerGetAsString(to->header, RPMTAG_EVR);
Mark Wielaard da3af5
+    isaprov = rpmExpand(name, "%{?_isa}", NULL);
Mark Wielaard da3af5
+    addReqProv(from, RPMTAG_REQUIRENAME, isaprov, evr, RPMSENSE_EQUAL, 0);
Mark Wielaard da3af5
+    free(isaprov);
Mark Wielaard da3af5
+    free(evr);
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
Mark Wielaard da3af5
 			int installSpecialDoc, int test)
Mark Wielaard da3af5
 {
Mark Wielaard da3af5
     Package pkg;
Mark Wielaard da3af5
     rpmRC rc = RPMRC_OK;
Mark Wielaard da3af5
+    char *buildroot;
Mark Wielaard da3af5
+    char *uniquearch = NULL;
Mark Wielaard da3af5
+    Package maindbg = NULL;		/* the (existing) main debuginfo package */
Mark Wielaard da3af5
+    Package deplink = NULL;		/* create requires to this package */
Mark Wielaard da3af5
     
Mark Wielaard da3af5
 #if HAVE_LIBDW
Mark Wielaard da3af5
     elf_version (EV_CURRENT);
Mark Wielaard da3af5
 #endif
Mark Wielaard da3af5
     check_fileList = newStringBuf();
Mark Wielaard da3af5
     genSourceRpmName(spec);
Mark Wielaard da3af5
+    buildroot = rpmGenPath(spec->rootDir, spec->buildRoot, NULL);
Mark Wielaard da3af5
     
Mark Wielaard da3af5
+    if (rpmExpandNumeric("%{?_debuginfo_subpackages}")) {
Mark Wielaard da3af5
+	maindbg = findDebuginfoPackage(spec);
Mark Wielaard da3af5
+	if (maindbg) {
Mark Wielaard da3af5
+	    /* move debuginfo package to back */
Mark Wielaard da3af5
+	    if (maindbg->next) {
Mark Wielaard da3af5
+		Package *pp;
Mark Wielaard da3af5
+		/* dequeue */
Mark Wielaard da3af5
+		for (pp = &spec->packages; *pp != maindbg; pp = &(*pp)->next)
Mark Wielaard da3af5
+		    ;
Mark Wielaard da3af5
+		*pp = maindbg->next;
Mark Wielaard da3af5
+		maindbg->next = 0;
Mark Wielaard da3af5
+		/* enqueue at tail */
Mark Wielaard da3af5
+		for (; *pp; pp = &(*pp)->next)
Mark Wielaard da3af5
+		    ;
Mark Wielaard da3af5
+		*pp = maindbg;
Mark Wielaard da3af5
+	    }
Mark Wielaard da3af5
+	    /* delete unsplit file list, we will re-add files back later */
Mark Wielaard da3af5
+	    maindbg->fileFile = argvFree(maindbg->fileFile);
Mark Wielaard da3af5
+	    maindbg->fileList = argvFree(maindbg->fileList);
Mark Wielaard da3af5
+	    if (rpmExpandNumeric("%{?_unique_debug_names}"))
Mark Wielaard da3af5
+		uniquearch = rpmExpand("-%{VERSION}-%{RELEASE}.%{_arch}", NULL);
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+
Mark Wielaard da3af5
     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
Mark Wielaard da3af5
 	char *nvr;
Mark Wielaard da3af5
 	const char *a;
Mark Wielaard da3af5
 	int header_color;
Mark Wielaard da3af5
 	int arch_color;
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+	if (pkg == maindbg) {
Mark Wielaard da3af5
+	    /* if there is just one debuginfo package, we put our extra stuff
Mark Wielaard da3af5
+	     * in it. Otherwise we put it in the main debug package */
Mark Wielaard da3af5
+	    Package extradbg = !maindbg->fileList && maindbg->next && !maindbg->next->next ?
Mark Wielaard da3af5
+		 maindbg->next : maindbg;
Mark Wielaard da3af5
+	    if (addDebugDwz(extradbg, buildroot))
Mark Wielaard da3af5
+		deplink = extradbg;
Mark Wielaard da3af5
+	    if (addDebugSrc(extradbg, buildroot))
Mark Wielaard da3af5
+		deplink = extradbg;
Mark Wielaard da3af5
+	    maindbg = NULL;	/* all normal packages processed */
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 	if (pkg->fileList == NULL)
Mark Wielaard da3af5
 	    continue;
Mark Wielaard da3af5
 
Mark Wielaard da3af5
@@ -2685,9 +2941,16 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
Mark Wielaard da3af5
 	nvr = headerGetAsString(pkg->header, RPMTAG_NVRA);
Mark Wielaard da3af5
 	rpmlog(RPMLOG_NOTICE, _("Processing files: %s\n"), nvr);
Mark Wielaard da3af5
 	free(nvr);
Mark Wielaard da3af5
-		   
Mark Wielaard da3af5
-	if ((rc = processPackageFiles(spec, pkgFlags, pkg, installSpecialDoc, test)) != RPMRC_OK ||
Mark Wielaard da3af5
-	    (rc = rpmfcGenerateDepends(spec, pkg)) != RPMRC_OK)
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+	if ((rc = processPackageFiles(spec, pkgFlags, pkg, installSpecialDoc, test)) != RPMRC_OK)
Mark Wielaard da3af5
+	    goto exit;
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+	if (maindbg)
Mark Wielaard da3af5
+	    filterDebuginfoPackage(spec, pkg, maindbg, buildroot, uniquearch);
Mark Wielaard da3af5
+	else if (deplink && pkg != deplink)
Mark Wielaard da3af5
+	    addPackageRequires(pkg, deplink);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+        if ((rc = rpmfcGenerateDepends(spec, pkg)) != RPMRC_OK)
Mark Wielaard da3af5
 	    goto exit;
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 	a = headerGetString(pkg->header, RPMTAG_ARCH);
Mark Wielaard da3af5
@@ -2722,6 +2985,8 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
Mark Wielaard da3af5
     }
Mark Wielaard da3af5
 exit:
Mark Wielaard da3af5
     check_fileList = freeStringBuf(check_fileList);
Mark Wielaard da3af5
+    _free(buildroot);
Mark Wielaard da3af5
+    _free(uniquearch);
Mark Wielaard da3af5
     
Mark Wielaard da3af5
     return rc;
Mark Wielaard da3af5
 }
Mark Wielaard da3af5
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
Mark Wielaard da3af5
index 6d25f4c..5715d25 100644
Mark Wielaard da3af5
--- a/build/parsePreamble.c
Mark Wielaard da3af5
+++ b/build/parsePreamble.c
Mark Wielaard da3af5
@@ -544,6 +544,13 @@ static void fillOutMainPackage(Header h)
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 /**
Mark Wielaard da3af5
  */
Mark Wielaard da3af5
+void copyInheritedTags(Header h, Header fromh)
Mark Wielaard da3af5
+{
Mark Wielaard da3af5
+    headerCopyTags(fromh, h, (rpmTagVal *)copyTagsDuringParse);
Mark Wielaard da3af5
+}
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/**
Mark Wielaard da3af5
+ */
Mark Wielaard da3af5
 static rpmRC readIcon(Header h, const char * file)
Mark Wielaard da3af5
 {
Mark Wielaard da3af5
     char *fn = NULL;
Mark Wielaard da3af5
@@ -1197,8 +1204,7 @@ int parsePreamble(rpmSpec spec, int initialPackage)
Mark Wielaard da3af5
     }
Mark Wielaard da3af5
 
Mark Wielaard da3af5
     if (pkg != spec->packages) {
Mark Wielaard da3af5
-	headerCopyTags(spec->packages->header, pkg->header,
Mark Wielaard da3af5
-			(rpmTagVal *)copyTagsDuringParse);
Mark Wielaard da3af5
+	copyInheritedTags(pkg->header, spec->packages->header);
Mark Wielaard da3af5
     }
Mark Wielaard da3af5
 
Mark Wielaard da3af5
     if (checkForRequired(pkg->header, NVR)) {
Mark Wielaard da3af5
diff --git a/build/parseSpec.c b/build/parseSpec.c
Mark Wielaard da3af5
index 2928e85..d0c42a4 100644
Mark Wielaard da3af5
--- a/build/parseSpec.c
Mark Wielaard da3af5
+++ b/build/parseSpec.c
Mark Wielaard da3af5
@@ -572,7 +572,7 @@ static void initSourceHeader(rpmSpec spec)
Mark Wielaard da3af5
 }
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 /* Add extra provides to package.  */
Mark Wielaard da3af5
-static void addPackageProvides(Package pkg)
Mark Wielaard da3af5
+void addPackageProvides(Package pkg)
Mark Wielaard da3af5
 {
Mark Wielaard da3af5
     const char *arch, *name;
Mark Wielaard da3af5
     char *evr, *isaprov;
Mark Wielaard da3af5
diff --git a/build/rpmbuild_internal.h b/build/rpmbuild_internal.h
Mark Wielaard da3af5
index 948dc31..46d9676 100644
Mark Wielaard da3af5
--- a/build/rpmbuild_internal.h
Mark Wielaard da3af5
+++ b/build/rpmbuild_internal.h
Mark Wielaard da3af5
@@ -442,6 +442,13 @@
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 /** \ingroup rpmbuild
Mark Wielaard da3af5
+ * Add self-provides to package.
Mark Wielaard da3af5
+ * @param pkg		package
Mark Wielaard da3af5
+ */
Mark Wielaard da3af5
+RPM_GNUC_INTERNAL
Mark Wielaard da3af5
+void addPackageProvides(Package pkg);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/** \ingroup rpmbuild
Mark Wielaard da3af5
  * Add rpmlib feature dependency.
Mark Wielaard da3af5
  * @param pkg		package
Mark Wielaard da3af5
  * @param feature	rpm feature name (i.e. "rpmlib(Foo)" for feature Foo)
Mark Wielaard da3af5
@@ -463,6 +470,16 @@ int rpmlibNeedsFeature(Package pkg, const char * feature, const char * featureEV
Mark Wielaard da3af5
 
Mark Wielaard da3af5
 RPM_GNUC_INTERNAL
Mark Wielaard da3af5
 rpmRC checkForEncoding(Header h, int addtag);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+/** \ingroup rpmbuild
Mark Wielaard da3af5
+ * Copy tags inherited by subpackages from the source header to the target header
Mark Wielaard da3af5
+ * @param h		target header
Mark Wielaard da3af5
+ * @param fromh		source header
Mark Wielaard da3af5
+ */
Mark Wielaard da3af5
+RPM_GNUC_INTERNAL
Mark Wielaard da3af5
+void copyInheritedTags(Header h, Header fromh);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 #ifdef __cplusplus
Mark Wielaard da3af5
 }
Mark Wielaard da3af5
 #endif
Mark Wielaard da3af5
diff --git a/macros.in b/macros.in
Mark Wielaard da3af5
index 007b8d4..cb65f4f 100644
Mark Wielaard da3af5
--- a/macros.in
Mark Wielaard da3af5
+++ b/macros.in
Mark Wielaard da3af5
@@ -549,6 +549,9 @@ package or when debugging this package.\
Mark Wielaard da3af5
 # Whether rpm should put debug source files into its own subpackage
Mark Wielaard da3af5
 #%_debugsource_packages	1
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+# Whether rpm should create extra debuginfo packages for each subpackage
Mark Wielaard da3af5
+#%_debuginfo_subpackages 1
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 #
Mark Wielaard da3af5
 # Use internal dependency generator rather than external helpers?
Mark Wielaard da3af5
 %_use_internal_dependency_generator	1
Mark Wielaard da3af5
Mark Wielaard da3af5
commit a517554e36666f58724620347a4b8224471d2225
Mark Wielaard da3af5
Author: Michael Schroeder <mls@suse.de>
Mark Wielaard da3af5
Date:   Wed Mar 29 14:55:10 2017 +0200
Mark Wielaard da3af5
Mark Wielaard da3af5
    Also add directories to split debuginfo packages
Mark Wielaard da3af5
    
Mark Wielaard da3af5
    This gets rid of the last difference between debuginfo subpackages
Mark Wielaard da3af5
    and normal debuginfo packages.
Mark Wielaard da3af5
Mark Wielaard da3af5
diff --git a/build/files.c b/build/files.c
Mark Wielaard da3af5
index e3fc8d6..5022069 100644
Mark Wielaard da3af5
--- a/build/files.c
Mark Wielaard da3af5
+++ b/build/files.c
Mark Wielaard da3af5
@@ -2745,8 +2745,9 @@ static void filterDebuginfoPackage(rpmSpec spec, Package pkg,
Mark Wielaard da3af5
 {
Mark Wielaard da3af5
     rpmfi fi;
Mark Wielaard da3af5
     ARGV_t files = NULL;
Mark Wielaard da3af5
-    Package dbg = NULL;
Mark Wielaard da3af5
-    char *path = NULL;
Mark Wielaard da3af5
+    ARGV_t dirs = NULL;
Mark Wielaard da3af5
+    int lastdiridx = -1, dirsadded;
Mark Wielaard da3af5
+    char *path = NULL, *p, *pmin;
Mark Wielaard da3af5
     size_t buildrootlen = strlen(buildroot);
Mark Wielaard da3af5
 
Mark Wielaard da3af5
     /* ignore noarch subpackages */
Mark Wielaard da3af5
@@ -2779,12 +2780,37 @@ static void filterDebuginfoPackage(rpmSpec spec, Package pkg,
Mark Wielaard da3af5
 		argvAdd(&files, "%defattr(-,root,root)");
Mark Wielaard da3af5
 		argvAddDir(&files, DEBUG_LIB_DIR);
Mark Wielaard da3af5
 	    }
Mark Wielaard da3af5
+
Mark Wielaard da3af5
 	    /* Add the files main debug-info file */
Mark Wielaard da3af5
 	    argvAdd(&files, path + buildrootlen);
Mark Wielaard da3af5
+
Mark Wielaard da3af5
+	    /* Add the dir(s) */
Mark Wielaard da3af5
+	    dirsadded = 0;
Mark Wielaard da3af5
+	    pmin = path + buildrootlen + strlen(DEBUG_LIB_DIR);
Mark Wielaard da3af5
+	    while ((p = strrchr(path + buildrootlen, '/')) != NULL && p > pmin) {
Mark Wielaard da3af5
+		*p = 0;
Mark Wielaard da3af5
+		if (lastdiridx >= 0 && !strcmp(dirs[lastdiridx], path + buildrootlen))
Mark Wielaard da3af5
+		    break;		/* already added this one */
Mark Wielaard da3af5
+		argvAdd(&dirs, path + buildrootlen);
Mark Wielaard da3af5
+		dirsadded++;
Mark Wielaard da3af5
+	    }
Mark Wielaard da3af5
+	    if (dirsadded)
Mark Wielaard da3af5
+		lastdiridx = argvCount(dirs) - dirsadded;	/* remember longest dir */
Mark Wielaard da3af5
 	}
Mark Wielaard da3af5
 	path = _free(path);
Mark Wielaard da3af5
     }
Mark Wielaard da3af5
 
Mark Wielaard da3af5
+    /* add collected directories to file list */
Mark Wielaard da3af5
+    if (dirs) {
Mark Wielaard da3af5
+	int i;
Mark Wielaard da3af5
+	argvSort(dirs, NULL);
Mark Wielaard da3af5
+	for (i = 0; dirs[i]; i++) {
Mark Wielaard da3af5
+	    if (!i || strcmp(dirs[i], dirs[i - 1]) != 0)
Mark Wielaard da3af5
+		argvAddDir(&files, dirs[i]);
Mark Wielaard da3af5
+	}
Mark Wielaard da3af5
+	dirs = argvFree(dirs);
Mark Wielaard da3af5
+    }
Mark Wielaard da3af5
+
Mark Wielaard da3af5
     if (files) {
Mark Wielaard da3af5
 	/* we have collected some files. Now put them in a debuginfo
Mark Wielaard da3af5
          * package. If this is not the main package, clone the main