Building Packages

Tips for Building Packages

BinaryBuilder provides a convenient environment to enable cross-platform building. But, many libraries have complicated build scripts that may need to be adapted to support all of the BinaryBuilder targets.

If you have additional tips, please submit a PR with suggestions.

Initiating different shell commands based on target

Sometimes, you need to adapt build scripts based on the target platform. This can be done within the shell script. Here is an example from staticfloat/OpenBLASBuilder:

# Set BINARY=32 on i686 platforms and armv7l
if [[ ${nbits} == 32 ]]; then
    flags="${flags} BINARY=32"
fi

Here are other examples of scripts with target-specific checks:

It is also possible to run quite different scripts for each target by running different build scripts for different sets of targets. Here is an example where windows builds are separated from other targets:

Autoconfigure builds

Autoconfigure builds are generally quite straightforward. Here is a typical approach:

./configure --prefix=$prefix --host=${target}
make -j${nproc}
make install

Here are examples of autoconfigure build scripts:

CMake builds

For CMake, the wizard will suggest a template for running CMake. Typically, this will look like:

make -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_TOOLCHAIN_FILE=/opt/$target/$target.toolchain

The toolchain file sets up several CMake environment variables for better cross-platform support:

# Toolchain file for x86_64-linux-gnu
set(CMAKE_SYSTEM_NAME Linux)

set(CMAKE_SYSROOT /opt/x86_64-linux-gnu/x86_64-linux-gnu/sys-root/)
set(CMAKE_INSTALL_PREFIX /)

set(CMAKE_C_COMPILER /opt/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /opt/x86_64-linux-gnu/bin/x86_64-linux-gnu-g++)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

Examples of builds that include CMake parts include:

Builds with binary dependencies

A build script can depend on binaries generated by another Builder repository. A builder specifies dependencies like:

dependencies = [
    # We need libogg to build FLAC
    "https://github.com/staticfloat/OggBuilder/releases/download/v1.3.3-0/build.jl"
]

Each of the dependencies points to a build.jl file, usually provided with a release of another Builder repository.

In the wizard, this can be specified with the prompt: Do you require any (binary) dependencies? [y/N].

Examples of builders that depend on other binaries include:

Editing files in the wizard

In the wizard, the vi editor is available for editing files. But, it doesn't leave any record in the build script. One generally needs to provide patch files or sue something like sed. Here is an approach using diff and patch:

cp file.ext file.ext.orig
vi file.ext     # make the changes
diff -u file.ext.orig file.ext
# Create a patch based on the results copy-pasted from the output of `diff`
cat > file.patch <<'END'
--- file.ext.orig 2017-12-14 19:28:48.816021000 -0500
+++ file.ext2017-12-14 19:29:03.912021000 -0500
@@ -1,4 +1,5 @@
 -https://computation.llnl.gov/projects/sundials/download/sundials-3.0.0.tar.gz
 +https://computation.llnl.gov/projects/sundials/download/sundials-3.1.0.tar.gz
  
  http://faculty.cse.tamu.edu/davis/SuiteSparse/SuiteSparse-5.0.0.tar.gz
 
END
# Apply the patch
patch -l file.ext.orig file.patch -o file.ext

There are plans to handle file changes in the wizard automatically (#25).

Other examples

Examples of other interesting builders include: