-
Notifications
You must be signed in to change notification settings - Fork 560
Build Tricks
This page collects some known build errors and trick how to fix them
Sometimes the build system can't find the header files of the dependencies, even if they're properly installed. When this happens, you have to tell the C/C++ preprocessor where the files are by setting the CPPFLAGS
environment variable:
export CPPFLAGS="-I${prefix}/include"
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target}
make -j${nprocs}
make install
See for example Cairo build script.
Like in the section above, it may happen that the build system fails to find the libraries of the dependencies, even when they're installed to the right place. In these case, you have to inform the linker where the libraries are by setting the LDFLAGS
environment variable:
export LDFLAGS="-L${libdir}"
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target}
make -j${nprocs}
make install
See for example libwebp build script (in this case this was needed only when building for FreeBSD).
The keyword argument preferred_gcc_version
to the build_tarballs
function allows you to select a newer compiler to build a library, if needed. Pure C libraries have good compatibility so that a library built with a newer compiler should be able to run on a system using an older GCC version without problems. However, keep in mind that each GCC version in BinaryBuilder.jl
comes bundled with a specific version of binutils -- which provides the ld
linker -- see this table.
ld
is quite picky and a given version of this tool doesn't like to link a library linked with a newer version: this means that if you build a library with, say, GCC v6, you'll need to build all libraries depending on it with GCC >= v6. If you fail to do so, you'll get a cryptic error like this:
/opt/x86_64-linux-gnu/bin/../lib/gcc/x86_64-linux-gnu/4.8.5/../../../../x86_64-linux-gnu/bin/ld: /workspace/destdir/lib/libvpx.a(vp8_cx_iface.c.o): unrecognized relocation (0x2a) in section `.text'
/opt/x86_64-linux-gnu/bin/../lib/gcc/x86_64-linux-gnu/4.8.5/../../../../x86_64-linux-gnu/bin/ld: final link failed: Bad value
The solution is to build the downstream libraries with at least the maximum of the GCC versions used by the dependencies:
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies; preferred_gcc_version=v"8")
For instance, FFMPEG has to be built with GCC v8 because LibVPX requires GCC v8.
Generally speaking, we try to build with the as old as possible version of GCC (v4.8.5 being the oldest one currently available), for maximum compatibility.
The build environment provided by BinaryBuilder
is a x86_64-linux-musl
, and it can run executables for the following platforms: x86_64-linux-musl
, x86_64-linux-gnu
, i686-linux-gnu
. For all other platforms, if the build system tries to run a foreign executable you'll get an error, usually something like
./foreign.exe: line 1: ELF��
@@xG@8@@@@@@���@�@@����A�A����A�A���@�@: not found
./foreign.exe: line 1: syntax error: unexpected end of file (expecting ")")
This is one of worst cases when cross-compiling, and there isn't a simple solution. You have to look into the build process to see if running the executable can be skipped (see for example the patch to not run dot
in #351), or replaced by something else. If the executable is a compile-time only utility, try to build it with the native compiler (see for example the patch to build a native mkdefs
in #351)
If compilation fails because of the following errors
undefined reference to `backtrace_symbols'
undefined reference to `backtrace'
then you need to link to execinfo
:
if [[ "${target}" == *-freebsd* ]]; then
export LDFLAGS="-lexecinfo"
fi
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target}
make -j${nprocs}
make install
See for example #354.
When building for Windows, sometimes libtool refuses to build the shared library because of undefined symbols. When this happens, compilation is successful but BinaryBuilder's audit can't find the expected LibraryProduct
s.
In the log of compilation you can usually find messages like
libtool: warning: undefined symbols not allowed in i686-w64-mingw32 shared libraries; building static only
or
libtool: error: can't build i686-w64-mingw32 shared library unless -no-undefined is specified
In these cases you have to pass the -no-undefined
option to the linker, as explicitly suggested by the second message.
Doing this properly is a bit tricky: I couldn't make CFLAGS=-Wl,-no-undefined
work, instead setting LDFLAGS=-no-undefined
before ./configure
make this fail (because it will run a command like cc -no-undefined conftest.c
, which upsets the compiler). What I use to do is to pass LDFLAGS=-no-undefined
only to make
:
FLAGS=()
if [[ "${target}" == *-mingw* ]]; then
FLAGS+=(LDFLAGS="-no-undefined")
fi
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target}
make -j${nprocs} "${FLAGS[@]}"
make install