From Fakeroot NG
Jump to: navigation, search

Compiling Fakeroot-NG

Here are a few tips and solutions to possible compilation problems:

Generic Compilation Instructions

In general, as the README file says, compiling fakeroot-ng is just a matter of running:

sudo make install

The project is an automake project, which means it supports out of tree builds, install targets and changing the installation path. Still, there are a few caveats that might be a problem, under certain conditions.

Passing Custom Compiler Flags

The following holds for any autoconf based project.

During the configure stage, the environment is read for environment variables for CFLAGS and CXXFLAGS (a full list is available by running ./configure --help). These values are then coded into the generated Makefile, and need not be set later on.

For fakeroot-ng in particular, care must be taken that the ptlib library is written in C, while fakeroot-ng itself is written in C++. As a result, it is important to set any flags you want for both CFLAGS and CXXFLAGS.

For example, if you want to compile a version with higher optimization values, you should use the following command when running configure (assuming bourne shell or derived shell):

CFLAGS='-O0' CXXFLAGS="$CFLAGS" ./configure

In this particular case, it would have been shorter to just repeat the flags for the CXXFLAGS variable, but this mechanism ensures that the C and C++ compiler receive the same flags. Also note that this does not apply to preprocessor defines, which are shared between C and C++. So, if all we wanted was to disable all of the asserts in the code, we would have done:

CPPFLAGS='-DNDEBUG' ./configure

Enabling Extra Warnings

It is possible to raise the warning level when compiling fakeroot-ng. It is written to be warning free when compiled with -Wall -Wextra. The only exception is the unused parameter warning, which I find unhelpful and counter-productive to eliminate. My debug environment is set up with the following command:

CFLAGS='-O0 -Wall -Wextra -Wno-unused-parameter' CXXFLAGS="$CFLAGS" ./configure

Configure error: Fakeroot-ng needs a compiler that supports C++11

As of version 0.18 of Fakeroot-ng, a compiler with a fairly complete support for the new C++11 standard is required in order to compile the program. In particular, fakeroot-ng makes use of decltype[1], nullptr[2] and std::unordered_map[3].

During the configure stage, fakeroot-ng tries to compile a small test program that utilizes all three capabilities, and checks which compiler flags are necessary in order to activate the relevant C++ language support. Mostly, this involves testing the "-std=c++11" flag, required for gcc.

If no flag passes the compilation, your configure state will look something like this:

checking for PTRACE_GETREGS... yes
checking for PTRACE_PEEKUSER... yes
checking what flags are needed for compiler support of the ISO C++11 standard... not supported
configure: error: Fakeroot-ng needs a compiler that supports C++11. If you are using gcc, that
                  means version 4.7 or higher.

If you are using gcc with a version lower than 4.7, then your only option is to upgrade. Versions before 4.7 simply did not support the C++11 standard to the extent required by fakeroot-ng. If you are using another compiler, in particular, one that does support nullptr, decltype and std::unordered_map, then you might be missing the correct compilation command line. Find out what those are. As a temporary workaround, pass them through the CXXFLAGS environment variable to configure. If that works, then do contact us on the mailing list and we'll gladly add that detection into the configure script.

Building a i386 binary on an AMD64/X86_64 host

Sometimes it is desired to build a 32bit target on a computer that, itself, is running a 64bit operating system. This is possible, but is not as straight forward as with other projects.

First, make sure that your installed compiler knows how to generate 32bit binaries. On Debian based systems this requires installing the "g++-multilib" package. If you only installed the "gcc-multilib" package, then your compiler will know how to generate 32 binaries for C, but not C++.

Once that's resolved, two things must be done. The first is to tell the build system you are cross compiling. This is done by passing configure the option --target=i686-pc-linux-gnu. This is important, as fakeroot-ng has specific code for each destination platform, and so must know which platform it is compiling for. This, however, does not actually causes make to generate 32 bit binaries (which is probably a bug in autoconf). To actually generate 32 bit binaries, the -m32 flags must be passed to gcc. See the above section on passing custom compiler flags. The complete command line to compile 32 bit is:

CFLAGS='-O2 -m32' CXXFLAGS="$CFLAGS" ./configure --target=i686-pc-linux-gnu

Error messages, and their meanings

In each error message, the important part is displayed in bold:

arch/linux/x86_64/platform.c:453:50: error: ‘RIP’ undeclared (first use in this function)

This means that you told the compiler to compile in 32 bit, but did not tell configure that your target is 32 bit.

arch/linux/i386/platform.c:80:44: error: ‘ORIG_EAX’ undeclared (first use in this function

This means that you told fakeroot-ng you are compiling for a 32 bit target, but did not tell the compiler to compile for 32 bit.

parent.cpp: In function ‘void init_handlers()’:
parent.cpp:210:1: error: ‘sys_fstatat64’ was not declared in this scope
parent.cpp: In function ‘bool hma_state0(int, pid_t, pid_state*)’:
parent.cpp:986:29: error: ‘SYS_mmap2’ was not declared in this scope
parent.cpp: In function ‘bool hma_state3(int, pid_t, pid_state*)’:
parent.cpp:1054:38: error: ‘SYS_mmap2’ was not declared in this scope

This means that you passed the flags to compile 32 bit to CFLAGS, but not to CXXFLAGS.