Może to zabrzmi patetycznie, ale ta sekcja jest sercem pliku spec. A przynajmniej ja tak myślę. Tutaj określa się, jakie pliki w końcu wylądują w pakiecie, jakie będą miały uprawnienia, i inne takie.

Pakiet RPM będzie zawierał tylko te pliki, które wymieni się w tej sekcji. Zwykle trzeba tutaj tylko wylistować pliki/katalogi znajdujące się po fazie %install w ,,fake root''. Teoretycznie RPM mógłby to zrobić za użytkownika i można by uznać tę konieczność za bardzo denerwującą. Ale mimo wszystko lepiej jest jednak, gdy autor pakietu świadomie poustawia te rzeczy. Często będzie tu szło o szczegóły, ale będą to szczegóły bardzo ważne.

Załóżmy, że mamy w ,,fake root'' po instalacji tylko dwa pliki:
$RPM_BUILD_ROOT/usr/bin/program
$RPM_BUILD_ROOT/usr/share/man/man1/program.1
czyli jakiś program i jego stronę manuala. Wiem, nieczęsta sytuacja, ale nie chcę od razu przegiąć z pierwszym przykładem :) Prosta sekcja %files dla tego przykładu mogłaby wyglądać tak:
%files
/usr/bin/program
/usr/share/man/man1/program.1.gz
Proste, prawda? Jeśli ktoś jednak czyta z uwagą, ten zauważył pojawienie się ,,znikąd'' rozszerzenia .gz przy pliku manuala. To konieczność, bowiem rpm w magiczny sposób kompresuje manuale i dokumentację info w standardowych dla tych plików ,,lokacjach'' (czyli /usr/share/info, /usr/X11R6/man itp.). Nawet jeśli ,,make install'' zainstalowało dokumentację w formie nieskompresowanej, to nie gra roli - rpmbuild wykona jeszcze przed interpretowaniem sekcji %files jeden przebieg po całym ,,fake root'', kompresując manuale. Fajne :) Dlatego w %files zakładam, że manual jest zgzipowany. Muszę tak robić. Ale można pójść krok dalej - makro %configure używało zamiast ,,jawnych'' ścieżek takich jak /usr czy /usr/lib specjalnych makr. I tutaj można zrobić tak samo. Powinno się w każdym razie.
W zmodyfikowanej postaci ta sama sekcja może wyglądać tak:
%files
%{_bindir}/program
%{_mandir}/man1/program.1.gz
(Notka na boku: jeśli ktoś do tej pory nie domyślił się, dlaczego podczas budowania pakietów RPM tak silny nacisk kładzie się na unikanie podawania jawnych ścieżek, to tutaj łopatologiczne wyjaśnienie na przykładzie z historii linuksa:
Kiedyś standardowo kładło się strony manuala do /usr/man/man*/. Ale potem nastąpiły zmiany w standardzie lokowania plików i manuale zaczęto umieszczać w /usr/share/man/man*/. Podobne zmiany mogą zachodzić jeszcze w przyszłości - albo w ramach ogólnolinuksowych standardów, albo w ramach pojedynczej dystrybucji, albo w ramach normalnego dostosowywania pakietów do konkretnego, pojedynczego systemu. Ale do czego dążę? To proste: Wyobraźmy sobie plik .spec, w którym wszędzie są odwołania ,,proste'', w stylu /usr/man. Zarówno przy ./configure, jak i w %files. Jeśli teraz zajdzie potrzeba skompilowania pakietu z przeniesieniem manuali do /usr/local/man (nie, nie pytaj ,,po co'' - bo to tylko abstrakcyjny przykład), no więc jeśli trzeba będzie wprowadzić takie zmiany, to taki plik .spec trzeba będzie zmienić, w dwóch miejscach poprawić. I tak trzeba będzie postąpić z każdym jednym rekompilowanym pakietem. Niezbyt to miłe. A co się stanie, jeśli będzie się używać makra %{_mandir}? Proste - wystarczy zmienić to makro raz, globalnie, w ~/.rpmmacros. Pliki .spec nie zmienią się, ale wynikowe, zrekompilowane pakiety będą umieszczały swoje manuale w /usr/local. Co jest prostsze - zmienić jedną globalną definicję, czy też zmieniać dziesiątki wpisów w plikach .spec? Zalet takiego podejścia jest więcej - np. większa zgodność między systemami, bo wystarczy że na danym systemie te kluczowe zmienne będą zdefiniowane prawidłowo. Dodatkowo te makra można zmieniać w linii poleceń, przy wywołaniu rpmbuild - wystarczy użyć opcji --define aby ,,w locie'' zmienić ustawienie jakiegoś katalogu, np. ,,--define="_prefix /opt"'' Proste, bo nie zmienia ani globalnych ustawień systemu, ani pliku .spec, a działa :)
A po ludzku: używając takich różnych owijek w postaci różnych zmiennych czy makrodefinicji jest później łatwiej nad tym zapanować, kiedy trzeba będzie coś zmienić. Mam nadzieję, że to jasne?

Dobra, teraz dodajmy jeszcze parę plików. Dodajmy do naszego przykładu jakąś drugą binarkę, jej manual, jakąś bibliotekę z której to wszystko korzysta i parę nowych stron manuala. Czyli będziemy bliżej tego, co normalnie spotka się w życiu. O, mam pomysł - weźmy naprawdę przykład z życia - fragment plików z paczki gpm:
%files
/etc/gpm-root.conf
/usr/bin/disable-paste
/usr/bin/gpm-root
/usr/bin/mev
/usr/include/gpm.h
/usr/lib/libgpm.so
/usr/lib/libgpm.so.1
/usr/lib/libgpm.so.1.19.0
/usr/sbin/gpm
/usr/share/info/gpm.info.gz
/usr/share/man/man1/gpm-root.1.gz
/usr/share/man/man1/mev.1.gz
/usr/share/man/man1/mouse-test.1.gz
/usr/share/man/man7/gpm-types.7.gz
/usr/share/man/man8/gpm.8.gz
no, już tego więcej. Świetnie. Jak widać, mamy tu wszystkiego po trochę - plik konfiguracyjny w /etc, trzy programy w /usr/bin, jeden plik nagłówkowy, bibliotekę, jeden program w /usr/sbin, parę stron manuala i jeden plik info. Strony manuala i plik info muszą mieć w tej sekcji rozszerzenie .gz - bo jak mówiłem, zostały automagicznie skompresowane. Teraz jeszcze przeróbmy to na formę używającą makr zamiast sztywnych katalogów:
%files
%{_sysconfdir}/gpm-root.conf
%{_bindir}/disable-paste
%{_bindir}/gpm-root
%{_bindir}/mev
%{_includedir}/gpm.h
%{_libdir}/libgpm.so
%{_libdir}/libgpm.so.1
%{_libdir}/libgpm.so.1.19.0
%{_sbindir}/gpm
%{_infodir}/gpm.info.gz
%{_mandir}/man1/gpm-root.1.gz
%{_mandir}/man1/mev.1.gz
%{_mandir}/man1/mouse-test.1.gz
%{_mandir}/man7/gpm-types.7.gz
%{_mandir}/man8/gpm.8.gz
Nieźle. I teraz mogę pokazać następny krok - redukowanie wpisów. To będzie, mam nadzieję, proste do zrozumienia:
%files
%{_sysconfdir}/gpm-root.conf
%{_bindir}/*
%{_includedir}/gpm.h
%{_libdir}/*
%{_sbindir}/gpm
%{_infodir}/gpm.info.gz
%{_mandir}/man1/*
%{_mandir}/man7/gpm-types.7.gz
%{_mandir}/man8/gpm.8.gz
W sekcji %files mogę się posługiwać normalnym, shellowym dopasowywaniem, więc jeśli napiszę ,,katalog/*'' to wzorzec ten zostanie zinterpretowany jako ,,wszystkie pliki w tym katalogu''. Bardzo fajnie. No to jeszcze trochę to poprawmy:
%files
%{_sysconfdir}/gpm-root.conf
%{_bindir}/*
%{_includedir}/*
%{_libdir}/*
%{_sbindir}/*
%{_infodir}/*.gz
%{_mandir}/man*/*.gz
Jeszcze bardziej to uprościłem, zwłaszcza część z manualami jest bardzo ładna.
Tutaj uwaga: w ten sposób sam plik .spec stał się bardziej uniwersalny - jeśli w następnej wersji gpm dojdzie np. jakiś dodatkowy plik nagłówkowy w /usr/include, to ta sekcja %files nie będzie potrzebowała modyfikacji i zadziała sama z siebie. Muszę szybko powiedzieć, że nie popełnia się przez to żadnego błędu - bo możnaby co prawda pomyśleć, że robiąc taki przesycony ,,wildcards'' plik .spec może dojść do tego, że jakieś ważne zmiany przejdą niezauważone, że coś będzie nie tak z pakietem jeśli w którejś wersji coś się bardzo pozmienia - ale bez obaw. Jeśli w wyniku ewolucji gpm zniknie np. plik /etc/gpm-root.conf, to rpmbuild powie o tym (powie, że ten plik nie istnieje i odmówi zbudowania paczki). Podobnie będzie jeśli dojdzie coś nowego, co nie jest uwzględnione obecnie w sekcji %files - rpmbuild powie wtedy, że znalazł jakieś przeoczone pliki. Tak więc zachowując zdrowy rozsądek można napisać w miarę uniwersalne pliki .spec, których będzie można używać normalnie zmieniając tylko wersję źródeł, i to bez narażania się na powstanie ,,zdeformowanych'' pakietów.

OK, więc mamy już w miarę sensowną sekcję %files. Porozmawiajmy teraz o uprawnieniach. RPM ma jakieś tam uprawnienia domyślne, które będą nakładane na wszystkie pliki z sekcji %files. Ale ja nigdy nie pamiętam jakie one są, zresztą mogą znienacka się nam zmienić przy następnej wersji RPM, więc lepiej jest te domyślne uprawnienia ustawić samemu. Robi się to makrem %defattr(perm_file,user,group,perm_dir). Dziwna notacja, ale już wyjaśniam: makro to wywołuje się z opcjami w nawiasie, trochę jak wywołuje się funkcje z parametrami. ,,user'' i ,,group'' powinny być jasne - to będzie właściciel i grupa nadawane plikom. Ale o co chodzi z ,,perm_file'' i ,,perm_dir''? Pierwsza z tych opcji oznacza uprawnienia jakie należy nałożyć na zwykłe pliki, druga uprawnienia jakie należy nałożyć na katalogi. Tak, o tym trzeba decydować osobno, choćby z tego powodu, że katalogi zawsze muszą mieć bit wykonywalności by użytkownik mógł do nich wejść, za to zwykłe pliki zwykle wykonywalne nie muszą być. Przykładowy (chyba najczęstszy) zapis będzie wyglądał tak:
%defattr(0644,root,root,0755)
ustawi to sensowne domyślne prawa - root może wszystko, inni mogą sobie co najwyżej popatrzeć, ale nie wykonywać ani zapisywać. Wyjątkiem są katalogi, które mają zawsze ustawiony bit wykonywalności - po to, by każdy mógł do nich zajrzeć.
Mały bonus: mogę nie podać praw dla katalogów, wtedy zostaną użyte prawa dla plików. Zamiast praw czy też właściciela/grupy mogę też po prostu wpisać ,,-'' (minus), wtedy rpm pozostawi takie uprawnienia, jakie ustawił plikom proces instalujący je w fake root. Ale to akurat niezbyt szczęśliwy pomysł, tak pozwalać jakiemuś przygodnemu ,,make install'' mieszać nam w uprawnieniach które przecież potem mogą nam namieszać w całym systemie. Lepiej trzymać rękę na pulsie i nie dać się skusić Mrocznemu Minusowi.
No dobra, tak naprawdę to RPM użyje wtedy swoich domyślnych (fabrycznych) ustawień %defattr, ale to się do tego samego sprowadza.

Te ustawienia domyślne są bardzo fajne i sprawdzają się w 80% przypadków - z jednym wyjątkiem. Gdy idzie o pliki wykonywalne. Bo na tych ,,defaultach'' wszystkie pliki by się stały niewykonywalne - 0644 w końcu swoje robi. A my w naszym przykładzie przecież mieliśmy binarki... i co teraz? Zmienić %defattr? Ale to bez sensu, bo jeśli zacznę nadawać bit wykonywalny wszystkim plikom, to skończę np. z ,,wykonywalnymi'' plikami manuala itp. Mógłbym co prawda skusić się i użyć minusa jako uprawnień, wtedy rpm by wziął to, co dostał od ,,make install'' - ale ja tak nie chcę, bo nie wiem czy ,,make install'' nie ustawił np. suida na jakiejś binarce albo nie zrobił czegoś jeszcze gorszego... Nie, to trzeba zrobić inaczej. Trzeba zmienić uprawnienia pojedynczym plikom z listy, bez zmieniania atrybutów. I temu (a także innym rzeczom) służy makro %attr(perm,owner,group). Wystarczy, jeśli zaznaczę pliki w %{_bindir} i %{_sbindir} nieco innymi flagami...
%files
%defattr(0644,root,root,0755)
%{_sysconfdir}/gpm-root.conf
%attr(0755,-,bin) %{_bindir}/*
%attr(0755,-,bin) %{_includedir}/*
%{_libdir}/*
%{_sbindir}/*
%{_infodir}/*.gz
%{_mandir}/man*/*.gz
Co zmieniłem? Dodałem linię %defattr (najlepiej wstawić ją zaraz po %files), no i doszły te dwa wywołania %attr. Jak widać, używa się ich w linii z plikami, które mają być zmienione. Po prostu wpisuje się %attr() przed ścieżką do pliku. Tutaj zmieniłem prawa binarkom na 0755, przy okazji zmieniłem grupę na ,,bin''. Ot, tak sobie :)
Tutaj, w wywołaniu %attr bezpiecznym już jest użycie Minusa, bo ustawienia będą dziedziczone z naszych ustawień %defattr - a więc to my wybieramy. Użyłem minusa, więc ,,owner'' zostanie odziedziczony z poprzednich ustawień. Czyli tutaj będzie to ,,root''.

Zaczyna to wyglądać coraz bardziej złożenie, ale mam nadzieję że nadal jest to zrozumiałe.

A teraz jeszcze sprawa plików konfiguracyjnych. Z plikami konfiguracyjnymi jest tak, że jeśli je sobie ręcznie zmodyfikujemy, to zwykle chcemy by te zmiany zostały zachowane ,,dla potomnych''. Trzeba rpm-owi powiedzieć, który plik jest dla nas tak ważny. Robi się to makrem %config:
%files
%defattr(0644,root,root,0755)
%config %{_sysconfdir}/gpm-root.conf
%attr(0755,-,bin) %{_bindir}/*
%attr(0755,-,bin) %{_includedir}/*
%{_libdir}/*
%{_sbindir}/*
%{_infodir}/*.gz
%{_mandir}/man*/*.gz
Jak widać, makra %config używa się podobnie jak %attr - czyli wpisuje przed ścieżką do pliku. To taki system :) Jeśli trzeba by połączyć więcej makr na jednym pliku, to się je po prostu dopisuje. Aby np. zmienić od razu uprawnienia tego pliku, trzeba by wpisać:
%config %attr(0600,root,root) %{_sysconfdir}/gpm-root.conf
po ,,załapaniu'' podstaw okazuje się to być całkiem prostym, prawda? Ot, budowanie z klocków. Kinderspiel, jak mawiają Francuzi ;)

Dobrze, ale nie powiedziałem jeszcze co daje to makro %config. Działanie jest w sumie proste: plik tak oznaczony nie będzie w razie czego usuwany przy odinstalowywaniu pakietu - i gdy przyjdzie nam jednak na myśl na nowo zainstalować jakiś usunięty onegdaj pakiet, to będziemy mieć stary, ręcznie rzeźbiony konfig. Wygodne i proste. Makro %config ma też swoje opcje, podawane w nawiasie, nieco podobnie jak w przypadku %attr - opcje te to ,,noreplace'' i ,,missingok''.
%config(noreplace) %{_sysconfdir}/gpm-root.conf
spowoduje, że ten plik nigdy nie zostanie automatycznie nadpisany przy upgrade-owaniu pakietu. Pozostanie niezmieniony, zamiast tego ten nowy plik, który powinien wylądować normalnie na jego miejscu, zostanie zapisany obok, z rozszerzeniem .rpmnew. Tej opcji używa się bardzo często, bo rpm nie ingeruje wtedy automatycznie w pliki konfiguracji. Zamiast tego kładzie swoje propozycje obok, z rozszerzeniem .rpmnew, a administrator będzie mógł przejrzeć je i zadecydować ,,co dalej?''.
%config(missingok) %{_sysconfdir}/gpm-root.conf
Ta opcja z kolei wpływa na sposób w jaki działa weryfikowanie poprawności pakietów (rpm -V). Pliki oznaczone tą flagą można spokojnie usunąć, a rpm nie uzna tego potem za ,,uszkodzenia pakietu''. Inaczej: tą flagą oznacza się pliki konfiguracyjne, które wolno usunąć i nie wpłynęłoby to w negatywny sposób na pracę programu. Przykładu zastosowania nie podam, to dla mnie zbyt abstrakcyjne ;)

Oprócz makr %defattr, %attr oraz %config w sekcji %flags może wystąpić także kilka innych konstrukcji. Jedną z nich jest makro %dir, którego używa się podobnie jak makra %config (tyle że nie ma żadnych opcji). Tutaj znowu trzeba wyjaśnić kilka spraw - jeśli w sekcji %files podam np. po prostu
%files
/usr/bin
to w skład pakietu wejdą wszystkie pliki zawarte w /usr/bin oraz sam katalog /usr/bin. A makro %dir oznacza ,,dołącz do pakietu tylko katalog, nie włączaj automatycznie jego zawartości''.

Ale żeby nie było w ogóle żadnych niejasności: Załóżmy, że mamy w $RPM_BUILD_ROOT katalog /usr/bin, i w tym katalogu różne pliki. Teraz mamy trzy sposoby na oznaczenie tego w sekcji %files:

1. Do pakietu będzie należał katalog /usr/bin wraz zawartością.
%files
/usr/bin
2. Do pakietu będzie należała tylko zawartość /usr/bin, ale bez samego katalogu. Na czym polega różnica? Jeśli katalog by należał do pakietu, jak ma to miejsce w pierwszym punkcie, to rpm przy odinstalowywaniu pakietu będzie próbował usunąć sam katalog (o ile będzie pusty).
%files
/usr/bin/*
3. Do pakietu będzie należał tylko katalog /usr/bin, bez zawartości.
%files
%dir /usr/bin
Teoria teorią, ale kiedy stosuje się taki, a nie inny sposób zapisu? Pomyślmy... Jeśli instaluje się jakiś program który umieszcza swoje binarki w /usr/bin, to zwykle załącza się tylko pliki, bez katalogu (bo /usr/bin ma pozostać, i pozostanie, na swoim miejscu nawet po odinstalowaniu programu).

Jeśli jednak instaluje się program który tworzy sobie jakiś katalog z własnymi danymi w /usr/share/foo, to zwykle po usunięciu takiego pakietu oczekuje się, że /usr/share/foo zniknie z dysku - bo używał go tylko jeden program, który właśnie usunęliśmy. I w takim wypadku załącza się do pakietu zarówno zawartość /usr/share/foo jak też sam katalog /usr/share/foo. Gdyby nie załączyć tego katalogu, to po usunięciu pakietu na dysku by pozostał pusty katalog /usr/share/foo - zawartość by wyparowała, ale katalog pozostał. A to by było brzydkie, prawda?

A trzeci sposób, czyli załączenie samego katalogu można stosować np. w przypadku pakietu zawierającego szkielet katalogów na dysku. Niektóre dystrybucje mają takie pakiety, które zawierają tylko siatkę katalogów /usr, /usr/bin, /usr/share/man/man5 itp. I tutaj zwykle użyje się tego makra. Albo w sytuacjach, gdy sekcja %files wymienia każdy plik pojedynczo, wtedy też makro %dir znajdzie zastosowanie. Ale to bardzo rzadkie sytuacje...

Następnym makrem jest makro %doc. To makro jest nieco dziwne, bo typowy przykład użycia tego makra to wpis w rodzaju:
%files
%doc README LICENSE ChangeLog
I działanie jest nieco odmienne niż by można oczekiwać - makro to pobierze pliki README, LICENSE, ChangeLog z katalogu z rozpakowanymi źródłami, a nie z $RPM_BUILD_ROOT, następnie umieści te pliki w fake root w podkatalogu %{_docdir}/%{name}-%{version}, i pooznacza je jako ,,pliki dokumentacji''. Czyli po prostu weźmie kilka luźnych plików z katalogu ze źródłami, założy im w razie czego katalog /usr/share/doc/nazwa-wersja, i skopiuje je tam. To taki sposób na dodanie do pakietu dodatkowej dokumentacji z pakietu źródłowego, dokumentacji która normalnie by nie została zainstalowana (bo ,,make install'' jej nie kopiowało).

Jest jeszcze jeden sposób użycia tego makra, można go jednak faktycznie użyć w odniesieniu do plików zainstalowanych w $RPM_BUILD_ROOT, wtedy zostaną one oflagowane jako ,,pliki dokumentacji''. Użycie przypomina wtedy nieco korzystanie z makra %config. Zastanawiające jest w jaki sposób rpmbuild rozpoznaje, czy makro odwołuje się do pliku z $RPM_BUILD_ROOT czy też jest rozkazem przekopiowania pliku z katalogu ze źródłami. Nie byłem w stanie nigdzie tego wyszperać, a w źródłach rpm-a nie chce mi się już grzebać, ale przypuszczam że rozpoznawane jest to na podstawie wyglądu ścieżki - jeśli ścieżka zaczyna się od ukośnika, to oznacza plik w $RPM_BUILD_ROOT. Jeśli jednak podawana jest sama nazwa pliku, bez początkowego ukośnika (czyli tzw. ścieżka względna), to chodzi o plik z katalogu ze źródłami.

W komplecie do makra %dir istnieje jeszcze makro %docdir. Oznacza się nim katalog, a wtedy cała jego zawartość zostanie oflagowana jako ,,pliki z rodzaju dokumentacji''. Ważna uwaga - makro to nie załącza plików do pakietu, to znaczy że trzeba najpierw w jakiś sposób ,,normalnie'' włączyć katalog w listę %files, a potem dodatkowo, w osobnej linii, oznaczyć ten katalog za pomocą %docdir.

Ale ja tutaj tak gadam i gadam o dokumentacji, ale nie powiedziałem najważniejszego - o co w ogóle chodzi z tym oznaczaniem dokumentacji. Cóż, cel jest tylko jeden - przy instalacji pakietów rpm można za pomocą specjalnego przełącznika (lub ustawienia w ~/.rpmrc) pomijać instalowanie dokumentacji. To znaczy, że pakiet się zainstaluje ale pliki oznaczone jako ,,dokumentacja'' nie zostaną zainstalowane. Przydatne jest to np. przy instalowaniu pakietów na małym serwerze, gdzie cenny będzie każdy megabajt dysku. Przydaje się to też użytkownikom - bowiem polecenie ,,rpm -qd nazwapakietu wyświetli listę dokumentacji w danym pakiecie - i użytkownik od razu będzie wiedział, jakie pliki można przeczytać.

RPM oznacza niektóre pliki automatycznie jako dokumentację. Będą to pliki lądujące w różnych %{_mandir}, %{_infodir}, %{_docdir}. Czyli tylko sporadycznie trzeba będzie samemu używać flag %doc/%docdir.

Powoli zbliżamy się do końca opisywania sekcji %files, zostało nam w sumie tylko jedno ważne makro do opisania - makro %verify. RPM posiada bardzo fajną możliwość weryfikowania pakietów po instalacji. Oznacza to po prostu, że RPM porównuje stan plików na dysku z tym, co ma zapisane w swoich bazach danych. Jeśli coś się różni, to rpm to zgłasza. A więc wykryje zmiany dat, rozmiaru, uprawnień, sum kontrolnych itp. Fajne. A makro %verify służy do sterowania zachowaniem rpm-a właśnie przy przeprowadzaniu weryfikacji. Makro %verify wywołuje się podobnie jak %config, to makro również przyjmuje opcje w nawiasach. A jakie są to opcje?
md5
Pod weryfikację podpada sprawdzanie sumy kontrolnej md5
size
Wykrywane będą zmiany wielkości pliku
link
Sprawdza, czy plik jest linkiem, a jeśli jest, to czy nie zmieniła się lokacja na którą wskazuje
user
Sprawdza, czy zmianie nie uległ właściciel pliku
group
Sprawdza grupę do której przynależy plik
mtime
Sprawdza czas ostatniej modyfikacji pliku
mode
Wykrywa zmiany w prawach dostępu
Makra używa się np. w taki sposób
%files
%{_bindir}/*
%verify(mode user group) %{_datadir}/foo/plik
co spowoduje, że rpm będzie w przypadu pliku ,,%{_datadir}/foo/plik'' wykrywał tylko zmiany właściciela/grupy i praw dostępu. Zmiany rozmiaru, daty modyfikacji itp. będą ignorowane.

Jeśli opcje poprzedzi się pojedynczym słowem ,,not'', to zostaną one zanegowane. Np.
%files
%{_bindir}/*
%verify(not size md5 mtime) %{_datadir}/foo/plik
oznacza ,,sprawdzaj wszystko, oprócz rozmiaru, sumy kontrolnej i daty modyfikacji''.

W pewnych wypadkach rpm automatycznie wyłączy pewne rodzaje weryfikacji w zależności od typu pliku, np. zliczanie sumy md5 na urządzeniach (np. wpisy w /dev).

I na deser została nam tylko jedna cecha sekcji %files, nie jest to co prawda makro, ale raczej opcja dla samej sekcji. Normalnie sekcję rozpoczyna się deklaracją ,,%files'', po której następuje lista plików wraz z ew. makrami %attr, %verify itp. Jeśli jednak sekcję rozpocznie się w taki sposób:
%files -f plik_z_listą
to rpmbuild odczyta plik ,,plik_z_listą'' i użyje go tak, jakby jego zawartość wpisać w sekcji %files. Oznacza to, że można nadal normalnie umieścić listę plików w %files, opcja -f działa po prostu trochę jak dyrektywa ,,#include'' w C. Zwykle używa się jej w połączeniu z makrem %find_lang, ale o tym przy innej okazji.

I to by było wszystko co mam do powiedzenia o sekcji %files.