Writing a CMakeLists.txt
Steps: Initialize the target, declare its dependencies, then finalize it.
Any optional tweaks go between initialize and finalize.
ot_initialize_<kind>(<Target> <ROOT_PATH_VAR> [EXPORT_MACRO])
... optional modifiers (warnings, definitions, subsystem, resources) ...
ot_add_dependency(<Target> <TOKEN> <TOKEN> ...)
ot_finalize_<kind>(<Target>)
ot_add_test(<Target>) # optional
<ROOT_PATH_VAR> is the name of the CMake variable that holds the project’s
root path. OTEnvironment.cmake derives it from the OT_<NAME>_ROOT
environment variable, for example OT_LOGGER_SERVICE_ROOT becomes
OT_LOGGER_SERVICE_ROOT_PATH.
Preamble
Every CMakeLists.txt starts the same way:
cmake_minimum_required(VERSION 3.20)
project(<Target> LANGUAGES CXX)
include("$ENV{OT_CMAKE_DIR}/OTProject.cmake")
A library (DLL)
Libraries live in Libraries/ and build as shared libraries. Use
ot_initialize_lib and ot_finalize_lib:
cmake_minimum_required(VERSION 3.20)
project(OTExample LANGUAGES CXX)
include("$ENV{OT_CMAKE_DIR}/OTProject.cmake")
ot_initialize_lib(OTExample OT_EXAMPLE_ROOT_PATH)
ot_add_dependency(OTExample
OTSystem
OTCore
RJSON
)
ot_finalize_lib(OTExample)
ot_add_test(OTExample)
The export macro controls the __declspec(dllexport/dllimport) switch. Leave it
out and you get OPENTWIN<NAME>_EXPORTS by default, so OTExample ends up
with OPENTWINEXAMPLE_EXPORTS. To set your own, pass it as the third argument:
ot_initialize_lib(OToolkitAPI OT_OTOOLKITAPI_ROOT_PATH OTOOLKITAPI_LIB)
A service (DLL)
A service is a shared library too.
cmake_minimum_required(VERSION 3.20)
project(LoggerService LANGUAGES CXX)
include("$ENV{OT_CMAKE_DIR}/OTProject.cmake")
ot_initialize_lib(LoggerService OT_LOGGER_SERVICE_ROOT_PATH SESSIONSERVICE_EXPORTS)
ot_disable_warnings(LoggerService 4996)
ot_add_dependency(LoggerService
OTSystem
OTCore
OTCommunication
OTServiceFoundation
RJSON
CURL
OSLibs
)
ot_finalize_lib(LoggerService)
ot_add_test(LoggerService)
Note
Services can also be binaries/executables. In that case use the ot_initialize_bin and ot_finalize_bin.
An executable
cmake_minimum_required(VERSION 3.20)
project(KeyGenerator LANGUAGES CXX)
include("$ENV{OT_CMAKE_DIR}/OTProject.cmake")
ot_initialize_bin(KeyGenerator OT_KEYGENERATOR_ROOT_PATH)
ot_set_subsystem(KeyGenerator CONSOLE)
ot_set_runtime_static_release(KeyGenerator) # ships as a self contained exe
ot_add_dependency(KeyGenerator
OTSystem
OTCore
OSLibs
)
ot_finalize_bin(KeyGenerator)
ot_finalize_bin takes an optional output name if the produced .exe should
differ from the target name:
ot_finalize_bin(uiService uiFrontend)
Note
ot_set_runtime_static_release is only for stand alone tools that ship as a
single executable. Do not use it for libraries, services, or anything that
runs next to the OpenTwin DLLs; those stay on the dynamic CRT.
A Python subprocess
A binary that embeds Python uses ot_initialize_bin_python. It keeps the
release runtime in every configuration so it can link the shipped Python
(see Runtime library):
cmake_minimum_required(VERSION 3.20)
project(PythonExecution LANGUAGES CXX)
include("$ENV{OT_CMAKE_DIR}/OTProject.cmake")
ot_initialize_bin_python(PythonExecution OT_PYTHON_EXECUTION_ROOT_PATH SESSIONSERVICE_EXPORTS)
ot_disable_warnings(PythonExecution 4996)
ot_add_compile_definitions(PythonExecution QT_NO_KEYWORDS)
ot_set_subsystem(PythonExecution CONSOLE)
ot_add_dependency(PythonExecution
OTSystem OTCore OTGui OTCommunication OTServiceFoundation
OTModelAPI OTBlockEntities
RJSON CURL MONGO_C MONGO_CXX MONGO_BOOST
PYTHON
QtCore QtNetwork QtWidgets
)
ot_finalize_bin(PythonExecution)
ot_add_test(PythonExecution)
Warning
A service that just talks to the Python subprocess over the service interface
is an ordinary library and uses ot_initialize_lib.
Unit tests
If ot_add_test(<Target>) is present, the build system descends into the
project’s tests/ directory when it exists and BUILD_TESTING is on. The
tests/CMakeLists.txt reuses the already compiled core objects:
# <Project>/tests/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(OTExample_tests LANGUAGES CXX)
include("$ENV{OT_CMAKE_DIR}/OTProject.cmake")
ot_initialize_test(OTExample_tests OTExample)
ot_initialize_test compiles tests/src/*.cpp, links gtest, matches the
runtime library of the target under test, and registers the test with CTest. The
first argument is the test executable name; the second is the main target whose
core objects and dependencies it reuses.
Warning
If ot_add_test() is defined in the core target CMakeLists, and no tests subdir is present,
the configuration step will throw a BUILD_TESTING not configured warning.
Modifiers (between initialize and finalize)
These act on the core target. Call them after ot_initialize_* and before
ot_finalize_*:
Call |
Effect |
|---|---|
|
Adds private preprocessor definitions. |
|
Adds raw compile flags (a bare number becomes |
|
Suppresses warnings by numeric ID ( |
|
Sets the linker subsystem of the final binary. |
|
Same, but only for one configuration. |
|
Static CRT ( |
|
Globs |
|
Globs |
|
Copies |
See the API reference for full signatures and
Dependency tokens for everything you can
pass to ot_add_dependency.