Using Corrade with CMake
Guide how to find and use Corrade with CMake build system.
Corrade uses CMake as a primary build system for both building and integration into your projects.
Using Corrade that was externally built and installed
The main logic is in the FindCorrade.cmake module distributed with the engine in the modules/
directory, you are encouraged to copy it into your project and add path to the file to CMAKE_MODULE_PATH
:
# Path where FindCorrade.cmake can be found, adapt as needed set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/modules/" ${CMAKE_MODULE_PATH}) find_package(Corrade REQUIRED ...) # see below
Otherwise, if CMake won't be able to find this file in predefined locations, it will error out even if Corrade might be installed on the system. Note that the module files areupdated as the library evolves, you are encouraged to update your copies from time to time to avoid strange building issues.
If you installed the library to non-standard location (other than /usr
, e.g. /home/xyz/projects
), set CMAKE_PREFIX_PATH
to that directory to help CMake find it.
Using Corrade as a CMake subproject
A self-contained alternative to a shared instance of the libraries, is to add the repositories directly into your project (as Git submodules, bundling downloaded archives etc.), and then to use CMake's add_subdirectory()
command to compile them on demand. With this approach, you don't need to care about manually installing Corrade, however the usual tradeoffs when bundling code apply — slower full rebuilds, IDEs having more to parse etc. In this case, build-time options can be set()
before calling add_subdirectory()
. Note that, unless you require CMake 3.13 at least, it's necessary to use the CACHE ... FORCE
arguments in order to have the options set properly. For example:
set(CORRADE_WITH_TESTSUITE OFF CACHE BOOL "" FORCE) # disable what you don't use add_subdirectory(corrade EXCLUDE_FROM_ALL) # so only things you use are built find_package(Corrade REQUIRED ...) # see below
Note that the use of add_subdirectory()
does not replace the configuration necessary for an installed version of Corrade. The modules/
directory and calls to find_package()
are needed in both the installed and the subproject case for a properly configured environment.
To simplify your project setup, the subproject globally configures CMAKE_<CONFIG>/bin
/ <CONFIG>/lib
directories inside your build directory. This makes the subproject workflow easier when dynamically-loaded plugins are involved; and on Windows it makes it possible to run built executables without having to do a $PATH
setup for dependency DLLs. If your project already configures CMAKE_{RUNTIME,LIBRARY,ARCHIVE}_OUTPUT_DIRECTORY
, those will get used instead (and you can also set your own output directories after the add_subdirectory()
call, which will make Corrade keep the above). If you want to disable this behavior altogether and keep all executables and libraries in their implicit locations, set those variables to an empty string (as opposed to nothing at all, which is the same as if the variable is not set) — Corrade will detect and respect that:
# I'm happy with having binaries scattered around the build dir set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "") add_subdirectory(corrade EXCLUDE_FROM_ALL)
Finding the package and its components
Basic usage is:
find_package(Corrade REQUIRED)
This module tries to find the base Corrade library and then defines the following:
Corrade_FOUND
— Whether the base library was foundCORRADE_LIB_SUFFIX_MODULE
— Path toCorradeLibSuffix.cmake
module, which tries to autodetect value ofLIB_SUFFIX
variableCORRADE_INCLUDE_INSTALL_PREFIX
— Prefix where to put platform-independent include and other files, defaults to.
. If a relative path is used, it's relative toCMAKE_INSTALL_PREFIX
.
This command will try to find only the base library, not the optional components, which are:
Containers
— Containers libraryInterconnect
— Interconnect libraryMain
— Main libraryPluginManager
— PluginManager libraryTestSuite
— TestSuite libraryUtility
— Utility libraryrc
— corrade-rc executable
Example usage with specifying additional components is:
find_package(Corrade REQUIRED Utility TestSuite)
For each component is then defined:
Corrade_*_FOUND
— Whether the component was foundCorrade::*
— Component imported target
The package is found if either debug or release version of each library is found. If both debug and release libraries are found, proper version is chosen based on actual build configuration of the project (i.e. Debug
build is linked to debug libraries, Release
build to release libraries).
Corrade conditionally defines the CORRADE_Debug
(not Corrade itself, but build configuration of the project using it). Useful e.g. for selecting proper plugin directory.
Corrade defines the following custom target properties:
CORRADE_CXX_STANDARD
— C++ standard to require when compiling given target. Does nothing ifCMAKE_CXX_FLAGS
already contains particular standard setting flag or if given target contains either of theCXX_STANDARD
orCOMPILE_FEATURES
properties. Allowed value is11
,14
,17
or20
. See also the CORRADE_CXX_ STANDARD C++ macro, which allows for checking of used C++ standard in a portable way. INTERFACE_CORRADE_CXX_STANDARD
— C++ standard to require when using given target. Does nothing ifCMAKE_CXX_FLAGS
already contains particular standard setting flag or if given target containsCMAKE_CXX_STANDARD
property. Allowed value is11
,14
,17
or20
.CORRADE_USE_PEDANTIC_FLAGS
— Enable additional compiler/linker flags. Boolean. The particular flags are contained in theCORRADE_PEDANTIC_COMPILER_OPTIONS
andCORRADE_PEDANTIC_COMPILER_DEFINITIONS
variables.
These properties are inherited from directory properties, meaning that if you set them on directories, they get implicitly set on all targets in given directory (with a possibility to do target-specific overrides). All Corrade libraries have the INTERFACE_CORRADE_CXX_STANDARD
property set to 11
, meaning that you will always have at least C++11 enabled once you link to any Corrade library.
Features of found Corrade library are exposed in these variables, they are also available as preprocessor variables if you include Corrade/
CORRADE_MSVC_COMPATIBILITY
— Defined if compiled with compatibility mode for MSVC 2019+ without the/permissive-
flag setCORRADE_MSVC2017_COMPATIBILITY
— Defined if compiled with compatibility mode for MSVC 2017CORRADE_MSVC2015_COMPATIBILITY
— Defined if compiled with compatibility mode for MSVC 2015CORRADE_BUILD_DEPRECATED
— Defined if compiled with deprecated features includedCORRADE_BUILD_STATIC
— Defined if compiled as static libraries. Default are shared libraries.CORRADE_BUILD_STATIC_UNIQUE_GLOBALS
— Defined if static libraries keep their globals unique even across different shared libraries. Enabled by default for static builds.CORRADE_BUILD_MULTITHREADED
— Defined if compiled in a way that makes it possible to safely use certain Corrade features simultaneously in multiple threads.CORRADE_BUILD_CPU_RUNTIME_DISPATCH
— Defined if built with code paths optimized for multiple architectres with the best matching variant selected at runtime based on detected CPU featuresCORRADE_TARGET_UNIX
— Defined if compiled for some Unix flavor (Linux, BSD, macOS, iOS, Android, ...)CORRADE_TARGET_APPLE
— Defined if compiled for Apple platformsCORRADE_TARGET_IOS
— Defined if compiled for iOS (device or simulator)CORRADE_TARGET_IOS_SIMULATOR
— Defined if compiled for iOS SimulatorCORRADE_TARGET_WINDOWS
— Defined if compiled for WindowsCORRADE_TARGET_WINDOWS_RT
— Defined if compiled for Windows RTCORRADE_TARGET_EMSCRIPTEN
— Defined if compiled for EmscriptenCORRADE_TARGET_ANDROID
— Defined if compiled for AndroidCORRADE_TARGET_GCC
— Defined if compiling with GCC or GCC-compatible ClangCORRADE_TARGET_CLANG
— Defined if compiling with Clang or any of its variantsCORRADE_TARGET_APPLE_CLANG
— Defined if compiling with Apple's ClangCORRADE_TARGET_CLANG_CL
— Defined if compiling with Clang-CL (Clang with a MSVC frontend)CORRADE_TARGET_MSVC
— Defined if compiling with MSVC or Clang with a MSVC frontendCORRADE_TARGET_MINGW
— Defined if compiling under MinGWCORRADE_CPU_USE_IFUNC
- Defined if GNU IFUNC is allowed to be used for runtime dispatch in the Cpu libraryCORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT
— Defined if PluginManager doesn't support dynamic plugin loading due to platform limitationsCORRADE_TESTSUITE_TARGET_XCTEST
— Defined if TestSuite is targeting Xcode XCTestCORRADE_UTILITY_USE_ANSI_COLORS
— Defined if ANSI escape sequences are used for colored output with Utility::Debug on Windows
Besides all the defines above, the Corrade/
Note that each namespace contains more detailed guide how to use given library with CMake.
Macros and functions
Add unit test using Corrade's TestSuite
corrade_add_test(<test name> <sources>... [LIBRARIES <libraries>...] [FILES <files>...] [ARGUMENTS <arguments>...])
Test name is also executable name. You can use LIBRARIES
to specify libraries to link with instead of using target_link_libraries()
. The Corrade::TestSuite
target is linked automatically to each test, together with Corrade::enable_testing()
function must be called explicitly. Arguments passed after ARGUMENTS
will be appended to the test command line. ARGUMENTS
are supported everywhere except when CORRADE_
You can list files needed by the test in the FILES
section. If given filename is relative, it is treated relatively to CMAKE_CURRENT_SOURCE_DIR
. The files are added to the REQUIRED_FILES
target property. On Emscripten they are bundled to the executable and available in the virtual filesystem root. On Android they are copied along the executable to the target. In case of Emscripten and Android, if the file is absolute or contains ..
, only the leaf name is used. Alternatively you can have a filename formatted as <input>@<output>
, in which case the <input>
is treated as local filesystem location and <output>
as remote/virtual filesystem location. The remote location can't be absolute or contain ..
/ @
characters.
Unless CORRADE_CORRADE_TESTSUITE_BUNDLE_IDENTIFIER_PREFIX
to change it to something else.
On Emscripten this automatically adds -s DISABLE_EXCEPTION_CATCHING=0
to both compiler and linker flags since early-exit from test cases (failure, expected failure, skipped test case...) is done via exceptions.
By default, the tests are compiled as part of the implicit ALL
target. If that's undesirable, the CORRADE_TESTSUITE_TEST_TARGET
variable can be set to create a dedicated target for building just the tests. For example, passing -DCORRADE_TESTSUITE_TEST_TARGET=build-tests
to CMake will mean cmake --build .
builds only the project, and cmake --build . --target build-tests
builds the tests. The variable can be also set by the project itself, and even to a different value for different tests for more precise grouping.
Compile data resources into application binary
corrade_add_resource(<name> <input> [SINGLE])
Depends on corrade-rc, which is part of Corrade utilities. This command generates resource data using a resource configuration file passed in <input>
. The <name>
argument is a CMake variable name that subsequently contains a filename of the resulting C++ file, which is meant to be passed to add_executable()
or add_library()
, and is also a C identifier under which the resources can be explicitly loaded if needed as described in CORRADE_
corrade_add_resource(app_resources resources.conf) add_executable(app source1 source2 ... ${app_resources})
Alternatively, the SINGLE
signature can be used to directly compile a single file into a C++ source file containing its binary representation, exposing the data under extern const unsigned char resourceData_name[]
and extern const unsigned int resourceSize_name
symbols, with no dependency on Utility::
corrade_add_resource(binary_contents binary.dat SINGLE) # resourceData_binary_contents and resourceSize_binary_contents should be then # directly referenced by application sources add_executable(app ... ${binary_contents})
Add dynamic plugin
corrade_add_plugin(<plugin name> "<debug binary install dir>;<debug library install dir>" "<release binary install dir>;<release library install dir>" <metadata file> <sources>...)
The macro adds a preprocessor directive CORRADE_DYNAMIC_PLUGIN
when compiling <sources>
. Additional libraries can be linked in via target_link_libraries(plugin_name ...)
. On DLL platforms, the plugin DLLs and metadata files are put into <debug binary install dir>
/ <release binary install dir>
and the *.lib
files into <debug library install dir>
/ <release library install dir>
. On non-DLL platforms everything is put into <debug library install dir>
/ <release library install dir>
.
If <metadata file>
is not an absolute path, it's treated as relative to CMAKE_CURRENT_SOURCE_DIR
. If the plugin interface disables plugin metadata files via PluginManager::<metadata file>
can be set to ""
, in which case no metadata file is copied anywhere. Otherwise the metadata file is copied and renamed to <plugin name>
, retaining its original extension.
corrade_add_plugin(<plugin name> <debug install dir> <release install dir> <metadata file> <sources>...)
Unlike the above version this puts everything into <debug install dir>
on both DLL and non-DLL platforms. If <debug install dir>
is set to CMAKE_CURRENT_BINARY_DIR
(e.g. for testing purposes), the files are copied directly, without the need to perform install step. Note that the files are actually put into configuration-based subdirectory, i.e. ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
. See documentation of CMAKE_CFG_INTDIR
variable for more information.
Add static plugin
corrade_add_static_plugin(<plugin name> "<binary install dir>;<library install dir>" <metadata file> <sources>...)
The macro adds a preprocessor directive CORRADE_STATIC_PLUGIN
when compiling <sources>
. Additional libraries can be linked in via target_link_libraries(plugin_name ...)
. The <binary install dir>
is ignored and included just for compatibility with the corrade_<library install dir>
. Note that plugins built in debug configuration (e.g. with CMAKE_BUILD_TYPE
set to Debug
) have -d
suffix to make it possible to have both debug and release plugins installed alongside each other.
If <metadata file>
is not an absolute path, it's treated as relative to CMAKE_CURRENT_SOURCE_DIR
. If the plugin interface disables plugin metadata files via PluginManager::<metadata file>
can be set to ""
, in which case no metadata file is used. Otherwise the metadata file is bundled and renamed to <plugin name>
, retaining its original extension.
corrade_add_static_plugin(<plugin name> <install dir> <metadata file> <sources>...)
Equivalent to the above with <library install dir>
set to <install dir>
. If <install dir>
is set to CMAKE_CURRENT_BINARY_DIR
(e.g. for testing purposes), no installation rules are added.
Find corresponding DLLs for library files
corrade_find_dlls_for_libs(<output variable> <libs>...)
Available only on Windows, for all *.lib
files tries to find corresponding DLL file. Useful for bundling dependencies for e.g. WinRT packages.