CMake Setup

The Toplevel CMakeLists.txt

# CMake Policy Line
cmake_minimum_required(VERSION 3.10)

# Detect the ArmarXCore framework
find_package("ArmarXCore" REQUIRED)

# Include the ArmarXProject.cmake file which provides all necessary ArmarX CMake macros
include(${ArmarXCore_USE_FILE})

# Choose a name for the project
armarx_project("ProjectName")

# Call this macro for each dependent package
depends_on_armarx_package(ArmarXGui)

# Standard CMake way of adding dependent libraries
find_package(AdditionalLibrary QUIET)
if (AdditionalLibrary_FOUND)
    include_directories(${AdditionalLibrary_INCLUDE_DIR})
endif()

# Add all source directories afterwards
add_subdirectory(etc)
add_subdirectory(source)

# The last line hast to be install_project() because it needs complete knowledge about all
# libraries and executales which are part of the project
install_project()

The interface directory

The interface directorie has the following layout:

The interface CMakeLists.txt

The CMakeLists.txt file in the source/PackageName/interface directory looks as follows for every project:

###
### CMakeLists.txt file for ArmarX Interfaces
###

# if the slice files depend on interfaces defined in other projects
# those projectnames must be specified as the fourth parameter of the
# armarx_interfaces_generate_library() macro
set(PROJECT_INTERFACE_DEPENDENCIES ArmarXCore)

set(SLICE_FILES
core/MyInterface.ice
)

# generate the interface library (ATTENTION! the last parameter must be put into quotes)
armarx_interfaces_generate_library(ProjectName 0.1.0 0 "${PROJECT_INTERFACE_DEPENDENCIES}")

The interface directory

All interface definition files are located in the source/PackageName/interface/ directory. The language specific code is then getting generated into the build directory where it is getting compiled into libraries.

Note that Slice files should be grouped meaningfully in subdirectories.

The source directory

The source directory holds the sourcecode of the package.

It contains on single subdirectory with the name of the package. This enables consistent includes like #include <$PACKAGE_NAME/...> without breaking the directory structure by having multiple checkouts of the same package. All sourcecode is stored inside this directory and is grouped by topic.

The Each sourcecode directory contains the C++ header and sourcefiles and a CMakeLists.txt which looks like the following one:

\verbatim

armarx_set_target("XYZ Library: ProjectName")

find_package(SomeLibrary QUIET) armarx_build_if(SomeLibrary_FOUND "SomeLibrary could not be found")

set(LIB_NAME ProjectName)

set(LIBS ProjectNameInterfaces ${QT_LIBRARIES} ${Boost_LIBRARIES} ${SomeLibrary_LIBRARIES})

set(LIB_SOURCE_FILES File1.cpp File2.cpp) set(LIB_HEADER_FILES File1.h) File2.h)

armarx_add_library("${LIB_NAME}" "${LIB_FILES}" "${LIB_HEADERS}" "${LIBS}")

if (SomeLibrary_FOUND) target_include_directories("${LIB_NAME}" PUBLIC ${SomeLibrary_INCLUDE_DIR}) endif()

By convention each component/library/executable does a find_package() for all the libraries it depends on.

This helps clarifying which libraries the target depends on. It also allows to specify different versions for different targets. Only a few select libraries such as Ice or Boost (which the complete system depends on) are provided by the Core CMake scripts.

If required libraries are located in another ArmarX Package the macro depends_on_armarx_package() must be used in the toplevel CMakeLists.txt file of the current package.

Adding external/custom Executables to a Package

If you want to provide scripts or other executables in your package, that do not use the usual compilation process, you can specify them using a simple cmake-macro in any of your CMakeLists.txt-files in your package:

armarx_add_external_executable("path/to/myexecutable")

The parameter is the relative path to the executable that you want to provide. Relative to the directory where the CMakeLists.txt is located. This executable is copied to the build/bin directory as any other ArmarX executable keeping the permissions of that file. This executable is also installed like any other executable and can be specified in ArmarX scenarios:

set(SCENARIO_COMPONENTS
    myexecutable
    )

# optional 3rd parameter: "path/to/global/config.cfg"
armarx_scenario("ExampleUnitTest" "${SCENARIO_COMPONENTS}")

Upgrading cmake to 3.10

There are a few changes that should be done (avoid using include_directories etc and use the target_include_directories version instead).

Most places requiring upgrades can be found using this regex

(^|[^_])(add_definitions|add_compile|include_dir|link_lib|setupSimoxExternalLibraries|policy|Simox_|ARMARX_USE_QT5|armarx_check_qt4|QT_UIC_EXECUTABLE|QT_RCC_EXECUTABLE|qt4|armarx_build_if_not_qt5|armarx_qt_wrap_ui|armarx_qt_wrap_cpp|armarx_qt_add_resources|CMAKE_VERSION|setupSimoxExternalLibraries|CMAKE_MINIMUM_REQUIRED|CMAKE_POLICY)