4

I am packaging an internal product which has dependencies on dozens of second level libraries. Ideally, these libraries would be created and managed as independent packages themselves, but our legacy build system makes this difficult.

Instead, we have a deployment mechanism (script) which picks the required dependencies and recursively installs them into the file system as required. So... we are building RPMs by making use of this deployment script (this is our first mistake, but cannot easily be resolved). The RPM spec file tells the script to install directly into $RPM_BUILD_ROOT, then we massage and package the files as necessary.

This brings me around to my question:

I have dozens of dependencies, each of which changes semi-frequently. Tracking the library version numbers frequently requires tweaking the .spec file in a half dozen places. What I would like to do is write a macro which could be called as:

%dependency -B libstrutil -M 1 -m 5 -p 0

which would expand to:

%define libstrutil     libstrutil.so
%define libstrutil_m   libstrutil.so.1
%define libstrutil_mm  libstrutil.so.1.5
%define libstrutil_mmp libstrutil.so.1.5.0

Where the '-B' option is the library base name, '-M' option is the major version number,'-m' is the minor version number, and '-p' is the patch level. Then, these macros could be used throughout the spec file where specific versions might be needed (especially in the %files section).

I've combed through the macros which ship with RHEL 6 (especially /usr/lib/rpm/macros), but have found very few examples of macros with arguments. The ONE I have located is %GNUconfigure, and it's not entirely simple given that it uses a lot of conditional logic in its definition. More relevant to the immediate question, %GNUconfigure does not itself define other macros.

I suspect that what I'm trying to do is accomplished with %{expand:...}, but I'm not even close to getting this syntax to work.

Jeff W
  • 414
  • 5
  • 16

1 Answers1

1

I'm not sure you need to expand the lines yourself. rpm might just handle that for you if you return the %define lines.

If that's true then this might work:

%dependency(B:M:m:p:) \
    %%define %{-B*} %{-B*}.so \
    %%define %{-B*}_m %{-B*}.so.%{-M*} \
    %%define %{-B*}_mm %{-B*}.so.%{-M*}.%{-m*} \
    %%define %{-B*}_mmp %{-B*}.so.%{-M*}.%{-m*}.%{-p*}

If not then you might need:

%dependency(B:M:m:p:) \
    %{expand:%%define %{-B*} %{-B*}.so} \
    %{expand:%%define %{-B*}_m %{-B*}.so.%{-M*}} \
    %{expand:%%define %{-B*}_mm %{-B*}.so.%{-M*}.%{-m*}} \
    %{expand:%%define %{-B*}_mmp %{-B*}.so.%{-M*}.%{-m*}.%{-p*}}

Either one of those might need to use %global instead of %define. (I'm not entirely clear on when those differ unfortunately.)

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • macros are scoped with automatic garbage collection. so %global adds at level 0, while %define adds at the current recursion nesting level. – Jeff Johnson Mar 07 '15 at 21:37
  • @JeffJohnson So `%{expand}` there is recursion level n+1 and would want/need `%global` then? And recursion is implicit whenever a value includes another macro? Or only at certain places? (This is the bit that I've never fully taken the time to understand.) – Etan Reisner Mar 09 '15 at 15:00
  • %global never hurts and is likeliest what everyone is expecting. Every recursion of a newly encountered macro happens at level+1, which is used for garbage collection on any %defines encountered. %global will never be garbage collected. . %expand is really a marker into the expansion buffer to continue at the beginning, not the end, of its expanded argument. the expansion levels will be the same when restarted – Jeff Johnson Mar 10 '15 at 22:25