Difference between revisions of "Problems and issues with packaging"

From Wiki [en] OpenMandriva
Jump to: navigation, search
(SyntaxError: invalid syntax)
(fix ld error)
Line 57: Line 57:
 
-friend Fl_Widget *make_type_browser(int,int,int,int,const char *l=0);
 
-friend Fl_Widget *make_type_browser(int,int,int,int,const char *l=0);
 
+friend Fl_Widget *make_type_browser(int,int,int,int,const char *l);
 
+friend Fl_Widget *make_type_browser(int,int,int,int,const char *l);
 +
</pre>
 +
 +
 +
=== ld: multiple definition of ===
 +
Some packages tend to use GNU extensions in their code without specifying -std= appropriately. GCC allows that usage, yet clang disables some of more specific GNU extensions by default.
 +
<pre>
 +
/usr/bin/ld: warning: /usr/uclibc/usr/lib64/crti.o: missing .note.GNU-stack section implies executable stack
 +
/usr/bin/ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_add'
 +
/usr/bin/ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here
 +
/usr/bin/ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_add_1'
 +
/usr/bin/ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here
 +
</pre>
 +
 +
==== fix ====
 +
This is because clang uses C99 inline rules by default which do not work with gnu89 code. To work around it, you most likely have to pass -std=gnu89.
 +
<pre>
 +
export CFLAGS="${optflags} -std=gnu89"
 +
export CXXFLAGS="${optflags} -std=gnu89"
 
</pre>
 
</pre>
  

Revision as of 21:09, 8 August 2014

Packaging problems

Contents

build errors

LLVM/clang build errors

error: function definition is not allowed here

The code uses a rarely used gcc extension called nested functions (defining one function inside another) that isn't part of the C/C++ standards and that will never be supported by clang. Future gcc versions may warn about it as well. The fix is to un-nest the function - move the inner function to the outside and make it static so it doesn't pollute the symbol table. Since nested functions have access to variables inside the outer function, you may have to add them as parameters (see 2nd example of a simple fix) seen in elfutils, rpm

simple fixes

-void doSomething() {
-    void doSomethingElse() { }
-    doSomethingElse();
-}
+static void doSomethingElse() {
+}
+void doSomething() {
+    doSomethingElse();
+}
-void doSomething() {
-    int a;
-    int doSomethingElse() { return a+1; }
-    doSomethingElse();
-}
+static int doSomethingElse(int x) {
+    return x+1;
+}
+void doSomething() {
+    int a;
+    doSomethingElse(a);
+}

error: 'FULLSCREEN' is a protected member of 'Fl_Widget'

gcc treats the values of an enum as numbers, and therefore has no concept of them being private or protected. clang correctly denies access. seen in fltk

fix

Make the enum being used public, or where that is inappropriate, use a friend declaration to allow access.

error: friend declaration specifying a default argument must be a definition

A default argument is repeated in a friend declaration. seen in fltk

fix

Simply remove the default argument from the friend declaration. It shouldn't be there in the first place. The default argument has no place anywhere but in the function's/method's initial declaration.

-friend Fl_Widget *make_type_browser(int,int,int,int,const char *l=0);
+friend Fl_Widget *make_type_browser(int,int,int,int,const char *l);


ld: multiple definition of

Some packages tend to use GNU extensions in their code without specifying -std= appropriately. GCC allows that usage, yet clang disables some of more specific GNU extensions by default.

/usr/bin/ld: warning: /usr/uclibc/usr/lib64/crti.o: missing .note.GNU-stack section implies executable stack
/usr/bin/ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_add'
/usr/bin/ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here
/usr/bin/ld: error: ../mpi/.libs/libmpi.a(mpi-bit.o): multiple definition of '_gcry_mpih_add_1'
/usr/bin/ld: ../mpi/.libs/libmpi.a(mpi-add.o): previous definition here

fix

This is because clang uses C99 inline rules by default which do not work with gnu89 code. To work around it, you most likely have to pass -std=gnu89.

export CFLAGS="${optflags} -std=gnu89"
export CXXFLAGS="${optflags} -std=gnu89"

How to use gcc if clang fails

If the package uses any standard means for configuration (cmake, autoconf or similar), simply

export CC=gcc
export CXX=g++

before running cmake or configure.

If you do this, please add the package to the list (even if you don't know what the problem is) so we can keep track of things.

Python 3 migration

SyntaxError: invalid syntax

  File "test.py", line 3
    except Xyz, x:
              ^
SyntaxError: invalid syntax

Code being run through python is written for python 2.x, but python is python 3.x now.

The preferred fix is to fix the code to work with python 3.x. There is a tool called 2to3 that makes this task easier; in the best case,

  find . -name "*.py" |xargs 2to3 -w

can be all you need.

If the code can't be fixed easily, force using python2 -- add a build dependency on python 2.x and make sure the code runs through python2 rather than python.

A variant of this can be seen even in packages that don't have anything to do with python -- if they use a local copy of a python based build system (e.g. waf, gyp) making incorrect assumptions about /usr/bin/python. The fix in that case is to either port the build scripts or to make sure they're run with python2 (typically sed -i -e 's,env python,env python2,' path/to/script).

See This scons commit for an example of how to do this.

With some very convoluted build scripts (chromium!), it may also make sense to

ln -s %{_bindir}/python2 python
export PATH=`pwd`:$PATH

or the likes.

File(s) packaged into both python-something and python3-something:

The package builds both a python2 and a python3 module (this is good - it should keep doing this for now) and then uses %{python_sitearch} to list the python2 bits and %{python3_sitearch} to list the python3 bits in the file lists.

With python 3.x becoming the default, the %{python_sitearch} macro has been updated to list python3 locations (to make life easier for packages only packaging a module for the main version of python) - and %{python3_sitearch} points at the same directories, causing the python3 related files to be listed twice and the python2 related files not to be listed at all.

The fix is to replace %{python_sitearch} with %{python2_sitearch}.

%{python3_sitearch} can stay (during python 3.x's lifetime, it will always point at python 3, even after we've moved on to python 4.x), or be replaced with %{python_sitearch}, which will always point at the current version of python. Which of those is preferable depends on the context.

Any other problem related to python3 migration

Check out http://python3porting.com/

format not a string literal and no format arguments

Since December 2008, things like printf(error_message) instead of printf("%s", error_message) are detected by -Werror=format-security which is used by default. The reason for this error is described on the following Wikipedia page: format string attack

Example of error:

fud.c:72: error: format not a string literal and no format arguments

simple fixes

The fix can be something like:

-      printf(xkblayouttext);
+      printf("%s", xkblayouttext);
-      syslog(LOG_ERR, error_message(r));
+      syslog(LOG_ERR, "%s", error_message(r));
-   snprintf(id_resp_command, MAXIDVALUELEN, *argv);
+   snprintf(id_resp_command, MAXIDVALUELEN, "%s", *argv);

(another example: nautilus fix)

C++ code

Beware of C++ objects in C statements:

  QCString msgText = substitute(outputFormat, "$file", fileSubst) + '\n';
  fprintf(warnFile, msgText);

simply doing fprintf(warnFile, "%s", msgText) would introduce a crash, as warned by gcc:

message.cpp:150: warning: cannot pass objects of non-POD type 'class QCString' through '...'; call will abort at runtime
message.cpp:150: warning: format '%s' expects type 'char*', but argument 3 has type 'int'

You must explicitly cast to (const char *) (or call a method that returns a C style string):

fprintf(warnFile, "%s", (const char *) msgText);

or

fprintf(warnFile, "%s", qPrintable(msgText));

or simpler:

fputs(msgText, warnFile);

code doing % escaping by hand

Beware of weird code like (from doxygen):

  QCString msgText = substitute(substitute(outputFormat, "$file", fileSubst),
                                "%", "%%") + '\n';
  fprintf(warnFile, msgText);

Doing fputs(msgText, warnFile) modifies the program's behaviour since % will be displayed %% since % is escaped in msgText. The correct fix is to also get rid of the %s escaping:

  QCString msgText = substitute(outputFormat, "$file", fileSubst) + '\n';
  fputs(msgText, warnFile);

but you can also disable the warning (see below) and keep the code unchanged, since the code is valid (even if ugly).

disabling this warning

If the code is valid, you can disable the check using %define Werror_cflags %nil

The use of -Werror=format-security is inpired by Debian Hardening and Ubuntu CompilerFlags which use -Wformat-security to detect such issues. But warnings are not enough (especially since people typically don't bother to read build logs for a successful build), so OpenMandriva chose to enforce it by making such warnings fatal.


Assorted other failures

Failed attempt to access /dev/st0 or /dev/st1

This is caused by an incorrect invocation of the tar command.

The standard does not define what tar is supposed to do if it's not told what file to operate on -- GNU tar assumes it should use stdout, bsdtar assumes it should use a tape drive (that may or may not exist). The fix is to tell tar what it should do, e.g. change

tar c blah | tar x -C somewhere

to

tar cf - blah | tar xf - -C somewhere

This will work with any implementation of tar.

No X display available

Some packages require the availability of an X display during the package build. If no interaction is needed, this can be solved with Xvfb: just add
BuildRequires: x11-server-xvfb
and run the command with xvfb-run, e.g.
xvfb-run make check

undefined reference to `xxx'

Since May 2008, packages are built with ld flag --no-undefined to prevent underlinking shared libraries.

gcc -shared foo.o -ldl /usr/lib/libglib-2.0.so /usr/lib/libXext.so ... -Wl,--no-undefined -o .libs/libkeymouselistener.so
.libs/keymouselistener.o: In function `parse_line':
.../gdm-2.20.6/gui/modules/keymouselistener.c:410: undefined reference to `XKeysymToKeycode'
collect2: ld returned 1 exit status

Check underlinking to understand how to fix.

Missing %files for subpackage xxx

Since June 2008, subpackage xxx with no %files xxx raises a fatal error. It helps to detect dead subpackages, or typos in .spec file.

It also occurs in valid spec files, when "%files xxx" appears inside a %if %ccc ... %endif. The fix is to put the whole %package xxx section inside a %if %ccc ... %endif.

error: possibly undefined macro: AM_ACLOCAL_INCLUDE

Fix is to replace AM_ACLOCAL_INCLUDE call in configure.in or configure.ac with ACLOCAL_AMFLAGS variable in Makefile.am. For example, if configure.ac has AM_ACLOCAL_INCLUDE(macros), remove it and add this to Makefile.am:

ACLOCAL_AMFLAGS = -I macros

conflicting types for `getline'

A file includes /usr/include/stdio.h but at the same time defines a local getline function. Fix is to rename the local getline, e.g. 'parseline'. You may do this automatically with this command:

sed -i -e 's|getline|parseline|' path/to/src/*.c

build warnings

overlinking

To reduce overlinking, rpm can display some warnings alike:

Warning: unused libraries in /usr/bin/xdm: /usr/lib/libXext.so.6 /usr/lib/libXt.so.6 /usr/lib/libSM.so.6 /usr/lib/libXpm.so.4 /usr/lib/libxcb-xlib.so.0 /usr/lib/libxcb.so.1

Check overlinking to understand how to fix.

underlinking

To reduce underlinking, rpm can display some warnings alike:

Warning: undefined symbols in /usr/lib/libgmodule-1.2.so.0.0.10: g_free g_thread_functions_for_glib_use g_threads_got_initialized ...

Check underlinking to understand how to fix.

rpm loop warnings

LOOP warnings from tsort relations

Example:
warning: LOOP:
warning: removing libdrakx-net-0.94-1.1.noarch "Requires: /usr/share/locale/fr/LC_MESSAGES" from tsort relations.
warning: removing harddrake-13.52-1.i586 "Requires: drakxtools-curses = 13.52-1" from tsort relations.
warning: removing drakxtools-curses-13.52-1.i586 "Requires(hint): drakx-net-text" from tsort relations.
warning: removing drakx-net-text-0.94-1.1.noarch "Requires: libdrakx-net = 0.94" from tsort relations.
  • What is a Tsort relation?

The set of ordered dependencies, before rpm installation, so if rpm installation order is not correct, this may result in broken installations, it is important to prevent these erros in order to have a more robust installation system.

  • How to solve the error?

Remove unnecessary circular dependencies when encountered.

Often the loops may be harmless, but sometimes they might cause packages to be installed in the wrong order, ie. like one package requiring a specific user for ownership of directories which are created by another package, or maybe running a script requiring a file from another package that due to dependency loop gets installed only after the script is attempted to run..

  • In practical, how to solve this?

Edit the spec file of the application to remove unnecessary circular dependencies.

If not possible, add the dependency detection to this bug report in bugzilla or create a new bug linking to it.

check errors

Rpmlint errors

script-without-shebang

This executable text file does not contain a shebang (#!/bin/sh), thus it cannot be properly 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 by looking at the top of the file, and either remove the executable bits or add the shebang.

Add sh shebang: [me@mandrivapc]$ sed -i -e '1d;2i#!/bin/sh' foo.sh

Add Perl shebang: [me@mandrivapc]$ sed -i -e '1d;2i#!/usr/bin/perl' foo.pl

Add Python shebang: [me@mandrivapc]$ sed -i -e '1d;2i#!/usr/bin/python' foo.py

no-signature

The package was not signed with a gpg key. You need to use [me@mandrivapc]$ rpm --sign package.rpm after having built it. This is not a problem if you plan to send the rpm to contribs or another packaging project, as they usually resign the package with the project key. You can ignore it in rpmlint config.

binary-or-shlib-defines-rpath

'The binary or shared library defines the PATH'. Usually this is a bad thing because it hard codes the path to search libraries and so it makes it difficult to move libraries around. Most likely you will find a Makefile with a line like: [me@mandrivapc]$ gcc test.o -o test -Wl,--rpath.

If the program uses [me@mandrivapc]$ ./configure, you can probably add --disable-rpath (verify with [me@mandrivapc]$ ./configure --help to see if the option is available).

You can look at the Debian wiki for more information.

If you can not change that easily, you can use [me@mandrivapc]$ chrpath -d on the given file at the end of %build. If you do so, do not forget to add a BuildRequires2: chrpath to your spec.

configure-without-libdir-spec

This usually happens when you don't use the %configure or %configure2_5x macro to call the [me@mandrivapc]$ configure script. They run [me@mandrivapc]$ configure with predefined default options, so the files get installed in the right location. You can ignore the error if the sources contain a [me@mandrivapc]$ configure script that wasn't generated by autoconf.

explicit-lib-dependency

Don't include dependencies like "Requires: libdvdread3" in your spec file. Library dependencies are managed automatically, so if your program is linked against libdvdread.so.3, the libdvdread3 package will be an automatic dependency. Also, this isn't portable to architectures like amd64, where the package is named lib64dvdread3. If you really need a library dependency, e.g. to force the upgrade to a new version, use the virtual name provided by that package, in this example "Requires: libdvdread".

invalid-directory-reference

Don't include files in /tmp or /home in your package.

lib-package-without-%mklibname

If you split out library packages, you should use the %mklibname macro to generate the name of the library package. Further information on the usage of %mklibname are in the library policy section.

no-prereq-on

Example error: no-prereq-on rpm-helper

Solution: Add "Requires(pre): rpm-helper", "Requires(preun): rpm-helper" as needed to the package.

prereq-use

Example error: prereq-use rpm-helper

Solution: prereq-use is no longer used, you should use Requires(stage) instead with stage in {pre,post,preun,postun}. For example: Requires(post): rpm-helper

no-signature

Packages get signed during upload process, so just ignore this or add addFilter("E: .* no-signature") into your ~/.rpmlintrc.

Rpmlint Warnings

spurious-executable-perm

FIXME

From an unexperienced packager :

It can happen for example for doc files (README, COPYING, etc...) that have executable permissions in the source tarball. To solve this you have to fix the permissions, for example in the %build section.

dangling-relative-symlink

The relative symbolic link points nowhere. If you are sure the pointed file will be there (e.g. you require the package containing it) you can safely ignore this. Else, just fix it :-)

postin-without-ghost-file-creation

You tagged a file with %ghost but did not create it in %postin nor in %prein

Upload errors

You have not built your package with the changes from the previous package

debug packages

Debug packages are built per default in Cooker, but sometimes this won't apply so you need a way to switch it off, you have to add these two lines in the spec file to disable debug packages:

%define _enable_debug_packages %{nil}
%define debug_package          %{nil}