265 lines
8.8 KiB
CMake
265 lines
8.8 KiB
CMake
|
|
# CMakeLists.txt for mbpoll - ModBus Master Simulator
|
||
|
|
# Originally generated by CodeLite IDE, modernized for CMake 3.13+
|
||
|
|
|
||
|
|
cmake_minimum_required(VERSION 3.13)
|
||
|
|
|
||
|
|
project(mbpoll
|
||
|
|
VERSION 1.5.3
|
||
|
|
DESCRIPTION "ModBus Master Simulator"
|
||
|
|
LANGUAGES C)
|
||
|
|
|
||
|
|
# Standard install directories (man, bin, lib, etc.)
|
||
|
|
include(GNUInstallDirs)
|
||
|
|
|
||
|
|
# Export compile commands for IDE support
|
||
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||
|
|
|
||
|
|
# Set default build type if not specified
|
||
|
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||
|
|
message(STATUS "Setting build type to 'Release' as none was specified.")
|
||
|
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||
|
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Set output directories
|
||
|
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||
|
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||
|
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||
|
|
|
||
|
|
# Option for custom RTS GPIO support
|
||
|
|
set(MBPOLL_CUSTOM_RTS_GPIO ON CACHE BOOL "Enable custom RTS GPIO (if libpiduino found, only on ARM)")
|
||
|
|
|
||
|
|
# Check for system getopt (use bundled version on Windows)
|
||
|
|
include(CheckSymbolExists)
|
||
|
|
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||
|
|
check_symbol_exists(getopt "getopt.h" HAVE_GETOPT)
|
||
|
|
if(NOT HAVE_GETOPT)
|
||
|
|
set(GETOPT_SOURCES ${CMAKE_SOURCE_DIR}/3rdparty/getopt/getopt.c)
|
||
|
|
set(GETOPT_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/getopt)
|
||
|
|
# Disable pedantic warnings for 3rdparty getopt (uses deprecated 'register' keyword)
|
||
|
|
if(NOT MSVC)
|
||
|
|
set_source_files_properties(${GETOPT_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-pedantic")
|
||
|
|
endif()
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Append cmake/ to module path
|
||
|
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||
|
|
|
||
|
|
# Find dependencies
|
||
|
|
if(WIN32)
|
||
|
|
# On Windows, build libmodbus from bundled sources (no pkg-config needed)
|
||
|
|
set(LIBMODBUS_INCLUDE_DIRS
|
||
|
|
${CMAKE_SOURCE_DIR}/libmodbus/src
|
||
|
|
${CMAKE_SOURCE_DIR}/libmodbus/src/win32)
|
||
|
|
file(GLOB_RECURSE LIBMODBUS_SRCS RELATIVE ${CMAKE_SOURCE_DIR} "libmodbus/src/*.c")
|
||
|
|
find_program(CSCRIPT_PATH NAMES cscript REQUIRED)
|
||
|
|
else()
|
||
|
|
# On Unix, use system libmodbus via pkg-config
|
||
|
|
# Note: 3.1.7+ required for quirks support (-Q/-X options)
|
||
|
|
find_package(PkgConfig REQUIRED)
|
||
|
|
pkg_check_modules(LIBMODBUS REQUIRED libmodbus>=3.1.7)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Search for piduino (optional, for GPIO-based RS-485 RTS control)
|
||
|
|
find_package(PIDUINO QUIET)
|
||
|
|
if(PIDUINO_FOUND AND PIDUINO_WITH_GPIO AND MBPOLL_CUSTOM_RTS_GPIO)
|
||
|
|
message(STATUS "PiDuino ${PIDUINO_VERSION} found - enabling GPIO RTS support")
|
||
|
|
set(MBPOLL_GPIO_RTS ON)
|
||
|
|
set(PROGRAM_PERMISSIONS
|
||
|
|
OWNER_WRITE OWNER_READ OWNER_EXECUTE
|
||
|
|
GROUP_READ GROUP_EXECUTE
|
||
|
|
WORLD_READ WORLD_EXECUTE
|
||
|
|
SETUID)
|
||
|
|
else()
|
||
|
|
if(MBPOLL_CUSTOM_RTS_GPIO AND NOT PIDUINO_FOUND)
|
||
|
|
message(STATUS "PiDuino not found - GPIO RTS support disabled")
|
||
|
|
endif()
|
||
|
|
set(MBPOLL_GPIO_RTS OFF)
|
||
|
|
set(PROGRAM_PERMISSIONS
|
||
|
|
OWNER_WRITE OWNER_READ OWNER_EXECUTE
|
||
|
|
GROUP_READ GROUP_EXECUTE
|
||
|
|
WORLD_READ WORLD_EXECUTE)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Get version from git tags
|
||
|
|
include(GitVersion)
|
||
|
|
GetGitVersion(MBPOLL_VERSION)
|
||
|
|
WriteGitVersionFile(${CMAKE_CURRENT_BINARY_DIR}/version-git.h)
|
||
|
|
set(MBPOLL_VERSION_STRING
|
||
|
|
${MBPOLL_VERSION_MAJOR}.${MBPOLL_VERSION_MINOR}.${MBPOLL_VERSION_PATCH})
|
||
|
|
|
||
|
|
# Define source files
|
||
|
|
set(MBPOLL_SOURCES
|
||
|
|
${CMAKE_SOURCE_DIR}/src/mbpoll.c
|
||
|
|
${CMAKE_SOURCE_DIR}/src/custom-rts.c
|
||
|
|
${CMAKE_SOURCE_DIR}/src/serial.c
|
||
|
|
${CMAKE_SOURCE_DIR}/src/chipio.c
|
||
|
|
${CMAKE_SOURCE_DIR}/src/utils.c
|
||
|
|
${LIBMODBUS_SRCS}
|
||
|
|
${GETOPT_SOURCES})
|
||
|
|
|
||
|
|
# Windows resource file
|
||
|
|
if(WIN32)
|
||
|
|
enable_language(RC)
|
||
|
|
set(CMAKE_RC_COMPILE_OBJECT
|
||
|
|
"<CMAKE_RC_COMPILER> ${RC_OPTIONS} -O coff -i <SOURCE> -o <OBJECT>")
|
||
|
|
list(APPEND MBPOLL_SOURCES ${CMAKE_SOURCE_DIR}/libmodbus/src/win32/modbus.rc)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Create the executable
|
||
|
|
add_executable(mbpoll ${MBPOLL_SOURCES})
|
||
|
|
|
||
|
|
# Include directories
|
||
|
|
target_include_directories(mbpoll PRIVATE
|
||
|
|
${CMAKE_SOURCE_DIR}
|
||
|
|
${CMAKE_SOURCE_DIR}/src
|
||
|
|
${CMAKE_CURRENT_BINARY_DIR}
|
||
|
|
${LIBMODBUS_INCLUDE_DIRS}
|
||
|
|
${GETOPT_INCLUDE_DIR})
|
||
|
|
|
||
|
|
# Compiler-specific options
|
||
|
|
if(MSVC)
|
||
|
|
target_compile_definitions(mbpoll PRIVATE _CRT_SECURE_NO_WARNINGS)
|
||
|
|
else()
|
||
|
|
# Common warning flags
|
||
|
|
target_compile_options(mbpoll PRIVATE
|
||
|
|
-Wall
|
||
|
|
-Wextra
|
||
|
|
-Wpedantic
|
||
|
|
-Wformat-security
|
||
|
|
-Wno-unused-parameter
|
||
|
|
-Wno-unused-function
|
||
|
|
-Wno-unused-const-variable)
|
||
|
|
|
||
|
|
# Security hardening (Release builds)
|
||
|
|
target_compile_options(mbpoll PRIVATE
|
||
|
|
$<$<CONFIG:Release>:-fstack-protector-strong>
|
||
|
|
$<$<CONFIG:RelWithDebInfo>:-fstack-protector-strong>)
|
||
|
|
|
||
|
|
target_compile_definitions(mbpoll PRIVATE
|
||
|
|
$<$<CONFIG:Release>:_FORTIFY_SOURCE=2>
|
||
|
|
$<$<CONFIG:Release>:NDEBUG>
|
||
|
|
$<$<CONFIG:RelWithDebInfo>:_FORTIFY_SOURCE=2>)
|
||
|
|
|
||
|
|
# Debug build with Address Sanitizer support
|
||
|
|
target_compile_options(mbpoll PRIVATE
|
||
|
|
$<$<CONFIG:Debug>:-g>
|
||
|
|
$<$<CONFIG:Debug>:-O0>
|
||
|
|
$<$<CONFIG:Debug>:-fno-omit-frame-pointer>)
|
||
|
|
|
||
|
|
# Optional: Enable sanitizers in debug mode (uncomment to use)
|
||
|
|
# target_compile_options(mbpoll PRIVATE $<$<CONFIG:Debug>:-fsanitize=address,undefined>)
|
||
|
|
# target_link_options(mbpoll PRIVATE $<$<CONFIG:Debug>:-fsanitize=address,undefined>)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Compile definitions
|
||
|
|
target_compile_definitions(mbpoll PRIVATE _GNU_SOURCE)
|
||
|
|
target_compile_definitions(mbpoll PRIVATE SKIP_FAILURE_EXIT)
|
||
|
|
|
||
|
|
if(MBPOLL_GPIO_RTS)
|
||
|
|
target_compile_definitions(mbpoll PRIVATE MBPOLL_GPIO_RTS)
|
||
|
|
target_include_directories(mbpoll PRIVATE ${PIDUINO_INCLUDE_DIRS})
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Link libraries
|
||
|
|
if(WIN32)
|
||
|
|
target_link_libraries(mbpoll PRIVATE wsock32 ws2_32)
|
||
|
|
else()
|
||
|
|
target_link_libraries(mbpoll PRIVATE ${LIBMODBUS_LIBRARIES})
|
||
|
|
target_link_directories(mbpoll PRIVATE ${LIBMODBUS_LIBRARY_DIRS})
|
||
|
|
target_compile_options(mbpoll PRIVATE ${LIBMODBUS_CFLAGS_OTHER})
|
||
|
|
|
||
|
|
if(MBPOLL_GPIO_RTS)
|
||
|
|
target_link_libraries(mbpoll PRIVATE ${PIDUINO_LIBRARIES})
|
||
|
|
target_link_directories(mbpoll PRIVATE ${PIDUINO_LIBRARY_DIRS})
|
||
|
|
endif()
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Windows pre-build step for libmodbus configuration
|
||
|
|
if(WIN32)
|
||
|
|
add_custom_command(
|
||
|
|
TARGET mbpoll PRE_BUILD
|
||
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/libmodbus/src/win32
|
||
|
|
COMMAND ${CSCRIPT_PATH} ${CMAKE_SOURCE_DIR}/libmodbus/src/win32/configure.js
|
||
|
|
VERBATIM)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Install target
|
||
|
|
install(TARGETS mbpoll
|
||
|
|
RUNTIME DESTINATION bin
|
||
|
|
PERMISSIONS ${PROGRAM_PERMISSIONS})
|
||
|
|
|
||
|
|
# Install man page (Unix only)
|
||
|
|
if(UNIX)
|
||
|
|
install(FILES ${CMAKE_SOURCE_DIR}/doc/mbpoll.1
|
||
|
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Uninstall target
|
||
|
|
configure_file(
|
||
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||
|
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||
|
|
IMMEDIATE @ONLY)
|
||
|
|
add_custom_target(uninstall
|
||
|
|
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||
|
|
|
||
|
|
# Testing support
|
||
|
|
option(BUILD_TESTING "Build unit tests" ON)
|
||
|
|
if(BUILD_TESTING)
|
||
|
|
enable_testing()
|
||
|
|
add_subdirectory(tests)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# CPack configuration for Debian packages
|
||
|
|
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
|
||
|
|
set(CPACK_PACKAGE_VERSION "${MBPOLL_VERSION_MAJOR}.${MBPOLL_VERSION_MINOR}.${MBPOLL_VERSION_PATCH}")
|
||
|
|
set(CPACK_PACKAGE_VERSION_MAJOR "${MBPOLL_VERSION_MAJOR}")
|
||
|
|
set(CPACK_PACKAGE_VERSION_MINOR "${MBPOLL_VERSION_MINOR}")
|
||
|
|
set(CPACK_PACKAGE_VERSION_PATCH "${MBPOLL_VERSION_PATCH}")
|
||
|
|
set(CPACK_PACKAGE_CONTACT "Pascal JEAN <pascal.jean@piduino.org>")
|
||
|
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME} - ${PROJECT_DESCRIPTION}")
|
||
|
|
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/package_description.txt")
|
||
|
|
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
|
||
|
|
set(CPACK_GENERATOR "DEB")
|
||
|
|
|
||
|
|
if(CPACK_GENERATOR STREQUAL "DEB")
|
||
|
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/epsilonrt/mbpoll")
|
||
|
|
|
||
|
|
find_program(dpkg_cmd NAMES dpkg)
|
||
|
|
if(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE AND dpkg_cmd)
|
||
|
|
execute_process(
|
||
|
|
COMMAND ${dpkg_cmd} --print-architecture
|
||
|
|
RESULT_VARIABLE ret
|
||
|
|
OUTPUT_VARIABLE arch
|
||
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||
|
|
if(ret EQUAL 0)
|
||
|
|
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${arch}")
|
||
|
|
else()
|
||
|
|
message(WARNING "Unable to get debian architecture!")
|
||
|
|
endif()
|
||
|
|
endif()
|
||
|
|
|
||
|
|
message(STATUS "Debian architecture: ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||
|
|
|
||
|
|
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||
|
|
message(STATUS "Debian package name: ${CPACK_PACKAGE_FILE_NAME}.deb")
|
||
|
|
|
||
|
|
if(MBPOLL_GPIO_RTS)
|
||
|
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmodbus5 (>= 3.1.7), libpiduino (>= ${PIDUINO_VERSION})")
|
||
|
|
else()
|
||
|
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmodbus5 (>= 3.1.7)")
|
||
|
|
endif()
|
||
|
|
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
include(CPack)
|
||
|
|
|
||
|
|
# Print configuration summary
|
||
|
|
message(STATUS "")
|
||
|
|
message(STATUS "mbpoll configuration summary:")
|
||
|
|
message(STATUS " Version: ${MBPOLL_VERSION_STRING}")
|
||
|
|
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
|
||
|
|
message(STATUS " GPIO RTS support: ${MBPOLL_GPIO_RTS}")
|
||
|
|
message(STATUS " Install prefix: ${CMAKE_INSTALL_PREFIX}")
|
||
|
|
message(STATUS "")
|