|
All ArmarX packages use CMake as a build system generator. Each ArmarX package is a CMake project that has a top-level CMakeLists.txt file. Within nested CMakeLists.txt files, targets (e.g. libraries, executables) are defined with their dependencies.
General information about CMake can be found here: https://cmake.org/cmake/help/v3.21/.
The following is intended to provide developers with a reference for creating and extending
However, none of those CMakeLists.txt files has to be created manually. armarx-package is a command line tool that can be used for exactly this purpose. Developers only have to add source and header files as well as dependencies of their targets.
Lately, the ArmarX CMake functions have undergone a complete redesign. This redesign addresses several limitations of its predecessor and features the following
The legacy version is described here. All ArmarX packages should be migrated to the new version.
In the following, the new API will be described together with the armarx-package tool that creates the CMakeLists.txt files.
The top-level CMakeLists.txt describes the ArmarX package and all of its dependencies.
$ armarx-package init example_package
cmake_minimum_required(VERSION 3.18) find_package(ArmarXCore REQUIRED) include(${ArmarXCore_USE_FILE}) set(ARMARX_ENABLE_DEPENDENCY_VERSION_CHECK_DEFAULT FALSE) # Project definition. armarx_enable_modern_cmake_project() # Temporary until migration of ArmarXCore. armarx_project(example_package) add_subdirectory(etc) # Required ArmarX dependencies. # armarx_find_package(PUBLIC RobotAPI REQUIRED) # Optional ArmarX dependencies. armarx_find_package(PUBLIC ArmarXGui QUIET) # Required system dependencies. # armarx_find_package(PUBLIC Boost REQUIRED) # Optional system dependencies. # armarx_find_package(PUBLIC PCL QUIET) add_subdirectory(source/example_package) armarx_install_project()
The above example contained the following statements:
cmake_minimum_required(VERSION 3.18)
All new ArmarX CMake projects require at least CMake version 3.18. It is recommended to use CMake 3.21.
find_package(ArmarXCore REQUIRED) include(${ArmarXCore_USE_FILE}) set(ARMARX_ENABLE_DEPENDENCY_VERSION_CHECK_DEFAULT FALSE)
This is needed to use all custom ArmarX CMake functions. These are always prefixed with "armarx_".
To define dependencies, add the following
# Required ArmarX dependencies. # armarx_find_package(PUBLIC ... REQUIRED) # Optional ArmarX dependencies. armarx_find_package(PUBLIC ... QUIET) # Required system dependencies. # armarx_find_package(PUBLIC ... REQUIRED) # Optional system dependencies. # armarx_find_package(PUBLIC ... QUIET)
Please never use "find_package" without the "armarx_" prefix because armarx_find_package will automatically forwards the dependencies of this package to downstream packages. Also, don't use armarx_find_package in any nested CMakeLists.txt files. Dependencies should always be defined in the top-level CMakeLists.txt file!
In many cases, each ArmarX package has a central slice interface library located in "source/{package_name}/interfaces". Slice interface libraries can also be coupled with components if those slice files describe (private) interfaces. A central slice interface library can be defined as such:
armarx_add_ice_library(interfaces SLICE_FILES MyInterface.ice DEPENDENCIES other_package::interfaces # or any other dependency )
Libraries are located in "source/{PACKAGE_NAME}/"
In general, algorithms should be part of libraries, not components.
$ armarx-package add library example_library
armarx_add_library(example_library SOURCES MyClass.cpp HEADERS MyClass.h DEPENDENCIES other_package::library_foo example_package::library_bar DEPENDENCIES_LEGACY a_legacy_dependency )
Components are located in "source/{PACKAGE_NAME}/components".
$ armarx-package add component example_component
armarx_add_component(example_component ICE_FILES ComponentInterface.ice ICE_DEPENDENCIES ArmarXCoreInterfaces # RobotAPIInterfaces # ARON_FILES # aron/my_type.xml SOURCES Component.cpp HEADERS Component.h DEPENDENCIES # ArmarXCore ArmarXCore ## ArmarXCoreComponentPlugins # For DebugObserver plugin. # ArmarXGui ## ArmarXGuiComponentPlugins # For RemoteGui plugin. # RobotAPI ## RobotAPICore ## RobotAPIInterfaces ## RobotAPIComponentPlugins # For ArViz and other plugins. # DEPENDENCIES_LEGACY ## Add libraries that do not provide any targets but a ${FOO_LIBRARIES} variable # FOO # If you need a separate shared component library you can enable it with the following flag. # SHARED_COMPONENT_LIBRARY # If you want to define your own main method, use this command # EXECUTABLE_FILES # ... )
General:
Executable:
If the code-generation is used (default), the user must make sure that the macro 'ARMARX_REGISTER_COMPONENT_EXECUTABLE' is present in the component's source file.
Slice interface:
Aron interface:
Aron XML files should be placed in a subdirectory of the library they belong to called "aron". The following should added to the beginning of the CMakeLists.txt file of the library. In general, the aron target should be named *_aron
armarx_add_aron_library(example_library_aron ARON_FILES aron/MyAronFile.xml )
Usage example:
# use the Aron library armarx_add_library(example_library ... DEPENDENCIES example_package::example_library_aron )
A statechart group is defined by a scgxml file, e.g. ExampleGroup.scgxml. In this file, required proxies and states are listed. This file will be parsed during the CMake configuration step such that all of the information in the scgxml file does not have to be added to the user-maintained CMakeLists.txt.
armarx_add_statechart_group(ExampleGroup GROUP_FILE ExampleGroup.scgxml SOURCES ExampleGroupRemoteStateOfferer.cpp HEADERS ExampleGroupRemoteStateOfferer.h DEPENDENCIES )
Statecharts are located in "source/{PACKAGE_NAME}/statecharts".
Usually, the statechart group and states are created via the Statechart GUI. States must not be registered in the CMakeLists.txt. They will be discovered automatically by parsing the corresponding statechart group XML file (e.g. ExampleStatechartGroup.scgxml).
Tests are currently generated automatically for each library.
armarx_add_test(example_test TEST_FILES my_test_file.cpp DEPENDENCIES ... DEPENDENCIES_LEGACY ... )
Usually, only the library / component that is tested should be added to the DEPENDENCIES list.
To define dependencies between targets, add them to the DEPENDENCIES list e.g. "example_package::example_library". The namespace "example_package::" will be available for targets defined with the "armarx_" CMake functions.
Although it would be possible to also use the "example_library" target here, this is a bad practice. For consistency, always use the namespace, as only the target "example_package::example_library" will be available in downstream packages.