From 0dd9fc1390bb224d01a88a6c30097f446812fce8 Mon Sep 17 00:00:00 2001 From: Reinhard Biegel <reinhard.biegel@in-tech.com> Date: Tue, 7 Sep 2021 11:35:01 +0200 Subject: [PATCH] mod(CMake): Reworked OSI linkage handling In CMakeLists.txt, add_openpass_target() now supports a parameter to `LINKOSI`, specifying shared or static linking of OSI and protobuf. Signed-off-by: Reinhard Biegel <reinhard.biegel@in-tech.com> --- cmake/FindOSI.cmake | 149 +++++++++++------- cmake/FindProtobuf.cmake | 79 ++++++++++ cmake/HelperMacros.cmake | 54 +++++-- cmake/global.cmake | 1 - .../Algorithm_FmuWrapper/CMakeLists.txt | 5 +- .../Algorithm_FmuWrapper/CMakeLists.txt | 5 +- 6 files changed, 208 insertions(+), 85 deletions(-) create mode 100644 cmake/FindProtobuf.cmake diff --git a/cmake/FindOSI.cmake b/cmake/FindOSI.cmake index c754d7eb9..6b5552741 100644 --- a/cmake/FindOSI.cmake +++ b/cmake/FindOSI.cmake @@ -1,85 +1,112 @@ ################################################################################ # Copyright (c) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License 2.0 which is available at -# http://www.eclipse.org/legal/epl-2.0. +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ # # SPDX-License-Identifier: EPL-2.0 ################################################################################ # -# - Find OSI -# Find the OSI includes and library +# Find Package Adapter for OSI (Open Simulation Interface) # -# OSI_INCLUDE_DIR - Where to find OSI includes -# OSI_LIBRARIES - List of libraries when using OSI -# OSI_FOUND - True if OSI was found +# Creates the follwoing imported targets (if available): +# - osi::shared +# - osi::static +# - osi::pic -IF(OSI_INCLUDE_DIR) - SET(OSI_FIND_QUIETLY TRUE) -ENDIF(OSI_INCLUDE_DIR) - -FIND_PATH(OSI_INCLUDE_DIR "osi3/osi_version.pb.h" - PATHS - ${PREFIX_PATH} - $ENV{OSI_HOME}/include - $ENV{EXTERNLIBS}/OSI/include - /usr/local/include - /usr/include - PATH_SUFFIXES include - DOC "OSI - Headers" +set(OSI_SHARED_NAMES + open_simulation_interface.lib + libopen_simulation_interface.dll.a + libopen_simulation_interface.so ) -SET(OSI_NAMES - osi3/open_simulation_interface.lib - osi3/libopen_simulation_interface.dll.a - osi3/libopen_simulation_interface_pic.lib - osi3/libopen_simulation_interface.so +set(OSI_STATIC_NAMES + open_simulation_interface_static.lib + libopen_simulation_interface_static.a ) -SET(OSI_DBG_NAMES - osi3/open_simulation_interfaced.lib - osi3/libopen_simulation_interfaced.dll.a - osi3/libopen_simulation_interface_picd.lib +set(OSI_PIC_NAMES + open_simulation_interface_pic.lib + libopen_simulation_interface_pic.a ) -FIND_LIBRARY(OSI_LIBRARY NAMES ${OSI_NAMES} +find_library(OSI_SHARED_LIBRARY NAMES ${OSI_SHARED_NAMES} PATHS - ${PREFIX_PATH} - $ENV{OSI_HOME} - $ENV{EXTERNLIBS}/OSI - /usr/local - /usr - PATH_SUFFIXES lib lib64 - DOC "OSI - Library" + ${PREFIX_PATH} + /usr/local + /usr + PATH_SUFFIXES + lib/osi3 + lib + lib64 ) -INCLUDE(FindPackageHandleStandardArgs) +find_library(OSI_STATIC_LIBRARY NAMES ${OSI_STATIC_NAMES} + PATHS + ${PREFIX_PATH} + /usr/local + /usr + PATH_SUFFIXES + lib/osi3 + lib + lib64 +) -IF(MSVC) - # VisualStudio needs a debug version - FIND_LIBRARY(OSI_LIBRARY_DEBUG NAMES ${OSI_DBG_NAMES} - PATHS +find_library(OSI_PIC_LIBRARY NAMES ${OSI_PIC_NAMES} + PATHS ${PREFIX_PATH} - $ENV{OSI_HOME}/lib - $ENV{EXTERNLIBS}/OSI/lib - DOC "OSI - Library (Debug)" - ) + /usr/local + /usr + PATH_SUFFIXES + lib/osi3 + lib + lib64 +) + +if(OSI_SHARED_LIBRARY) + message(STATUS "Found OSI (shared): ${OSI_SHARED_LIBRARY}") - IF(OSI_LIBRARY_DEBUG AND OSI_LIBRARY) - SET(OSI_LIBRARIES optimized ${OSI_LIBRARY} debug ${OSI_LIBRARY_DEBUG}) - ENDIF(OSI_LIBRARY_DEBUG AND OSI_LIBRARY) + get_filename_component(OSI_SHARED_LIBRARY_DIR "${OSI_SHARED_LIBRARY}" DIRECTORY) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSI DEFAULT_MSG OSI_LIBRARY OSI_LIBRARY_DEBUG OSI_INCLUDE_DIR) + add_library(osi::shared IMPORTED SHARED) + set_target_properties(osi::shared + PROPERTIES + IMPORTED_LOCATION ${OSI_SHARED_LIBRARY} + IMPORTED_IMPLIB ${OSI_SHARED_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES ${OSI_SHARED_LIBRARY_DIR}/../../include + INTERFACE_LINK_LIBRARIES protobuf::libprotobuf) +else() + message(STATUS "Didn't find OSI (shared)") +endif() - MARK_AS_ADVANCED(OSI_LIBRARY OSI_LIBRARY_DEBUG OSI_INCLUDE_DIR) - -ELSE(MSVC) - # rest of the world - SET(OSI_LIBRARIES ${OSI_LIBRARY}) +if(OSI_STATIC_LIBRARY) + message(STATUS "Found OSI (static): ${OSI_STATIC_LIBRARY}") + get_filename_component(OSI_STATIC_LIBRARY_DIR "${OSI_STATIC_LIBRARY}" DIRECTORY) + add_library(osi::static IMPORTED STATIC) + set_target_properties(osi::static + PROPERTIES + IMPORTED_LOCATION ${OSI_STATIC_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES ${OSI_STATIC_LIBRARY_DIR}/../../include + INTERFACE_LINK_LIBRARIES protobuf::libprotobuf_static) +else() + message(STATUS "Didn't find OSI (static)") +endif() - FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSI DEFAULT_MSG OSI_LIBRARY OSI_INCLUDE_DIR) - - MARK_AS_ADVANCED(OSI_LIBRARY OSI_INCLUDE_DIR) - -ENDIF(MSVC) +if(OSI_PIC_LIBRARY) + message(STATUS "Found OSI (pic): ${OSI_PIC_LIBRARY}") + get_filename_component(OSI_PIC_LIBRARY_DIR "${OSI_PIC_LIBRARY}" DIRECTORY) + add_library(osi::pic IMPORTED STATIC) + set_target_properties(osi::pic + PROPERTIES + IMPORTED_LOCATION ${OSI_PIC_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES ${OSI_PIC_LIBRARY_DIR}/../../include + INTERFACE_LINK_LIBRARIES protobuf::libprotobuf_static) +else() + message(STATUS "Didn't find OSI (pic)") +endif() + + +unset(OSI_SHARED_LIBRARY) +unset(OSI_STATIC_LIBRARY) +unset(OSI_PIC_LIBRARY) diff --git a/cmake/FindProtobuf.cmake b/cmake/FindProtobuf.cmake new file mode 100644 index 000000000..5f4aca457 --- /dev/null +++ b/cmake/FindProtobuf.cmake @@ -0,0 +1,79 @@ +################################################################################ +# Copyright (c) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# +# This program and the accompanying materials are made +# available under the terms of the Eclipse Public License 2.0 +# which is available at https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +################################################################################ +# +# find_package adapter for protobuf +# +# Original protpbuf CMake Config file doesn't provide static targets. +# +# Creates the follwoing imported targets (if available): +# - protobuf::libprotobuf +# - protobuf::libprotobuf_static + +set(PROTOBUF_SHARED_NAMES + protobuf.lib + libprotobuf.dll.a + libprotobuf.so +) + +set(PROTOBUF_STATIC_NAMES + protobuf_static.lib + libprotobuf.a +) + +find_library(PROTOBUF_SHARED_LIBRARY NAMES ${PROTOBUF_SHARED_NAMES} + PATHS + ${PREFIX_PATH} + /usr/local + /usr + PATH_SUFFIXES + lib + lib64 +) + +find_library(PROTOBUF_STATIC_LIBRARY NAMES ${PROTOBUF_STATIC_NAMES} + PATHS + ${PREFIX_PATH} + /usr/local + /usr + PATH_SUFFIXES + lib + lib64 +) + +if(PROTOBUF_SHARED_LIBRARY) + message(STATUS "Found protobuf (shared): ${PROTOBUF_SHARED_LIBRARY}") + get_filename_component(PROTOBUF_SHARED_LIBRARY_DIR "${PROTOBUF_SHARED_LIBRARY}" DIRECTORY) + add_library(protobuf::libprotobuf IMPORTED SHARED) + set_target_properties(protobuf::libprotobuf + PROPERTIES + IMPORTED_LOCATION ${PROTOBUF_SHARED_LIBRARY} + IMPORTED_IMPLIB ${PROTOBUF_SHARED_LIBRARY} + INTERFACE_COMPILE_DEFINITIONS PROTOBUF_USE_DLLS + INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_SHARED_LIBRARY_DIR}/../include + INTERFACE_LINK_LIBRARIES pthread) +else() + message(STATUS "Didn't find protobuf (shared)") +endif() + +if(PROTOBUF_STATIC_LIBRARY) + message(STATUS "Found protobuf (static): ${PROTOBUF_STATIC_LIBRARY}") + get_filename_component(PROTOBUF_STATIC_LIBRARY_DIR "${PROTOBUF_STATIC_LIBRARY}" DIRECTORY) + add_library(protobuf::libprotobuf_static IMPORTED STATIC) + set_target_properties(protobuf::libprotobuf_static + PROPERTIES + IMPORTED_LOCATION ${PROTOBUF_STATIC_LIBRARY} + INTERFACE_INCLUDE_DIRECTORIES ${PROTOBUF_STATIC_LIBRARY_DIR}/../include + INTERFACE_LINK_LIBRARIES pthread) +else() + message(STATUS "Didn't find protobuf (static)") +endif() + +unset(PROTOBUF_SHARED_LIBRARY) +unset(PROTOBUF_STATIC_LIBRARY) diff --git a/cmake/HelperMacros.cmake b/cmake/HelperMacros.cmake index ab8ec54d5..586e53b53 100644 --- a/cmake/HelperMacros.cmake +++ b/cmake/HelperMacros.cmake @@ -81,7 +81,7 @@ endif() # [INCDIRS <include-directories>] # [LIBRARIES <libraries>] # [UIS <qt_uis>] -# [LINKOSI]) +# [LINKOSI [shared|static]] # [LINKGUI] # [FOLDER <category>] # [COMPONENT <gui|sim|core|bin|module>]) @@ -94,7 +94,7 @@ endif() # [INCDIRS <include-directories>] # [LIBRARIES <libraries>] # [UIS <qt_uis>] -# [LINKOSI] +# [LINKOSI [shared|static]] # [LINKGUI] # [FOLDER <category>] # [COMPONENT <gui|sim|core|bin|module>]) @@ -106,7 +106,7 @@ endif() # [INCDIRS <include-directories>] # [LIBRARIES <libraries>] # [UIS <qt_uis>] -# [LINKOSI] +# [LINKOSI [shared|static]] # [LINKGUI] # [DEFAULT_MAIN] # [SIMCORE_DEPS <dependencies>] @@ -122,7 +122,7 @@ endif() # UIS Qt UI files # INCDIRS Additional include directories # LIBRARIES Additional libraries to link -# LINKOSI Shortcut for adding OSI include directories and libraries (incl. protobuf) +# LINKOSI Shortcut for adding OSI include directories and libraries (incl. protobuf) as 'static' or 'shared' (default). # LINKGUI Shortcut for adding GUI Libraries # DEFAULT_MAIN Links a simple main() implementation for running GTest # SIMCORE_DEPS Adds dependencies on simulation core targets to a test @@ -137,12 +137,13 @@ endif() # - gtest/gmock/pthread libraries are linked # - Tests are excluded form the 'all' target # - If DEFAULT_MAIN argument is provided, adds '--default-xml' to test executable command line arguments +# - PATH and LD_LIBRARY_PATH are set under Windows and Linux, respectively, so that test executables can resolve run-time dependencies. # - General: # - Target properties PROJECT_LABEL and OUTPUT_NAME are set to the target's name # - Target property DEBUG_POSTFIX is set to CMAKE_DEBUG_POSTFIX ## function(add_openpass_target) - cmake_parse_arguments(PARSED_ARG "LINKGUI;LINKOSI;DEFAULT_MAIN" "NAME;TYPE;LINKAGE" "HEADERS;SOURCES;INCDIRS;LIBRARIES;UIS;SIMCORE_DEPS;RESOURCES;FOLDER;COMPONENT" ${ARGN}) + cmake_parse_arguments(PARSED_ARG "LINKGUI;DEFAULT_MAIN" "NAME;TYPE;LINKAGE;LINKOSI" "HEADERS;SOURCES;INCDIRS;LIBRARIES;UIS;SIMCORE_DEPS;RESOURCES;FOLDER;COMPONENT" ${ARGN}) if(TARGET ${PARSED_ARG_NAME}) message(STATUS "Target '${PARSED_ARG_NAME}' already defined. Skipping.") @@ -274,16 +275,26 @@ function(add_openpass_target) Boost::headers ) - if(${PARSED_ARG_LINKOSI}) - target_include_directories(${PARSED_ARG_NAME} PRIVATE - ${OSI_INCLUDE_DIR} - protobuf::libprotobuf - ) + # LINKOSI handling - target_link_libraries(${PARSED_ARG_NAME} - ${OSI_LIBRARIES} - protobuf::libprotobuf - ) + # fallback to default if value is omitted + if("LINKOSI" IN_LIST PARSED_ARG_KEYWORDS_MISSING_VALUES) + set(PARSED_ARG_LINKOSI "shared") + endif() + + if(DEFINED PARSED_ARG_LINKOSI) + # validate value + set(VALID_LINKOSI_VALUES "" "shared" "static") + if(NOT "${PARSED_ARG_LINKOSI}" IN_LIST VALID_LINKOSI_VALUES) + message(FATAL_ERROR "Invalid value for LINKOSI. Supported settings are '', 'shared' and 'static'") + endif() + + # replace static with pic for library targets + if("${PARSED_ARG_TYPE}" STREQUAL "library" AND "${PARSED_ARG_LINKOSI}" STREQUAL "static") + set(PARSED_ARG_LINKOSI "pic") + endif() + + target_link_libraries(${PARSED_ARG_NAME} osi::${PARSED_ARG_LINKOSI}) endif() target_compile_options(${PARSED_ARG_NAME} PRIVATE @@ -305,12 +316,13 @@ function(add_openpass_target) if(DEFINED PARSED_ARG_LIBRARIES) list(APPEND DEPS ${PARSED_ARG_LIBRARIES}) endif() - if(${PARSED_ARG_LINKOSI}) - list(APPEND DEPS "${OSI_LIBRARIES}" protobuf::libprotobuf) + if(DEFINED PARSED_ARG_LINKOSI) + list(APPEND DEPS osi::${PARSED_ARG_LINKOSI} protobuf::libprotobuf) endif() - message(DEBUG "Locating shared library test dependencies...") + message(DEBUG "Locating shared library test dependencies for ${PARSED_ARG_NAME}") foreach(DEP IN LISTS DEPS) + message(DEBUG "Locating ${DEP}...") if(TARGET ${DEP}) set(DEP_PATH "") message(DEBUG "Target dependency: ${DEP}") @@ -386,7 +398,15 @@ function(add_openpass_target) list(APPEND DEP_PATHS "${DEP_PATH}") endforeach() + list(REMOVE_DUPLICATES DEP_PATHS) + if(WIN32) + # try to move MSYS system folder to the end of the list + set(DEP_PATHS_NO_MSYS ${DEP_PATHS}) + list(FILTER DEP_PATHS EXCLUDE REGEX "msys") + list(FILTER DEP_PATHS_MSYS INCLUDE REGEX "msys") + list(APPEND DEP_PATHS ${DEP_PATHS_MSYS}) + list(JOIN DEP_PATHS "\\;" ADDITIONAL_PATHS) set(CURRENT_PATH "$ENV{PATH}") string(REGEX REPLACE "\;" "\\\;" CURRENT_PATH "${CURRENT_PATH}") diff --git a/cmake/global.cmake b/cmake/global.cmake index 3022d1f90..54aba6024 100644 --- a/cmake/global.cmake +++ b/cmake/global.cmake @@ -79,7 +79,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) if(WITH_SIMCORE OR WITH_TESTS) find_package(Protobuf REQUIRED) - add_compile_definitions(PROTOBUF_USE_DLLS) find_package(OSI REQUIRED) diff --git a/sim/src/components/Algorithm_FmuWrapper/CMakeLists.txt b/sim/src/components/Algorithm_FmuWrapper/CMakeLists.txt index 1af3cc7b2..96248601f 100644 --- a/sim/src/components/Algorithm_FmuWrapper/CMakeLists.txt +++ b/sim/src/components/Algorithm_FmuWrapper/CMakeLists.txt @@ -42,13 +42,12 @@ add_openpass_target( ${FMILibrary_INCLUDE_DIR}/JM src/FmiImporter/include ../../core/opSimulation/modules/World_OSI - ${OSI_INCLUDE_DIR} LIBRARIES Qt5::Core ${FMILibrary_LIBRARY_DIR} Common CoreCommon - protobuf::libprotobuf - -L${OSI_INCLUDE_DIR}/../lib/osi3 open_simulation_interface_pic + + LINKOSI static ) diff --git a/sim/tests/unitTests/components/Algorithm_FmuWrapper/CMakeLists.txt b/sim/tests/unitTests/components/Algorithm_FmuWrapper/CMakeLists.txt index 0b5ef1adf..491d5433a 100644 --- a/sim/tests/unitTests/components/Algorithm_FmuWrapper/CMakeLists.txt +++ b/sim/tests/unitTests/components/Algorithm_FmuWrapper/CMakeLists.txt @@ -40,13 +40,12 @@ add_openpass_target( ${FMILibrary_INCLUDE_DIR}/FMI1 ${FMILibrary_INCLUDE_DIR}/FMI2 ${FMILibrary_INCLUDE_DIR}/JM - ${OSI_INCLUDE_DIR} LIBRARIES Qt5::Core Common ${FMILibrary_LIBRARY_DIR} - protobuf::libprotobuf - -L${OSI_INCLUDE_DIR}/../lib/osi3 open_simulation_interface_pic + + LINKOSI static ) -- GitLab