From d8e15fab3ac1f1bd55f18773ce6d6ac846336a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Ondruch?= Date: Tue, 24 Oct 2023 16:42:12 +0200 Subject: [PATCH] Add %__local_file_attrs macro This can declare file attributes which details can be defined in the spec file. This allows enabling file attributes and their dependency generators even if they are only shipped in the package itself and are not yet installed. The names need to be separated by colons (:). Co-authored-by: Florian Festi Resolves: #782 --- build/rpmfc.c | 40 +++++++++++++++++++++------- docs/manual/dependency_generators.md | 10 +++++++ tests/rpmbuild.at | 19 +++++++++++++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/build/rpmfc.c b/build/rpmfc.c index 3b95bf2cb5..097c0e3773 100644 --- a/build/rpmfc.c +++ b/build/rpmfc.c @@ -1185,22 +1185,42 @@ static int initAttrs(rpmfc fc) { ARGV_t files = NULL; char * attrPath = rpmExpand("%{_fileattrsdir}/*.attr", NULL); - int nattrs = 0; + int nfiles = 0; + int nlocals = 0; + int attrcnt = 0; + int j; /* Discover known attributes from pathnames + initialize them */ if (rpmGlob(attrPath, NULL, &files) == 0) { - nattrs = argvCount(files); - fc->atypes = xcalloc(nattrs + 1, sizeof(*fc->atypes)); - for (int i = 0; i < nattrs; i++) { - char *bn = basename(files[i]); - bn[strlen(bn)-strlen(".attr")] = '\0'; - fc->atypes[i] = rpmfcAttrNew(bn); + nfiles = argvCount(files); + } + char * local_attr_names = rpmExpand("%{?__local_file_attrs}", NULL); + ARGV_t local_attrs = argvSplitString(local_attr_names, ":", ARGV_SKIPEMPTY); + nlocals = argvCount(local_attrs); + fc->atypes = xcalloc(nfiles + nlocals + 1, sizeof(*fc->atypes)); + + for (int i = 0; i < nfiles; i++) { + char *bn = basename(files[i]); + bn[strlen(bn)-strlen(".attr")] = '\0'; + // skip file attrs found in __local_file_attrs for now + for (j=0; (j < nlocals) && strcmp(bn, local_attrs[j]); j++); + if (j < nlocals) { + free(bn); + continue; } - fc->atypes[nattrs] = NULL; - argvFree(files); + fc->atypes[attrcnt++] = rpmfcAttrNew(bn); } + + for (int i = 0; i < nlocals; i++) { + fc->atypes[attrcnt++] = rpmfcAttrNew(local_attrs[i]); + } + fc->atypes[attrcnt] = NULL; + + argvFree(files); + free(local_attr_names); + argvFree(local_attrs); free(attrPath); - return nattrs; + return attrcnt; } static uint32_t getElfColor(const char *fn) diff --git a/docs/manual/dependency_generators.md b/docs/manual/dependency_generators.md index 512bdf344e..6f75d29b99 100644 --- a/docs/manual/dependency_generators.md +++ b/docs/manual/dependency_generators.md @@ -132,6 +132,16 @@ Enabling the multifile mode is done by setting %__foo_protocol multifile ``` +## Using File Attributes in their own Package + +Normally file attributes and their dependency generators are shipped in separate packages that need to be installed before the package making use of them can be build. + +Since rpm 4.20 the names of file attributes from the package itself can be put into the *__local_file_attrs* macro separated by colons (:). The macros that normally go into the *\*.attr* files still need to be defined (the dependency generators typically pointing to some Source files or some files in the install root). + +This mechanism can be used for both file attributes the package ships to be installed but also for file attributes that are used during the own building process only. + +For the former packagers need to be aware that a previus version of the package might be installed on the system the package is build on. Thus the Spec file must set all macros used in the past and undefine the ones not longer being used. + ## Tweaking Dependency Generators Technically, all aspects of file attributes and the generator helpers they use can be overridden from spec by (re)defining the related macros, but packagers should generally avoid this, as the attributes and their names are subject to change, depending on rpm version and which packages are present during build. Unwanted dependencies can be filtered with a separate set of macros which are intended primarily for use in spec files: diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index f492a030e2..8075f6397e 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -995,6 +995,25 @@ runroot rpm -qp --requires /build/RPMS/noarch/shebang-0.1-1.noarch.rpm|grep -v ^ []) RPMTEST_CLEANUP +AT_SETUP([Local dependency generator]) +AT_KEYWORDS([build]) +RPMTEST_CHECK([ +RPMDB_INIT + +runroot rpmbuild -bb --quiet \ + --define '__local_file_attrs my_test_attr' \ + --define '__my_test_attr_provides() foo(%{basename:%{1}})' \ + --define '__my_test_attr_path .*' \ + /data/SPECS/shebang.spec +runroot rpm -qp --provides /build/RPMS/noarch/shebang-0.1-1.noarch.rpm|grep -v ^rpmlib +], +[0], +[foo(shebang) +shebang = 0.1-1 +], +[]) +RPMTEST_CLEANUP + AT_SETUP([elf dependencies]) AT_KEYWORDS([build]) RPMDB_INIT