From e191e2d72656d9298df36772a82440ed8cc3d177 Mon Sep 17 00:00:00 2001 From: Carlos Gomes Martinho Date: Wed, 22 Apr 2020 17:07:24 +0200 Subject: [PATCH] build: add cmake support --- .github/workflows/main.yml | 48 +++ .gitignore | 10 +- BUILDING | 23 +- CMakeLists.txt | 627 +++++++++++++++++++++++++++++++++ cmake-format.yaml | 25 ++ cmake/Config.cmake.in | 4 + cmake/FindMbedTLS.cmake | 35 ++ cmake/FindTinyDTLS.cmake | 88 +++++ include/coap2/coap_config.h.in | 151 ++++++++ scripts/format_cmake.sh | 23 ++ src/net.c | 4 +- 11 files changed, 1034 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 CMakeLists.txt create mode 100644 cmake-format.yaml create mode 100644 cmake/Config.cmake.in create mode 100644 cmake/FindMbedTLS.cmake create mode 100644 cmake/FindTinyDTLS.cmake create mode 100644 include/coap2/coap_config.h.in create mode 100755 scripts/format_cmake.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..866b0e07 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,48 @@ +name: CMake + +on: [push] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + BUILD_SHARED_LIBS: ["ON", "OFF"] + ENABLE_DTLS: ["ON", "OFF"] + ENABLE_TCP: ["ON", "OFF"] + DTLS_BACKEND: ["openssl", "gnutls", "mbedtls", "tinydtls"] + + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: setup (linux) + if: startsWith(matrix.os, 'ubuntu') + run: | + sudo apt install libcunit1-dev libmbedtls-dev libgnutls28-dev + + - name: Create Build Environment + run: cmake -E make_directory ${{runner.workspace}}/build + + - name: Configure CMake + shell: bash + working-directory: ${{runner.workspace}}/build + run: | + cmake $GITHUB_WORKSPACE \ + -DENABLE_EXAMPLES=ON \ + -DENABLE_TESTS=ON \ + -DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} \ + -DENABLE_DTLS=${{matrix.ENABLE_DTLS}} \ + -DENABLE_TCP=${{matrix.ENABLE_TCP}} \ + -DDTLS_BACKEND=${{matrix.DTLS_BACKEND}} + + - name: Build + working-directory: ${{runner.workspace}}/build + shell: bash + run: cmake --build . + # TODO: add tests to the pipeline + # - name: Test + # working-directory: ${{runner.workspace}}/build + # shell: bash + # run: ctest . diff --git a/.gitignore b/.gitignore index c8c62c69..c5cf8f64 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ aclocal.m4 ar-lib autom4te.cache/ coap_config.h -coap_config.h.in +/coap_config.h.in compile config.* configure @@ -40,6 +40,7 @@ src/*.o src/.deps/ src/.dirstamp src/.libs/ +build/ # the doc/ folder doc/Doxyfile @@ -89,3 +90,10 @@ TAGS **/*.gcda **/*.gcno **/*.gcov + +# IDE files +CMakeLists.txt.user +/.vs/ +/out/ +/.vscode/ +/_build/ \ No newline at end of file diff --git a/BUILDING b/BUILDING index 7396a71e..7fe1286c 100644 --- a/BUILDING +++ b/BUILDING @@ -39,7 +39,24 @@ get the TinyDTLS code into your project, so the TinyDTLS library can be used. git submodule init git submodule update -General Building (not for LwIP or Contiki - see below) +General Building with cmake for linux/windows/macos/android (not for LwIP or Contiki - see below) +================ + + cmake -E remove_directory build + cmake -E make_directory build + cd build + cmake .. -DENABLE_EXAMPLES=ON + cmake --build . + [sudo] cmake --build . -- install + Note: to see possible options (TLS lib, doc, tests, examples etc.): + cmake -LH . + Note: For windows, this is supported by Visual Studio Code with CMake extension + Note: You should use cmake version >=3.10. + + Note: you can use cmake's find package after installation: find_package(libcoap REQUIRED), and target_link_libraries(myTarget PRIVATE libcoap::coap) + + +General Building with autoconf (not for LwIP or Contiki - see below) ================ ./autogen.sh @@ -53,7 +70,7 @@ that is missing. Install the missing package and try ./autogen.sh again. It is possible that you may need to provide some options to ./configure to customize your installation. -In particular you may need to define which (D)TLS ligrary to use as well as +In particular you may need to define which (D)TLS library to use as well as disable some building of documentation. General configure instructions can be found in INSTALL, which is built @@ -131,3 +148,5 @@ You may need to edit win32\libcoap.props to update the OpenSSLRootDir and OpenSSLRootDirDbg variables to point to the top level directory where OpenSSL is installed so that the include, lib etc. directories are correctly set up. Note: Make sure that you include a trailing \ in the variable definitions. + +Alternatively you can build everything in Visual Studio with CMake. \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..150850ec --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,627 @@ +cmake_minimum_required(VERSION 3.10) + +project( + libcoap + VERSION 4.3.0 + LANGUAGES CXX C) + +set(LIBCOAP_API_VERSION 2) +set(COAP_LIBRARY_NAME "coap") + +add_library(${COAP_LIBRARY_NAME}) + +# +# options to tweak the library +# + +option( + ENABLE_DTLS + "Enable building with DTLS support" + ON) +set(DTLS_BACKEND + "default" + CACHE + STRING + " \ + Name of the dtls backend, only relevant if `ENABLE_DTLS` is ON which is default. \ + Possible values: default, gnutls, openssl, tinydtls and mbedtls. \ + If specified then this library will be searched and if found also used. \ + If not found then the cmake configuration will stop with an error. \ + If not specified, then cmake will try to use the first one found in the following order: \ + gnutls, openssl, tinydtls, mbedtls \ + ") +set_property( + CACHE DTLS_BACKEND + PROPERTY STRINGS + default + openssl + gnutls + tinydtls + mbedtls) +option( + USE_VENDORED_TINYDTLS + "compile with the tinydtls project in the submodule if on, otherwise try to find the compiled lib with find_package" + ON) +option( + WITH_EPOLL + "compile with epoll support" + ON) +option( + ENABLE_SMALL_STACK + "Define if the system has small stack size" + OFF) +option( + ENABLE_TCP + "Enable building with TCP support" + ON) +option( + ENABLE_TESTS + "build also tests" + OFF) +option( + ENABLE_EXAMPLES + "build also examples" + ON) +option( + ENABLE_DOCS + "build also doxygen documentation" + ON) +option( + BUILD_SHARED_LIBS + "Build shared libs" + OFF) + +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) +endif() + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif() + +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) +endif() + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_BINARY_DIR}) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +include(CheckCSourceCompiles) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckSymbolExists) +include(CheckTypeSize) +include(TestBigEndian) + +# check for headers +check_include_file(byteswap.h HAVE_BYTESWAP_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(limits.h HAVE_LIMITS_H) +check_include_file(memory.h HAVE_MEMORY_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(sys/sysctl.h HAVE_SYS_SYSCTL_H) +check_include_file(netinet/in.h HAVE_NETINET_IN_H) +check_include_file(sys/epoll.h HAVE_EPOLL_H) +check_include_file(sys/timerfd.h HAVE_TIMERFD_H) +check_include_file(arpa/inet.h HAVE_ARPA_INET_H) +check_include_file(stdbool.h HAVE_STDBOOL_H) +check_include_file(netdb.h HAVE_NETDB_H) +check_include_file(pthread.h HAVE_PTHREAD_H) +check_include_file(stdlib.h HAVE_STDINT_H) +check_include_file(stdint.h HAVE_STDLIB_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(syslog.h HAVE_SYSLOG_H) +check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H) +check_include_file(sys/socket.h HAVE_SYS_SOCKET_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/time.h HAVE_SYS_TIME_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(sys/unistd.h HAVE_SYS_UNISTD_H) +check_include_file(time.h HAVE_TIME_H) +check_include_file(unistd.h HAVE_UNISTD_H) +check_include_file(float.h HAVE_FLOAT_H) +check_include_file(stddef.h HAVE_STDDEF_H) +check_include_file(winsock2.h HAVE_WINSOCK2_H) +check_include_file(ws2tcpip.h HAVE_WS2TCPIP_H) + +# check for functions +check_function_exists(malloc HAVE_MALLOC) +check_function_exists(memset HAVE_MEMSET) +check_function_exists(select HAVE_SELECT) +check_function_exists(socket HAVE_SOCKET) +check_function_exists(strcasecmp HAVE_STRCASECMP) +check_function_exists(pthread_mutex_lock HAVE_PTHREAD_MUTEX_LOCK) +check_function_exists(getaddrinfo HAVE_GETADDRINFO) +check_function_exists(strnlen HAVE_STRNLEN) +check_function_exists(strrchr HAVE_STRRCHR) + +# check for symbols +if(WIN32) + set(HAVE_STRUCT_CMSGHDR 1) +else() + check_symbol_exists( + cmsghdr + sys/socket.h + HAVE_STRUCT_CMSGHDR) +endif() + +if(${WITH_EPOLL} + AND ${HAVE_EPOLL_H} + AND ${HAVE_TIMERFD_H}) + set(COAP_EPOLL_SUPPORT "1") + message(STATUS "compiling with epoll support") +else() + message(STATUS "compiling without epoll support") +endif() + +if(ENABLE_SMALL_STACK) + set(ENABLE_SMALL_STACK "${ENABLE_SMALL_STACK}") + message(STATUS "compiling with small stack support") +endif() + +set(WITH_GNUTLS OFF) +set(WITH_OPENSSL OFF) +set(WITH_TINYDTLS OFF) +set(WITH_MBEDTLS OFF) + +function(compile_tinydtls) + set(TINYDTLS_SOURCES_DIR ${CMAKE_CURRENT_LIST_DIR}/ext/tinydtls) + set(TINYDTLS_SOURCES_GENERATED ${TINYDTLS_SOURCES_DIR}/dtls_config.h) + + message(STATUS "compiling the tinydtls lib") + + include(ExternalProject) + + externalproject_add( + external_tinydtls + SOURCE_DIR "${TINYDTLS_SOURCES_DIR}" + BUILD_IN_SOURCE 1 + DOWNLOAD_COMMAND "" + UPDATE_COMMAND "" + CONFIGURE_COMMAND + ${TINYDTLS_SOURCES_DIR}/configure + --disable-manpages + --prefix=${CMAKE_BINARY_DIR} + BUILD_COMMAND make install + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 + LOG_CONFIGURE 1) + + externalproject_add_step( + external_tinydtls autoheader + COMMAND "autoheader" + ALWAYS 1 + WORKING_DIRECTORY "${TINYDTLS_SOURCES_DIR}" + DEPENDERS configure + DEPENDEES autoconf) + + externalproject_add_step( + external_tinydtls autoconf + COMMAND "autoconf" + ALWAYS 1 + WORKING_DIRECTORY "${TINYDTLS_SOURCES_DIR}" + DEPENDERS autoheader + DEPENDEES download) + + # Let cmake know that it needs to execute the external_tinydtls target to generate those files. + add_custom_command( + OUTPUT ${TINYDTLS_SOURCES_GENERATED} + WORKING_DIRECTORY "${TINYDTLS_SOURCES_DIR}" + COMMAND "make install" + DEPENDS external_tinydtls) + + add_dependencies(${COAP_LIBRARY_NAME} external_tinydtls) + + if(BUILD_SHARED_LIBS) + set(LIBTINYDTLS_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib/libtinydtls.so") + else() + set(LIBTINYDTLS_PATH "${CMAKE_CURRENT_BINARY_DIR}/lib/libtinydtls.a") + endif() + + add_library( + tinydtls + UNKNOWN + IMPORTED) + set_target_properties( + tinydtls + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/include" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${LIBTINYDTLS_PATH}") + +endfunction() + +if(ENABLE_DTLS) + message(STATUS "compiling with DTLS support") + message(STATUS "DTLS_BACKEND: ${DTLS_BACKEND}") + + if(DTLS_BACKEND + STREQUAL + "default") + # try to find a crypto lib and use it, use the first one found + + # libgnutls (e.g. debian libgnutls28-dev) + find_package(GnuTLS) + if(GnuTLS_FOUND) + set(WITH_GNUTLS ON) + message(STATUS "compiling with gnutls support") + set(HAVE_LIBGNUTLS 1) + else() + # gnutls not found + find_package(OpenSSL) + if(OpenSSL_FOUND) + set(WITH_OPENSSL ON) + message(STATUS "compiling with openssl support") + set(HAVE_OPENSSL 1) + else() + # openssl not found + # libmbedtls (e.g. debian libmbedtls-dev) + find_package(MbedTLS) + if(MbedTLS_FOUND) + set(WITH_MBEDTLS ON) + message(STATUS "compiling with mbedtls support") + set(HAVE_MBEDTLS 1) + else() + # mbedtls not found + if(USE_VENDORED_TINYDTLS) + compile_tinydtls() + else() + find_package(TinyDTLS) + if(TINYDTLS_FOUND) + + else() + # no cryto lib found + message(FATAL_ERROR "cannot find any cryto lib, either install one or compile without DTLS support") + endif() + + endif() + + set(WITH_TINYDTLS ON) + message(STATUS "compiling with tinydtls support") + set(HAVE_LIBTINYDTLS 1) + + endif() + + endif() + + endif() + + else() + # DTLS_BACKEND variable is not empty, so set all to false and set the only right to true + set(WITH_GNUTLS OFF) + set(WITH_TINYDTLS OFF) + set(WITH_MBEDTLS OFF) + set(WITH_OPENSSL OFF) + + if(DTLS_BACKEND + STREQUAL + "gnutls") + # libgnutls (e.g. debian libgnutls28-dev) + find_package(GnuTLS REQUIRED) + set(WITH_GNUTLS ON) + message(STATUS "compiling with gnutls support") + set(HAVE_LIBGNUTLS 1) + endif() + + if(DTLS_BACKEND + STREQUAL + "openssl") + # libssl (e.g. debian libssl1.0-dev) + find_package(OpenSSL REQUIRED) + set(WITH_OPENSSL ON) + message(STATUS "compiling with openssl support") + set(HAVE_OPENSSL 1) + endif() + + if(DTLS_BACKEND + STREQUAL + "mbedtls") + # libmbedtls (e.g. debian libmbedtls-dev) + find_package(MbedTLS REQUIRED) + set(WITH_MBEDTLS ON) + message(STATUS "compiling with mbedtls support") + set(HAVE_MBEDTLS 1) + endif() + + if(DTLS_BACKEND + STREQUAL + "tinydtls") + + if(USE_VENDORED_TINYDTLS) + compile_tinydtls() + else(USE_VENDORED_TINYDTLS) + find_package(TinyDTLS REQUIRED) + endif(USE_VENDORED_TINYDTLS) + + message(STATUS "compiling with tinydtls support") + set(WITH_TINYDTLS ON) + set(HAVE_LIBTINYDTLS 1) + + endif() + + endif() + +endif() + +message(STATUS "ENABLE_DTLS:.....................${ENABLE_DTLS}") +message(STATUS "ENABLE_TCP:......................${ENABLE_TCP}") +message(STATUS "ENABLE_DOCS:.....................${ENABLE_DOCS}") +message(STATUS "ENABLE_EXAMPLES:.................${ENABLE_EXAMPLES}") +message(STATUS "DTLS_BACKEND:....................${DTLS_BACKEND}") +message(STATUS "WITH_GNUTLS:.....................${WITH_GNUTLS}") +message(STATUS "WITH_TINYDTLS:...................${WITH_TINYDTLS}") +message(STATUS "WITH_OPENSSL:....................${WITH_OPENSSL}") +message(STATUS "WITH_MBEDTLS:....................${WITH_MBEDTLS}") +message(STATUS "HAVE_LIBTINYDTLS:................${HAVE_LIBTINYDTLS}") +message(STATUS "HAVE_LIBGNUTLS:..................${HAVE_LIBGNUTLS}") +message(STATUS "HAVE_OPENSSL:....................${HAVE_OPENSSL}") +message(STATUS "HAVE_MBEDTLS:....................${HAVE_MBEDTLS}") +message(STATUS "COAP_EPOLL_SUPPORT:..............${COAP_EPOLL_SUPPORT}") +message(STATUS "CMAKE_C_COMPILER:................${CMAKE_C_COMPILER}") +message(STATUS "BUILD_SHARED_LIBS:...............${BUILD_SHARED_LIBS}") +message(STATUS "CMAKE_BUILD_TYPE:................${CMAKE_BUILD_TYPE}") +message(STATUS "CMAKE_SYSTEM_PROCESSOR:..........${CMAKE_SYSTEM_PROCESSOR}") + +set(PACKAGE_URL "https://libcoap.net/") +set(PACKAGE_NAME "${PROJECT_NAME}") +set(PACKAGE_TARNAME "${PROJECT_NAME}") +set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") +set(PACKAGE_VERSION "${PROJECT_VERSION}") +set(LIBCOAP_PACKAGE_VERSION "${PROJECT_VERSION}") +set(LIBCOAP_PACKAGE_URL "${PACKAGE_URL}") +set(LIBCOAP_PACKAGE_NAME "${PROJECT_NAME}") +set(LIBCOAP_PACKAGE_STRING "TODO") +set(LIBCOAP_PACKAGE_BUGREPORT "libcoap-developers@lists.sourceforge.net") +set(PACKAGE_BUGREPORT "libcoap-developers@lists.sourceforge.net") +set(top_srcdir "${CMAKE_CURRENT_LIST_DIR}") +set(top_builddir "${CMAKE_CURRENT_BINARY_DIR}") +set(COAP_DISABLE_TCP NOT "${ENABLE_TCP}") + +# creates config header file in build directory +configure_file(${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/coap2/coap.h) + +configure_file(${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/coap2/coap_config.h) + +# +# sources +# + +target_sources( + ${COAP_LIBRARY_NAME} + PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/pdu.c + ${CMAKE_CURRENT_LIST_DIR}/src/net.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_debug.c + ${CMAKE_CURRENT_LIST_DIR}/src/encode.c + ${CMAKE_CURRENT_LIST_DIR}/src/uri.c + ${CMAKE_CURRENT_LIST_DIR}/src/subscribe.c + ${CMAKE_CURRENT_LIST_DIR}/src/resource.c + ${CMAKE_CURRENT_LIST_DIR}/src/str.c + ${CMAKE_CURRENT_LIST_DIR}/src/option.c + ${CMAKE_CURRENT_LIST_DIR}/src/async.c + ${CMAKE_CURRENT_LIST_DIR}/src/block.c + ${CMAKE_CURRENT_LIST_DIR}/src/mem.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_io.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_session.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_hashkey.c + ${CMAKE_CURRENT_LIST_DIR}/src/address.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_time.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_event.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_notls.c + ${CMAKE_CURRENT_LIST_DIR}/src/coap_tcp.c + # no need to parse those files if we do not need them + $<$:${CMAKE_CURRENT_LIST_DIR}/src/coap_openssl.c> + $<$:${CMAKE_CURRENT_LIST_DIR}/src/coap_tinydtls.c> + $<$:${CMAKE_CURRENT_LIST_DIR}/src/coap_gnutls.c> + $<$:${CMAKE_CURRENT_LIST_DIR}/src/coap_mbedtls.c> + # headers + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/address.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/async.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/bits.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/block.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_debug.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_dtls.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_event.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_hashkey.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap.h.in + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_io.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_session.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/coap_time.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/encode.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/libcoap.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/lwippools.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/mem.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/net.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/option.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/pdu.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/prng.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/resource.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/str.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/subscribe.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/uri.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/uthash.h + ${CMAKE_CURRENT_LIST_DIR}/include/coap2/utlist.h) +# TODO: some *.c are still including the filename instead of "coap2/header.h" +target_include_directories( + ${COAP_LIBRARY_NAME} + PUBLIC # config headers are generated during configuration time + $ + $ + $ + $ + $ + $<$:${CMAKE_BINARY_DIR}/include/tinydtls> + $<$:${GNUTLS_INCLUDE_DIR}> + $<$:${MBEDTLS_INCLUDE_DIRS}>) +target_link_libraries( + ${COAP_LIBRARY_NAME} + PUBLIC $<$:OpenSSL::SSL> + $<$:OpenSSL::Crypto> + $<$:${GNUTLS_LIBRARIES}> + $<$:tinydtls> + $<$:${MBEDTLS_LIBRARY}> + $<$:${MBEDX509_LIBRARY}> + $<$:${MBEDCRYPTO_LIBRARY}>) + +add_library( + ${PROJECT_NAME}::${COAP_LIBRARY_NAME} + ALIAS + ${COAP_LIBRARY_NAME}) + +# +# compiler options +# + +add_compile_options( + $<$,$>:-Wall> + $<$,$>:-pedantic> + $<$,$>:-Wcast-qual> + $<$,$>:-Wextra> + $<$,$>:-Wformat-security> + $<$,$>:-Winline> + $<$,$>:-Wmissing-declarations> + $<$,$>:-Wmissing-prototypes> + $<$,$>:-Wnested-externs> + $<$,$>:-Wpointer-arith> + $<$,$>:-Wshadow> + $<$,$>:-Wstrict-prototypes> + $<$,$>:-Wswitch-default> + $<$,$>:-Wswitch-enum> + $<$,$>:-Wunused> + $<$,$>:-Wwrite-strings>) + +# +# tests +# + +if(ENABLE_TESTS) + add_executable( + testdriver + ${CMAKE_CURRENT_LIST_DIR}/tests/testdriver.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_encode.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_encode.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_error_response.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_error_response.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_options.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_options.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_pdu.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_pdu.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_sendqueue.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_sendqueue.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_session.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_session.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_tls.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_tls.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_uri.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_uri.h + ${CMAKE_CURRENT_LIST_DIR}/tests/test_wellknown.c + ${CMAKE_CURRENT_LIST_DIR}/tests/test_wellknown.h) + # tests require libcunit (e.g. debian libcunit1-dev) + target_link_libraries(testdriver PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME} -lcunit) +endif() + +# +# examples +# + +if(ENABLE_EXAMPLES) + add_executable(coap-client ${CMAKE_CURRENT_LIST_DIR}/examples/client.c) + target_link_libraries(coap-client PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME}) + + add_executable(coap-rd ${CMAKE_CURRENT_LIST_DIR}/examples/coap-rd.c) + target_link_libraries(coap-rd PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME}) + + add_executable(coap-server ${CMAKE_CURRENT_LIST_DIR}/examples/coap-server.c) + target_link_libraries(coap-server PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME}) + + if(NOT WIN32) + add_executable(etsi_iot_01 ${CMAKE_CURRENT_LIST_DIR}/examples/etsi_iot_01.c) + target_link_libraries(etsi_iot_01 PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME}) + + add_executable(tiny ${CMAKE_CURRENT_LIST_DIR}/examples/tiny.c) + target_link_libraries(tiny PUBLIC ${PROJECT_NAME}::${COAP_LIBRARY_NAME}) + endif() +endif() + +# +# docs +# + +if(ENABLE_DOCS) + find_package(Doxygen) + + if(Doxygen_FOUND) + # set input and output files + set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in) + set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + + # request to configure the file + configure_file( + ${DOXYGEN_IN} + ${DOXYGEN_OUT} + @ONLY) + + # note the option ALL which allows to build the docs together with the + # application + add_custom_target( + doc_doxygen ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" + VERBATIM) + + message(STATUS "Setup up the Doxygen documention build") + + else(Doxygen_FOUND) + message(WARNING "Doxygen need to be installed to generate the doxygen documentation") + endif(Doxygen_FOUND) + +endif() + +# +# install +# + +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +set(LIBCOAP_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) +install( + TARGETS ${COAP_LIBRARY_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 ${LIBCOAP_CONFIG_INSTALL_DIR} + NAMESPACE ${PROJECT_NAME}:: + COMPONENT dev) + +configure_package_config_file( + cmake/Config.cmake.in + ${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION + ${LIBCOAP_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 ${LIBCOAP_CONFIG_INSTALL_DIR} + COMPONENT dev) + +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT dev + FILES_MATCHING + PATTERN "*.h" + PATTERN "*internal.h" EXCLUDE) +install( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT dev + FILES_MATCHING + PATTERN "*.h") diff --git a/cmake-format.yaml b/cmake-format.yaml new file mode 100644 index 00000000..869c625d --- /dev/null +++ b/cmake-format.yaml @@ -0,0 +1,25 @@ +# to format cmake files we use cmake-format: +# pip install cmake-format --upgrade +# information about the configuration here: +# https://github.com/cheshirekow/cmake_format + +# How wide to allow formatted cmake files +line_width: 120 + +# How many spaces to tab for indent +tab_size: 2 + +# Format command names consistently as 'lower' or 'upper' case +command_case: "lower" + +first_comment_is_literal: False + +# enable comment markup parsing and reflow +enable_markup: False + +# If arglists are longer than this, break them always +max_subargs_per_line: 1 + +max_subgroups_hwrap: 2 + +max_pargs_hwrap: 2 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/cmake/FindMbedTLS.cmake b/cmake/FindMbedTLS.cmake new file mode 100644 index 00000000..75d8598d --- /dev/null +++ b/cmake/FindMbedTLS.cmake @@ -0,0 +1,35 @@ +find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h) + +find_library(MBEDTLS_LIBRARY mbedtls) +find_library(MBEDX509_LIBRARY mbedx509) +find_library(MBEDCRYPTO_LIBRARY mbedcrypto) + +set(MBEDTLS_LIBRARIES + "${MBEDTLS_LIBRARY}" + "${MBEDX509_LIBRARY}" + "${MBEDCRYPTO_LIBRARY}") + +if(MBEDTLS_LIBRARY) + set(MbedTLS_FOUND TRUE) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + MBEDTLS + DEFAULT_MSG + MBEDTLS_INCLUDE_DIRS + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY) + +mark_as_advanced( + MBEDTLS_INCLUDE_DIRS + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY) + +message(STATUS "MBEDTLS_INCLUDE_DIRS: ${MBEDTLS_INCLUDE_DIRS}") +message(STATUS "MBEDTLS_LIBRARY: ${MBEDTLS_LIBRARY}") +message(STATUS "MBEDX509_LIBRARY: ${MBEDX509_LIBRARY}") +message(STATUS "MBEDCRYPTO_LIBRARY: ${MBEDCRYPTO_LIBRARY}") +message(STATUS "MBEDTLS_LIBRARIES: ${MBEDTLS_LIBRARIES}") diff --git a/cmake/FindTinyDTLS.cmake b/cmake/FindTinyDTLS.cmake new file mode 100644 index 00000000..99557321 --- /dev/null +++ b/cmake/FindTinyDTLS.cmake @@ -0,0 +1,88 @@ +# FindTinyDTLS +# ----------- +# +# Find the tinyDTLS encryption library. +# +# Imported Targets +# ^^^^^^^^^^^^^^^^ +# +# This module defines the following :prop_tgt:`IMPORTED` targets: +# +# ``tinydtls`` +# The tinyDTLS ``tinydtls`` library, if found. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module will set the following variables in your project: +# +# ``TINYDTLS_FOUND`` +# System has the tinyDTLS library. +# ``TINYDTLS_INCLUDE_DIR`` +# The tinyDTLS include directory. +# ``TINYDTLS_LIBRARIES`` +# All tinyDTLS libraries. +# +# Hints +# ^^^^^ +# +# Set ``TINYDTLS_ROOT_DIR`` to the root directory of an tinyDTLS installation. + +if(TINYDTLS_ROOT_DIR) + set(_EXTRA_FIND_ARGS "NO_CMAKE_FIND_ROOT_PATH") +endif() + +find_path( + TINYDTLS_INCLUDE_DIR + NAMES tinydtls/dtls.h + PATH_SUFFIXES include + HINTS ${PROJECT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${TINYDTLS_ROOT_DIR} + ${_EXTRA_FIND_ARGS}) + +find_library( + TINYDTLS_LIBRARIES + NAMES tinydtls + PATH_SUFFIXES lib + HINTS ${PROJECT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${TINYDTLS_ROOT_DIR} + ${_EXTRA_FIND_ARGS}) + +if(TINYDTLS_LIBRARIES) + set(TINYDTLS_FOUND TRUE) +else() + set(TINYDTLS_FOUND FALSE) + if(TinyDTLS_FIND_REQUIRED) + message(FATAL_ERROR "Tinydtls could not be found") + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + tinyDTLS + FOUND_VAR + TINYDTLS_FOUND + REQUIRED_VARS + TINYDTLS_INCLUDE_DIR + TINYDTLS_LIBRARIES + VERSION_VAR) + +if(NOT + TARGET + tinydtls) + add_library( + tinydtls + UNKNOWN + IMPORTED) + set_target_properties( + tinydtls + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${TINYDTLS_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${TINYDTLS_LIBRARIES}") +endif() + +message(STATUS "TINYDTLS_INCLUDE_DIR: ${TINYDTLS_INCLUDE_DIR}") +message(STATUS "TINYDTLS_LIBRARIES: ${TINYDTLS_LIBRARIES}") +message(STATUS "TINYDTLS_ROOT_DIR: ${TINYDTLS_ROOT_DIR}") diff --git a/include/coap2/coap_config.h.in b/include/coap2/coap_config.h.in new file mode 100644 index 00000000..534002e5 --- /dev/null +++ b/include/coap2/coap_config.h.in @@ -0,0 +1,151 @@ +/* coap_config.h. Generated from coap_config.h.in by cmake. */ + +#ifndef COAP_CONFIG_H_ +#define COAP_CONFIG_H_ + +/* Define to 1 if you have header file. */ +#cmakedefine HAVE_WS2TCPIP_H "@HAVE_WS2TCPIP_H@" + +/* Define if the system has small stack size */ +#cmakedefine COAP_CONSTRAINED_STACK "@COAP_CONSTRAINED_STACK@" + +/* Define to 1 if you have header file. */ +#cmakedefine HAVE_WINSOCK2_H "@HAVE_WINSOCK2_H@" + +/* Define if the system has epoll support */ +#cmakedefine COAP_EPOLL_SUPPORT "@COAP_EPOLL_SUPPORT@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_INET_H "@HAVE_ARPA_INET_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H "@HAVE_ASSERT_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H "@HAVE_DLFCN_H@" + +/* Define to 1 if you have the `getaddrinfo' function. */ +#cmakedefine HAVE_GETADDRINFO "@HAVE_GETADDRINFO@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H "@HAVE_INTTYPES_H@" + +/* Define if the system has openssl */ +#cmakedefine HAVE_OPENSSL "@HAVE_OPENSSL@" + +/* Define if the system has libgnutls28 */ +#cmakedefine HAVE_LIBGNUTLS "@HAVE_LIBGNUTLS@" + +/* Define if the system has libtinydtls */ +#cmakedefine HAVE_LIBTINYDTLS "@HAVE_LIBTINYDTLS@" + +/* Define if the system has libmbedtls */ +#cmakedefine HAVE_MBEDTLS "@HAVE_MBEDTLS@" + +/* Define to 1 to build without TCP support. */ +#cmakedefine01 COAP_DISABLE_TCP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIMITS_H "@HAVE_LIMITS_H@" + +/* Define to 1 if you have the `malloc' function. */ +#cmakedefine HAVE_MALLOC "@HAVE_MALLOC@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H "@HAVE_MEMORY_H@" + +/* Define to 1 if you have the `memset' function. */ +#cmakedefine HAVE_MEMSET "@HAVE_MEMSET@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETDB_H "@HAVE_NETDB_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_IN_H "@HAVE_NETINET_IN_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PTHREAD_H "@HAVE_PTHREAD_H@" + +/* Define to 1 if you have the `pthread_mutex_lock' function. */ +#cmakedefine HAVE_PTHREAD_MUTEX_LOCK "@HAVE_PTHREAD_MUTEX_LOCK@" + +/* Define to 1 if you have the `select' function. */ +#cmakedefine HAVE_SELECT "@HAVE_SELECT@" + +/* Define to 1 if you have the `socket' function. */ +#cmakedefine HAVE_SOCKET "@HAVE_SOCKET@" + +/* 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 `strcasecmp' function. */ +#cmakedefine HAVE_STRCASECMP "@HAVE_STRCASECMP@" + +/* 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 `strnlen' function. */ +#cmakedefine HAVE_STRNLEN "@HAVE_STRNLEN@" + +/* Define to 1 if you have the `strrchr' function. */ +#cmakedefine HAVE_STRRCHR "@HAVE_STRRCHR@" + +/* Define to 1 if the system has the type `struct cmsghdr'. */ +#cmakedefine HAVE_STRUCT_CMSGHDR "@HAVE_STRUCT_CMSGHDR@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYSLOG_H "@HAVE_SYSLOG_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_IOCTL_H "@HAVE_SYS_IOCTL_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H "@HAVE_SYS_SOCKET_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_TIME_H "@HAVE_SYS_TIME_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_SYS_UNISTD_H "@HAVE_SYS_UNISTD_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H "@HAVE_TIME_H@" + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H "@HAVE_UNISTD_H@" + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" + +/* 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. */ +#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@" + +/* Define to the home page for this package. */ +#cmakedefine PACKAGE_URL "@PACKAGE_URL@" + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" + +#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(snprintf) +#define snprintf _snprintf +#endif + +#endif /* COAP_CONFIG_H_ */ diff --git a/scripts/format_cmake.sh b/scripts/format_cmake.sh new file mode 100755 index 00000000..2d8a94c5 --- /dev/null +++ b/scripts/format_cmake.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +cmakeFormat="cmake-format" + +path_to_cmake_format="$(which $cmakeFormat)" +echo "$path_to_cmake_format" + +if [ -z "$cmakeFormat" ] +then + echo "$cmakeFormat is not installed. Cannot format cmake files..." + echo "run: pip install cmake-format" + exit 1 +fi + +echo "$cmakeFormat was found, going to format your cmake scripts..." >&2 + +find $(dirname "$0")/ \ +-not \( -path "*/build/*" -prune \) \ +\( -name *.cmake -o -name CMakeLists.txt \) \ +| xargs $cmakeFormat -c cmake-format.yaml -i + + +echo "done formatting with cmake-format" diff --git a/src/net.c b/src/net.c index 4543e45e..42569a33 100644 --- a/src/net.c +++ b/src/net.c @@ -16,9 +16,11 @@ #endif #ifdef HAVE_UNISTD_H #include -#elif HAVE_SYS_UNISTD_H +#else +#ifdef HAVE_SYS_UNISTD_H #include #endif +#endif #ifdef HAVE_SYS_TYPES_H #include #endif