| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #######################################
- # Required CMake version #
- #######################################
- cmake_minimum_required( VERSION 3.18 )
- #######################################
- # Project name #
- #######################################
- project( OpENer LANGUAGES C VERSION 2.3 )
- #######################################
- # C Settings #
- # #
- # Here you can set various C-related #
- # options for the project. #
- #######################################
- # Set C17 as minimum standard
- set(CMAKE_C_STANDARD 17)
- set(CMAKE_C_STANDARD_REQUIRED ON)
- set(CMAKE_C_EXTENSIONS OFF)
- # Add modern compiler warnings
- if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
- add_compile_options(
- -Wall
- -Wextra
- -pedantic
- -Wconversion
- -Wshadow
- -Wformat
- -Wformat-security
- )
- elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
- add_compile_options(/W4)
- endif()
- #######################################
- # AddressSanitizer Configuration #
- #######################################
- option(ENABLE_ADDRESS_SANITIZER "Enable AddressSanitizer for memory error detection" OFF)
- option(ENABLE_UNDEFINED_SANITIZER "Enable UndefinedBehaviorSanitizer" OFF)
- if(ENABLE_ADDRESS_SANITIZER OR ENABLE_UNDEFINED_SANITIZER)
- if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
- message(STATUS "Enabling sanitizers for security testing")
- set(SANITIZER_FLAGS "")
- if(ENABLE_ADDRESS_SANITIZER)
- list(APPEND SANITIZER_FLAGS "-fsanitize=address")
- message(STATUS " - AddressSanitizer (ASAN) enabled")
- endif()
- if(ENABLE_UNDEFINED_SANITIZER)
- list(APPEND SANITIZER_FLAGS "-fsanitize=undefined")
- message(STATUS " - UndefinedBehaviorSanitizer (UBSAN) enabled")
- endif()
- # Common sanitizer flags
- add_compile_options(
- ${SANITIZER_FLAGS}
- -fno-omit-frame-pointer
- -g
- )
- add_link_options(${SANITIZER_FLAGS})
- # For memory leak detection in ASAN
- set(ENV{ASAN_OPTIONS} "detect_leaks=1:halt_on_error=1")
- set(ENV{UBSAN_OPTIONS} "print_stacktrace=1:halt_on_error=1")
- else()
- message(WARNING "Sanitizers requested but compiler is not GNU or Clang")
- endif()
- endif()
- #######################################
- # Project version #
- #######################################
- if( NOT DEFINED OpENer_Device_Config_Vendor_Id )
- set( OpENer_Device_Config_Vendor_Id 1 CACHE STRING "Device Vendor ID" )
- endif()
- if( NOT DEFINED OpENer_Device_Config_Device_Type )
- set( OpENer_Device_Config_Device_Type 12 CACHE STRING "Device Type ID" )
- endif()
- if( NOT DEFINED OpENer_Device_Config_Product_Code )
- set( OpENer_Device_Config_Product_Code 65001 CACHE STRING "Device Product Code" )
- endif()
- if( NOT DEFINED OpENer_Device_Config_Device_Name )
- set( OpENer_Device_Config_Device_Name "OpENer PC" CACHE STRING "Device Name" )
- endif()
- if(NOT DEFINED OpENer_Device_Major_Version)
- set(OpENer_Device_Major_Version ${PROJECT_VERSION_MAJOR} CACHE STRING "Major Version")
- endif()
- if(NOT DEFINED OpENer_Device_Minor_Version)
- set(OpENer_Device_Minor_Version ${PROJECT_VERSION_MINOR} CACHE STRING "Minor Version")
- endif()
- configure_file(
- "${PROJECT_SOURCE_DIR}/src/ports/devicedata.h.in"
- "${PROJECT_BINARY_DIR}/src/ports/devicedata.h"
- )
- find_path( OpENer_BUILDSUPPORT_DIR OpENer.cmake ${PROJECT_SOURCE_DIR}/buildsupport )
- INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/OpENer.cmake )
- option(OPENER_RANDOMIZE_CONNECTION_ID "Use randomized connection IDs also for lower 16-bits?" FALSE)
- option(OPENER_PRODUCED_DATA_HAS_RUN_IDLE_HEADER "Shall produced data from OpENer also include a run idle header?" FALSE)
- option(OPENER_CONSUMED_DATA_HAS_RUN_IDLE_HEADER "Will consumed data from OpENer also include a run idle header?" TRUE)
- option(OPENER_INSTALL_AS_LIB "Build and install OpENer as a library" FALSE)
- option(BUILD_SHARED_LIBS "Build OpENer as shared library" FALSE)
- if(OPENER_RANDOMIZE_CONNECTION_ID)
- add_definitions(-DOPENER_RANDOMIZE_CONNECTION_ID)
- endif()
- if(OPENER_PRODUCED_DATA_HAS_RUN_IDLE_HEADER)
- add_definitions(-DOPENER_PRODUCED_DATA_HAS_RUN_IDLE_HEADER)
- endif()
- if(OPENER_CONSUMED_DATA_HAS_RUN_IDLE_HEADER)
- add_definitions(-DOPENER_CONSUMED_DATA_HAS_RUN_IDLE_HEADER)
- endif()
- option(OPENER_IS_DLR_DEVICE "Is OpENer built with support for a basic DLR device?" FALSE)
- if (OPENER_IS_DLR_DEVICE)
- add_definitions(-DOPENER_IS_DLR_DEVICE)
- endif()
- # This buffer size will be used for any received message.
- # The same buffer is used for the replied explicit message.
- # There are two uses in OpENer:
- # 1. Explicit messages will use this buffer to store the data generated by the request
- # 2. I/O Connections will use this buffer for the produced data
- set( OPENER_ETHERNET_BUFFER_SIZE "512" CACHE STRING "Number of bytes used for the Ethernet message buffer")
- add_definitions(-DPC_OPENER_ETHERNET_BUFFER_SIZE=${OPENER_ETHERNET_BUFFER_SIZE} )
- #######################################
- # Platform switches #
- #######################################
- set( OpENer_KNOWN_PLATFORMS "POSIX" "WIN32" "MINGW")
- set( OpENer_PLATFORM CACHE STRING "Platform OpENer will be built for" )
- set_property(CACHE OpENer_PLATFORM PROPERTY STRINGS ${OpENer_KNOWN_PLATFORMS} )
- #######################################
- # Platform-dependent functions check #
- #######################################
- INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/OpENer_function_checks.cmake )
- #######################################
- # OpENer tracer switches #
- #######################################
- set( OpENer_TRACES OFF CACHE BOOL "Activate OpENer traces" )
- if(OpENer_TRACES)
- createTraceLevelOptions()
- endif(OpENer_TRACES)
- #######################################
- # OpENer documentation target "doc" #
- #######################################
- # check if Doxygen is installed
- find_package(Doxygen)
- if (DOXYGEN_FOUND)
- # set input and output files
- set(DOXYGEN_IN ${OpENer_SOURCE_DIR}/opener.doxyfile.in)
- set(DOXYGEN_OUT ${OpENer_BINARY_DIR}/opener.doxyfile)
- # exclude subdirectories of non active platforms depending on OpENer_PLATFORM
- set(OpENer_EXCLUDE_PATTERNS "")
- if (NOT OpENer_PLATFORM STREQUAL "POSIX")
- set(OpENer_EXCLUDE_PATTERNS "${OpENer_EXCLUDE_PATTERNS} */src/ports/POSIX/*")
- endif ()
- if (NOT OpENer_PLATFORM STREQUAL "WIN32")
- set(OpENer_EXCLUDE_PATTERNS "${OpENer_EXCLUDE_PATTERNS} */src/ports/WIN32/*")
- endif ()
- if (NOT OpENer_PLATFORM STREQUAL "MINGW")
- set(OpENer_EXCLUDE_PATTERNS "${OpENer_EXCLUDE_PATTERNS} */src/ports/MINGW/*")
- endif ()
- # request to configure the file
- configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
- # note the option ALL which will build the docs always with the default target
- add_custom_target( doc # ALL
- COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
- WORKING_DIRECTORY ${OpENer_SOURCE_DIR}
- COMMENT "Generating API documentation with Doxygen"
- VERBATIM )
- message("-- Doxygen setup done")
- else (DOXYGEN_FOUND)
- message("Doxygen needs to be installed to generate the Doxygen documentation")
- endif (DOXYGEN_FOUND)
- #######################################
- # Test switch #
- #######################################
- set( OpENer_TESTS OFF CACHE BOOL "Enable tests to be built" )
- if( OpENer_TESTS )
- enable_testing()
- enable_language( CXX )
- set( CPPUTEST_HOME "" CACHE PATH "Path to CppUTest directory" )
- INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/OpENer_Tests.cmake )
- INCLUDE( ${OpENer_BUILDSUPPORT_DIR}/CodeCoverage.cmake )
- APPEND_COVERAGE_COMPILER_FLAGS()
- # The used CppUTest framework does not support parallel jobs
- SETUP_TARGET_FOR_COVERAGE_LCOV(NAME ${PROJECT_NAME}_coverage EXECUTABLE OpENer_Tests EXCLUDE "tests/*" "src/ports/*/sample_application/*" "${CPPUTEST_HOME}/*")
- add_test_includes()
- add_definitions( -DOPENER_UNIT_TEST )
- add_subdirectory( tests )
- endif( OpENer_TESTS )
- #######################################
- # OpENer C flags #
- #######################################
- if (OpENer_PLATFORM STREQUAL "WIN32")
- set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W4" )
- else ()
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wconversion")
- endif ()
- ####################################################
- # Internal cache holding the available CIP objects #
- ####################################################
- # Add definitions for additional CIP Objects
- string(COMPARE NOTEQUAL "${OpENer_ADD_CIP_OBJECTS}" "" OpENer_HAS_ADDITIONAL_OBJECT)
- if (OpENer_HAS_ADDITIONAL_OBJECT)
- string(REPLACE " " ";" OpENer_ADD_CIP_OBJECTS_LIST ${OpENer_ADD_CIP_OBJECTS})
- foreach (CIP_OBJECT IN LISTS OpENer_ADD_CIP_OBJECTS_LIST)
- add_definitions(-D${CIP_OBJECT})
- endforeach ()
- endif ()
- set( OpENer_ADD_CIP_OBJECTS "" CACHE INTERNAL STRING )
- set( OpENer_ADD_CIP_OBJECTS_INCLUDES "" CACHE INTERNAL STRING )
- #######################################
- # Add custom CIP objects #
- #######################################
- set( OpENer_CIP_OBJECTS_DIR ${PROJECT_SOURCE_DIR}/src/cip_objects )
- include(${OpENer_BUILDSUPPORT_DIR}/OpENer_CIP_Object_generator.cmake)
- # ######################################
- # Add subdirectories #
- # ######################################
- add_subdirectory( src )
|