Skip to content

Commit

Permalink
Add %_local_file_attrs macro
Browse files Browse the repository at this point in the history
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 <[email protected]>
Resolves: #782
  • Loading branch information
voxik and ffesti committed Feb 14, 2024
1 parent 34cb5ee commit 95b89b6
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 11 deletions.
42 changes: 31 additions & 11 deletions build/rpmfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,22 +1184,42 @@ static rpmRC rpmfcApplyInternal(rpmfc fc)
static int initAttrs(rpmfc fc)
{
ARGV_t files = NULL;
int nfiles = 0;
char * attrPath = rpmExpand("%{_fileattrsdir}/*.attr", NULL);
int nattrs = 0;
ARGV_t all_attrs = argvNew();

/* Discover known attributes from pathnames + initialize them */
/* Discover known attributes from pathnames */
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);
}
fc->atypes[nattrs] = NULL;
argvFree(files);
nfiles = argvCount(files);
}
for (int i = 0; i < nfiles; i++) {
char *bn = basename(files[i]);
bn[strlen(bn)-strlen(".attr")] = '\0';
argvAddUniq(&all_attrs, bn);
}

/* Get file attributes from _local_file_attrs macro */
char * local_attr_names = rpmExpand("%{?_local_file_attrs}", NULL);
ARGV_t local_attrs = argvSplitString(local_attr_names, ":", ARGV_SKIPEMPTY);
int nlocals = argvCount(local_attrs);
for (int i = 0; i < nlocals; i++) {
argvAddUniq(&all_attrs, local_attrs[i]);
}

/* Initialize attr objects */
int nattrs = argvCount(all_attrs);
fc->atypes = xcalloc(nattrs + 1, sizeof(*fc->atypes));

for (int i = 0; i < nattrs; i++) {
fc->atypes[i] = rpmfcAttrNew(all_attrs[i]);
}
fc->atypes[nattrs] = NULL;

free(attrPath);
argvFree(files);
free(local_attr_names);
argvFree(local_attrs);
argvFree(all_attrs);
return nattrs;
}

Expand Down
10 changes: 10 additions & 0 deletions docs/manual/dependency_generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
52 changes: 52 additions & 0 deletions tests/rpmbuild.at
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,58 @@ 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_CHECK([
RPMDB_INIT

runroot rpmbuild -bb --quiet \
--define '_local_file_attrs script' \
--define '__script_provides() foobar(%{basename:%{1}})' \
/data/SPECS/shebang.spec
runroot rpm -qp --provides /build/RPMS/noarch/shebang-0.1-1.noarch.rpm|grep -v ^rpmlib
],
[0],
[foobar(shebang)
shebang = 0.1-1
],
[])

RPMTEST_CHECK([
RPMDB_INIT

runroot rpmbuild -bb --quiet \
--define '_local_file_attrs my_test_attr:script' \
--define '__my_test_attr_provides() foo(%{basename:%{1}})' \
--define '__my_test_attr_path .*' \
--define '__script_provides() foobar(%{basename:%{1}})' \
/data/SPECS/shebang.spec
runroot rpm -qp --provides /build/RPMS/noarch/shebang-0.1-1.noarch.rpm|grep -v ^rpmlib
],
[0],
[foo(shebang)
foobar(shebang)
shebang = 0.1-1
],
[])
RPMTEST_CLEANUP

AT_SETUP([elf dependencies])
AT_KEYWORDS([build])
RPMDB_INIT
Expand Down

0 comments on commit 95b89b6

Please sign in to comment.