One command builds the C++ libraries your robotics project needs.
robotFarm is a CMake super build. You pick the libraries. It downloads their sources, builds them in dependency order, and installs everything into one prefix. Use it when the apt versions are too old, when you need CUDA builds, or when every machine on a team should carry the same stack.
π§ Linux only. Needs C, C++, Fortran, and CUDA (13 or newer) compilers. Tested on Ubuntu 22.04, 24.04, and 26.04. MIT license.
-
No lock-in: your project stays a plain
find_packageclient. Nothing robotFarm-specific enters your CMake:# Configure your project with -DCMAKE_PREFIX_PATH=/opt/robotFarm and use the libraries as usual. find_package(OpenCV REQUIRED) target_link_libraries(myApp PRIVATE opencv_core opencv_imgproc)
-
Hands-off: inter-library build order resolves automatically, and the system packages each library needs are computed for you.
-
Auditable: each library's version and feature flags live in one reviewable recipe under externalProjects/.
| Abseil | Boost | Cap'n Proto | Ceres Solver | Eigen | FlatBuffers |
| Google Gflags | Google Glog | Google Test | Nlohmann Json | Oat++ * | OGRE |
| OpenCV | Protocol Buffers | Python 3 | Spdlog | SuiteSparse β | VTK |
* oatpp also bundles oatpp-websocket.
β SuiteSparse bundles AMD, CAMD,
CCOLAMD, CHOLMOD, COLAMD, SPQR, and
SuiteSparse_config.
Exact versions and feature flags are pinned per recipe in
externalProjects/. One licensing-sensitive gate to know about: OpenCV's
contrib modules and CUDA features build only with
-DROBOT_FARM_OPENCV_WITH_NON_FREE_CONTRIB:BOOL=ON, which is off by default and off in the
release tarballs.
Three ways in, ordered by effort. Building everything from source takes tens of minutes; the first two options skip that.
A release is cut by tagging, and each release attaches one install archive per Ubuntu version and
CMake preset (gnu-shared, gnu-static, clang-shared, clang-static; pick
shared unless you know you need static). Download yours from the
releases page and extract it under /opt:
tar --zstd -C /opt -xf robotFarm-<os>-<preset>-sha-<commit>.tar.zstThe archive ships a systemDependencies.txt at its root. It lists the system packages the
libraries need at runtime. Install them:
sudo apt update && sudo apt install -y --no-install-recommends \
$(cat /opt/robotFarm/systemDependencies.txt)CI publishes a build-environment image per Ubuntu version. Compilers, every build dependency, and
a recent cmake are preinstalled; robotFarm itself is not:
ghcr.io/ajakhotia/robotfarm/ubuntu-22-04/base:latestghcr.io/ajakhotia/robotfarm/ubuntu-24-04/base:latestghcr.io/ajakhotia/robotfarm/ubuntu-26-04/base:latest
Replace latest with a sha-<commit> tag to pin a version. The recipe is
docker/ubuntu.dockerfile.
Build robotFarm inside a container and keep the install tree on the host:
git clone https://github.com/ajakhotia/robotFarm.git /tmp/robotFarm-src
git -C /tmp/robotFarm-src submodule update --init
mkdir -p /tmp/robotFarm-install
docker run --rm \
--volume /tmp/robotFarm-src:/src:ro \
--volume /tmp/robotFarm-install:/opt/robotFarm \
ghcr.io/ajakhotia/robotfarm/ubuntu-24-04/base:latest \
bash -c '
set -euo pipefail
cmake -G Ninja -S /src -B /tmp/build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/robotFarm
cmake --build /tmp/build
'Replace /tmp/robotFarm-install with any writable host path. Before using the install tree,
install the runtime packages on the host:
sudo apt update && sudo apt install -y --no-install-recommends \
$(cat /tmp/robotFarm-install/systemDependencies.txt)For CI, bake a derived image once: FROM the base image, then either run the same build in a
RUN layer or extract a release tarball into it. Jobs then start with the stack already in
place.
quickBuild.sh builds robotFarm directly on your machine. It clones the source, registers the apt sources, installs the dependencies, builds, installs, and cleans up after itself. Good for a build-once machine setup.
Warning
The commands below use sudo.
curl -fsSL \
https://raw.githubusercontent.com/ajakhotia/robotFarm/refs/heads/main/tools/quickBuild.sh | \
sudo bashVersion, toolchain, install prefix, and build list are overridable:
curl -fsSL \
https://raw.githubusercontent.com/ajakhotia/robotFarm/refs/heads/main/tools/quickBuild.sh | \
sudo bash -s -- \
--version v2.3.1 \
--toolchain linux-clang-22 \
--prefix /tmp/robotFarm \
--build-list "GlogExternalProject;GoogleTestExternalProject;FlatBuffersExternalProject"nioc is a real consumer; its README shows this in use.
The full manual path. Tested on Ubuntu 22.04, 24.04, and 26.04; docker/ubuntu.dockerfile is the working reference.
To pick a compiler, linkage, or a subset of libraries, read Build Customization first.
Pick three writable paths. The commands below refer to them through environment variables:
| Variable | Purpose | Example |
|---|---|---|
SOURCE_TREE |
Where robotFarm is cloned. Temporary is fine. | /tmp/robotFarm |
BUILD_TREE |
Where CMake builds. Temporary is fine. | /tmp/robotFarm-build |
INSTALL_TREE |
Where the libraries install. Keep this one. | ${HOME}/opt/robotFarm |
An install path that needs root (/opt, /usr) needs sudo on the Build step;
prefer a path your user can write.
export SOURCE_TREE=/tmp/robotFarm
export BUILD_TREE=/tmp/robotFarm-build
export INSTALL_TREE=${HOME}/opt/robotFarm
git clone https://github.com/ajakhotia/robotFarm.git ${SOURCE_TREE}
git -C ${SOURCE_TREE} submodule update --init
cd ${SOURCE_TREE}Mandatory: jq, a recent cmake (3.27 or newer, provided by the kitware apt source), and
the basic build tools:
sudo apt update && \
sudo apt install -y --no-install-recommends \
ca-certificates curl gnupg jq software-properties-common && \
sudo bash external/infraCommons/tools/apt/addAptSources.sh -y kitware && \
sudo apt update && \
sudo apt install -y --no-install-recommends \
$(sh external/infraCommons/tools/extractDependencies.sh Basics systemDependencies.json)Compilers: robotFarm needs C, C++, CUDA, and Fortran compilers. The C, C++, and Fortran
compilers must be reachable through their unversioned names (gcc, clang, gfortran); CUDA's
nvcc is handed to CMake by path in the Configure step. Install them any way
you like. One option is to register the gnu, llvm, and nvidia apt sources and install the
Compilers group:
sudo bash external/infraCommons/tools/apt/addAptSources.sh -y gnu llvm nvidia && \
sudo apt update && \
sudo apt install -y --no-install-recommends \
$(sh external/infraCommons/tools/extractDependencies.sh Compilers systemDependencies.json)The minimum supported CUDA Toolkit is 13. The packages above install versioned names only
(gcc-15, clang-22, and so on), so register them as the defaults for the unversioned names:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 100 \
--slave /usr/bin/g++ g++ /usr/bin/g++-15 \
--slave /usr/bin/gfortran gfortran /usr/bin/gfortran-15 && \
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-22 100 \
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-22 \
--slave /usr/bin/flang flang /usr/bin/flang-22The CUDA toolkit installs under /usr/local/cuda, outside the default search paths. No PATH
change is needed: the Configure step hands nvcc's location to CMake as a
cache entry, and every cache entry handed to the top-level configure forwards into each
library's own configure.
Warning
Do not symlink nvcc into /usr/bin, by hand or through update-alternatives. nvcc
locates its toolkit through the literal path it is invoked as, without resolving symlinks,
and CMake prefers an nvcc that sits next to the C++ compiler over the ones on PATH. Such
a symlink therefore breaks CUDA toolkit detection even when /usr/local/cuda/bin is on
PATH.
docker/ubuntu.dockerfile performs the same registration when baking the base images.
Three steps, one command each.
Creates the build tree and sets the install location. The default compilers on PATH, the ones
registered in Install tools, do the compiling. The CMAKE_CUDA_COMPILER
entry points at nvcc through the alternatives-managed /usr/local/cuda symlink, so a CUDA
upgrade needs no edit:
cmake -G Ninja -S ${SOURCE_TREE} -B ${BUILD_TREE} \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc \
-DCMAKE_CUDA_ARCHITECTURES=all-major \
-DCMAKE_INSTALL_PREFIX=${INSTALL_TREE}BUILD_SHARED_LIBS=ON selects shared libraries, the recommended and best-tested mode;
robotFarm defaults to static archives when the flag is omitted.
all-major compiles device code for every major GPU architecture the CUDA toolkit supports, so
the install tree runs on any of them. To shorten the build for a single known machine, replace
it with that GPU's architecture (nvidia-smi --query-gpu=compute_cap --format=csv,noheader,
dot removed, e.g. 120), or with native to let CMake detect the GPU present at build time.
To pin a compiler family or version explicitly instead, add
-DCMAKE_TOOLCHAIN_FILE=<path-to-toolchain-file> from
Pre-packaged toolchain files.
The configure writes the required system packages to ${BUILD_TREE}/systemDependencies.txt.
Install them:
sudo apt install -y --no-install-recommends $(cat ${BUILD_TREE}/systemDependencies.txt)Builds and installs every library into ${INSTALL_TREE}; no separate cmake --install is needed:
cmake --build ${BUILD_TREE}CMakePresets.json covers the compiler-family and linkage combinations CI
builds: clang-shared, clang-static, gnu-shared, and gnu-static. They use the unversioned
system compilers at /usr/bin/gcc and /usr/bin/clang, through the linux-gnu.cmake and
linux-clang.cmake toolchain files. If one matches your environment, it replaces the
Configure step:
cmake --preset gnu-shared -S ${SOURCE_TREE} -B ${BUILD_TREE} \
-DCMAKE_INSTALL_PREFIX=${INSTALL_TREE}If none matches, ignore them, or copy one into a gitignored CMakeUserPresets.json and edit it
there.
A toolchain file pins the compiler family and version explicitly, overriding the defaults
registered in Install tools. Ready-to-use files ship in the infraCommons
submodule at ${SOURCE_TREE}/external/infraCommons/cmake/toolchains/:
- linux-clang.cmake and linux-gnu.cmake: the default compilers on the system
- linux-clang-21.cmake, linux-clang-22.cmake
- linux-gnu-14.cmake, linux-gnu-15.cmake
Every file probes for CUDA and wires it in when present. The versioned files pin absolute
compiler paths (/usr/bin/gcc-15 and so on), and the configure fails if a pinned compiler is
not installed. Pass your pick as -DCMAKE_TOOLCHAIN_FILE in the
Configure step.
By default robotFarm builds every supported library. To build a subset, name the projects:
cmake -G Ninja -S ${SOURCE_TREE} -B ${BUILD_TREE} \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc \
-DCMAKE_CUDA_ARCHITECTURES=all-major \
-DCMAKE_INSTALL_PREFIX=${INSTALL_TREE} \
-DROBOT_FARM_REQUESTED_BUILD_LIST="Eigen3ExternalProject;OpenCVExternalProject"Dependencies of the requested projects build automatically. The allowed values are:
- AbseilExternalProject
- BoostExternalProject
- CapnprotoExternalProject
- CeresSolverExternalProject
- Eigen3ExternalProject
- FlatBuffersExternalProject
- GFlagsExternalProject
- GlogExternalProject
- GoogleTestExternalProject
- NlohmannJsonExternalProject
- OatppExternalProject
- OatppWebSocketExternalProject
- OgreExternalProject
- OpenCVExternalProject
- ProtobufExternalProject
- Python3ExternalProject
- SpdLogExternalProject
- SuiteSparseExternalProject
- VTKExternalProject
A consumer project owns the complete list of system packages it needs, including the packages
required to build its robotFarm subset; nothing is read from robotFarm's generated files when a
consumer builds its images. To derive a RobotFarmDependencies group for your project's
systemDependencies.json:
- Expand your requested build list to its transitive closure. Each recipe in
externalProjects/include()s the recipes it depends on, so follow those includes; for example,Eigen3ExternalProjectpulls inSuiteSparseExternalProject. - Union the groups named after each project in the closure from robotFarm's own
systemDependencies.json. A project without a group needs no system packages and contributes nothing.
The systemDependencies.txt that a configure emits is the same computation performed for the
configured build list, so it makes a convenient cross-check for a hand-derived group.
robotFarm uses the system Python 3 by default. To build Python 3 from source instead, pass
-DROBOT_FARM_SKIP_Python3ExternalProject:BOOL=OFF in the Configure step.
- Contrib modules and CUDA features are gated behind
-DROBOT_FARM_OPENCV_WITH_NON_FREE_CONTRIB:BOOL=ON(off by default): the CUDA features depend oncudevfrom contrib, and contrib carries non-free licensing that you must comply with. - CUDA codecs are absent from CUDA 10.0 and later, so the build turns off
cudacodec. - The full flag set is in externalProjects/OpenCVExternalProject.cmake; read it before assuming a feature is on.
MIT.