From 219a2eac8ab81d1ba359c487624cc3b6969660a1 Mon Sep 17 00:00:00 2001 From: d-rothe Date: Thu, 16 Mar 2023 13:38:46 +0100 Subject: [PATCH] Wip/11221 modernize cmake (#25) This provides ChimeraTK:: as cmake imported target. Variables _INCLUDE_DIRS, LIBRARY_DIRS, _LIBRARIES, _CXX_FLAGS, _LINKER_FLAGS are provided for compatibility but are generated from cmake-exports where possible and cmake imported targets should be preferred. * provide function for option array conversion to be used with target_compile_options etc + FindPackage results, where findPackage results are of incorrect/old format * FindDOOCS: - DOOCS components as imported targets - clean up no longer needed tweaks - add timinglib as component - make use of log levels and respect QUIET argument * add_dependency: fail on wrong add_dependency usage this was unseen since it worked in most cases but in general does not in particular was causing trouble with imports from cppext second arg must be version number * pkgconfig exports - generated from cmake-exports - make linker flags come before libs, order is required e.g. for --no-as-needed flag - remove duplicates in output * FindGccAtomic - do not put absolute lib path in output since it was causing trouble with yocto builds. Should be in system lib paths anyway. Also, make GccAtomic variable output name more consistent. --- cmake/Modules/FindDOOCS.cmake | 218 +++++++++++++------ cmake/Modules/FindGccAtomic.cmake | 9 +- cmake/PROJECT_NAMEConfig.cmake.in.in | 91 +++++--- cmake/add_dependency.cmake | 12 ++ cmake/create_cmake_config_files.cmake | 281 ++++++++++++++++++++++--- cmake/format_options.cmake | 8 + cmake/set_control_system_adapter.cmake | 8 +- 7 files changed, 504 insertions(+), 123 deletions(-) create mode 100644 cmake/format_options.cmake diff --git a/cmake/Modules/FindDOOCS.cmake b/cmake/Modules/FindDOOCS.cmake index 07182359..a6b76c0c 100644 --- a/cmake/Modules/FindDOOCS.cmake +++ b/cmake/Modules/FindDOOCS.cmake @@ -4,17 +4,23 @@ # # By default, only the client API is included. If the component "server" is specified, also the # server library will be used. If the component "zmq" is specified, the DOOCSdzmq library will be used as well. +# Currently support components: api, server, zmq, dapi, ddaq, daqreader, daqsndlib, timinglib # # returns: # DOOCS_FOUND : true or false, depending on whether the package was found # DOOCS_VERSION : the package version +# DOOCS_LIBRARIES : list of libraries to link against +# DOOCS_DIR : doocs library dir +# +# Also returns following for compatibility, however imported targets should be preferred for usage: # DOOCS_INCLUDE_DIRS : path to the include directory # DOOCS_LIBRARY_DIRS : path to the library directory -# DOOCS_LIBRARIES : list of libraries to link against # DOOCS_CXX_FLAGS : Flags needed to be passed to the c++ compiler # DOOCS_LINK_FLAGS : Flags needed to be passed to the linker # -# @author Martin Hierholzer, DESY +# For each component , an imported target DOOCS:: is returned. +# We support calling find_package(DOOCS COMPONENTS ) several times, for adding in different components . +# DOOCS_LIBRARIES will be updated to include all requested components as imported targets. # ####################################################################################################################### @@ -32,80 +38,170 @@ SET(DOOCS_FOUND 0) -list(PREPEND DOOCS_FIND_COMPONENTS doocsapi) +# if set, include the --no-as-needed linker flag which helps if inner dependencies between libs are not properly +# set inside the library binaries +set(DOOCS_noAsNeededFlag 1) -if (";${DOOCS_FIND_COMPONENTS};" MATCHES ";zmq;") - list(APPEND DOOCS_FIND_COMPONENTS doocsdzmq) - list(REMOVE_ITEM DOOCS_FIND_COMPONENTS zmq) -endif() +# note, helper functions and variables should also be prefixed with DOOCS_, since everything is exported to +# project calling find_package(DOOCS) -if (";${DOOCS_FIND_COMPONENTS};" MATCHES ";dapi;") - list(APPEND DOOCS_FIND_COMPONENTS doocsdapi) - list(REMOVE_ITEM DOOCS_FIND_COMPONENTS dapi) -endif() +function (DOOCS_addToPkgConfPath newPath) + if (NOT (":$ENV{PKG_CONFIG_PATH}:" MATCHES ":${newPath}:")) + set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_PATH}:${newPath}) + endif() +endfunction() -if (";${DOOCS_FIND_COMPONENTS};" MATCHES ";server;") - list(APPEND DOOCS_FIND_COMPONENTS serverlib) - list(REMOVE_ITEM DOOCS_FIND_COMPONENTS server) +if(DOOCS_DIR) + DOOCS_addToPkgConfPath(${DOOCS_DIR}/pkgconfig) endif() - -set(DOOCS_FIND_COMPONENTS_DDAQ false) -if (";${DOOCS_FIND_COMPONENTS};" MATCHES ";ddaq;") - # This library seems not yet to come with a pkg-config module - list(REMOVE_ITEM DOOCS_FIND_COMPONENTS ddaq) - set(DOOCS_FIND_COMPONENTS_DDAQ true) +DOOCS_addToPkgConfPath(/export/doocs/lib/pkgconfig) +if (NOT DOOCS_FIND_QUIETLY) + message("FindDOOCS: Using PKG_CONFIG_PATH=$ENV{PKG_CONFIG_PATH}") endif() -if (";${DOOCS_FIND_COMPONENTS};" MATCHES ";daqreader;") - list(APPEND DOOCS_FIND_COMPONENTS daqreaderlib) - list(REMOVE_ITEM DOOCS_FIND_COMPONENTS daqreader) -endif() - -# For newer cmake versions, the following foreach() can be replaced by this: -# list(TRANSFORM DOOCS_FIND_COMPONENTS PREPEND "doocs-") -foreach(component ${DOOCS_FIND_COMPONENTS}) - list(APPEND DOOCS_FIND_COMPONENTS_TRANSFORMED "doocs-${component}") -endforeach() -set(DOOCS_FIND_COMPONENTS ${DOOCS_FIND_COMPONENTS_TRANSFORMED}) - -include(FindPkgConfig) - -if(DEFINED DOOCS_DIR) - set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_PATH}:${DOOCS_DIR}/pkgconfig) +# We add the always - required API component +if (NOT (";${DOOCS_FIND_COMPONENTS};" MATCHES ";api;")) + list(PREPEND DOOCS_FIND_COMPONENTS "api") endif() -set(ENV{PKG_CONFIG_PATH} $ENV{PKG_CONFIG_PATH}:/export/doocs/lib/pkgconfig) -message("Using PKG_CONFIG_PATH=$ENV{PKG_CONFIG_PATH}") - -# WORK AROUND FOR BROKEN DOOCS PKG CONFIG FILES: Search for libgul14 which is required by DOOCS libraries -list(APPEND DOOCS_FIND_COMPONENTS libgul14) -# END OF WORK AROUND -pkg_check_modules(DOOCS REQUIRED ${DOOCS_FIND_COMPONENTS}) +function(expandDoocsComponentName longName shortName) + if (";${shortName};" MATCHES ";api;") + set(${longName} "doocs-doocsapi" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";zmq;") + set(${longName} "doocs-doocsdzmq" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";dapi;") + set(${longName} "doocs-doocsdapi" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";server;") + set(${longName} "doocs-serverlib" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";ddaq;") + set(${longName} "doocs-doocsddaq" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";daqreader;") + set(${longName} "doocs-daqreaderlib" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";daqsndlib;") + set(${longName} "doocs-daqsndlib" PARENT_SCOPE) + elseif (";${shortName};" MATCHES ";timinglib;") + # we define it as alias to doocs-doocsapi and check additional requirements + set(${longName} "doocs-doocsapi" PARENT_SCOPE) + else() + set(${longName} "${shortName}" PARENT_SCOPE) + endif() +endfunction() -string(REPLACE ";" " " DOOCS_CFLAGS "${DOOCS_CFLAGS}") -string(REPLACE ";" " " DOOCS_LDFLAGS "${DOOCS_LDFLAGS}") +include(FindPkgConfig) # thread libraries are required by DOOCS but seem not to be added through pkgconfig... find_package(Threads REQUIRED) -set(DOOCS_DIR "${DOOCS_doocs-doocsapi_LIBDIR}") -set(DOOCS_VERSION "${DOOCS_doocs-doocsapi_VERSION}") +# We expect that find_package will be called more than once, with different components. +# Since imported targets cannot be replaced, the only clean solution is to define an imported component per pkgconfig component. +# pkg_check_modules can be called more than once, with different components. +# We define DOOCS_FIND_COMPONENTS_ALL to collect all asked-for components +foreach(component ${DOOCS_FIND_COMPONENTS}) + expandDoocsComponentName(componentLongName ${component}) + if (NOT ";${DOOCS_FIND_COMPONENTS_ALL};" MATCHES ";${componentLongName};") + list(APPEND DOOCS_FIND_COMPONENTS_ALL ${componentLongName}) + # IMPORTED_TARGET means also imported target PkgConfig::DOOCS will be defined. GLOBAL so we can alias. + pkg_check_modules(DOOCS_${component} REQUIRED IMPORTED_TARGET GLOBAL ${componentLongName}) + if (DOOCS_${component}_FOUND) + set(importedTarget PkgConfig::DOOCS_${component}) + if (NOT DOOCS_FIND_QUIETLY) + message(STATUS "FindDOOCS: imported target is ${importedTarget}. Defining alias DOOCS::${component}") + endif() + add_library(DOOCS::${component} ALIAS ${importedTarget}) + set(DOOCS_LIBRARIES ${DOOCS_LIBRARIES} "DOOCS::${component}") + + if (${component} STREQUAL "api") + # add Threads lib only if not yet in + get_target_property(doocsLinkLibs ${importedTarget} INTERFACE_LINK_LIBRARIES) + if (NOT (";${doocsLinkLibs};" MATCHES ";Threads::Threads;")) + set_target_properties(${importedTarget} PROPERTIES INTERFACE_LINK_LIBRARIES "${doocsLinkLibs};Threads::Threads" ) + endif() + if(DOOCS_noAsNeededFlag) + get_target_property(doocsLinkFlags ${importedTarget} INTERFACE_LINK_OPTIONS) + string(REGEX REPLACE ".*-NOTFOUND" "" doocsLinkFlags "${doocsLinkFlags}") + set_target_properties(${importedTarget} PROPERTIES INTERFACE_LINK_OPTIONS "-Wl,--no-as-needed;${doocsLinkFlags}") + endif() + else() + # since we did some changes on DOOCS::api, add that as implicit dependency of the other components + # This makes sure projects not explicitly linking to DOOCS::api have the changes + get_target_property(doocsLinkLibs ${importedTarget} INTERFACE_LINK_LIBRARIES) + string(REGEX REPLACE ".*-NOTFOUND" "" doocsLinkLibs "${doocsLinkLibs}") + set_target_properties(${importedTarget} PROPERTIES INTERFACE_LINK_LIBRARIES "DOOCS::api;${doocsLinkLibs}") + endif() + + # print some info about targets + get_target_property(doocsIncDirs ${importedTarget} INTERFACE_INCLUDE_DIRECTORIES) + message(VERBOSE " include dirs: ${doocsIncDirs}") + get_target_property(doocsCxxFlags ${importedTarget} INTERFACE_COMPILE_OPTIONS) + message(VERBOSE " compile options: ${doocsCxxFlags}") + get_target_property(doocsLinkFlags ${importedTarget} INTERFACE_LINK_OPTIONS) + message(VERBOSE " link options: ${doocsLinkFlags}") + get_target_property(doocsLinkLibs ${importedTarget} INTERFACE_LINK_LIBRARIES) + message(VERBOSE " link libs: ${doocsLinkLibs}") + get_target_property(doocsLinkDirs ${importedTarget} INTERFACE_LINK_DIRECTORIES) + message(VERBOSE " link dirs: ${doocsLinkDirs}") + + else() + message(FATAL_ERROR "DOOCS component ${component} not found!") + endif() + endif() + if(${component} STREQUAL "timinglib") + # Find doocs/TimingWord.h from dev-doocs-doocstiminglib + # which unfortunately does not provide pkgconfig + find_path(DOOCS_timingLib_INCLUDE_DIRS doocs/TimingWord.h REQUIRED PATHS ${DOOCS_api_INCLUDE_DIRS}) + if (NOT DOOCS_timingLib_INCLUDE_DIRS) + message(FATAL_ERROR "FindDOOCS: Failed to find TimingWord.h") + set(DOOCS_timingLib_FOUND FALSE) + else() + if (NOT DOOCS_FIND_QUIETLY) + message(STATUS "FindDOOCS: Found timinglib, include dirs: ${DOOCS_timingLib_INCLUDE_DIRS}") + endif() + set(DOOCS_timingLib_FOUND TRUE) + # include dir is always same as for api component, so alias is sufficient + add_library(DOOCS::${component} ALIAS PkgConfig::DOOCS_api) + endif() + endif() +endforeach() +#message(DEBUG "complete list of searched components: ${DOOCS_FIND_COMPONENTS_ALL}") + +# append to list (arg) to space-separated list, only include not yet existing elements +macro(DOOCS_appendListToList list arg) + foreach(DOOCS_appendListToList_arg ${arg}) + string(FIND " ${${list}} " " ${DOOCS_appendListToList_arg} " DOOCS_appendListToList_pos) + if (${DOOCS_appendListToList_pos} EQUAL -1) + string(APPEND ${list} " ${DOOCS_appendListToList_arg}") + # strip leading spaces since they might cause problems + string(REGEX REPLACE "^[ \t]+" "" ${list} "${${list}}") + endif() + endforeach() +endmacro() + +# note, pkg_check_modules output variables _VERSION and _LIBDIR are different, +# depending on length of given module list! +set(DOOCS_DIR "${DOOCS_api_LIBDIR}") +set(DOOCS_VERSION "${DOOCS_api_VERSION}") + +set(DOOCS_LIBRARIES ${DOOCS_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + +# following lines are compatibiliy layer, required only if using project does not make use of imported targets +# here we should gather from all components +set(DOOCS_CFLAGS "") +set(DOOCS_LDFLAGS "") +if(DOOCS_noAsNeededFlag) + set(DOOCS_LDFLAGS "-Wl,--no-as-needed") +endif() +set(DOOCS_INCLUDE_DIRS "") +set(DOOCS_LIBRARY_DIRS "") +foreach(component api zmq server ddaq daqreader daqsndlib) + DOOCS_appendListToList(DOOCS_CFLAGS "${DOOCS_${component}_CFLAGS}") + DOOCS_appendListToList(DOOCS_LDFLAGS "${DOOCS_${component}_LDFLAGS}") + DOOCS_appendListToList(DOOCS_INCLUDE_DIRS "${DOOCS_${component}_INCLUDE_DIRS}") + DOOCS_appendListToList(DOOCS_LIBRARY_DIRS "${DOOCS_${component}_LIBRARY_DIRS}") +endforeach() set(DOOCS_CXX_FLAGS ${DOOCS_CFLAGS}) -set(DOOCS_LIBRARIES ${DOOCS_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} tinemt) -set(DOOCS_LINKER_FLAGS "-Wl,--no-as-needed") +set(DOOCS_LINKER_FLAGS ${DOOCS_LDFLAGS}) set(DOOCS_LINK_FLAGS ${DOOCS_LINKER_FLAGS}) -set(COMPONENT_DIRS "") -if(DOOCS_FIND_COMPONENTS_DDAQ) - message("Searching for libDOOCSddaq.so") - FIND_PATH(DOOCS_DIR_ddaq libDOOCSddaq.so - ${DOOCS_DIR} - ) - set(DOOCS_LIBRARIES ${DOOCS_LIBRARIES} DOOCSddaq timinginfo daqevstat DAQFSM TTF2XML xerces-c BM TTF2evutl DAQsvrutil) - set(COMPONENT_DIRS ${COMPONENT_DIRS} DOOCS_DIR_ddaq) -endif() - # use a macro provided by CMake to check if all the listed arguments are valid and set DOOCS_FOUND accordingly include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(DOOCS REQUIRED_VARS DOOCS_DIR ${COMPONENT_DIRS} VERSION_VAR DOOCS_VERSION ) - +FIND_PACKAGE_HANDLE_STANDARD_ARGS(DOOCS REQUIRED_VARS DOOCS_DIR VERSION_VAR DOOCS_VERSION ) diff --git a/cmake/Modules/FindGccAtomic.cmake b/cmake/Modules/FindGccAtomic.cmake index 5b6e233e..284f7bed 100644 --- a/cmake/Modules/FindGccAtomic.cmake +++ b/cmake/Modules/FindGccAtomic.cmake @@ -1,7 +1,7 @@ # This scripts finds gcc's built-in atomic shared library (libatomic.so). # It is required to link against this library on gcc when using 16 byte atomics, even when running on x86_64/amd64. -FIND_LIBRARY(GCCLIBATOMIC_LIBRARY NAMES atomic atomic.so.1 libatomic.so.1 +FIND_LIBRARY(GccAtomic_LIBRARY NAMES atomic atomic.so.1 libatomic.so.1 HINTS $ENV{HOME}/local/lib64 $ENV{HOME}/local/lib @@ -15,5 +15,10 @@ FIND_LIBRARY(GCCLIBATOMIC_LIBRARY NAMES atomic atomic.so.1 libatomic.so.1 /lib ) +# we don't want to export the full path since this introduces problems with yocto cross-compilation +# so replace by simple lib name +if (GccAtomic_LIBRARY) + set(GccAtomic_LIBRARY "atomic") +endif() include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GCCLIBATOMIC DEFAULT_MSG GCCLIBATOMIC_LIBRARY) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GccAtomic DEFAULT_MSG GccAtomic_LIBRARY) diff --git a/cmake/PROJECT_NAMEConfig.cmake.in.in b/cmake/PROJECT_NAMEConfig.cmake.in.in index 17f556a0..b07f6352 100644 --- a/cmake/PROJECT_NAMEConfig.cmake.in.in +++ b/cmake/PROJECT_NAMEConfig.cmake.in.in @@ -11,6 +11,14 @@ # @PROJECT_NAME@_CXX_FLAGS : additional C++ compiler flags # @PROJECT_NAME@_LINKER_FLAGS : additional linker flags # +# Note for exporting project: +# If @PROJECT_NAME@ sets PROVIDES_EXPORTED_TARGETS, we also generate target EXPORTS. In this case the its CMakeLists.txt +# must also have +# install(TARGETS EXPORT ${PROJECT_NAME}Targets) +# before. The target will be named ChimeraTK::${PROJECT_NAME} . +# We keep above mentioned return variables for compatibility, but finally, when all projects use imported targets, +# all execept _FOUND and _VERSION will be superfluous. +# # @author Martin Killenberg, DESY # ####################################################################################################################### @@ -27,42 +35,73 @@ # ####################################################################################################################### -# The library itself must be "searched" using the FIND_LIBRARY command in the known install directory, to set -# the variable properly -FIND_LIBRARY(@PROJECT_NAME@_LIBRARY @PROJECT_NAME@ - @CMAKE_INSTALL_PREFIX@/lib - NO_DEFAULT_PATH -) +# In case of packages with components, loading dependencies can cause trouble if required component list are differ. +# E.g. if Boost is required from the project, and also required from the dependency, but with less components, +# and the dependency is resolved later, then Boost_LIBRARIES content will be different than expected. +# To protect against this, save state and restore it later. +# Since imported targets are never unloaded, the loaded dependency should still work. +set(Boost_LIBRARIES_savedState_@PROJECT_NAME@ ${Boost_LIBRARIES}) +# this code loads public dependencies @@PROJECT_NAME@_PUBLIC_DEPENDENCIES_L@ +set(Boost_LIBRARIES ${Boost_LIBRARIES_savedState_@PROJECT_NAME@}) # Since this file is already part of the installation to be found, the configuration can be hard-coded at # installation time set(@PROJECT_NAME@_VERSION "@@PROJECT_NAME@_SOVERSION@") -set(@PROJECT_NAME@_INCLUDE_DIRS @@PROJECT_NAME@_INCLUDE_DIRS@) -set(@PROJECT_NAME@_LIBRARY_DIRS @@PROJECT_NAME@_LIBRARY_DIRS@) -if(@@PROJECT_NAME@_HAS_LIBRARY@) - set(@PROJECT_NAME@_LIBRARIES ${@PROJECT_NAME@_LIBRARY} @@PROJECT_NAME@_LIBRARIES@) -else() - set(@PROJECT_NAME@_LIBRARIES @@PROJECT_NAME@_LIBRARIES@) -endif() -set(@PROJECT_NAME@_CXX_FLAGS "@@PROJECT_NAME@_CXX_FLAGS@") -set(@PROJECT_NAME@_LINKER_FLAGS "@@PROJECT_NAME@_LINKER_FLAGS@ @@PROJECT_NAME@_LINK_FLAGS@") -set(@PROJECT_NAME@_LINK_FLAGS "@@PROJECT_NAME@_LINKER_FLAGS@ @@PROJECT_NAME@_LINK_FLAGS@") set(@PROJECT_NAME@_PREFIX "@CMAKE_INSTALL_PREFIX@") # Use a macro provided by CMake to check if all the listed arguments are valid and set @PROJECT_NAME@_FOUND accordingly. # This is mainly important to check the version. -set(@PROJECT_NAME@_FOUND 0) include(FindPackageHandleStandardArgs) -# The FOUND_VAR option in FIND_PACKAGE_HANDLE_STANDARD_ARGS was introduced in cmake-2.8.11, but Ubuntu 12.04 has cmake-2.8.7 only. -# Thus we use a work around here for older cmake versions. -if("${CMAKE_VERSION}" VERSION_LESS 2.8.11) - # The old version always provides a variable with upper case project name, so we just copy that - FIND_PACKAGE_HANDLE_STANDARD_ARGS(@PROJECT_NAME@ REQUIRED_VARS @PROJECT_NAME@_PREFIX VERSION_VAR @PROJECT_NAME@_VERSION) - STRING(TOUPPER "@PROJECT_NAME@" PROJECT_NAME_UPPERCASE) - set(@PROJECT_NAME@_FOUND ${${PROJECT_NAME_UPPERCASE}_FOUND}) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(@PROJECT_NAME@ REQUIRED_VARS @PROJECT_NAME@_PREFIX VERSION_VAR @PROJECT_NAME@_VERSION FOUND_VAR @PROJECT_NAME@_FOUND) + +# switch for exported target. We don't do this automatically, because the calling CMakeLists.txt +# first must be edited so that it properly defines PUBLIC set of compile and link options +if(@PROVIDES_EXPORTED_TARGETS@) + + @PACKAGE_INIT@ + + # include cmake's auto-generated exports file + include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") + # this will set ${PROJECT_NAME}_FOUND if required components are missing + check_required_components(@PROJECT_NAME@) + else() - FIND_PACKAGE_HANDLE_STANDARD_ARGS(@PROJECT_NAME@ REQUIRED_VARS @PROJECT_NAME@_PREFIX VERSION_VAR @PROJECT_NAME@_VERSION FOUND_VAR @PROJECT_NAME@_FOUND) -endif() + if(@@PROJECT_NAME@_HAS_LIBRARY@) + # has true compiled library as output + # The library itself must be "searched" using the FIND_LIBRARY command in the known install directory, to set + # the variable properly + FIND_LIBRARY(@PROJECT_NAME@_LIBRARY @PROJECT_NAME@ + @CMAKE_INSTALL_PREFIX@/lib + NO_DEFAULT_PATH + ) + if(NOT @PROJECT_NAME@_LIBRARY) + set(@PROJECT_NAME@_FOUND FALSE) + message(SEND_ERROR "FIND_LIBRARY returned error: ${@PROJECT_NAME@_LIBRARY}") + else() + # prepend it to lib list + set(@PROJECT_NAME@_LIBRARIES ${@PROJECT_NAME@_LIBRARY} ${@PROJECT_NAME@_LIBRARIES}) + endif() + endif() +endif() + +# Compatibility layer definitions. +# The following variables are generated automatically for projects supporting cmake-exports. +# Otherwise, values must be provided as inputs to create_cmake_config_files. +# The types of generated lists are precisely as in old DeviceAccess config +# inc dirs, lib dirs, libs are ";" separated +# cxx flags, link flags are " " separated +# ";" separated +set(@PROJECT_NAME@_INCLUDE_DIRS @@PROJECT_NAME@_INCLUDE_DIRS@) +# ";" separated +set(@PROJECT_NAME@_LIBRARY_DIRS @@PROJECT_NAME@_LIBRARY_DIRS@) +# ";" separated +set(@PROJECT_NAME@_LIBRARIES ${@PROJECT_NAME@_LIBRARIES} @@PROJECT_NAME@_LIBRARIES@) +# " " separated +set(@PROJECT_NAME@_CXX_FLAGS "@@PROJECT_NAME@_CXX_FLAGS@") +# " " separated +set(@PROJECT_NAME@_LINKER_FLAGS "@@PROJECT_NAME@_LINKER_FLAGS@ @@PROJECT_NAME@_LINK_FLAGS@") +# " " separated +set(@PROJECT_NAME@_LINK_FLAGS "@@PROJECT_NAME@_LINKER_FLAGS@ @@PROJECT_NAME@_LINK_FLAGS@") diff --git a/cmake/add_dependency.cmake b/cmake/add_dependency.cmake index 539efe02..bccd9196 100644 --- a/cmake/add_dependency.cmake +++ b/cmake/add_dependency.cmake @@ -32,6 +32,9 @@ FUNCTION(add_dependency dependency_project_name required_version) foreach(arg IN LISTS ARGN) SET(components ${components} ${arg}) endforeach() + if("${required_version}" MATCHES "REQUIRED") + message(FATAL_ERROR "wrong usage: add_dependency(${dependency_project_name} ${required_version} ...)") + endif() FIND_PACKAGE(${dependency_project_name} ${required_version} COMPONENTS ${components}) include_directories(SYSTEM ${${dependency_project_name}_INCLUDE_DIRS} ${${dependency_project_name}_INCLUDE_DIR}) link_directories(${${dependency_project_name}_LIBRARY_DIRS}) @@ -50,3 +53,12 @@ FUNCTION(add_dependency dependency_project_name required_version) SET(${dependency_project_name}_PREFIX ${${dependency_project_name}_PREFIX} PARENT_SCOPE) ENDFUNCTION(add_dependency) +# make sure that cmake finds modules provided by project-template. +# since with new cmake concept for imported targets, dependencies also search for implicit dependencies, +# all projects using add_dependency also require this module path. +set(_projectTemplateModulePath ${CMAKE_SOURCE_DIR}/cmake/Modules) +# substr search is better than regex if paths have special characters +string(FIND ":${CMAKE_MODULE_PATH}:" ":${_projectTemplateModulePath}:" _projectTemplateModulePathPos) +if (${_projectTemplateModulePathPos} EQUAL -1) + list(APPEND CMAKE_MODULE_PATH "${_projectTemplateModulePath}") +endif() diff --git a/cmake/create_cmake_config_files.cmake b/cmake/create_cmake_config_files.cmake index 6924fac7..70922052 100644 --- a/cmake/create_cmake_config_files.cmake +++ b/cmake/create_cmake_config_files.cmake @@ -5,13 +5,15 @@ # # Expects the following input variables: # ${PROJECT_NAME}_SOVERSION - version of the .so library file (or just MAJOR.MINOR without the patch level) +# ${PROJECT_NAME}_MEXFLAGS - (optional) mex compiler flags +# +# and only required, if project does not yet provide cmake-export: # ${PROJECT_NAME}_INCLUDE_DIRS - list include directories needed when compiling against this project # ${PROJECT_NAME}_LIBRARY_DIRS - list of library directories needed when linking against this project # ${PROJECT_NAME}_LIBRARIES - list of additional libraries needed when linking against this project. The library # provided by the project will be added automatically # ${PROJECT_NAME}_CXX_FLAGS - list of additional C++ compiler flags needed when compiling against this project # ${PROJECT_NAME}_LINKER_FLAGS - list of additional linker flags needed when linking against this project -# ${PROJECT_NAME}_MEXFLAGS - (optional) mex compiler flags # ####################################################################################################################### @@ -27,51 +29,242 @@ # ####################################################################################################################### +macro(handleGeneratorExprs var) + # Unfortunately, I do not see a solution for correct generator expression handling by cmake. So instead, do some simple replacements. + # $ defines path relative to install location. + string(REGEX REPLACE "\\$" "${CMAKE_INSTALL_PREFIX}/\\1" ${var} "${${var}}") + # remove any other generator expression + string(REGEX REPLACE "\\$<.*>" "" ${var} "${${var}}") +endmacro() + +# append element-wise to (space-separated!) list, but only if not yet existing +# arg is allowed to be space-separated or ;-separated list +macro(appendToList list arg) + string(REPLACE " " ";" appendToList_args "${arg}") + foreach(item ${appendToList_args}) + handleGeneratorExprs(item) + string(FIND " ${${list}} " " ${item} " appendToList_pos) + if (${appendToList_pos} EQUAL -1) + string(APPEND ${list} " ${item}") + # strip leading spaces since they might cause problems + string(REGEX REPLACE "^[ \t]+" "" ${list} "${${list}}") + endif() + endforeach() +endmacro() +# prepend element-wise to (space-separated!) list, but only if not yet existing +# arg is allowed to be space-separated or ;-separated list +macro(prependToList list arg) + string(REPLACE " " ";" prependToList_args "${arg}") + foreach(item ${prependToList_args}) + handleGeneratorExprs(item) + string(FIND " ${${list}} " " ${item} " prependToList_pos) + if (${prependToList_pos} EQUAL -1) + string(PREPEND ${list} "${item} ") + # strip trailing spaces since they might cause problems + string(REGEX REPLACE "[ \t]+$" "" ${list} "${${list}}") + endif() + endforeach() +endmacro() + +# for lib, which might be lib File or linker flag or imported target, +# puts recursively resolved library list into ${linkLibs}, which will contain a library file list +# and recursively resolve link flags into ${linkFlags} +# Note, since some projects ignore libDirs, we put them also into linkFlags. +function(resolveImportedLib lib linkLibs linkFlags libDirs incDirs cxxFlags) + set(linkLibs1 "") + set(linkFlags1 "") + set(libDirs1 "") + set(incDirs1 "") + set(cxxFlags1 "") + if(lib MATCHES "/") # library name contains slashes: link against the a file path name + appendToList(linkLibs1 "${lib}") + elseif(lib MATCHES "^[ \t]*-l") + # library name does not contain slashes but already the -l option: directly quote it + # although technically a linker flag, we put it to lib list because order matters sometimes + appendToList(linkLibs1 "${lib}") + elseif(lib MATCHES "::") # library name is an imported target - we need to resolve it for Makefiles + if (NOT TARGET ${lib}) + message(FATAL_ERROR "dependency ${lib} not available as target, maybe find_package was forgotten?") + endif() + get_target_property(_libraryType ${lib} TYPE) + # boost exports appear as UNKNOWN_LIBRARY but also have target location + if ((${_libraryType} MATCHES SHARED_LIBRARY) OR (${_libraryType} MATCHES STATIC_LIBRARY) OR (${_libraryType} MATCHES UNKNOWN_LIBRARY)) + if(";${lib};" MATCHES ";.*::${PROJECT_NAME};") + # We cannot find target library location of this project via target properties at this point. + # Therefore, we simply assume that by convention, all our libs are installed into ${CMAKE_INSTALL_PREFIX}/lib. + # Exceptions are allowed if -L is already in linker flags + appendToList(linkFlags1 "-L${CMAKE_INSTALL_PREFIX}/lib") + appendToList(libDirs1 "${CMAKE_INSTALL_PREFIX}/lib") + appendToList(linkLibs1 "-l${PROJECT_NAME}") + else() + get_property(lib_loc TARGET ${lib} PROPERTY LOCATION) + #message("imported target ${lib} is actual library. location=${lib_loc}") + appendToList(linkLibs1 "${lib_loc}") + endif() + endif() + get_target_property(_linkLibs ${lib} INTERFACE_LINK_LIBRARIES) + if (NOT "${_linkLibs}" MATCHES "-NOTFOUND") + message(VERBOSE "imported target ${lib} is interface, recursively go over its interface requirements ${_linkLibs}") + foreach(_lib ${_linkLibs}) + if (${lib} STREQUAL ${_lib}) + message(FATAL_ERROR "self-reference in dependencies of ${_lib}! Aborting recursion.") + endif() + resolveImportedLib(${_lib} linkLibs2 linkFlags2 libDirs2 incDirs2 cxxFlags2) + appendToList(linkLibs1 "${linkLibs2}") + appendToList(linkFlags1 "${linkFlags2}") + appendToList(libDirs1 "${libDirs2}") + appendToList(incDirs1 "${incDirs2}") + appendToList(cxxFlags1 "${cxxFlags2}") + endforeach() + endif() + + get_target_property(_incDirs ${lib} INTERFACE_INCLUDE_DIRECTORIES) + if (_incDirs) + appendToList(incDirs1 "${_incDirs}") + endif() + get_target_property(_cxxFlags ${lib} INTERFACE_COMPILE_OPTIONS) + if (_cxxFlags) + appendToList(cxxFlags1 "${_cxxFlags}") + endif() + get_target_property(_cxxFlags ${lib} INTERFACE_COMPILE_DEFINITIONS) + if (_cxxFlags) + foreach(flag ${_cxxFlags}) + appendToList(cxxFlags1 "-D${flag}") + endforeach() + endif() + get_target_property(_linkFlags ${lib} INTERFACE_LINK_OPTIONS) + if (_linkFlags) + appendToList(linkFlags1 "${_linkFlags}") + endif() + get_target_property(_linkDirs ${lib} INTERFACE_LINK_DIRECTORES) + if (_linkDirs) + foreach(flag ${_linkDirs}) + handleGeneratorExprs(flag) + appendToList(linkFlags1 "-L${flag}") + appendToList(libDirs1 "${flag}") + endforeach() + endif() + + else() + # link against library with -l option + handleGeneratorExprs(lib) + # although technically a linker flag, we put it to lib list because for some linker flags, it is important + # that they come before libs + appendToList(linkLibs1 "-l${lib}") + endif() + + set(${linkLibs} "${linkLibs1}" PARENT_SCOPE) + set(${linkFlags} "${linkFlags1}" PARENT_SCOPE) + set(${libDirs} "${libDirs1}" PARENT_SCOPE) + set(${incDirs} "${incDirs1}" PARENT_SCOPE) + set(${cxxFlags} "${cxxFlags1}" PARENT_SCOPE) +endfunction() + + +# if we already have cmake-exports for this project: +# sets the vars ${PROJECT_NAME}_INCLUDE_DIRS, ${PROJECT_NAME}_CXX_FLAGS, ${PROJECT_NAME}_LIBRARY_DIRS, +# ${PROJECT_NAME}_LINKER_FLAGS, and ${PROJECT_NAME}_LIBRARIES +# so that compatibility layer is provided automatically. +if(${PROVIDES_EXPORTED_TARGETS}) + # imported targets should be namespaced, so define namespaced alias + add_library(ChimeraTK::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + + resolveImportedLib(ChimeraTK::${PROJECT_NAME} linkLibs linkFlags libDirs incDirs cxxFlags) + + # printing results will help resolve problems with auto-generated compatibility layer + message(VERBOSE "explicitly provided compatibility layer,") + message(VERBOSE " old libset: ${${PROJECT_NAME}_LIBRARIES}") + message(VERBOSE " old linkflags: ${${PROJECT_NAME}_LINKER_FLAGS}") + message(VERBOSE " old cxxflags: ${${PROJECT_NAME}_CXX_FLAGS}") + message(VERBOSE " old incDirs: ${${PROJECT_NAME}_INCLUDE_DIRS}") + message(VERBOSE " old libDirs: ${${PROJECT_NAME}_LIBRARY_DIRS}") + set(${PROJECT_NAME}_INCLUDE_DIRS "${incDirs}" ) + set(${PROJECT_NAME}_LIBRARY_DIRS "${libDirs}" ) + set(${PROJECT_NAME}_LIBRARIES "${linkLibs}" ) + set(${PROJECT_NAME}_CXX_FLAGS "${cxxFlags}" ) + set(${PROJECT_NAME}_LINKER_FLAGS "${linkFlags}" ) + message(VERBOSE "will be overwritten by automatically generated compatibility layer from cmake-exports,") + message(VERBOSE " new libset: ${${PROJECT_NAME}_LIBRARIES}") + message(VERBOSE " new linkflags: ${${PROJECT_NAME}_LINKER_FLAGS}") + message(VERBOSE " new cxxflags: ${${PROJECT_NAME}_CXX_FLAGS}") + message(VERBOSE " new incDirs: ${${PROJECT_NAME}_INCLUDE_DIRS}") + message(VERBOSE " new libDirs: ${${PROJECT_NAME}_LIBRARY_DIRS}") +endif() + # create variables for standard makefiles and pkgconfig set(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "${${PROJECT_NAME}_CXX_FLAGS}") string(REPLACE " " ";" LIST "${${PROJECT_NAME}_INCLUDE_DIRS}") foreach(INCLUDE_DIR ${LIST}) - set(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "${${PROJECT_NAME}_CXX_FLAGS_MAKEFILE} -I${INCLUDE_DIR}") + appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "-I${INCLUDE_DIR}") endforeach() -set(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINKER_FLAGS} ${${PROJECT_NAME}_LINK_FLAGS}") +# some old code still might call linker flags _LINK_FLAGS, also include that +appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINK_FLAGS}") string(REPLACE " " ";" LIST "${${PROJECT_NAME}_LIBRARY_DIRS}") foreach(LIBRARY_DIR ${LIST}) - set(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE} -L${LIBRARY_DIR}") + appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "-L${LIBRARY_DIR}") endforeach() -string(REPLACE " " ";" LIST "${PROJECT_NAME} ${${PROJECT_NAME}_LIBRARIES}") -foreach(LIBRARY ${LIST}) - if(LIBRARY MATCHES "/") # library name contains slashes: link against the a file path name - set(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE} ${LIBRARY}") - elseif(LIBRARY MATCHES "^-l") # library name does not contain slashes but already the -l option: directly quote it - set(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE} ${LIBRARY}") - elseif(LIBRARY MATCHES "::") # library name is an exported target - we need to resolve it for Makefiles - get_property(lib_loc TARGET ${LIBRARY} PROPERTY LOCATION) - string(APPEND ${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE " ${lib_loc}") - else() # link against library with -l option - set(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE} -l${LIBRARY}") - endif() -endforeach() +if(${PROVIDES_EXPORTED_TARGETS}) + # libraries have already been resolved above, add them to linker flags + appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${${PROJECT_NAME}_LIBRARIES}") +else() + # recursive resolution of linker flags is necessary, since dependencies could contain imported targets + string(REPLACE " " ";" LIST "${PROJECT_NAME} ${${PROJECT_NAME}_LIBRARIES}") + foreach(LIBRARY ${LIST}) + resolveImportedLib(${LIBRARY} linkLibs linkFlags libDirs incDirs cxxFlags) + + appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "${cxxFlags}") + + string(REPLACE " " ";" LIST "${incDirs}") + foreach(INCLUDE_DIR ${LIST}) + appendToList(${PROJECT_NAME}_CXX_FLAGS_MAKEFILE "-I${INCLUDE_DIR}") + endforeach() + + # for some linker flags, it is important that they come before the libs + prependToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${linkFlags}") + appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "${linkLibs}") + string(REPLACE " " ";" LIST "${libDirs}") + foreach(LIBRARY_DIR ${LIST}) + appendToList(${PROJECT_NAME}_LINKER_FLAGS_MAKEFILE "-L${LIBRARY_DIR}") + endforeach() + endforeach() +endif() set(${PROJECT_NAME}_PUBLIC_DEPENDENCIES_L "") foreach(DEPENDENCY ${${PROJECT_NAME}_PUBLIC_DEPENDENCIES}) + # we only care about required dependencies: if some lib has an optional dependency and is built against it + # after it has been found, the dependency became mandatory for downstream libs. + # Note, keyword REQUIRED as not according to spec but it works... string(APPEND ${PROJECT_NAME}_PUBLIC_DEPENDENCIES_L "find_package(${DEPENDENCY} REQUIRED)\n") endforeach() if(TARGET ${PROJECT_NAME}) - set(${PROJECT_NAME}_HAS_LIBRARY 1) + # set _HAS_LIBRARY only if we have a true library, interface libraries (introduced for imported targets, + # e.g. header-only library) don't count. + get_target_property(targetLoc ${PROJECT_NAME} TYPE) + if(NOT "INTERFACE_LIBRARY" MATCHES "${targetLoc}") + set(${PROJECT_NAME}_HAS_LIBRARY 1) + endif() else() set(${PROJECT_NAME}_HAS_LIBRARY 0) endif() + # we have nested @-statements, so we have to parse twice: # create the cmake find_package configuration file +set(PACKAGE_INIT "@PACKAGE_INIT@") # replacement handled later, so leave untouched here +cmake_policy(SET CMP0053 NEW) # less warnings about irrelevant stuff in comments configure_file(cmake/PROJECT_NAMEConfig.cmake.in.in "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" @ONLY) -configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" @ONLY) +if(${PROVIDES_EXPORTED_TARGETS}) + # we will configure later +else() + set(PACKAGE_INIT "") # required to avoid parse error + configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" @ONLY) +endif() configure_file(cmake/PROJECT_NAMEConfigVersion.cmake.in.in "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake.in" @ONLY) configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" @ONLY) @@ -83,19 +276,47 @@ configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}-config.in "${PROJECT_ configure_file(cmake/PROJECT_NAME.pc.in.in "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}.pc.in" @ONLY) configure_file(${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}.pc.in "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc" @ONLY) - -# install cmake find_package configuration file -install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - DESTINATION lib/cmake/${PROJECT_NAME} COMPONENT dev) -install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION lib/cmake/${PROJECT_NAME} COMPONENT dev) - -# install same cmake configuration file another time into the Modules cmake subdirectory for compatibility reasons -install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - DESTINATION share/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules RENAME Find${PROJECT_NAME}.cmake COMPONENT dev) - # install script for Makefiles install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config DESTINATION bin COMPONENT dev) # install configuration file for pkgconfig install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc" DESTINATION share/pkgconfig COMPONENT dev) + + +if(${PROVIDES_EXPORTED_TARGETS}) + # imported targets should be namespaced, so define namespaced alias + add_library(ChimeraTK::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + + # generate and install export file + install(EXPORT ${PROJECT_NAME}Targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ChimeraTK:: + DESTINATION "lib/cmake/${PROJECT_NAME}" + ) + + include(CMakePackageConfigHelpers) + # create config file + # although @ONLY arg is not supported, this behaves in the same way. + configure_package_config_file("${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}" + ) + + # remove any previously installed share/cmake-xx/Modules/Find.cmake from this project since it does not harmonize with new Config + set(fileToRemove "share/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules/Find${PROJECT_NAME}.cmake") + install(CODE "FILE(REMOVE ${CMAKE_INSTALL_PREFIX}/${fileToRemove})") +else() + # install same cmake configuration file another time into the Modules cmake subdirectory for compatibility reasons + # We do this only if we did not move yet to exported target, since it does not harmonize + install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + DESTINATION share/cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/Modules RENAME Find${PROJECT_NAME}.cmake COMPONENT dev) + +endif() + +# install cmake find_package configuration file +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "lib/cmake/${PROJECT_NAME}" + COMPONENT dev +) diff --git a/cmake/format_options.cmake b/cmake/format_options.cmake new file mode 100644 index 00000000..ed97831e --- /dev/null +++ b/cmake/format_options.cmake @@ -0,0 +1,8 @@ + +# function that reformat flags so they become compatible with target_compile_options, target_link_options etc. +function(formatOptionsAsArray outVar inVar) + string(REGEX REPLACE " +" ";" tmpVar "${inVar}") + string(REGEX REPLACE "^;+" "" tmpVar "${tmpVar}") + string(REGEX REPLACE ";+$" "" tmpVar "${tmpVar}") + set(${outVar} "${tmpVar}" PARENT_SCOPE) +endfunction() diff --git a/cmake/set_control_system_adapter.cmake b/cmake/set_control_system_adapter.cmake index a9521695..e95c1a13 100644 --- a/cmake/set_control_system_adapter.cmake +++ b/cmake/set_control_system_adapter.cmake @@ -28,22 +28,22 @@ # Select control system adapter IF(ADAPTER STREQUAL "OPCUA") message("Building against the OPC UA ControlSystemAdater") - add_dependency(ChimeraTK-ControlSystemAdapter-OPCUAAdapter REQUIRED) + add_dependency(ChimeraTK-ControlSystemAdapter-OPCUAAdapter 03.00 REQUIRED) set(Adapter_LINK_FLAGS ${ChimeraTK-ControlSystemAdapter-OPCUAAdapter_LINK_FLAGS}) set(Adapter_LIBRARIES ${ChimeraTK-ControlSystemAdapter-OPCUAAdapter_LIBRARIES}) ELSEIF(ADAPTER STREQUAL "DOOCS") message("Building against the DOOCS ControlSystemAdater") - add_dependency(ChimeraTK-ControlSystemAdapter-DoocsAdapter REQUIRED) + add_dependency(ChimeraTK-ControlSystemAdapter-DoocsAdapter 01.08 REQUIRED) set(Adapter_LINK_FLAGS ${ChimeraTK-ControlSystemAdapter-DoocsAdapter_LINK_FLAGS}) set(Adapter_LIBRARIES ${ChimeraTK-ControlSystemAdapter-DoocsAdapter_LIBRARIES}) ELSEIF(ADAPTER STREQUAL "EPICSIOC") message("Building against the EPICS IOC ControlSystemAdater") - add_dependency(ChimeraTK-ControlSystemAdapter-EPICS-IOC-Adapter REQUIRED) + add_dependency(ChimeraTK-ControlSystemAdapter-EPICS-IOC-Adapter 02.00 REQUIRED) set(Adapter_LINK_FLAGS ${ChimeraTK-ControlSystemAdapter-EPICS-IOC-Adapter_LINK_FLAGS}) set(Adapter_LIBRARIES ${ChimeraTK-ControlSystemAdapter-EPICS-IOC-Adapter_LIBRARIES}) ELSEIF(ADAPTER STREQUAL "EPICS7IOC") message("Building against the EPICS ver. 7.0 IOC ControlSystemAdater") - add_dependency(ChimeraTK-ControlSystemAdapter-EPICS7-IOC-Adapter REQUIRED) + add_dependency(ChimeraTK-ControlSystemAdapter-EPICS7-IOC-Adapter 02.00 REQUIRED) set(Adapter_LINK_FLAGS ${ChimeraTK-ControlSystemAdapter-EPICS7-IOC-Adapter_LINK_FLAGS}) set(Adapter_LIBRARIES ${ChimeraTK-ControlSystemAdapter-EPICS7-IOC-Adapter_LIBRARIES}) ELSE()