cmake_minimum_required(VERSION 3.16) function(git_tag_version VERSION_RESULT) set(${VERSION_RESULT} "0.0.0.0" PARENT_SCOPE) find_package(Git) if(NOT Git_FOUND) return() endif() execute_process( COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE LAST_TAG RESULT_VARIABLE RESULT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT RESULT EQUAL 0) return() endif() execute_process( COMMAND ${GIT_EXECUTABLE} rev-list ${LAST_TAG}..HEAD --count WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE COMMIT_COUNT_SINCE_TAG RESULT_VARIABLE RESULT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT RESULT EQUAL 0) return() endif() set(${VERSION_RESULT} "${LAST_TAG}.${COMMIT_COUNT_SINCE_TAG}" PARENT_SCOPE) endfunction() git_tag_version(LIBICSNEO_VERSION) if(LIBICSNEO_VERSION STREQUAL "0.0.0.0") message(WARNING "Unable to parse version from git history") endif() project(libicsneo VERSION ${LIBICSNEO_VERSION}) cmake_policy(SET CMP0074 NEW) if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() option(LIBICSNEO_BUILD_UNIT_TESTS "Build unit tests." OFF) option(LIBICSNEO_BUILD_DOCS "Build documentation. Don't use in Visual Studio." OFF) option(LIBICSNEO_BUILD_EXAMPLES "Build examples." ON) option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON) option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C library" ON) option(LIBICSNEO_BUILD_ICSNEOC2 "Build dynamic C2 library" ON) option(LIBICSNEO_BUILD_ICSNEOC2_STATIC "Build static C2 library" ON) option(LIBICSNEO_BUILD_ICSNEOLEGACY "Build icsnVC40 compatibility library" ON) option(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC "Build static icsnVC40 compatibility library" ON) # Device Drivers # You almost certainly don't want firmio for your build, # it is only relevant for communication between Linux and # CoreMini from the onboard processor of the device. option(LIBICSNEO_ENABLE_FIRMIO "Enable communication between Linux and CoreMini within the same device" OFF) option(LIBICSNEO_ENABLE_BINDINGS_PYTHON "Enable Python library" OFF) option(LIBICSNEO_ENABLE_BOOTLOADER "Enable bootloader firmware update support" OFF) set(CMAKE_CXX_STANDARD 17) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(GNUInstallDirs) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Enable Warnings if(MSVC) set(LIBICSNEO_COMPILER_WARNINGS /W4) # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html # Still supported until a suitable replacement is standardized add_definitions(-D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) add_definitions(-D_ITERATOR_DEBUG_LEVEL=0) else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) set(LIBICSNEO_COMPILER_WARNINGS -Wall -Wno-unknown-pragmas) endif() find_package(Threads REQUIRED) # doxygen find_package(Doxygen) if(DOXYGEN_FOUND) set(DOXYGEN_OUT ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile) set(ICSNEO_DOCS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs) if(NOT EXISTS "${DOXYGEN_OUT}") set(DOXYGEN_FOUND FALSE) endif() endif() if(LIBICSNEO_BUILD_DOCS) if(DOXYGEN_FOUND) message("Will build Doxygen based documentation") add_custom_target(libicsneo_doxygen COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM DEPENDS icsneocpp icsneoc icsneolegacy) # sphinx find_package(Sphinx) if(SPHINX_EXECUTABLE) message("Will build Sphinx based documentation") set(SPHINX_OUT ${ICSNEO_DOCS_DIR}/build/sphinx) # configured documentation tools and intermediate build results set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/_build) # Sphinx cache with pickled ReST documents set(SPHINX_CACHE_DIR ${CMAKE_CURRENT_BINARY_DIR}/_doctrees) # HTML output directory set(SPHINX_HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx) configure_file( "${ICSNEO_DOCS_DIR}/conf.py.template" "${ICSNEO_DOCS_DIR}/conf.py" @ONLY) add_custom_target(libicsneo_sphinx ALL ${SPHINX_EXECUTABLE} -q -b html -c "${ICSNEO_DOCS_DIR}" -d "${SPHINX_CACHE_DIR}" "${ICSNEO_DOCS_DIR}" "${SPHINX_HTML_DIR}" COMMENT "Building HTML documentation with Sphinx" DEPENDS icsneocpp icsneoc icsneolegacy) endif() endif() endif() if(LIBICSNEO_ENABLE_FIRMIO AND NOT WIN32) set(PLATFORM_SRC platform/posix/firmio.cpp) endif() set(SRC_FILES communication/message/flexray/control/flexraycontrolmessage.cpp communication/message/callback/streamoutput/a2bwavoutput.cpp communication/message/a2bmessage.cpp communication/message/apperrormessage.cpp communication/message/neomessage.cpp communication/message/ethphymessage.cpp communication/message/linmessage.cpp communication/message/livedatamessage.cpp communication/message/logdatamessage.cpp communication/message/tc10statusmessage.cpp communication/message/gptpstatusmessage.cpp communication/message/allmacaddressesmessage.cpp communication/message/ethernetstatusmessage.cpp communication/message/networkmutexmessage.cpp communication/message/clientidmessage.cpp communication/message/mfgconfigmessage.cpp communication/message/transmitmessage.cpp communication/message/spiportkeymessage.cpp communication/message/genericapidatamessage.cpp communication/message/genericapistatusmessage.cpp communication/message/iso15765message.cpp communication/packet/flexraypacket.cpp communication/packet/canpacket.cpp communication/packet/a2bpacket.cpp communication/packet/spipacket.cpp communication/packet/ethernetpacket.cpp communication/packet/versionpacket.cpp communication/packet/iso9141packet.cpp communication/packet/ethphyregpacket.cpp communication/packet/livedatapacket.cpp communication/packet/logicaldiskinfopacket.cpp communication/packet/wivicommandpacket.cpp communication/packet/i2cpacket.cpp communication/packet/linpacket.cpp communication/packet/mdiopacket.cpp communication/packet/scriptstatuspacket.cpp communication/packet/componentversionpacket.cpp communication/packet/supportedfeaturespacket.cpp communication/packet/genericbinarystatuspacket.cpp communication/packet/hardwareinfopacket.cpp communication/decoder.cpp communication/encoder.cpp communication/ethernetpacketizer.cpp communication/packetizer.cpp communication/multichannelcommunication.cpp communication/communication.cpp communication/driver.cpp communication/livedata.cpp core/ringbuffer.cpp core/crc32.cpp core/macseccfg.cpp device/extensions/flexray/extension.cpp device/extensions/flexray/controller.cpp device/idevicesettings.cpp device/devicefinder.cpp device/device.cpp device/neodevice.cpp disk/diskreaddriver.cpp disk/diskwritedriver.cpp disk/nulldiskdriver.cpp disk/neomemorydiskdriver.cpp disk/plasiondiskreaddriver.cpp disk/extextractordiskreaddriver.cpp disk/fat.cpp disk/diskdetails.cpp disk/vsa/vsa.cpp disk/vsa/vsa02.cpp disk/vsa/vsa03.cpp disk/vsa/vsa04.cpp disk/vsa/vsa05.cpp disk/vsa/vsa06.cpp disk/vsa/vsa07.cpp disk/vsa/vsa08.cpp disk/vsa/vsa09.cpp disk/vsa/vsa0b.cpp disk/vsa/vsa0c.cpp disk/vsa/vsa0d.cpp disk/vsa/vsa0e.cpp disk/vsa/vsa0f.cpp disk/vsa/vsa6a.cpp disk/vsa/vsaparser.cpp platform/servd.cpp ${PLATFORM_SRC} ) if(LIBICSNEO_ENABLE_BOOTLOADER) list(APPEND SRC_FILES device/extensions/bootloader/api.cpp device/extensions/bootloader/version.cpp device/extensions/bootloader/platform/logging.cpp device/extensions/bootloader/parser/ief.cpp device/extensions/bootloader/parser/fwzip.cpp device/extensions/bootloader/parser/fwbin.cpp device/extensions/bootloader/parser/fwbundle.cpp device/extensions/bootloader/parser/fwloader.cpp device/extensions/bootloader/communication/red.cpp device/extensions/bootloader/communication/radmultichipcommunication.cpp device/extensions/bootloader/communication/communication.cpp device/extensions/bootloader/communication/radperiphcommunication.cpp device/extensions/bootloader/communication/radcommunication.cpp device/extensions/bootloader/communication/redpacketizer.cpp device/extensions/bootloader/communication/redcore.cpp device/extensions/bootloader/communication/application.cpp device/extensions/bootloader/communication/redbase.cpp ) endif() # Generate build info header execute_process( COMMAND git rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE GIT_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND git describe --abbrev=6 --dirty --always --tags WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE GIT_DESCRIBE ERROR_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${BUILD_METADATA}) set(BUILD_METADATA_PLUS +${BUILD_METADATA}) endif() if(NOT ${GIT_BRANCH} STREQUAL "master") set(BUILD_GIT_INFO "${GIT_BRANCH} @ ") endif() string(SUBSTRING GIT_DESCRIBE 0 1 GIT_DESCRIBE_FIRST) if(NOT ${GIT_DESCRIBE_FIRST} STREQUAL "v") string(APPEND BUILD_GIT_INFO "${GIT_DESCRIBE}") endif() configure_file(api/icsneocpp/buildinfo.h.template ${CMAKE_CURRENT_BINARY_DIR}/generated/buildinfo.h) configure_file(api/icsneoc/version.rc.template ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc) configure_file(api/icsneoc2/version.rc.template ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc2/version.rc) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) add_library(icsneocpp api/icsneocpp/icsneocpp.cpp api/icsneocpp/event.cpp api/icsneocpp/eventmanager.cpp api/icsneocpp/heartbeat.cpp api/icsneocpp/version.cpp ${SRC_FILES} ) target_include_directories(icsneocpp PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneocpp PUBLIC Threads::Threads $<$:ws2_32 iphlpapi>) target_compile_features(icsneocpp PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_options(icsneocpp PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) if(LIBICSNEO_ENABLE_FIRMIO) target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_FIRMIO) endif() # fatfs add_subdirectory(third-party/fatfs) target_link_libraries(icsneocpp PRIVATE fatfs) # protobuf if(DEFINED ENV{LIBICSNEO_ICSPB_REPO}) set(LIBICSNEO_ICSPB_REPO "$ENV{LIBICSNEO_ICSPB_REPO}") endif() if(NOT LIBICSNEO_ICSPB_REPO) set(LIBICSNEO_ICSPB_REPO https://github.com/intrepidcs/icspb.git) endif() include(FetchContent) FetchContent_Declare(icspb GIT_REPOSITORY ${LIBICSNEO_ICSPB_REPO} GIT_TAG 3339fa6b83a6b3e7704d41f5c2f2175cfc761a1f ) FetchContent_MakeAvailable(icspb) target_link_libraries(icsneocpp PRIVATE icspb::icspb) # libicsbl if(LIBICSNEO_ENABLE_BOOTLOADER) if(NOT LIBICSNEO_LIBICSBL_ZIP_URL) if(DEFINED ENV{LIBICSNEO_LIBICSBL_ZIP_URL}) set(LIBICSNEO_LIBICSBL_ZIP_URL "$ENV{LIBICSNEO_LIBICSBL_ZIP_URL}") else() if(NOT LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX) if(DEFINED ENV{LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX}) set(LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX "$ENV{LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX}") else() set(LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX "https://cdn.intrepidcs.net/libicsbl/5ce699ada0ccaadb92cabda6e3537c09b333020e") endif() endif() if(NOT LIBICSNEO_LIBICSBL_VERSION) if(DEFINED ENV{LIBICSNEO_LIBICSBL_VERSION}) set(LIBICSNEO_LIBICSBL_VERSION "$ENV{LIBICSNEO_LIBICSBL_VERSION}") else() set(LIBICSNEO_LIBICSBL_VERSION "26.4.0") endif() endif() if(WIN32) if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8 OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "ARM") message(FATAL_ERROR "Unsupported bootloader architecture: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}") endif() set(LIBICSNEO_LIBICSBL_ZIP_URL "${LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX}/libicsbl-${LIBICSNEO_LIBICSBL_VERSION}-windows-amd64.zip") elseif(APPLE) set(LIBICSNEO_LIBICSBL_ZIP_URL "${LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX}/libicsbl-${LIBICSNEO_LIBICSBL_VERSION}-macos-universal.zip") else() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") set(LIBICSNEO_LIBICSBL_ZIP_URL "${LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX}/libicsbl-${LIBICSNEO_LIBICSBL_VERSION}-linux-x86_64-glibc.zip") elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") set(LIBICSNEO_LIBICSBL_ZIP_URL "${LIBICSNEO_LIBICSBL_ZIP_URL_PREFIX}/libicsbl-${LIBICSNEO_LIBICSBL_VERSION}-linux-aarch64-glibc.zip") else() message(FATAL_ERROR "Unsupported CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") endif() endif() endif() endif() FetchContent_Declare( libicsbl URL "${LIBICSNEO_LIBICSBL_ZIP_URL}" ) FetchContent_MakeAvailable(libicsbl) set(libicsbl_ROOT "${libicsbl_SOURCE_DIR}") find_package(libicsbl CONFIG REQUIRED) target_link_libraries(icsneocpp PUBLIC libicsbl::icsbl) # miniz add_subdirectory(third-party/miniz) target_link_libraries(icsneocpp PRIVATE miniz) endif() if(LIBICSNEO_BUILD_ICSNEOC) add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc) target_include_directories(icsneoc PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneoc PRIVATE icsneocpp) target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_options(icsneoc PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) endif() if(LIBICSNEO_BUILD_ICSNEOC_STATIC) add_library(icsneoc-static STATIC api/icsneoc/icsneoc.cpp) target_include_directories(icsneoc-static PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneoc-static PUBLIC icsneocpp) target_compile_features(icsneoc-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_definitions(icsneoc-static PUBLIC ICSNEOC_BUILD_STATIC) target_compile_options(icsneoc-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) endif() if(LIBICSNEO_BUILD_ICSNEOC2) add_library(icsneoc2 SHARED api/icsneoc2/icsneoc2.cpp api/icsneoc2/icsneoc2settings.cpp api/icsneoc2/icsneoc2messages.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc2/version.rc) target_include_directories(icsneoc2 PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneoc2 PRIVATE icsneocpp) target_compile_features(icsneoc2 PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_options(icsneoc2 PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) if(WIN32) set_target_properties(icsneoc2 PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() endif() if(LIBICSNEO_BUILD_ICSNEOC2_STATIC) add_library(icsneoc2-static STATIC api/icsneoc2/icsneoc2.cpp api/icsneoc2/icsneoc2settings.cpp api/icsneoc2/icsneoc2messages.cpp) target_include_directories(icsneoc2-static PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneoc2-static PUBLIC icsneocpp) target_compile_features(icsneoc2-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_definitions(icsneoc2-static PUBLIC ICSNEOC2_BUILD_STATIC) target_compile_options(icsneoc2-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) endif() if(LIBICSNEO_BUILD_ICSNEOLEGACY) add_library(icsneolegacy SHARED api/icsneolegacy/icsneolegacy.cpp api/icsneolegacy/icsneolegacyextra.cpp api/icsneoc/icsneoc.cpp platform/windows/icsneolegacy.def ) target_include_directories(icsneolegacy PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneolegacy PRIVATE icsneocpp) target_compile_features(icsneolegacy PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_options(icsneolegacy PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) endif() if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC) add_library(icsneolegacy-static STATIC api/icsneolegacy/icsneolegacy.cpp api/icsneolegacy/icsneolegacyextra.cpp api/icsneoc/icsneoc.cpp ) target_include_directories(icsneolegacy-static PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_link_libraries(icsneolegacy-static PUBLIC icsneocpp) target_compile_features(icsneolegacy-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_definitions(icsneolegacy-static PUBLIC ICSNEOC_BUILD_STATIC) target_compile_options(icsneolegacy-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) endif() add_subdirectory(bindings) if(LIBICSNEO_BUILD_EXAMPLES) add_subdirectory(examples) endif() # googletest if(LIBICSNEO_BUILD_UNIT_TESTS) include(FetchContent) FetchContent_Declare(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG 6986c2b575f77135401a4e1c65a7a42f20e18fef ) FetchContent_MakeAvailable(googletest) include(GoogleTest) add_executable(libicsneo-unit-tests test/unit/main.cpp test/unit/diskdriverreadtest.cpp test/unit/diskdriverwritetest.cpp test/unit/eventmanagertest.cpp test/unit/ethernetpacketizertest.cpp test/unit/i2cencoderdecodertest.cpp test/unit/linencoderdecodertest.cpp test/unit/a2bencoderdecodertest.cpp test/unit/mdioencoderdecodertest.cpp test/unit/livedataencoderdecodertest.cpp test/unit/macsectest.cpp test/unit/ringbuffertest.cpp test/unit/apperrordecodertest.cpp test/unit/icsneoc2.cpp test/unit/ethphyregistertest.cpp test/unit/tc10test.cpp test/unit/periodictest.cpp ) target_compile_options(libicsneo-unit-tests PRIVATE ${LIBICSNEO_COMPILER_WARNINGS}) target_link_libraries(libicsneo-unit-tests gtest gtest_main) target_link_libraries(libicsneo-unit-tests icsneocpp) target_link_libraries(libicsneo-unit-tests icsneoc2-static) target_include_directories(libicsneo-unit-tests PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) enable_testing() gtest_discover_tests(libicsneo-unit-tests TEST_PREFIX "unit/" PROPERTIES LABELS "unit") endif() set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack)