RpmLint
De Wiki de la Comunidad Mandriva
Artículo en traducción
RPM Lint
Rpmlint se ejecuta luego de realizar el empaquetado exitosamente. Se ejecuta con una configuración personalizada, que busca en los resultados las advertencias problemáticas, opcionalmente si estas advertencias superan un umbral, falla la construcción. La idea detrás de esto es que los errores no entren en la distribución, sino que se detectan a tiempo.
El concepto erróneo
Con el fin de obtener una visión más clara, y limitar el impacto al empaquetar, sólo los mensajes seleccionados de RPMLint se consideran un error. El conjunto de estos mensajes es configurable. Todo lo demás será tomado como tan solo advertencia, y las advertencias no detienen un empaquetado exitoso.
A couple of checks have been assigned a badness rating. En cada generación del paquete se acumularán errores, y si estos superan un umbral, puede fallar la construcción. Mientras los errores no superen ese umbral el empaquetado será exitoso. Sin embargo, ellos serán enumerados para guiar su trabajo y debe dar una mayor prioridad a algunos para arreglarlos o suprimirlos.
Suprimiendo falsos positivos
Use este método solo para falsos positivos. Para deshacer errores acerca de violaciónes ne la política de distribución
use el método descrito en la siguiente secciónEn casos donde quieras In cases where you want to disable a false positive that is specific to your package, you can add a custom suppression to your source dir. For that to work, add a file named %{name}-%{version}-rpmlintrc to your Source list in the spec file. For example add:
[...]
Source5: %{name}-%{version}-rpmlintrc
[...]
In that file, add the following content to it:
addFilter("perl.* devel-file-in-non-devel-package")
This example filter suppresses any hits of the warning named devel-file-in-non-devel-package when the (sub-)package name is perl. In general, you should write the check to be as specific as possible and as unspecific as needed. So, in order to suppress only a hit about one particular file, you should write something like
addFilter("spurious-executable-perm .*/usr/share/doc/packages/cups/PrintAnalyzer")
In general, you can use any valid Perl/Python regular expression for filtering, and it will match it directly on the line of text as it was printed by rpmlint.
As this suppression file is however not part of the binary package, running rpmlint manually on the resulting rpm will again print even the suppressed warnings. This is by intention. If there is a systematic rpmlint warning that should be removed in general, please file a bug report.
Disarming Fatal Errors
Some checks, such as security checks have such a high badness score that a single occurence already fails the build. Packages that are not intended for inclusion in openSUSE may want to turn such fatal errors into warnings. To do that create an rpmlintrc file as described in the previous section but with different content. To build a package that includes an unauthorized permissions file for example add the following line:
setBadness('permissions-unauthorized-file', 0)
Testing your package
The SUSE version of RPM Lint is frequently updated and contains many customisations that are not upstream (and some of them being SUSE specific probably will never be). The one in SuSE Factory is the one that is used for Factory builds, but you don't actually have to rebuild your package to test it against rpmlint. It can be called from command line
rpmlint <list of rpm packages>
For that, you should install the rpmlint from the openSUSE build service
RPM Lint checks during Factory build
The following is a list of checks that currently have badness assigned inside SUSE Factory build.
arch-dependent-file-in-usr-share
This package installs an ELF binary in the /usr/share hierarchy, which is reserved for architecture-independent files. Binaries that are only usable on a certain architecture (e.g. compiled C code), should be installed under %libdir/package.
As an exception for certain packages, this check tries to avoid a warning if the path is architecture specific, like for example /usr/share/tetex/bin/linux/x86/tetex. The use of this exception is however not recommended.
wrong-script-interpreter
This script uses an incorrect interpreter in its shebang. the script interpreter should be a full path to a packaged interpreter, which means it shouldn't point to /usr/local/bin for example.
arch-independent-package-contains-binary-or-object
Your package has been marked as noarch, but contains a binary that is architecture specific.
library-without-ldconfig-postin
The package installs a library, but doesn't call ldconfig in its %post install. without an updated ldconfig cache, the library cannot be used. This is a frequent problem during installation, because following packages might require the library in their %post script.
file-contains-buildroot
A string in the file is an exact match to the build root. The package files should not include such details about package creation.
files-duplicated
The package contains some files duplicate, which wastes installation space and rpm size. consider using the %fdupes macro.
summary-not-capitalized
Package summaries should start with a capital letter.
executable-docs
Documentation under %docdir contains executable files. Documentation should not be executable.
spurious-executable-perm
Files that are likely not supposed to be executable are marked as such. This can be subject of false positives, so carefully review if those are correct or if not, suppress them.
devel-file-in-non-devel-package
The package contains content that should be in a -devel subpackage. The advantage of cleaning your package up and splitting it properly into a -devel package is twofold:
- it will keep installation size for customers/users who do not compile stuff on their own small
- it will allow you to add proper build dependencies to the -devel subpackage as requires, which makes life of your customer easier: In order to install the -devel package, he also has to install all the tools that are commonly required for this package, making troubleshooting a lot easier for them.
There a several subchecks that could cause this check to be triggered.
- A header file under /usr/include. It detects files ending as \.h and a couple of other extensions as header files
- A .so symlink in %libdir that points to a versioned so file. Usually, those files are only needed during building. However, there can be the exception that the application tries to dlopen() the library for some reason, so there might be valid reasons for not splitting the .so file into a subpackage. However, this should be a rare event.
In most cases however, the error is triggered because of versioned libtool modules. Plugins should be build with -avoid-version and -module parameters in LDFLAGS, which will avoid triggering this check as well.
If for example the sole purpose of your the particular shared library is to be a plugin that is loaded by some other application (a good indication for this is that it is installed not directly in %libdir but a subdirectory of it, and this sub directory is not in /etc/ld.so.conf path), then you should validate the LDFLAGS that were used for building this module, and make sure that -module and -avoid-version were in it. To apply versioning, the subdirectory the plugins are installed to should be versioned instead.
wrong-file-end-of-line-encoding
Some of the files have windows style (CRLF) line ending. Under certain circumstances, this can cause incompatibilities with viewer applications. The check is scored very low, so you might just not care about it. If you care, you should try recoding the files in question to unix-style LF only.
To fix this you can either use "dos2unix" or
sed -i 's/\r//' <file_to_strip>
in %prep.
wrong-script-end-of-line-encoding
E: foo-package wrong-script-end-of-line-encoding /var/www/foo-package/plugins/foo.php
This script has wrong end-of-line encoding, usually caused by creation or modification on a non-Unix system. It will prevent its execution.Solution:- Create files on Linux only. Don't create files on non-Unix environment and add it in package.
hardlink-across-partition
Your package contains two files that are apparently hardlinked and that are likely on different partitions. Installation of such an RPM will fail due to RPM being unable to unpack the hardlink, if the files that are hardlinked are ending up on two different physical partitions. By policy, do not hardlink across the first two levels of a path, e.g. between /srv/ftp and /srv/www or /etc and /usr.
invalid-spec-name
The specfile should be name %{name}.spec
no-packager-tag
The spec file does not contain a "Packager" tag, if you are using the openSUSE BuildService, ignore this warning.
static-library-without-debuginfo
An static library included in your package does not contain debug information, in general they are not useful, use --disable-static configure option or rm %{buildroot}%{_libdir}/*.a at the end of the %install section if and only if there is no such option available.
shlib-legacy-policy-name-error
Your package does not follow the SUSE library packaging Policy.
ghost-files-without-postin
The files are not in the RPM archive itself but created dynamically by the package, at install time or most often later when a daemon is run, i.e. the files are some status or log files. They get erased with the package when you 'rpm -e'.
no-binary
E: foo-package no-binary The package should be of the noarch architecture because it doesn't contain any binaries. Solution:- Then you can add to SPEC file BuildArchitectures: noarch unless it is a python package, in which case you should ignore this warning.
standard-dir-owned-by-package
E: foo-package standard-dir-owned-by-package /usr/share This package owns a directory that is part of the standard hierarchy, which can lead to default directory permissions or ownerships being changed to something non-standard. Solution:- You should not make Systems standard directory's to belong to your package.
non-conffile-in-etc
W: foo-package non-conffile-in-etc /etc/xdg/menus/applications-merged/foo-package.menu A non-executable file in your package is being installed in /etc, but is not a configuration file. All non-executable files in /etc should be configuration files. Mark the file as %config in the spec file. Solution:- under %files section you can add %config /etc/xdg/menus/applications-merged/foo-package.menu
summary-ended-with-dot
W: foo-package summary-ended-with-dot A content management system for foo package. Summary ends with a dot. Solution:- Remove period in Summary.
incoherent-version-in-changelog
W: foo-package incoherent-version-in-changelog 0.6.1-1 0.6.1-1..fc6 Your last entry in %changelog contains a version that is not coherent with the current version of your package. Solution:- Check Last entry under changelog section for version and release tags in SPEC file.
incoherent-init-script-name
incoherent-init-script-name Solution:- The init script name should be the same as the package name in lower case.
script-without-shebang
E: foo-package script-without-shebang /var/www/foo-package/plugins/foo.php This executable text file does not contain a shebang, thus it cannot be propely executed. Often this is a sign of spurious executable bits for a non-script file, but can also be a case of a missing shebang. To fix this error, find out which case of the above it is, and either remove the executable bits or add the shebang. Solution:- You forgot to set executable bits on files reported by this error.
version-control-internal-file
E: foo-package version-control-internal-file /var/www/foo-package/CVS/Entries You have included file(s) internally used by a version control system in the package. Move these files out of the package and rebuild it. Solution:- CVS directories and anything under them should just be deleted.
zero-length
E: foo-package zero-length /var/www/foo-package/foo.js
Solution:- These shouldn't be included unless they're required for something.
description-line-too-long
E: foo-package description-line-too-long Your description lines must not exceed %d characters. If a line is exceeding this number, cut it to fit in two lines. Solution:- Make description lines each of max 80 characters.
non-standard-group
W: foo-package non-standard-group Networking/Other The group specified in your spec file is not valid. To find a valid group, please refer to the distribution + RPM documentation. Solution:- On FC5, Check /usr/share/doc/rpm-4.4.2/GROUPS for valid group names.
non-coherent-filename
W: foo-package non-coherent-filename foo-package-0.99-0.Fedora.src.rpm The file which contains the package should be named <NAME>-<VERSION>-<RELEASE>.<ARCH>.rpm. Solution:- Your package name must be of form <NAME>-<VERSION>-<RELEASE>.<ARCH>.rpm
strange-permission
W: foo-package strange-permission foo-package.spec 0744 A file that you listed to include in your package has strange permissions. Usually, a file should have 0644 permissions. Solution:- Change permissions on SPEC file.
hardcoded-library-path
E: foo-package hardcoded-library-path in %{buildroot}/usr/lib/menu/ A library path is hardcoded to one of the following paths: /lib, /usr/lib. It should be replaced by something like /%{_lib} or %{_libdir}. Solution:- Don't hardcode path in SPEC rather use macros.
unstripped-binary-or-object
Solution: You must enable debuginfo in your OBS project, if still happends check if your package strips binaries automatically on %makeinstall or if binaries and objects lack of executable permissions.
no-default-runlevel
no-default-runlevel
Solution:- The default runlevel isn't specified in the init script. You need to add a line like the following one in the header of the init script: 2345 are the default runlevels. When installed, the package will be started on runlevel 2, 3, 4 and 5, and stopped for 1 and 6. 04 and 70 are starting order and stopping order. See InitscriptHowto for more information.
dbus-policy-*
The dbus package used a too permissive configuration in the past which led to security problems (CVE-2008-4311). During investigation of that problem it was found that many packages contain dbus configuration files that contain useless settings, settings that harm other services or settings that even break after the dbus security update.
Solution: - fix the dbus configuration file. In most cases the config can be reduced to a few lines. See also https://bugs.launchpad.net/ubuntu/+source/avahi/+bug/318783
executable-stack
Rpmlint says:
The binary declares the stack as executable. Executable stack is usually an error as it is only needed if the code contains GCC trampolines or similar constructs which uses code on the stack. One common source for needlessly executable stack cases are object files built from assembler files which don't define a proper .note.GNU-stack section.
Solutions:
- A comprehensive article about this problem can be foundat http://www.gentoo.org/proj/en/hardened/gnu-stack.xml
- Probably the easiest solution is to pass '-Wl,-z,noexecstack' to the linker.
- Don't forget to enable debuginfo in your build service project or call
$ obs build --debug
RPM Lint checks that might end up in Factory builds
There is a general group of checks that try to validate the SUSE Shared Library Packaging policy. Those checks start with "shlib-policy" and are non-fatal right now. If you introduce new packages, you should try to make them match the policy. For established packages, there is probably little reason to go through the additional hassle of renaming them and keeping the upgrade path working.
The remaining tests are documented below in more detail.
file-not-in-%lang
This usually indicates gettext translation files (those ending in .mo) that were not properly tagged by their language for rpm. We might use this information in the future to be able to leave out certain languages during installation (for example, other ideas are possible and are already in experimental implementation available). To properly tag them, use the %find_lang macro that is provided.
untranslated-desktop-file
We frequently get translation bugs that occur because .desktop files were not tagged for Novell translations. In order to do that, you have to run %suse_update_desktop_file on each of those files. Doing so will allow the openSUSE translators and the Novell translation team to add translations for your desktop files automatically during your package build.
Note that if this is a KDE3 or KDE4 package, the error is caused by a missing call to %kde_post_install at the end of the %install section.
init-script-without-%stop_on_removal-preun
The package contains an /etc/init.d script and the package that installs it doesn't contain a call to %stop_on_removal in the %preun script. This is required per SUSE packaging conventions.
init-script-without-%insserv_cleanup-postun
The package contains an /etc/init.d script and the package does not call %insserv_cleanup in the %postun script. This is required per SUSE packaging conventions.
no-prereq-on
The package contains a %pre/%post/%preun%postun script that references an external binary that is however not explicitely listed in the prerequires (PreReq:) or requires (Requires:) of the package. Fixing this is necessary so that installation of the package happens in the correct order, e.g. the packages necessary for executing the %post script are already installed.

