diff --git a/.gitignore b/.gitignore index 085383d5..1136a1aa 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ test/Makefile.in /compile config.guess config.sub -config.h.in configure /depcomp /install-sh @@ -72,3 +71,9 @@ test/test-frames/*.xml.new test/error-frames/*.xml.new test/unsupported-frames/*.xml.new +/build/ +_build/ + +# IDE +/.vscode/ +CMakeLists.txt.user \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..5161fe0b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,150 @@ +cmake_minimum_required(VERSION 3.8) + +project(libmbus LANGUAGES CXX C) + +set(PROJECT_VERSION "0.9.0") + +if(CMAKE_BUILD_TYPE STREQUAL "") + message(STATUS "CMAKE_BUILD_TYPE empty setting to Debug") + set(CMAKE_BUILD_TYPE "Debug") +endif() + +option(LIBMBUS_BUILD_EXAMPLES "build examples" OFF) +option(LIBMBUS_BUILD_TESTS "build tests" OFF) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_C_STANDARD 11) + +# Append our module directory to CMake +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) + +# Set the output of the libraries and executables. +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) + +# +# static analysis +# + +if(LIBMBUS_RUN_CLANG_TIDY) + find_program( + CLANG_TIDY_EXE + NAMES "clang-tidy" + DOC "/usr/bin/clang-tidy") + if(NOT CLANG_TIDY_EXE) + message(WARNING "clang-tidy not found.") + else() + message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") + set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}") + endif() +endif(LIBMBUS_RUN_CLANG_TIDY) + +include(CheckIncludeFile) + +check_include_file(dlfcn.h HAVE_DLFCN_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(memory.h HAVE_MEMORY_H) +check_include_file(stdlib.h HAVE_STDINT_H) +check_include_file(stdint.h HAVE_STDLIB_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(unistd.h HAVE_UNISTD_H) + +# +# library +# +set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + +set(PACKAGE_VERSION "${PROJECT_VERSION}") +set(VERSION "${PROJECT_VERSION}") +configure_file(${CMAKE_CURRENT_LIST_DIR}/mbus/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/mbus/config.h) + +add_library( + ${PROJECT_NAME} + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-protocol.c + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-protocol.h + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-tcp.c + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-tcp.h + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus.c + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus.h + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-protocol-aux.c + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-protocol-aux.h + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-serial.c + ${CMAKE_CURRENT_LIST_DIR}/mbus/mbus-serial.h) +target_include_directories( + ${PROJECT_NAME} + PUBLIC $ + $ + $) +target_link_libraries(${PROJECT_NAME} PRIVATE m) +target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wno-pedantic) + +if(CLANG_TIDY_EXE) + set_target_properties(${PROJECT_NAME} PROPERTIES CXX_CLANG_TIDY + "${DO_CLANG_TIDY}") +endif() + +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + +# +# examples +# + +if(LIBMBUS_BUILD_EXAMPLES) + message(STATUS "building examples") + add_subdirectory(bin) +endif() + +# +# tests +# + +if(LIBMBUS_BUILD_TESTS) + message(STATUS "building tests") + enable_testing() + add_subdirectory(test) +endif() + +# +# install +# + +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +set(LIBMBUS_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) +install( + TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib) + +install( + EXPORT ${PROJECT_NAME}Targets + DESTINATION ${LIBMBUS_CONFIG_INSTALL_DIR} + NAMESPACE ${PROJECT_NAME}:: + COMPONENT dev) + +configure_package_config_file(cmake/Config.cmake.in ${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION ${LIBMBUS_CONFIG_INSTALL_DIR}) +write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake + COMPATIBILITY SameMajorVersion) +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${LIBMBUS_CONFIG_INSTALL_DIR} + COMPONENT dev) + +# BUG: installing empty dirs https://gitlab.kitware.com/cmake/cmake/issues/17122 +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/mbus/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mbus/ + COMPONENT dev + FILES_MATCHING + PATTERN "*.h") diff --git a/README.md b/README.md index 27d393c0..133c243d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# libmbus: M-bus Library from Raditex Control (http://www.rscada.se) ![Build Status](https://travis-ci.org/rscada/libmbus.svg?branch=master) +# libmbus: M-bus Library from Raditex Control (http://www.rscada.se) + +![Build Status](https://travis-ci.org/rscada/libmbus.svg?branch=master) libmbus is an open source library for the M-bus (Meter-Bus) protocol. @@ -8,4 +10,32 @@ signals on the M-Bus, and the protocol and data format used in transmissions on the M-Bus. The role of libmbus is to decode/encode M-bus data, and to handle the communication with M-Bus devices. + +## BUILD + +with cmake + +```bash +rm -rf _build +mkdir _build +cd _build +# configure +# e.g. on linux +cmake .. -DLIBMBUS_BUILD_EXAMPLES=ON +# e.g. for a target device +cmake .. -DLIBMBUS_BUILD_EXAMPLES=ON -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain/foo-bar-baz.cmake +# compile +cmake --build . -j +# install - optional +cmake --build . --target install +``` + +## CONSUME + +```cmake +find_package(libmbus) +add_executable(my_app main.cpp) +target_link_libraries(my_app libmbus::libmbus) +``` + For more information see http://www.rscada.se/libmbus diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt new file mode 100644 index 00000000..73e15002 --- /dev/null +++ b/bin/CMakeLists.txt @@ -0,0 +1,19 @@ +function(add_example SRCS) + add_executable(${SRCS} ${CMAKE_CURRENT_LIST_DIR}/${SRCS}.c) + target_link_libraries(${SRCS} PRIVATE libmbus::libmbus) +endfunction() + +add_example(mbus-serial-request-data) +add_example(mbus-serial-request-data-multi-reply) +add_example(mbus-serial-scan) +add_example(mbus-serial-scan-secondary) +add_example(mbus-serial-select-secondary) +add_example(mbus-serial-set-address) +add_example(mbus-serial-switch-baudrate) +add_example(mbus-tcp-application-reset) +add_example(mbus-tcp-raw-send) +add_example(mbus-tcp-request-data) +add_example(mbus-tcp-request-data-multi-reply) +add_example(mbus-tcp-scan) +add_example(mbus-tcp-scan-secondary) +add_example(mbus-tcp-select-secondary) diff --git a/build.sh b/build.sh index 34c2799b..16653a9f 100755 --- a/build.sh +++ b/build.sh @@ -1,21 +1,7 @@ #!/bin/sh -# -if [ -f Makefile ]; then - # use existing automake files - echo >> /dev/null -else - # regenerate automake files - echo "Running autotools..." - - autoheader \ - && aclocal \ - && case \ - $(uname) in Darwin*) glibtoolize --ltdl --copy --force ;; \ - *) libtoolize --ltdl --copy --force ;; esac \ - && automake --add-missing --copy \ - && autoconf \ - && ./configure -fi - -make +rm -rf _build +mkdir _build +cd _build +cmake .. -DLIBMBUS_BUILD_EXAMPLES=ON -DLIBMBUS_BUILD_TESTS=ON +cmake --build . -j diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/mbus/config.h.in b/mbus/config.h.in new file mode 100644 index 00000000..369c7c80 --- /dev/null +++ b/mbus/config.h.in @@ -0,0 +1,59 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H "@HAVE_DLFCN_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H "@HAVE_INTTYPES_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H "@HAVE_MEMORY_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H "@HAVE_STDINT_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H "@HAVE_STDLIB_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H "@HAVE_STRINGS_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H "@HAVE_STRING_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H "@HAVE_SYS_STAT_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H "@HAVE_SYS_TYPES_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H "@HAVE_UNISTD_H@" + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libmbus" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "info@rscada.se" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libmbus" + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libmbus" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "http://www.rscada.se/libmbus/" + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" + +/* Version number of package */ +#cmakedefine VERSION "@PACKAGE_VERSION@" diff --git a/mbus/mbus-protocol.h b/mbus/mbus-protocol.h index 60b7424b..18a87527 100755 --- a/mbus/mbus-protocol.h +++ b/mbus/mbus-protocol.h @@ -554,6 +554,8 @@ const char *mbus_data_fixed_function(int status); long mbus_data_record_storage_number(mbus_data_record *record); long mbus_data_record_tariff(mbus_data_record *record); int mbus_data_record_device(mbus_data_record *record); +const char *mbus_data_record_unit(mbus_data_record *record); +const char *mbus_data_record_value(mbus_data_record *record); // // M-Bus frame data struct access/write functions diff --git a/mbus/mbus.c b/mbus/mbus.c index 0ff0f8ef..83079e9b 100644 --- a/mbus/mbus.c +++ b/mbus/mbus.c @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ #include "mbus-protocol.h" -#include "../config.h" +#include "mbus/config.h" // // diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..0303d236 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(mbus_parse ${CMAKE_CURRENT_LIST_DIR}/mbus_parse.c) +target_link_libraries(mbus_parse PRIVATE libmbus::libmbus) + +add_executable(mbus_parse_hex ${CMAKE_CURRENT_LIST_DIR}/mbus_parse_hex.c) +target_link_libraries(mbus_parse_hex PRIVATE libmbus::libmbus)