-
Notifications
You must be signed in to change notification settings - Fork 3
Building with CMake
- Table of Contents
- Motivation
- Build operations and variables
- Writing CMakeLists.txt for Jamoma subprojects
- Using Jamoma from external projects using CMake.
- Known problems & TODO
Make a reliable cross-platform build-system for Jamoma. The minimal CMake version required is 3.0.
Setup :
git clone https://github.com/Jamoma/Jamoma
# ...[clone Core, Implementations/Max & Implementations/PureData, switch everything to dev]...
mkdir build
cd build
Release build on OS X with full package :
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_JAMOMAMAX:Bool=True -DBUILD_JAMOMAPD:Bool=True ../Jamoma
make package -j16
Release build on Linux :
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_JAMOMAPD:Bool=True ../Jamoma
make package -j16
Release build on Win32 with full package :
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_JAMOMAMAX:Bool=True -G "Visual Studio 12 2013" ../Jamoma
msbuild PACKAGE.vcxproj /p:Configuration=Release /m
Release build on Win64 with full package :
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_JAMOMAMAX:Bool=True -G "Visual Studio 12 2013" -A x64 ../Jamoma
msbuild PACKAGE.vcxproj /p:Configuration=Release /m
CMake is not a build system per se, but more a meta-build system, in the sense that CMake's work is to generate platform-specific build scripts, in the format chosen by the user. One can for instance generate:
- Makefiles / Ninja (a faster(about 10% for Jamoma)
make
replacement by google) - XCode projects
- Visual Studio solutions
- Code::blocks, Eclipse and project files for other common IDEs
The basic syntax is :
cmake [options] ..path to a folder containing a CMakeLists.txt..
For Jamoma, there is a CMakeLists.txt
in the umbrella repository, and another in JamomaCore.
When built from umbrella, only JamomaCore will be built by default. You can enable other implentation build with switches.
CMake will then generate a build tree in the folder it is called from. It is good practice to make an out-of-source build (and for Jamoma it is critical since the Max package and some test files will be copied from the source folder to the build tree).
For instance :
git clone https://github.com/Jamoma/Jamoma
pushd Jamoma
git submodule update --init
git submodule foreach git checkout dev
git submodule foreach git pull
cd Implementations/PureData
git submodule update --init
popd
mkdir build
cd build
cmake ../Jamoma
Will generate a build tree in the build folder. The rest of this document will assume that the folder hierarchy is as follows :
base folder \
build
Jamoma \
Core, etc...
CMake operate with targets.
When there is a CMake command to add a library, a test, or an executable, CMake will generate targets. They will map to project files for the IDE generators, or simple make
targets.
For instance, there are specific targets for all the core libraries (Foundation, Modular, Graph, etc...) and all the extensions.
There are also some useful targets either automatically generated by CMake in every case or added for the Jamoma project.
For instance :
- `ExperimentalTest` to batch-run unit tests
- `code_coverage` to run code coverage on the unit tests (added by me).
- `ALL_BUILD` behaves like `make all`
- `CLEAN` behaves like `make clean`
- `INSTALL` behaves like `make install`
- `PACKAGE` creates a platform-specific package/installer (DMG on OS X, NSIS installer on Windows, Debian / RPM package on Linux...) with the things that are to be installed by `INSTALL`.
cmake -DCMAKE_BUILD_TYPE=Debug [...]
cmake -DCMAKE_BUILD_TYPE=Release [...]
cmake -DBUILD_JAMOMAMAX=ON [...]
cmake -DBUILD_JAMOMAPD=ON [...]
When developping for Max or Puredata it is often useful to keep the Max/Pd package the application uses up-to-date after each build.
You can use make package
then open the archive and manually copy the file to ~/Documents/Max*/Package
.
But this could be boring if you are building Jamoma several times a day.
Instead you can set the installation folder with -DJAMOMAPD_INSTALL_FOLDER=/absolute/path/to/Where/you/want
.
And then run cmake
on cmake_install.cmake
with the requiered component.
For instance, to install JamomaPd in the default user's package folder on OS X :
cmake -DBUILD_JAMOMAPD=ON -DJAMOMAPD_INSTALL_FOLDER=$HOME/Library/Pd ../Jamoma-CMake
make
cmake -DCMAKE_INSTALL_COMPONENT=JamomaPd -P cmake_install.cmake
Then to load Jamoma into PureData, add "Jamoma" to the library to load at startup. You can do that by launching Pd with pd -lib Jamoma
or by adding it in the Preferences->Startup panel or even by putting a [Jamoma]
object somewhere in your patch.
And to install Max package to the default user's package folder on OS X :
cmake -DBUILD_JAMOMAMAX=ON -DJAMOMAMAX_INSTALL_FOLDER=$HOME/Documents/Max/Package ../Jamoma-CMake
make
cmake -DCMAKE_INSTALL_COMPONENT=JamomaMax -P cmake_install.cmake
Thanks to the Max's extension mechanism, Jamoma will be automatically loaded at startup.
This requires gcovr, lcov, and a Debug build.
cmake -DCMAKE_BUILD_TYPE=Debug -DCODE_COVERAGE=True [...]
Generators are chosen with the -G command line switch.
cmake --help
will print all the available generators for the platform.
Calling CMake without generators generates Makefiles by default. To generate XCode projects :
cmake -G "XCode" ../Jamoma/
A Jamoma.xcodeproj
file is then generated in the current folder, that can be opened with XCode (however there are still problems with '~' and '=' in the name of externals, I have to check them out).
It is possible to build from the command line :
xcodebuild -target [The target, like ALL_BUILD or Foundation]
To generate XCode projects targeted for iOS : (still experimental, I only quickly tested this with the simulator and not everything builds. Also, it will only build JamomaCore.)
# iOS
cmake -G "Xcode" -DCMAKE_TOOLCHAIN_FILE=../Jamoma/Core/Shared/CMake/toolchains/iOS.cmake ../Jamoma/Core
# Simulator
cmake -G "Xcode" -DIOS_PLATFORM=SIMULATOR -DCMAKE_TOOLCHAIN_FILE=../Jamoma/Core/Shared/CMake/toolchains/iOS.cmake ../Jamoma/Core
To generate fat binaries (by default CMake only generates x64) :
cmake "-DCMAKE_OSX_ARCHITECTURES=x86_64;i386" ../Jamoma
This switch is automatically enabled when building JamomaMax.
To build tests statically linked : (this has to be reviewed, I haven't checked it since about two months)
cmake -DSTATIC_TESTING ../Jamoma
By default, CMake will look for an installed version of Visual Studio and generate solutions & projects for this version. To specify a version :
cmake -DCMAKE_BUILD_TYPE=[Debug or Release] -G "Visual Studio 12 2013" ../Jamoma/
cmake -DCMAKE_BUILD_TYPE=[Debug or Release] -G "Visual Studio 12 2013" -A x64 ../Jamoma/ # In progress
Jamoma has been tested with VS2013 but might work with VS2012.
This will generate a Jamoma.sln
in the current folder.
To build, either :
- Open the created VS solution and build from the IDE.
msbuild [ALL_BUILD/PACKAGE/...].vcxproj /p:Configuration=[Debug or Release, according to the configuration that was used for CMake] /m
cmake ../Jamoma
make -j[number of processors]
This requires the (heavy) Android SDK / NDK, and the Android toolchain file : https://github.com/taka-no-me/android-cmake/tree/experimental. But after that it's as straightforward as it is for Linux.
The easiest way to build Jamoma for Raspberry Pi from Ubuntu 64bit is to checkout the toolchain here : https://github.com/avilleret/tools/tree/Jamoma with :
git clone -b Jamoma https://github.com/avilleret/tools.git
It is based on the official Rapsberry Pi toolchain to which I added Jamoma dependencies.
Then configure the build with the following :
mkdir build
cd build
mkdir RPi-bin
cmake -DCMAKE_TOOLCHAIN_FILE=../Shared/CMake/toolchains/arm-linux-gnueabihf.cmake -DJAMOMAPD_INSTALL_FOLDER=${PWD}/RPi-bin -DCROSS_COMPILER_PATH=${PWD}/../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/ ..
make
make install
This will produce a Jamoma package in the build/RPi-bin
folder that you can copy to your Raspberry Pi's ~/pd-externals
folder.
You need a cutting edge version of the toolchain, at least the 4.0.2-4. Look at mingw-w64.org to find one for your OS.
Then configure your project with something like (for JamomaPuredata) :
cmake -DBUILD_JAMOMAPD=ON -DBUILD_JAMOMAMAX=OFF -DCMAKE_TOOLCHAIN_FILE=../PureData/Shared/CMake/toolchains/mingw-64.cmake -DJAMOMA_CORE_SRC_PATH=`realpath ${PWD}/../PureData/JamomaCore` -DPD_MAIN_PATH="$PWD/pd" -DCMAKE_INSTALL_PREFIX="$PWD/JamomaInstall" ../PureData/
Note that for building JamomaPuredata, you need Pd source and pass the path to the source with -DPD_MAIN_PATH="$PWD/pd"
option.
Of course you need to adjust all the paths to yours.
-> For a library (a simple one): https://github.com/jamoma/JamomaCore/blob/dev/Graph/library/CMakeLists.txt
-> For an extension : (showcases use of external libraries) https://github.com/jamoma/JamomaCore/blob/dev/DSP/extensions/AudioEngine/CMakeLists.txt
-> For a Max external : https://github.com/jamoma/JamomaMax/blob/dev/source/j.cue/CMakeLists.txt
A CMake configuration file for the Jamoma project is generated. This allows other apps that would like to use Jamoma to do things as straightforward as :
project (aProject)
find_package(Jamoma 0.6 REQUIRED) #Jamoma has to be installed somewhere.
add_executable(anExecutable "main.cpp")
target_link_libraries(anExecutable WIN32 MACOSX_BUNDLE Jamoma::Foundation Jamoma::Modular)
It is also possible to generate OS X .app bundles with the Jamoma libs & extensions correctly copied
# Make a copy at build time in the CMake-generated .app
copy_in_bundle_jamoma(anExecutable ${CMAKE_BINARY_DIR}/anExecutable.app "Foundation;Modular" "MIDI;Minuit;OSC;SystemLib")
# When installing, set the correct RPATHs in the executable, plug-ins and libraries.
fixup_bundle_jamoma(${CMAKE_INSTALL_PREFIX}/anExecutable.app anExecutable "Foundation;Modular")
This is in two steps because, basically, when building an app that involves both Qt and Jamoma, the official CMake Qt scripts will override the RPATHs in ways incompatible with Jamoma, hence we have to re-overwrite them afterwards.
- Run the Ruby tests from CMake.
- Maybe run the Max/MSP integrations tests too ?
- Check that the iOS build works correctly.
- Document the CMake code, and do a full check-up.
- Windows x64 build.
- Windows : copy MSVC100D.dll, PortAudio.dll, libsndfile.dll on the package.
- Use the FOLDER command to make nice folders in IDEs.
- Optimize the way things are linked together (for now some extensions may link with unneeded libraries, especially in JamomaMax world).
- Document the extensions that don't build on some platforms because of missing libraries (e.g. no portaudio at all on Android).