mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2025-10-29 19:32:24 +00:00
More build documentation.
parent
72f1aadab3
commit
64b1099cf4
23
Home.md
23
Home.md
@ -16,15 +16,18 @@ The Wiki is organized into three main sections:
|
||||
|
||||
## projectM user manuals
|
||||
|
||||
If you're using one of the "official" projectM applications maintained by this project, you can find documentation for
|
||||
those applications on the following pages. If you're unsure whether your application is actually affiliated with us,
|
||||
please check the [applications list](projectM-Applications) first. Only those listed as "provided by the projectM team"
|
||||
are covered here and can be supported by the maintainers. For all other applications, please refer to their respective
|
||||
project pages or contact their authors directly for support inquiries.
|
||||
If you're looking for manuals and information on one of the "official" projectM applications maintained by this project,
|
||||
you can find documentation for those applications in their respective repository wikis:
|
||||
|
||||
- [Standalone and Steam applications](User-Manual-(Standalone))
|
||||
- [EyeTune (Windows Store)](User-Manual-(EyeTune))
|
||||
- [Music.app Plug-In](User-Manual-(Music.app-PlugIn))
|
||||
- [SDL-based standalone and Steam applications](https://github.com/projectM-visualizer/frontend-sdl2/wiki)
|
||||
- [Qt-based standalone UI](https://github.com/projectM-visualizer/frontend-qt/wiki)
|
||||
- [EyeTune (Windows Store)](https://github.com/projectM-visualizer/frontend-uwp/wiki)
|
||||
- [Apple Music.app plug-in](https://github.com/projectM-visualizer/frontend-music-plug-in/wiki)
|
||||
|
||||
If you're unsure whether your application is actually affiliated with us, please check
|
||||
the [applications list](projectM-Applications) first. Only those listed as "provided by the projectM team" are covered
|
||||
here and can be supported by the maintainers. For all other applications, please refer to their respective project pages
|
||||
or contact their authors directly for support inquiries.
|
||||
|
||||
## Integrating projectM into applications
|
||||
|
||||
@ -35,7 +38,9 @@ Before starting, also make sure you have read the LGPL license and understood wh
|
||||
legally use and distribute projectM with your application.
|
||||
|
||||
- [Download and build projectM for application development](Building-libprojectM)
|
||||
- [Quickstart guide for integrating projectM into your application](Integration-Quickstart-Guide)
|
||||
- [projectM API reference](API-Reference)
|
||||
- [Build troubleshooting](Build-Troubleshooting)
|
||||
- [Licensing obligations](projectM-Licensing)
|
||||
|
||||
## Contributing to projectM
|
||||
@ -49,4 +54,4 @@ The pages below will help you get an overview of the projectM architecture, road
|
||||
- [Getting started with projectM development](Getting-started-with-projectM) - Read this first if you're new to projectM
|
||||
and/or OSS development in general.
|
||||
- [Architectural overview](projectM-Architecture)
|
||||
- [Coding and contribution guidelines](projectM-Developer-Guidelines)
|
||||
- [Coding and contribution guidelines](projectM-Developer-Guidelines)
|
||||
|
||||
@ -0,0 +1,586 @@
|
||||
# Building the projectM library
|
||||
|
||||
The following build instructions apply to the most recently released projectM sources.
|
||||
|
||||
### Important note on build tool changes in 4.0
|
||||
|
||||
Older projectM releases (up to 3.1.12, released in 2020) used autoconf/automake or native project files for building.
|
||||
This is no longer supported and all build files have been replaced with CMake build scripts that can be used on all
|
||||
platforms. If you need to build one of these old releases, please refer to the build instructions included in the
|
||||
top-level dir of the respective source release. This page is only valid for releases of lipbprojectM 4.0 or later.
|
||||
|
||||
For more detailed instructions and other operating systems, [skip below the Linux quick start guide](#dependencies).
|
||||
|
||||
## Quick Start for Linux (Debian / Ubuntu)
|
||||
|
||||
### Install the build tools and dependencies
|
||||
|
||||
Mandatory packages:
|
||||
|
||||
```bash
|
||||
sudo apt install build-essential cmake libgl1-mesa-dev mesa-common-dev libglm-dev
|
||||
```
|
||||
|
||||
Optional packages for additional features:
|
||||
|
||||
```bash
|
||||
sudo apt install libsdl2-dev # for building the integrated developer test UI
|
||||
sudo apt install llvm-dev # for using the experimental LLVM Jit
|
||||
sudo apt install ninja # To build projectM with Ninja instead of make
|
||||
```
|
||||
|
||||
### Download the projectM sources
|
||||
|
||||
If you want to use a stable version of projectM, download the latest release from
|
||||
the [Releases page on GitHub](https://github.com/projectM-visualizer/projectm/releases) and unpack it. You can then skip
|
||||
to the next step.
|
||||
|
||||
If you prefer a bleeding-edge version or want to modify the code, clone the Git repository:
|
||||
|
||||
```bash
|
||||
sudo apt install git # Probably already installed
|
||||
git clone https://github.com/projectM-visualizer/projectm.git /path/to/local/repo
|
||||
cd /path/to/local/repo
|
||||
git fetch --all --tags
|
||||
```
|
||||
|
||||
### Build and install projectM
|
||||
|
||||
Replace `/usr/local` with your preferred installation prefix.
|
||||
|
||||
#### Configure the project
|
||||
|
||||
```bash
|
||||
sudo apt install cmake
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..
|
||||
```
|
||||
|
||||
To generate Ninja scripts instead of Makefiles, add `-GNinja` to the above command.
|
||||
|
||||
#### Build and install
|
||||
|
||||
These commands will build projectM and install it to /usr/local or the configured installation prefix set in the step
|
||||
before:
|
||||
|
||||
```bash
|
||||
cmake --build . -- -j && sudo cmake --build . --target install
|
||||
```
|
||||
|
||||
**Note**: You won't need to use `sudo` if the install prefix is writeable by your non-privileged user.
|
||||
|
||||
#### Test projectM
|
||||
|
||||
You can't directly run libprojectM on its own. For development testing, the old pre-4.0 SDL UI is still available and
|
||||
can be enabled using `-DENABLE_SDL_UI=ON` via the CMake configuration command.
|
||||
|
||||
After building, you can run the SDL test UI directly from your build tree. It will not be installed alongside the
|
||||
library and headers. All end-user applications are available in separate repositories.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Depending on the OS/distribution and packaging system, libraries might be split into separate packages with binaries and
|
||||
development files. To build projectM, both binaries and development files need to be installed.
|
||||
|
||||
#### General build dependencies for all platforms:
|
||||
|
||||
* A working build toolchain.
|
||||
* [**CMake**](https://cmake.org/): Used to generate platform-specific build files.
|
||||
* **OpenGL**: 3D graphics library. Used to render the visualizations.
|
||||
* or **GLES3**: OpenGL libraries for embedded systems, version 3. Required to build projectM on Android devices,
|
||||
Raspberry Pi, Emscripten and the Universal Windows Platform.
|
||||
* [**glm**](https://github.com/g-truc/glm): OpenGL Mathematics library. Optional, will use a bundled version with
|
||||
autotools or if not installed.
|
||||
* [**SDL2**](https://github.com/libsdl-org/SDL): Simple Directmedia Layer. Version 2.0.5 or higher is required to build
|
||||
the test UI.
|
||||
* [**LLVM**](https://llvm.org/): Low-Level Virtual Machine. Optional and **experimental**, used to speed up preset
|
||||
execution by leveraging the LLVM JIT compiler.
|
||||
|
||||
### Only relevant for Windows:
|
||||
|
||||
* [**vcpkg**](https://github.com/microsoft/vcpkg): C++ Library Manager for Windows. _Optional_, but recommended to
|
||||
install the aforementioned library dependencies.
|
||||
* [**GLEW**](http://glew.sourceforge.net/): The OpenGL Extension Wrangler Library. Only required if using CMake to
|
||||
configure the build, the pre-created solutions use a bundled copy of GLEW.
|
||||
|
||||
NuGet is no longer supported.
|
||||
|
||||
## Building on Linux and macOS
|
||||
|
||||
### Installing dependencies
|
||||
|
||||
- Linux distributions will have packages available for most (if not all) required libraries. The package names and
|
||||
commands to install them vary widely between distributions (and even versions of the same distribution). Please refer
|
||||
to the documentation of your build OS on how to find and install the required libraries.
|
||||
- On *BSD, install the appropriate Ports with `pkg install`.
|
||||
- On macOS, using [Homebrew](https://brew.sh/) is the recommended way of installing any dependencies not supplied by
|
||||
Xcode.
|
||||
|
||||
### Building with CMake
|
||||
|
||||
---
|
||||
|
||||
:exclamation: **IMPORTANT NOTE**: Currently, CMake build support is still in active development and considered
|
||||
unfinished. It is working and produces running binaries, but there are still some features, build internals and whole
|
||||
targets missing. While testing the CMake build files on any platform and feedback on this is strongly encouraged,
|
||||
CMake-based builds should not yet be used in any production environment until this message is gone.
|
||||
|
||||
---
|
||||
|
||||
The steps documented below are a bare minimum quickstart guide on how to build and install the project. If you want to
|
||||
configure the build to your needs, require more in-depth information about the build process and available tweaks, or on
|
||||
how to use libprojectM in your own CMake-based projects, see [BUILDING-cmake.md](BUILDING-cmake.md).
|
||||
|
||||
Using CMake is the recommended and future-proof way of building projectM. CMake is a platform-independent tool that is
|
||||
able to generate files for multiple build systems and toolsets while using only a single set of build instructions.
|
||||
CMake support is still new and in development, but will replace the other project files (automake/autoconf scripts,
|
||||
Visual Studio solutions and Xcode projects) in this repository once mature and stable.
|
||||
|
||||
Building the project with CMake requires two steps:
|
||||
|
||||
- Configure the build and generate project files.
|
||||
- Build and install the project using the selected build tools.
|
||||
|
||||
**Note:** When building with CMake, the build directory should always be separate from the source directory. Generating
|
||||
the build files directly inside the source tree is possible, but strongly discouraged. Using a subdirectory,
|
||||
e.g. `cmake-build` inside the source directory is fine though.
|
||||
|
||||
This documentation only covers project-specific information. CMake is way too versatile and feature-rich to cover any
|
||||
possible platform- and toolset-specific configuration details here. If you are not experienced in using CMake, please
|
||||
first read the [official CMake documentation](https://cmake.org/cmake/help/latest/) (at least
|
||||
the [User Interaction Guide](https://cmake.org/cmake/help/latest/guide/user-interaction/index.html)) for basic usage
|
||||
instructions.
|
||||
|
||||
#### Configure the build
|
||||
|
||||
Configuring a non-debug build with default options and install prefix (`/usr/local`) can be done with these commands,
|
||||
building in a subdirectory inside the source directory:
|
||||
|
||||
```shell
|
||||
cd /path/to/source
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
```
|
||||
|
||||
CMake will check all required dependencies and display any errors. If configuration was successful, a summary of the
|
||||
build configuration is printed and CMake should display a `Generating done` line. The project is now ready to build.
|
||||
|
||||
#### Compile and install the project
|
||||
|
||||
Depending on your generator choice, you can use your selected toolset as usual to build and install projectM:
|
||||
|
||||
- With `Unix Makefiles`, run `make && sudo make install`.
|
||||
- With `Ninja`, run `ninja && sudo ninja install`.
|
||||
- With `Xcode`, select the appropriate target and configuration in Xcode and build it, or `INSTALL` to install the
|
||||
project.
|
||||
|
||||
You can also use CMake's build mode to run the selected toolset and build any specified target. CMake knows which
|
||||
command to call and which parameters to pass, so the syntax works on all platforms with all generators. If you've
|
||||
already set the top-level build directory as working directory, simply pass `.` as `/path/to/build/dir`:
|
||||
|
||||
```shell
|
||||
cmake --build /path/to/build/dir --config Release
|
||||
sudo cmake --build /path/to/build/dir --config Release --target install
|
||||
```
|
||||
|
||||
If you don't need root permissions to install running the second command without `sudo` is sufficient.
|
||||
|
||||
If you want to provide arguments directly to the toolset command, add `--` at the end of the CMake command line followed
|
||||
by any additional arguments. CMake will pass these *unchanged and unchecked* to the subcommand:
|
||||
|
||||
```shell
|
||||
cmake --build /path/to/build/dir --config Release -- -j 4
|
||||
```
|
||||
|
||||
## Building on Windows
|
||||
|
||||
To build the projectM library and the SDL-based standalone application, CMake must be used to create the project files
|
||||
first. Using vcpkg to pull in the build dependencies is highly recommended, as CMake can't use NuGet (NuGet pulls in
|
||||
dependencies using the project files, while CMake requires the libraries before creating the project files).
|
||||
|
||||
#### Installing the dependencies with vcpkg
|
||||
|
||||
As stated above, using vcpkg is the easiest way to get the required dependencies. First,
|
||||
install [vcpkg from GitHub](https://github.com/microsoft/vcpkg) by following the official guide. Then install the
|
||||
following packages for your desired architecture (called "triplet"):
|
||||
|
||||
- `glew`
|
||||
- `sdl2`
|
||||
|
||||
The `glew` package will also pull in the `opengl` libraries.
|
||||
|
||||
Example to install the libraries for the x64 architecture, run from a Visual Studio command prompt:
|
||||
|
||||
```commandline
|
||||
vcpkg install glew:x64-windows sdl2:x64-windows
|
||||
```
|
||||
|
||||
#### Creating the Visual Studio solution
|
||||
|
||||
CMake provides separate generators for different Visual Studio versions. Newer CMake versions will support recent Visual
|
||||
Studio releases, but may remove generators for older ones. To get a list of available generators from the command line,
|
||||
use the `-G` switch without an argument. The CMake GUI will present you a dropdown list you can easily select from.
|
||||
|
||||
To set the build architecture in Visual Studio builds, use the `-A` switch and specify either `Win32` or `X64` as the
|
||||
argument. If you want to build for both architectures, create separate build directories and configure them accordingly.
|
||||
|
||||
To make CMake aware of the installed vcpkg packages, simply use the provided toolchain file when configuring the
|
||||
projectM build by
|
||||
pointing [`CMAKE_TOOLCHAIN_FILE`](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html) to it.
|
||||
|
||||
Here is a full command line example to create a Visual Studio 2019 solution for X64:
|
||||
|
||||
```commandline
|
||||
cmake -G "Visual Studio 16 2019" -A "X64" -DCMAKE_TOOLCHAIN_FILE="<path to vcpkg>/scripts/buildsystems/vcpkg.cmake" -S "<path to source dir>" -B "<path to build dir>"
|
||||
```
|
||||
|
||||
If you use the CMake GUI, check the "Specify toolchain file for cross-compiling" option in the first page of the
|
||||
configuration assistant, then select the above `vcpkg.cmake` file on the second page.
|
||||
|
||||
Another option is to open the project folder in a recent Visual Studio version as a CMake project and configure CMake
|
||||
using Visual Studio's JSON-based settings file.
|
||||
|
||||
#### Building the solution
|
||||
|
||||
To build the project, open the generated solution in Visual Studio and build it like any other solution. Each time the
|
||||
CMake files are changed, Visual Studio will automatically regenerate the CMake build files and reload the solution
|
||||
before continuing the build. Be aware that in old Visual Studio versions (2015 and earlier) the reload-and-continue
|
||||
might not work properly.
|
||||
|
||||
You can also build the solution with msbuild via the command line, or use CMake's build wrapper to do that for you:
|
||||
|
||||
```commandline
|
||||
cmake --build "<path to build dir>" --config Release
|
||||
```
|
||||
|
||||
#### Using Ninja to build
|
||||
|
||||
The Ninja build system is shipped with Visual Studio since version 2019 and used by default if loading a CMake project
|
||||
directly from within the IDE. Ninja can also be [installed separately](https://github.com/ninja-build/ninja/releases).
|
||||
|
||||
To configure the build directory for Ninja, pass `Ninja` or `Ninja Multi-Config` as the argument for the `-G` switch.
|
||||
The difference between both generators is that the former uses `CMAKE_BUILD_TYPE` to specify the configuration (
|
||||
e.g. `Debug` or `Release`) while the latter supports all configurations in a single build directory, specified during
|
||||
build time.
|
||||
|
||||
The architecture is determined from the toolset, so make sure to run the commands in the correct Visual Studio command
|
||||
prompt, e.g. "Native Tools for X64".
|
||||
|
||||
Configure and build for a single-configuration Release build with vcpkg:
|
||||
|
||||
```commandline
|
||||
cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="<path to vcpkg>/scripts/buildsystems/vcpkg.cmake" -S "<path to source dir>" -B "<path to build dir>"
|
||||
cmake --build "<path to build dir>"
|
||||
```
|
||||
|
||||
Same, but using the multi-configuration generator:
|
||||
|
||||
```commandline
|
||||
cmake -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE="<path to vcpkg>/scripts/buildsystems/vcpkg.cmake" -S "<path to source dir>" -B "<path to build dir>"
|
||||
cmake --build "<path to build dir>" --config Release
|
||||
```
|
||||
|
||||
## Notes on other platforms and features
|
||||
|
||||
### Raspberry Pi (and other embedded systems)
|
||||
|
||||
* projectM is arch-independent, although there are some SSE2 enhancements for x86
|
||||
* [Notes on running on raspberry pi](https://github.com/projectM-visualizer/projectm/issues/115)
|
||||
|
||||
### Build using NDK for Android
|
||||
|
||||
To build projectM using the Android SDK, please refer to the official NDK docs:
|
||||
|
||||
> https://developer.android.com/ndk/guides/cmake
|
||||
|
||||
It is highly recommended using the latest NDK and CMake >= 3.21 for building.
|
||||
|
||||
### LLVM JIT
|
||||
|
||||
There are some optimizations for parsing preset equations that leverage the LLVM JIT. You can try adding the CMake
|
||||
option `-DENABLE_LLVM=ON` to enable them. They may not work with a newer version of
|
||||
LLVM (https://github.com/projectM-visualizer/projectm/pull/360).
|
||||
|
||||
### Presets and textures
|
||||
|
||||
The libprojectM repository does no longer contain any additional assets like presets and textures. These have been
|
||||
outsourced into [separate repositories](https://github.com/projectM-visualizer?q=presets-) to make it easier to select
|
||||
certain preset packs to be packaged in applications and to reduce the size and scope of the libprojectM repository.
|
||||
|
||||
# Detailed CMake reference
|
||||
|
||||
If you require more in-depth information about the CMake build scripts, you will find more information below.
|
||||
|
||||
## Selecting a specific project file generator
|
||||
|
||||
To specify a CMake generator, use the `-G` switch, followed by the generator name. Some newer generators take an
|
||||
additional architecture using the `-A` switch. To list all available generators available on your current platform,
|
||||
leave out the generator name:
|
||||
|
||||
```shell
|
||||
cmake -G
|
||||
```
|
||||
|
||||
Additional information on the supported generators can be
|
||||
found [in the CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).
|
||||
|
||||
### Popular generators
|
||||
|
||||
By default, CMake will use the [`Unix Makefiles`](https://cmake.org/cmake/help/latest/generator/Unix%20Makefiles.html)
|
||||
generator on Linux and macOS, which is a good choice and should work. Yet in some circumstances, you might want to
|
||||
generate project files for a specific build tool or IDE:
|
||||
|
||||
```shell
|
||||
cmake -G "Unix Makefiles" -S /path/to/source/dir -B /path/to/build/dir
|
||||
```
|
||||
|
||||
A common alternative is the [`Ninja`](https://cmake.org/cmake/help/latest/generator/Ninja.html) generator, which
|
||||
requires `ninja` to be installed. It is mostly a `make`
|
||||
replacement with less overhead and should work equally well. It is supported on all major platforms, including Windows:
|
||||
|
||||
```shell
|
||||
cmake -G Ninja -S /path/to/source/dir -B /path/to/build/dir
|
||||
```
|
||||
|
||||
On macOS, CMake also supports the [`Xcode`](https://cmake.org/cmake/help/latest/generator/Xcode.html) generator. It will
|
||||
create an `.xcodeproj` bundle which you can open in Xcode. It also adds support for automatic code signing, which might
|
||||
be required if your application using projectM needs to be notarized for store deployment.
|
||||
|
||||
```shell
|
||||
cmake -G Xcode -S /path/to/source/dir -B /path/to/build/dir
|
||||
```
|
||||
|
||||
If you develop on Windows, you will possibly use Visual Studio. While recent visual Studio versions have CMake support
|
||||
built-in, you can still pre-generate the solution and project files and open the `.sln` file from the build directory.
|
||||
CMake provides a separate generator for each Visual Studio release. For Visual Studio 2019 you would use
|
||||
the [`Visual Studio 16 2019`](https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2016%202019.html) generator
|
||||
and provide an additional architecture parameter:
|
||||
|
||||
```shell
|
||||
cmake -G "Visual Studio 16 2019" -A "X64" -S /path/to/source/dir -B /path/to/build/dir
|
||||
```
|
||||
|
||||
It is not possible to generate multi-arch solutions with CMake though. You need to create separate build directories and
|
||||
use the respective `-A` switch for each.
|
||||
|
||||
## Project-specific configuration options
|
||||
|
||||
CMake has no built-in way of printing all available configuration options. You can either refer to the
|
||||
top-level `CMakeLists.txt` which contains a block of `option` and `cmake_dependent_option` commands, or use one of the
|
||||
available CMake UIs which will display the options after configuring the project once.
|
||||
|
||||
### Boolean switches
|
||||
|
||||
The following table also gives you an overview of the available options and their defaults. All options accept a boolean
|
||||
value (`YES`/`NO`, `TRUE`/`FALSE`, `ON`/`OFF` or `1`/`0`) and can be provided on the configuration-phase command line
|
||||
using the `-D` switch.
|
||||
|
||||
| CMake option | Default | Required dependencies | Description |
|
||||
|-------------------------|---------|-----------------------|--------------------------------------------------------------------------------------------------|
|
||||
| `ENABLE_DEBUG_PREFIX` | `ON` | | Adds `d` to the name of any binary file in debug builds. |
|
||||
| `ENABLE_EMSCRIPTEN` | `OFF` | `GLES`, `Emscripten` | Build for the web using Emscripten. Automatically enabled when using the Emscripten build tools. |
|
||||
| `ENABLE_SDL_UI` | `OFF` | `SDL2` | Builds and installs the SDL test UI. Also required for the tests. |
|
||||
| `ENABLE_GLES` | `OFF` | `GLES` | Use OpenGL ES 3 profile for rendering instead of the Core profile. |
|
||||
| `ENABLE_THREADING` | `ON` | `pthreads` | Enable multithreading support. If enabled, will cause an error if pthreads are not available. |
|
||||
| `ENABLE_NATIVE_PRESETS` | `OFF` | | Builds and installs the binary (native) preset libraries. |
|
||||
| `ENABLE_TESTING` | `OFF` | `SDL2` | Builds the unit tests. |
|
||||
| `ENABLE_LLVM` | `OFF` | `LLVM` | Enables experimental LLVM JIT support. |
|
||||
|
||||
### Path options
|
||||
|
||||
There are also a few textual parameters that can be used to fine-tune the installation directories. Relative paths in
|
||||
the following options are appended to the value
|
||||
of [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html) (which, on most UNIX
|
||||
platforms, defaults to `/usr/local`):
|
||||
|
||||
| CMake option | Default | Description |
|
||||
|-------------------------|------------------|------------------------------------------------------------------------|
|
||||
| `PROJECTM_BIN_DIR` | `bin` | Directory where executables (e.g. the unit tests) are installed. |
|
||||
| `PROJECTM_LIB_DIR` | `lib` | Directory where libprojectM is installed. |
|
||||
| `PROJECTM_INCLUDE_DIR` | `include` | Directory where the libprojectM include files will be installed under. |
|
||||
|
||||
## Always perform out-of-tree builds!
|
||||
|
||||
Most classic IDEs and build systems directly make use of the source tree and create project files, temporary build
|
||||
artifacts (e.g. object files) and the final binaries in the same directory structure as the source files. An advantage
|
||||
of this approach is that you can find all compiled binaries side-by-side with their sources and generated headers are
|
||||
already in the same directories as the source files including them. This approach has some drawbacks though:
|
||||
|
||||
- Only a single build configuration is supported as files are overwritten in-place.
|
||||
- A lot of noise is created in the source directory, making it hard to distinguish between generated and original source
|
||||
files.
|
||||
- A very large `.gitignore` file is required to cover all unwanted files.
|
||||
- Mistakes in the build scripts can overwrite source files, causing errors and destroy uncommitted work.
|
||||
|
||||
Some of these can be mitigated by providing additional targets (`make clean` and `make distclean`) or creating
|
||||
subdirectories for Debug/Release build configurations.
|
||||
|
||||
While CMake also supports in-tree builds, it is "discouraged" in the official documentation, for the above reasons.
|
||||
Building out-of-tree allows it to create multiple build directories with different configurations which do not influence
|
||||
each other in any way. If a build directory contains unwanted artifacts, and you want to start fresh, simply delete and
|
||||
recreate the whole directory - no work is lost.
|
||||
|
||||
This project follow this principle by treating the original source tree as read-only and avoiding potential conflicts:
|
||||
|
||||
- Everything under [`CMAKE_SOURCE_DIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_SOURCE_DIR.html) must only be
|
||||
read, never changed or written to.
|
||||
- Everything under [`CMAKE_BINARY_DIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html) is temporary
|
||||
and related to the current build configuration.
|
||||
- When generating configuration-dependent files,
|
||||
use [`CMAKE_CONFIGURATION_TYPES`](https://cmake.org/cmake/help/latest/variable/CMAKE_CONFIGURATION_TYPES.html)
|
||||
and [`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) to create non-conflicting
|
||||
files in the build tree.
|
||||
|
||||
While this project will not force you to build out-of-tree, there is no mechanism to clean up the generated files after
|
||||
running cmake in-tree.
|
||||
|
||||
## CMake build directory layout
|
||||
|
||||
If you are new to CMake, the way of how CMake creates the build directory and where it creates the build targets might
|
||||
be confusing. Here is a summary of what's in the build directory and how it is structured in general.
|
||||
|
||||
### Using files from the build tree
|
||||
|
||||
It is generally not good practice to directly take binaries and other files from the build tree for packaging, for
|
||||
several reasons:
|
||||
|
||||
1. The directory structure is generated by CMake and depends on the generator used. The layout might change between
|
||||
CMake versions, even for the same generator.
|
||||
2. On platforms with RPATH support, CMake will store absolute paths in executables and shared libraries which point to
|
||||
the absolute paths of any linked dependencies, either from the build tree or external libraries as well. These
|
||||
binaries are not relocatable and will most certainly not work if run on any other computer (or even on the same after
|
||||
deleting the build directory).
|
||||
3. For some configurations, even Release build artifacts may contain debug symbols until they are installed.
|
||||
|
||||
It is fine to build and run executables from the build directory for development and debugging. For packaging, always
|
||||
use the `install` target and copy files from there.
|
||||
|
||||
### Generated files
|
||||
|
||||
In the top-level build directory, CMake creates a few files that are present on any platform:
|
||||
|
||||
- `CMakeCache.txt`: This file contains all variables and build settings CMake needs to remember from the first
|
||||
configuration run. This file can be edited on demand either manually or using a CMake UI to change any values. On the
|
||||
next build, CMake will regenerate the project files if this file has been modified.
|
||||
- `cmake_install.cmake`: Contains generated install-related settings.
|
||||
- `install_manifest.txt`: After installing the project, this file contains a list with absolute filenames of all
|
||||
installed files. It can be used for packaging or deleting installed files as CMake doesn't define an `uninstall`
|
||||
target.
|
||||
- The top-level project file for use with the selected build toolset, e.g. `Makefile`, `build.ninja`, `projectm.sln`
|
||||
or `projectm.xcodeproj`, plus additional toolset-specific files.
|
||||
|
||||
The projectM build files generate additional files used in the build and install phases:
|
||||
|
||||
- `config.inp`: The default configuration file, by default installed to `<prefix>/share/projectM`.
|
||||
- `libprojectM.pc`: Package configuration file for use with `pkgconfig`.
|
||||
- `include/config.h`: A forced include file that contains macro definitions to enable or disable certain code features
|
||||
based on the build configuration and availability of platform headers and features. Similar to the
|
||||
autoheader-generated file.
|
||||
|
||||
### Subdirectory structure
|
||||
|
||||
The rest of the directory structure generally resembles the source tree. Source directories containing
|
||||
a `CMakeLists.txt` file will also be created in the build tree with the same relative path. Each of these subdirectories
|
||||
contains a `CMakeFiles` directory with CMake-internal data, generated project files for the select toolset, e.g.
|
||||
makefiles and any temporary compile artifacts.
|
||||
|
||||
### Executable and library locations
|
||||
|
||||
Build targets - shared/static libraries and executables - are created in the same subdirectory in the build tree as
|
||||
the `CMakeLists.txt` file that defines the target in the source tree (which, in most cases, resides in the same
|
||||
directory as the source files). Depending on the generator used, the binaries are created directly in the directory for
|
||||
single-configuration generators (like `Unix Makefiles` or `Ninja`) and in a subdirectory with the configuration name,
|
||||
e.g. `Debug` or `Release`, for multi-configuration generators like `Xcode` or `Visual Studio 16 2019`.
|
||||
|
||||
You may also find additional files and symbolic links in the same location depending on the platform, e.g. `.pdb` files
|
||||
on Windows.
|
||||
|
||||
## Using libprojectM in other CMake projects
|
||||
|
||||
See also: [Integration quickstart guide](Integration-Quickstart-Guide)
|
||||
|
||||
The built and installed static or shared projectM library can be used in other CMake-based projects to provide embedded
|
||||
audio visualization using `find_package(libprojectM)`. There are also two additional ways:
|
||||
|
||||
- Importing the library CMake targets directly from the build tree without installation.
|
||||
- Directly adding/compiling the libprojectM source tree into the embedding application.
|
||||
|
||||
The latter approach is not recommended for different technical reasons and should generally be avoided.
|
||||
|
||||
### Importing libprojectM targets from the build tree
|
||||
|
||||
This approach is useful for projects that either require more in-depth access to the projectM library files, especially
|
||||
to headers that are not installed as part of the public API. This might cause issues if the internal headers change, but
|
||||
gives a broader set of features and more control to the developer.
|
||||
|
||||
To use the targets, follow these steps:
|
||||
|
||||
- Configure the build directory as needed.
|
||||
- Build the required library targets `projectM_static` and `projectM_shared` as needed, or simply everything.
|
||||
- Include the file `src/libprojectM/projectM-exports.cmake` from the projectM build tree in your project.
|
||||
|
||||
All targets and their interface properties are now defined and can be used.
|
||||
|
||||
#### Example
|
||||
|
||||
```cmake
|
||||
# libprojectM.a/.lib is already built.
|
||||
set(PROJECTM_BUILD_DIR "/some/path/to/projectM/build")
|
||||
include("${PROJECTM_BUILD_DIR}/src/libprojectM/projectM-exports.cmake")
|
||||
|
||||
add_executable(MyApp main.cpp)
|
||||
|
||||
target_link_libraries(MyApp PRIVATE libprojectM::static)
|
||||
```
|
||||
|
||||
This will also add all projectM include directories to the target's source files, pointing to the respective projectM
|
||||
source directories.
|
||||
|
||||
Look at the generated file in the build tree if you need more details about the available targets.
|
||||
|
||||
### Importing libprojectM targets from an installed version
|
||||
|
||||
This is the recommended way of importing libprojectM in your project. This project installs a set of CMake files
|
||||
in `<PREFIX>/<LIBDIR>/cmake/libprojectM`, containing target definitions, version and dependency checks as well as any
|
||||
additional libraries required for linking. Other projects then use CMake's `find_package` command to search for these
|
||||
files in [different locations](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure).
|
||||
|
||||
In the case projectM libraries and headers are not installed in any system search path, you need to add either the
|
||||
install prefix path (the top-level install dir) or the directory containing the libraries (the `lib` dir by default) to
|
||||
the [`CMAKE_PREFIX_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html) list.
|
||||
|
||||
If the package was found, you can then link against one of these provided targets:
|
||||
|
||||
- `libprojectM::static` - The static library (`.a` or `.lib`).
|
||||
- `libprojectM::shared` - The shared library (`.so`, `.dylib` or `.dll`).
|
||||
|
||||
Note that the availability of the targets depend on the platform and build configuration, so only one of those might be
|
||||
available. You can check with `if(TARGET libprojectM::static)` and `if(TARGET libprojectM::shared)` to select the
|
||||
available or preferred one.
|
||||
|
||||
Depending on how the package was built, targets might be available for multiple configurations or only `Release`. CMake
|
||||
will automatically select the most appropriate one to link.
|
||||
|
||||
Include dirs, additional link dependencies and possible compiler options will be propagated to any target the library is
|
||||
linked to.
|
||||
|
||||
#### Example
|
||||
|
||||
Links the shared library preferably, with fallback to static:
|
||||
|
||||
```cmake
|
||||
find_package(libprojectM REQUIRED)
|
||||
|
||||
if (TARGET libprojectM::shared)
|
||||
set(PROJECTM_LINK_TARGET libprojectM::shared)
|
||||
else ()
|
||||
# If this target is also unavailable, CMake will error out on target_link_libraries().
|
||||
set(PROJECTM_LINK_TARGET libprojectM::static)
|
||||
endif ()
|
||||
|
||||
add_executable(MyApp main.cpp)
|
||||
|
||||
target_link_libraries(MyApp PRIVATE ${PROJECTM_LINK_TARGET})
|
||||
```
|
||||
259
application-developers/Integration-Quickstart-Guide.md
Normal file
259
application-developers/Integration-Quickstart-Guide.md
Normal file
@ -0,0 +1,259 @@
|
||||
# Integration Quickstart Guide
|
||||
|
||||
projectM is released as either a shared or static library and provides a C-based API for all exposed functionality. This
|
||||
means that developers can use projectM in any application or with any programming language that supports calling native
|
||||
C functions and provide a proper OpenGL rendering context, including the platform-specific drawing surface.
|
||||
|
||||
The quickstart guide explains how to get started with projectM in a C/C++ application. If you need to use it in other
|
||||
languages, the best approach would be writing a small C-to-your-language layer, which will be very similar to using it
|
||||
directly in a C application. Since there are many different programming languages out there, we cannot cover them all
|
||||
|
||||
No operating system specific details like creating an OpenGL context are handled in this guide. libprojectM and its API
|
||||
are generally platform-agnostic and require the application to provide the rendering environment.
|
||||
|
||||
## Adding libprojectM to your application
|
||||
|
||||
The recommended way to integrate projectM into your application is by building libprojectM as a static or shared library
|
||||
and use the public C API (by including `projectM.h`) to instantiate and control it. This is the recommended way to use
|
||||
projectM. While the exposed functionality is limited to the public API libprojectM provides, you can easily update to
|
||||
recent releases without effort. If libprojectM is linked as a shared library, updating is as easy as replacing the
|
||||
library file - you don't even need to recompile your application.
|
||||
|
||||
If you need more control over projectM's internals, for example if you're building an advanced preset editor for which
|
||||
you require access to projectM's internal parser or rendering code, you can also directly integrate the source files
|
||||
into your application. Be aware that this comes with a more involved process of updating to newer libprojectM releases.
|
||||
|
||||
Also be aware that either statically linking libprojectM or directly including the sources into your codebase _requires_
|
||||
your application to be released under the GPL or LGPL licenses.
|
||||
|
||||
This integration guide will only cover integration via the official C API and linking the static or shared library.
|
||||
|
||||
### Build the library
|
||||
|
||||
First, [download and build libprojectM](Building-libprojectM) and install the build results in a location where you can
|
||||
access them easily.
|
||||
|
||||
### Add the libraries and include dirs
|
||||
|
||||
#### Using CMake
|
||||
|
||||
The recommended way to use libprojectM is by using CMake to build your application. In your CMakeLists.txt, you need to
|
||||
find the libprojectM package and then link the correct library target to your executable or library:
|
||||
|
||||
```cmake
|
||||
# After the project() command.
|
||||
# In the case projectM is optional in your build, leave out the REQUIRED.
|
||||
# If you need a specific libprojectM version, you can specify it after the package name,
|
||||
find_package(libprojectM REQUIRED)
|
||||
|
||||
add_executable(MyApp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
# Replace libprojectM::shared with libprojectM::static to link against the static library instead
|
||||
target_link_libraries(MyApp
|
||||
PRIVATE
|
||||
libprojectM::shared
|
||||
)
|
||||
```
|
||||
|
||||
That's all. If CMake finds libprojectM, it'll link the correct library and also add any required include dirs and
|
||||
compiler flags to your application's build configuration. To have CMake find your copy of libprojectM, you might need to
|
||||
add it via `CMAKE_PREFIX_PATH`:
|
||||
|
||||
```shell
|
||||
cmake -S /path/to/source \
|
||||
-B /path/to/build \
|
||||
-GNinja \
|
||||
-DCMAKE_PREFIX_PATH=/path/to/libprojectM
|
||||
```
|
||||
|
||||
If libprojectM is installed in a standard path your toolchain is configured to look into, you won't need it.
|
||||
|
||||
#### Using a different build system
|
||||
|
||||
If you can't or don't want to use CMake, you need to gather the library and include dirs on your own and add them
|
||||
manually to your project configuration.
|
||||
|
||||
On Linux, libprojectM will also create a `libprojectM.pc` file for use with pkgconfig, which will be the tool of choice
|
||||
for autotools-based builds for example.
|
||||
|
||||
Other build systems might provide libprojectM packages in the future, but the projectM developers are not planning on
|
||||
creating or maintinaing those.
|
||||
|
||||
### Call projectM in your code
|
||||
|
||||
#### One word about memory allocation
|
||||
|
||||
Before we start using the API, it is important to know how the API works in regard to memory allocation. The C API is
|
||||
technically a C wrapper around C++ code, to while you call C functions, they internally execute as C++ code in the
|
||||
library. In addition to that, the library, if loaded as a shared/dynamic library, might have a different heap area than
|
||||
your host application on some platforms.
|
||||
|
||||
To make sure all allocated memory is properly being disposed of after use, it must be freed in the same context where it
|
||||
has been allocated: if your application reserved memory, it has to release it. If libprojectM reserved memory, it must
|
||||
be released in the library code.
|
||||
|
||||
Currently, this only applies to either strings or the settings structure. As a rule of thumb, here is a quick reference:
|
||||
|
||||
- If a pointer (`char*` or `projectm_settings*`) is returned by an API function, _always_ use the
|
||||
appropriate `projectm_free_xxx()` function if you're done using the data.
|
||||
- If your code passes any self-allocated pointer to the API, it is safe to free the allocated memory immediately after
|
||||
the call. Do _not_ use the `projectm_free_xxx()` functions on these pointers.
|
||||
- It is safe to pass temporary pointers to any API call, e.g. using `std::string::c_str()` in an argument.
|
||||
- You can use `projectm_alloc_string` to allocate memory for strings, but you _must_ then use `projectm_free_string` to
|
||||
free it after use.
|
||||
- If you call `projectm_free_settings`, all non-null `char*`members _must_ have been allocated
|
||||
using `projectm_alloc_string`.
|
||||
- Any data pointers passed to callbacks are only valid until the callback returns. If you need the data afterwards,.make
|
||||
a copy. Your code _must not_ call `free` or `delete` on the passed data pointers inside the callback.
|
||||
|
||||
#### Create a new projectM instance
|
||||
|
||||
Now that you have your project files configured properly, you can immediately start using projectM. As stated above,
|
||||
this guide assumes your application already takes care of creating a proper OpenGL rendering context. This must be done
|
||||
before calling any projectM functions.
|
||||
|
||||
First, include the API header and create a new projectM instance:
|
||||
|
||||
```c
|
||||
#include <libprojectM/projectM.h>
|
||||
|
||||
/* In your setup code: */
|
||||
|
||||
/* Create a projectM instance with default settings */
|
||||
projectm_handle projectMHandle = projectm_create("", PROJECTM_FLAG_NONE);
|
||||
if (!projectMHandle)
|
||||
{
|
||||
/* Something went wrong. */
|
||||
}
|
||||
```
|
||||
|
||||
The opaque handle returned by `projectm_create()` identifies your instance and must be used as the first parameter to
|
||||
all API calls that have an `instance` parameter.
|
||||
|
||||
It is safe to include the header from both C and C++ files. It wraps `extern "C"` around declarations automatically.
|
||||
|
||||
#### Make sure to clean up the instance
|
||||
|
||||
Now is a good time to make sure the newly created instance is deleted after your application is done using it:
|
||||
|
||||
```c
|
||||
/* In your shutdown code: */
|
||||
projectm_destroy(projectMHandle);
|
||||
projectMHandle = NULL;
|
||||
```
|
||||
|
||||
If you make sure to set `projectMHandle` to `NULL` after destroying it, any further calls to `projectm_destroy()` will
|
||||
simply be a no-op: it is safe to pass a null pointer.
|
||||
|
||||
**Note**: It is _not_ safe to pass `NULL` or already-destroyed instance handles in `instance` to any other API call!
|
||||
Make sure your code doesn't do that.
|
||||
|
||||
#### Set the canvas size
|
||||
|
||||
Once your rendering context is ready and the dimensions of the target surface are known, you must provide the size to
|
||||
projectM once after initializing, and again every time the surface was invalidated or changed size, e.g. after a windows
|
||||
was resized, minimized and restored:
|
||||
|
||||
```c
|
||||
/* Initialize these with your current surface dimensions. */
|
||||
size_t renderWidth = 800;
|
||||
size_t renderHeight = 600;
|
||||
|
||||
projectm_set_window_size(projectMHandle, renderWidth, renderHeight);
|
||||
```
|
||||
|
||||
For performance reasons, make sure to only call `projectm_set_window_size()` if really needed, as this will currently
|
||||
cause a full recreation of projectM's internal rendering pipeline, including shader compilation.
|
||||
|
||||
#### Render a frame
|
||||
|
||||
projectM is now ready to start rendering frames. This needs to be done in your application's rendering loop:
|
||||
|
||||
```c
|
||||
projectm_render_frame(projectMHandle);
|
||||
/* Swap buffers here */
|
||||
```
|
||||
|
||||
libprojectM does not have any FPS limiting capabilities. This means you can render frames as fast as projectM can draw
|
||||
them. In end-user applications, this might not be a good thing as it will fully utilize one or more CPU cores while the
|
||||
display possibly cannot display frames at the same speed. By enabling VSync for buffer swaps, it will automatically
|
||||
limit FPS to the refresh rate. You might further consider FPS limiting to a certain target framerate to safe resources
|
||||
on the user's device.
|
||||
|
||||
#### Supplying audio data
|
||||
|
||||
With the above setup, the application will only render the default idle preset (the wandering "M" logo), but not do
|
||||
anything fancy. To make it react to some audio playing, the application must pass audio sample data into the library.
|
||||
|
||||
Where the application sources the audio data is up to the actual implementation, e.g. capturing external audio via some
|
||||
system API, directly decoding an audio file or using data from an underlying player application.
|
||||
|
||||
The API currently supports a few different data formats. All functions start with `projectm_pcm_add_`, followed by the
|
||||
sample data type, the number of channels and the data structure type accepted to pass in the actual data. For best
|
||||
performance and visuals, it is recommended to always use the `projectm_pcm_add_float_2ch_data()` function. It requires
|
||||
your data to be in this format:
|
||||
|
||||
- 32 bit floating-point samples
|
||||
- 2 channels (LR)
|
||||
- A simple data pointer, pointing to the first data byte
|
||||
- The number of samples
|
||||
|
||||
The actual sample frequency is not part of the interface, but projectM is optimized for 44.1 kHz, same as Milkdrop. It
|
||||
will also work with other sample frequencies, but the beat detection and presets drawing spectrum data might not behave
|
||||
as expected. Using 48 kHz is fine though as the difference is minimal.
|
||||
|
||||
The number of samples is the count of a full complement of data for all channels. This means if sample_count is 1, then
|
||||
the data must at least contain 16 _bytes_ or 2 _floats_ (General
|
||||
formula: `numBytes = sizeof(sample data type) * channels`).
|
||||
|
||||
Ideally, if the application is gathering audio data in a separate thread than the renderer, it _should not_ pass audio
|
||||
data only while `projectm_render_frame` is running. libprojectM does not use mutexes internally to prevent mutual access
|
||||
to the audio buffer. If there are race conditions, it won't cause crashes though, but may negatively impact the rendered
|
||||
visuals.
|
||||
|
||||
With all that said, let's say your application has a wrapper function that gets properly formatted audio data as a basic
|
||||
byte (`unsigned char*`) buffer:
|
||||
|
||||
```c
|
||||
/* audio_data is passed in float/2ch format */
|
||||
void add_audio_to_projectm(const unsigned char* audio_data, unsigned int length)
|
||||
{
|
||||
projectm_pcm_add_float_2ch_data(projectMHandle, (const float*)audio_data, length / sozeof(float) / 2 /* channels */);
|
||||
}
|
||||
```
|
||||
|
||||
Now projectM should start reacting to the audio.
|
||||
|
||||
#### Audio data caveats
|
||||
|
||||
The application does not need to care about how much data is stored inside projectM's internal buffer. If more data is
|
||||
added than projectM can consume on each frame, it is implemented as a ring buffer and will simply be overwritten. Each
|
||||
frame only renders the last added audio samples available in the buffer. This in turn means that if audio data is added
|
||||
only sporadically in large batches, multiple frames will use the same audio data for rendering, effectively "freezing"
|
||||
waveforms on screen.
|
||||
|
||||
Depending on the frequency and amount of audio data the application gets on each update (e.g. in callbacks from an
|
||||
external audio driver), it might be necessary to spread out adding the data over multiple frames instead of adding it
|
||||
all at once directly in the callback. Knowing the sample frequency and actual frame rendering time, the application can
|
||||
calculate the number of new audio samples to pass to projectM before each frame. If audio data comes in faster than
|
||||
frames are rendered, only the last few samples of the available audio data need to be passed. The application can query
|
||||
projectM's internal sample buffer size with the `projectm_pcm_get_max_samples()` function for optimization.
|
||||
|
||||
In addition to all that, the application should make sure not to get too much behind the actually played audio, as it
|
||||
might introduce visible lag between what the user hears and what projectM renders. As a rule of thumb, latencies over
|
||||
35ms will potentially be noticeable by the user.
|
||||
|
||||
### What next?
|
||||
|
||||
Now that the application is able to render visualizations with projectM, it should also take care of configuring
|
||||
additional features like adding presets, properly setting the different options projectM supports and handling user
|
||||
input as required.
|
||||
|
||||
A good further reading is the [API reference](API-Reference) and looking at the available members in
|
||||
the `projectm_settings` structure.
|
||||
|
||||
projectM also supports scanning a single directory recursively for presets, so your application doesn't need to do that.
|
||||
For proper playlist management, rating support and faster loading times it is recommended to fill the preset playlist
|
||||
using `projectm_add_preset_url()`. Future API extensions may add additional functionality for bulk playlist management.
|
||||
95
projectM-developers/Build-Troubleshooting.md
Normal file
95
projectM-developers/Build-Troubleshooting.md
Normal file
@ -0,0 +1,95 @@
|
||||
# Build Troubleshooting Q&A
|
||||
|
||||
On this page, you can find a list of common build issues you may encounter while building libprojectM and the frontends,
|
||||
providing possible solutions.
|
||||
|
||||
If your problem isn't listed, and you can't find a solution on your own, please note that the projectM developers can
|
||||
not provide technical support. If you think your build issue is caused by the projectM code or build system files (or
|
||||
you are unsure if that is the case), please open a bug report in the respective repository. You can also ask for help in
|
||||
the bug report channel or the [projectM Discord server](https://discord.gg/tpEuywB) and see if someone can help.
|
||||
|
||||
## CMake issues
|
||||
|
||||
### General advice
|
||||
|
||||
Things to check and try first:
|
||||
|
||||
- Always start with a fresh build directory if there is any issue, especially after checking out new code, switching
|
||||
branches or updating your local copy after a while.
|
||||
- If you don't want to delete your while build dir, at least try and delete the `CMakeCache.txt` in the top-level build
|
||||
dir and re-run CMake's configuration phase.
|
||||
- Make sure your C/C++ toolset and IDE is up-to-date and all components are properly set up.
|
||||
- Use the latest stable CMake release. If only a very old version is available on your platform or shipped with your
|
||||
IDE, building your own CMake binaries is really easy. There also are binary
|
||||
releases [available on cmake.org](https://cmake.org/download/) for many platforms.
|
||||
- Make sure the `cmake`/`cpack`/`ctest` commands are in your `PATH` variable.
|
||||
|
||||
### CMake can't find a working compiler
|
||||
|
||||
Depending on your OS and toolset, you might have to run CMake in a specific environment which defines paths for the
|
||||
compiler and other tools:
|
||||
|
||||
- On Windows using Visual Studio, either run CMake from within VS (version 2019 or higher is recommended) or from the
|
||||
developer command prompt for your target architecture which you can find in the Windows start menu.
|
||||
- On macOS using Xcode, make sure you have the command line tools installed. If in doubt, run `xcode-select --install`
|
||||
ina terminal with the user account you want to run CMake in. Run `xcode-select -p` to verify the tools are properly
|
||||
installed. When using CMake to create Xcode projects, also make sure to use the latest CMake version.
|
||||
- On Linux, make sure you have installed all required packages for compiling C/C++ code. Most distributions have meta
|
||||
packages called "build-essential" or similar that will pull in compiler, linker, make and other build tools. Since
|
||||
Linux is highly heterogeneous, refer to your distribution documentation on installing developer packages.
|
||||
- If the above hints don't work, double-check your developer tools installation and
|
||||
the [CMake generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) used to create your project
|
||||
files. The default generator might not be the correct one for your setup.
|
||||
|
||||
### CMake can't find a specific dependency
|
||||
|
||||
The projectM CMake scripts do not make any assumptions on where to look for build dependencies and solely rely on
|
||||
CMake's built-in mechanisms to find the needed packages. The lookup process is mostly platform-independent and generally
|
||||
requires packages and other files to be found in a specific set of directories:
|
||||
|
||||
- The [`CMAKE_PREFIX_PATH` variable](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html) can be used to
|
||||
add one or more directories to the build configuration in which CMake will first look into when searching for packages
|
||||
and libraries. Add any paths separated by `;` for libraries that are not installed in the toolset/OS default search
|
||||
paths.
|
||||
- When using [vcpkg](https://vcpkg.io/) to build the dependencies on any platform, always
|
||||
set [`CMAKE_TOOLCHAIN_FILE`](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html)
|
||||
to `<vcpkg-dir>/scripts/buildsystems/vcpkg.cmake`.
|
||||
- In some cases, even if the dependency normally provides CMake files, pre-built packages might not contain them. In
|
||||
this case, you need to either contact the author of the pre-built package or build the dependency yourself and add the
|
||||
installation dir to `CMAKE_PREFIX_PATH`.
|
||||
|
||||
## Compilation issues
|
||||
|
||||
### General advice
|
||||
|
||||
Things to check and try first:
|
||||
|
||||
- Make sure you use the latest available compiler and SDK versions for your platform.
|
||||
- Use a compiler that supports at least C++14.
|
||||
- If you build a recent version of projectM, also try to use the most recent versions of the required dependencies, e.g.
|
||||
SDL2.
|
||||
- Make sure all libraries were built with the same compiler/SDK, for the same architecture and runtime libraries (e.g.
|
||||
MSVC `/MD` and `/MT` flags).
|
||||
- In newly written code, always use case-sensitive filenames in `#include` directives and other project files. Keep in
|
||||
mind that most OS platforms have case-sensitive filesystems.
|
||||
|
||||
### There is some compiler error I don't understand
|
||||
|
||||
If you're only trying to build projectM, but are not a C/C++ developer, errors during compilation might not provide you
|
||||
with enough information to identify the reason or fix the code. In this case, you can open an issue or ask on Discord to
|
||||
get a possible solution. In some cases the error you're encountering might be a bug that needs to be solved in the
|
||||
source, so it's important that you let us know about it. Please make sure you provide all relevant information, e.g. OS,
|
||||
compiler and library versions etc. so we can reproduce the problem.
|
||||
|
||||
### An include file could not be found
|
||||
|
||||
- Make sure the filename casing in the `#include` directive is correct.
|
||||
- Look at the compiler command line if all required include directories are present. If you can't see the compiler
|
||||
commands, add `-DCMAKE_VERBOSE_MAKEFILE=ON` to CMake's configuration command to enable command output on all
|
||||
generators.
|
||||
- A third-party library might not be installed correctly or with an unexpected directory layout.
|
||||
- If the missing include is a system or SDK header, check if your toolset is configured properly.
|
||||
- Make sure the `#include` directive uses the correct quotes, e.g. `""` for project-internal headers and `<>` for
|
||||
third-party or SDK headers. Modern compilers differentiate between those.
|
||||
- Make sure include directories are provided via the correct compiler flag, e.g. `-i` for project-internal include paths
|
||||
used with `#include "header.h"`and `-I` for third-party and SDK/system headers for use with `#include <header.h>`.
|
||||
Loading…
x
Reference in New Issue
Block a user