Skip to content
Samuel Audet edited this page Nov 8, 2022 · 36 revisions

Introduction

This page contains a description of the environments that are used to build the JavaCPP Presets for Android (ARM, ARM64, x86, and x86_64), Linux (x86 and x86_64), Linux (ARM), Mac OS X (x86_64), and Windows (x86 and x86_64). We also explain our choices given the requirements and provide some recommendations. This information more or less reflects what is used for the builds with GitHub Actions, whose scripts offer more precision about the exact dependencies used for releases. Furthermore, JavaCPP is by no means limited to these platforms, so if you happen to know how to set up an environment for other platforms, by all means, please do add that information to this page to share with others. Thank you!

Prerequisites for all platforms

The build process for the modules of javacpp-presets usually depends on the same version of the javacpp module. To insure that you have the latest matching version of both, please execute the following before starting the build in the javacpp-presets directory or one of its subdirectories:

$ git clone https://github.com/bytedeco/javacpp.git --branch <tag>
$ git clone https://github.com/bytedeco/javacpp-presets.git --branch <tag>
$ cd javacpp
$ mvn clean install -Djavacpp.platform=...

For the latest tag please check https://github.com/bytedeco/javacpp-presets/tags or use "master".

Android (ARM, ARM64, x86, and x86_64)

To produce native libraries for Android, we basically only need to install the JDK and the NDK, which is available for Linux, Mac OS X, and Windows. However, the build scripts of some libraries only run correctly under Linux, so we recommend using a recent distribution of Linux (such as Fedora or Ubuntu) as build environment for Android.

Preparations

  1. Download the latest supported version of the NDK, which is r21e at the time of this writing and features Clang with libc++ instead of GCC with libstdc++, among other things.
  2. Install the NDK under, for example, ~/Android/android-ndk, where the build scripts will look for it by default.
  3. Finally, make sure to have installed at least OpenJDK and Maven as per the instructions of your distribution.
  4. Run the "Prerequisites for all platforms" tasks inside the shell.

After which the following command can be used to start the build inside the javacpp-presets directory or one of its subdirectories:

$ mvn clean install -Djavacpp.platform=android-xxx -Djavacpp.platform.root=/path/to/android-ndk/

where android-xxx is either android-arm, android-arm64, android-x86, or android-x86_64.

Linux (x86 and x86_64)

To produce native libraries that can run on the largest possible number of Linux installations out there, it is recommended to build under CentOS 7. This is because it relies on an old enough version of glibc, which nevertheless works for all the libraries found in the JavaCPP Presets, and since newer versions of glibc are backward compatible, all recent distributions of Linux should support the binaries generated. We do not actually need to install CentOS 7 though. Pretty much any recent distribution of Linux comes with a package for Docker. It is also possible to map existing directories, for example /usr/local/lib/bazel and /usr/local/cuda as shown in the steps below, to reuse an existing Bazel or CUDA installation as well as any other set of files for the purpose of the build.

Preparations

  1. Install Docker under, for example, Fedora or Ubuntu, respectively:

    $ sudo yum install docker
    $ sudo apt-get install docker.io
  2. When using SELinux, it might also be necessary to disable temporarily the firewall, for example:

    $ sudo systemctl stop firewalld
    $ sudo systemctl start docker
    
  3. Start the container for CentOS 7 (the command might be docker.io instead of docker):

    $ sudo docker run --privileged -it -v /usr/local/lib/bazel:/usr/local/lib/bazel -v /usr/local/cuda:/usr/local/cuda centos:7 /bin/bash
  4. Finally, inside the container, we need to install a bunch of things:

    $ ln -s /usr/local/lib/bazel/bin/bazel /usr/local/bin/bazel
    $ yum install centos-release-scl-rh epel-release
    $ yum install devtoolset-9 rh-git218 rh-java-common-ant rh-maven35 boost-devel ccache clang gcc-c++ gcc-gfortran java-1.8.0-openjdk-devel ant python python3-devel python3-pip swig file which wget unzip tar bzip2 gzip xz patch autoconf-archive automake make cmake3 libtool bison flex perl-core nasm alsa-lib-devel freeglut-devel gtk2-devel libusb-devel libusb1-devel curl-devel expat-devel gettext-devel openssl-devel bzip2-devel zlib-devel SDL2-devel libva-devel libxkbcommon-devel libxkbcommon-x11-devel xcb-util* fontconfig-devel libffi-devel ragel ocl-icd-devel GeoIP-devel pcre-devel ssdeep-devel yajl-devel
    $ yum install `rpm -qa | sed s/.x86_64$/.i686/`
    $ scl enable devtoolset-9 rh-git218 rh-java-common rh-maven35 bash
  5. Run the "Prerequisites for all platforms" tasks inside the shell.

After which the following command can be used to start the build inside the javacpp-presets directory or one of its subdirectories:

$ mvn clean install -Djavacpp.platform=linux-xxx

where linux-xxx is either linux-x86 or linux-x86_64.

Linux (ARM)

There are a growing number of arm platforms running Linux, though testing of this build has mainly focused on the Pi family of products. It's recommended to use the cross compiling approach, this is what happens automatically via GitHub Actions for every pull for testing, and for commits to provide up to date snapshots. If you just want the latest functionality, it's worth using these snapshot builds. However, it's possible to build natively on the target device too, both approaches are described here.

Cross compile

For an Ubuntu host, the following steps should work - but you may need to tune depending on your existing host setup, OS version, package conflicts etc. Alternatively you could build in a clean Docker container.

$ sudo dpkg --add-architecture i386
$ sudo apt-get update
$ sudo apt-get install python3 python2.7 python3-minimal python2.7-minimal libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 rpm libasound2-dev:armhf freeglut3-dev:armhf libgtk2.0-dev:armhf libusb-dev:armhf libusb-1.0-0-dev:armhf libffi-dev:armhf libbz2-dev:armhf zlib1g-dev:armhf libxcb1-dev:armhf
$ sudo apt-get install pkg-config ccache clang openjdk-8-jdk-headless ant maven python python3-pip swig git file wget unzip tar bzip2 gzip patch autoconf-archive autogen automake make cmake libtool bison flex perl nasm curl gfortran libasound2-dev freeglut3-dev libgtk2.0-dev libusb-dev zlib1g libffi-dev libbz2-dev zlib1g-dev
$ git -C ~/ clone https://github.com/raspberrypi/tools
$ export PATH=$PATH:~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin
$ git clone https://github.com/bytedeco/javacpp-presets.git
$ cd javacpp-presets
$ mvn install -Djavacpp.platform=linux-armhf -Djavacpp.platform.compiler=arm-linux-gnueabihf-g++

Note: The toolchains from https://github.com/raspberrypi/tools are deprecated. It is recommended to use the ones from Ubuntu instead.

Native compile

You can compile directly on the device as well, for the Pi series this can be very time consuming (OpenCV takes approx 2h on a Pi3, FFmpeg around 1h, etc). You'll also need to increase your swap size for packages such as OpenBLAS - which can be detrimental to the SD card.

Basic steps required here are:

$ sudo apt-get update
$ sudo apt-get install pkg-config ccache clang openjdk-8-jdk-headless ant maven python python3-pip swig git file wget unzip tar bzip2 gzip patch autoconf-archive autogen automake make cmake libtool bison flex perl nasm curl gfortran libasound2-dev freeglut3-dev libgtk2.0-dev libusb-dev zlib1g libffi-dev libbz2-dev zlib1g-dev
$ git clone https://github.com/bytedeco/javacpp-presets.git
$ cd javacpp-presets
$ mvn install -Djavacpp.platform=linux-armhf -Dmaven.javadoc.skip=true

Platform specifics

If you want to try alternative flags, you can modify in javacpp, ./src/main/resources/org/bytedeco/javacpp/properties/linux-armhf.properties and then in javacpp-presets any project cppbuild.sh file where you want to update too (e.g. ./opencv/cppbuild.sh linux-armhf section). For newer Pis on armv7 it does look like there are potential performance gains in armv7 and neon flags, and using a newer compiler rather than the bcm2708 build used here may further improve things (some earlier builds specific for armv7 did look faster). Also if you are using onboard picam devices, make sure you load the module with modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944 - this way if you test just using OpenCV or FFmpeg grabber you should get at least 30fps as a start point. The more computation you then do on each frame, the more this will drop.

Mac OS X (x86_64)

OS X Mavericks (10.9) is the first version of Mac OS X to support C++11 fully and properly, so to preserve your sanity, we do not recommend trying to build or use the JavaCPP Presets on any older versions of Mac OS X, but you will need at least Xcode 11 anyway for C++17 support and OpenMP.

Preparations

  1. Install Xcode and Homebrew.

  2. Ensure the command line tools for Xcode are installed:

    $ xcode-select --install
    $ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_*.pkg -target /
  3. Run the following commands to install CUDA, GCC, and the JDK, among other things that are not part of Xcode:

    $ brew install boost ccache cuda gcc java swig autoconf-archive automake bazel cmake libomp libtool libusb ant maven nasm xz pkg-config sdl2 gpg1 bison flex perl ragel binutils gradle gmp isl libmpc mpfr geoip pcre ssdeep yajl
  4. Run the "Prerequisites for all platforms" tasks inside the shell.

After which the following command can be used to start the build inside the javacpp-presets directory or one of its subdirectories:

$ mvn clean install -Djavacpp.platform=macosx-x86_64

Windows (x86 and x86_64)

Visual Studio Community 2013 is the first free version to have been bundled with support for C++11, OpenMP, the Windows SDK, and everything else from Microsoft, but we recommend installing version 2019 of Visual Studio since it is needed by some libraries, which consequently requires Windows 7. Still, to run the bash scripts and compile some things that the Microsoft C/C++ Compiler does not support, we need to install manually a few more things.

Preparations

  1. Install the Java SE Development Kit, Ant, Bazel, CMake, Maven, Ninja, MSYS2, Python 2.7, Python 3.x, Visual Studio Community, Windows SDK, and CUDA.

  2. Under an "MSYS2 Shell", run:

    $ pacman -S base-devel tar patch autoconf autoconf-archive automake libtool make git unzip zip p7zip pkg-config gnupg mingw-w64-x86_64-nasm mingw-w64-x86_64-toolchain mingw-w64-x86_64-libtool mingw-w64-x86_64-gcc mingw-w64-i686-gcc mingw-w64-x86_64-gcc-fortran mingw-w64-i686-gcc-fortran mingw-w64-x86_64-libwinpthread-git mingw-w64-i686-libwinpthread-git mingw-w64-x86_64-SDL2 mingw-w64-i686-SDL2 mingw-w64-x86_64-ragel
  3. From the "Visual Studio 2019" folder found inside the Start menu, open:

    • "x86 Native Tools Command Prompt for VS 2019" and run c:\msys64\mingw32.exe inside
    • "x64 Native Tools Command Prompt for VS 2019" and run c:\msys64\mingw64.exe inside
    • Making sure the MSYS2_PATH_TYPE=inherit line is not commented out in mingw64.ini or mingw32.ini.
  4. Run the "Prerequisites for all platforms" tasks inside the shell.

Afterwards the following command can be used to start the build inside the javacpp-presets directory or one of its subdirectories:

$ mvn clean install -Djavacpp.platform=windows-xxx

where windows-xxx is either windows-x86 or windows-x86_64. Run the builds for windows-x86 inside the "MINGW32" window, and the ones for windows-x86_64 in the "MINGW64" one.

∗ More detailed instructions available at Building-on-Windows#installation-recipe-for-visual-studiuo-2015-and-windows-10


Thank you very much for your interest in this project, and please feel free to post your questions on the mailing list and open new issues to communicate your suggestions or for additional help.