From cb35d69dd53d43dbdfbb3bb6dfdcce8e5cf77ab9 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 13:08:46 +0200 Subject: [PATCH 01/16] cmake: Use cmake >= 3.5, add project setup. Cmake made major changes in the 2.x -> 3.0 switch, keeping the 2.x compatiblity just isn't worth it. Since serial anyway doesn't build on versions before xenial, use xenial's cmake at 3.5 as baseline. Gbp-Pq: Name 0001-cmake-Use-cmake-3.5-add-project-setup.patch --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49270209..24ea92ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,16 @@ -cmake_minimum_required(VERSION 2.8.3) +cmake_minimum_required(VERSION 3.5.0) project(serial) # Find catkin find_package(catkin REQUIRED) +# General setup +project(serial + VERSION 1.2.1 + DESCRIPTION "Cross-platform, Serial Port library written in C++" + HOMEPAGE_URL "http://wjwwood.io/serial/" +) + if(APPLE) find_library(IOKIT_LIBRARY IOKit) find_library(FOUNDATION_LIBRARY Foundation) From ed0e389352359123ad400cc785b76158ac303933 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 13:28:04 +0200 Subject: [PATCH 02/16] cmake: Add defined so-version and public header to lib. Adding a so-version means defining an ABI level. This level is decoupled from the ordinary version, even a major version change doesn't necessarily mean that the so-version should change (and thus have all dependencies to be rebuilt). Adding the public header to clarify the setup. Gbp-Pq: Name 0002-cmake-Add-defined-so-version-and-public-header-to-li.patch --- CMakeLists.txt | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24ea92ea..ab371a66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ cmake_minimum_required(VERSION 3.5.0) -project(serial) + # Find catkin find_package(catkin REQUIRED) -# General setup +set(PROJ_SOVERSION 1) project(serial VERSION 1.2.1 DESCRIPTION "Cross-platform, Serial Port library written in C++" @@ -54,7 +54,19 @@ else() endif() ## Add serial library +set(serial_HEADERS + include/serial/serial.h + include/serial/v8stdint.h +) +# Build, link and install main library add_library(${PROJECT_NAME} ${serial_SRCS}) +set_target_properties(${PROJECT_NAME} PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJ_SOVERSION} + PUBLIC_HEADER "${serial_HEADERS}" +) +target_include_directories(${PROJECT_NAME} PUBLIC include) + if(APPLE) target_link_libraries(${PROJECT_NAME} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY}) elseif(UNIX) @@ -76,12 +88,10 @@ install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} + PUBLIC_HEADER DESTINATION + ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/${PROJECT_NAME} ) -## Install headers -install(FILES include/serial/serial.h include/serial/v8stdint.h - DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/serial) - ## Tests if(CATKIN_ENABLE_TESTING) add_subdirectory(tests) From 742555a6521ca90eb5cda791ae9ec96dfce2954d Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 14:26:33 +0200 Subject: [PATCH 03/16] cmake: Make test program depend on ENABLE_TEST_PROGRAM. Gbp-Pq: Name 0004-cmake-Make-test-program-depend-on-ENABLE_TEST_PROGRA.patch --- CMakeLists.txt | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab371a66..854e739e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,9 @@ if(APPLE) find_library(FOUNDATION_LIBRARY Foundation) endif() +# Public options and command line configuration +option(ENABLE_TEST_PROGRAM "Build test program" OFF) + if(UNIX AND NOT APPLE) # If Linux, add rt and pthread set(rt_LIBRARIES rt) @@ -75,11 +78,6 @@ else() target_link_libraries(${PROJECT_NAME} setupapi) endif() -## Uncomment for example -add_executable(serial_example examples/serial_example.cc) -add_dependencies(serial_example ${PROJECT_NAME}) -target_link_libraries(serial_example ${PROJECT_NAME}) - ## Include headers include_directories(include) @@ -92,7 +90,14 @@ install(TARGETS ${PROJECT_NAME} ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/${PROJECT_NAME} ) -## Tests + +# Other targets: test program, pkg-config and tests. if(CATKIN_ENABLE_TESTING) add_subdirectory(tests) endif() + +if (ENABLE_TEST_PROGRAM) + add_executable(serial_example examples/serial_example.cc) + add_dependencies(serial_example ${PROJECT_NAME}) + target_link_libraries(serial_example ${PROJECT_NAME}) +endif() From 00cbd2c1977ff2c506b51c7375ca58543be9c2de Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 14:49:18 +0200 Subject: [PATCH 04/16] cmake: Use doxygen for docs if found. Gbp-Pq: Name 0005-cmake-Use-doxygen-for-docs-if-found.patch --- CMakeLists.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 854e739e..9f0006c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,9 @@ endif() # Public options and command line configuration option(ENABLE_TEST_PROGRAM "Build test program" OFF) +set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/serial + CACHE STRING "Installation root for doxygen docs." +) if(UNIX AND NOT APPLE) # If Linux, add rt and pthread @@ -78,6 +81,7 @@ else() target_link_libraries(${PROJECT_NAME} setupapi) endif() + ## Include headers include_directories(include) @@ -101,3 +105,17 @@ if (ENABLE_TEST_PROGRAM) add_dependencies(serial_example ${PROJECT_NAME}) target_link_libraries(serial_example ${PROJECT_NAME}) endif() + +find_package(Doxygen) +if (DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND) + set(DOXYGEN_OUT ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile) + add_custom_target(doc ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" + VERBATIM + ) + install(DIRECTORY ${CMAKE_BINARY_DIR}/doc/html + DESTINATION ${SERIAL_DOCDIR} + ) +endif () From c0e9292ee1dd08ba4e474aec337431dff9ecab00 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 15:21:43 +0200 Subject: [PATCH 05/16] cmake: Make CATKIN_ENABLE_TESTING an official option. Gbp-Pq: Name 0006-cmake-Make-CATKIN_ENABLE_TESTING-an-offial-option.patch --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f0006c6..44b59014 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ endif() # Public options and command line configuration option(ENABLE_TEST_PROGRAM "Build test program" OFF) +option(CATKIN_ENABLE_TESTING "Enable catkin unit tests" ON) set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/serial CACHE STRING "Installation root for doxygen docs." ) From e1dabd86496113af3af5b84d385e5c64d869d5f7 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 15:37:34 +0200 Subject: [PATCH 06/16] cmake, include: Make use of v8stdint.h conditional. Make sure that in cases v8stdint.h is not used it's not even included in the package. Installation of this file is problematic when packaged since the file is used also in other packages and leads to installation conflicts. Gbp-Pq: Name 0007-cmake-include-Make-use-of-v8stdint.h-conditional.patch --- CMakeLists.txt | 24 +++++++++++++++--------- include/serial/serial.h | 5 +++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44b59014..6296f860 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/serial CACHE STRING "Installation root for doxygen docs." ) +find_path(HAVE_STDINT_H NAMES stdint.h) + if(UNIX AND NOT APPLE) # If Linux, add rt and pthread set(rt_LIBRARIES rt) @@ -41,11 +43,11 @@ else() endif() ## Sources -set(serial_SRCS - src/serial.cc - include/serial/serial.h - include/serial/v8stdint.h -) +set(serial_SRCS src/serial.cc include/serial/serial.h) +if (NOT HAVE_STDINT_H) + list(APPEND serial_SRCS include/serial/v8stdint.h) +endif () + if(APPLE) # If OSX list(APPEND serial_SRCS src/impl/unix.cc) @@ -61,10 +63,11 @@ else() endif() ## Add serial library -set(serial_HEADERS - include/serial/serial.h - include/serial/v8stdint.h -) +set(serial_HEADERS include/serial/serial.h) +if (NOT HAVE_STDINT_H) + list(APPEND serial_HEADERS include/serial/v8stdint.h) +endif () + # Build, link and install main library add_library(${PROJECT_NAME} ${serial_SRCS}) set_target_properties(${PROJECT_NAME} PROPERTIES @@ -73,6 +76,9 @@ set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${serial_HEADERS}" ) target_include_directories(${PROJECT_NAME} PUBLIC include) +if (HAVE_STDINT_H) + target_compile_definitions(${PROJECT_NAME} PRIVATE -DHAVE_STDINT_H) +endif () if(APPLE) target_link_libraries(${PROJECT_NAME} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY}) diff --git a/include/serial/serial.h b/include/serial/serial.h index a1657852..323cb489 100644 --- a/include/serial/serial.h +++ b/include/serial/serial.h @@ -43,7 +43,12 @@ #include #include #include + +#ifdef HAVE_STDINT_H +#include +#else #include +#endif #define THROW(exceptionClass, message) throw exceptionClass(__FILE__, \ __LINE__, (message) ) From 5f1ab387b7dd7bc9f08bd5d8961a7e101a5dcca2 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 22 Sep 2020 15:51:26 +0200 Subject: [PATCH 07/16] cmake: Add option for alternative name cxx-serial. The name serial is problematic when packaging since it's basically too generic and easily generates name clashes. Add an option which builds the package as cxx-serial instead, by default off to not break existing usage. Gbp-Pq: Name 0008-cmake-Add-option-for-alternative-name-cxx-serial.patch --- CMakeLists.txt | 14 ++++++++++++-- package.xml => package.xml.in | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) rename package.xml => package.xml.in (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6296f860..2bc9f9ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,26 @@ cmake_minimum_required(VERSION 3.5.0) +option(USE_CXX_SERIAL "build package name cxx-serial" OFF) +if (USE_CXX_SERIAL) + set(PKG_NAME cxx-serial) +else () + set(PKG_NAME serial) +endif () +message(STATUS "Building package ${PKG_NAME}") + # Find catkin find_package(catkin REQUIRED) set(PROJ_SOVERSION 1) -project(serial +project(${PKG_NAME} VERSION 1.2.1 DESCRIPTION "Cross-platform, Serial Port library written in C++" HOMEPAGE_URL "http://wjwwood.io/serial/" ) +configure_file(package.xml.in ${PROJECT_SOURCE_DIR}/package.xml @ONLY) + if(APPLE) find_library(IOKIT_LIBRARY IOKit) find_library(FOUNDATION_LIBRARY Foundation) @@ -19,7 +29,7 @@ endif() # Public options and command line configuration option(ENABLE_TEST_PROGRAM "Build test program" OFF) option(CATKIN_ENABLE_TESTING "Enable catkin unit tests" ON) -set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/serial +set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME} CACHE STRING "Installation root for doxygen docs." ) diff --git a/package.xml b/package.xml.in similarity index 96% rename from package.xml rename to package.xml.in index 27781e14..3320e4db 100644 --- a/package.xml +++ b/package.xml.in @@ -1,6 +1,6 @@ - serial + @PROJECT_NAME@ 1.2.1 Serial is a cross-platform, simple to use library for using serial ports on computers. From 94743a6b92857efc09d55c7511e0221c9cdb8460 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Thu, 24 Sep 2020 11:21:33 +0200 Subject: [PATCH 08/16] cmake: package.xml: Use version in PROJECT() call. --- .gitignore | 3 +++ CMakeLists.txt | 1 + package.xml.in | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2634447d..d024acab 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ doc/html ipch Debug Release + +# Generated from package.xml.in, must live in top dir. +package.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bc9f9ff..f69aa1f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ message(STATUS "Building package ${PKG_NAME}") find_package(catkin REQUIRED) set(PROJ_SOVERSION 1) + project(${PKG_NAME} VERSION 1.2.1 DESCRIPTION "Cross-platform, Serial Port library written in C++" diff --git a/package.xml.in b/package.xml.in index 3320e4db..2d56d828 100644 --- a/package.xml.in +++ b/package.xml.in @@ -1,7 +1,7 @@ @PROJECT_NAME@ - 1.2.1 + @PROJECT_VERSION@ Serial is a cross-platform, simple to use library for using serial ports on computers. This library provides a C++, object oriented interface for interacting with RS-232 From 9662bf6b1177cc360f86bb7eb02d7bedf35c1e92 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Fri, 25 Sep 2020 20:32:31 +0200 Subject: [PATCH 09/16] cmake: Make catkin package optional --- CMakeLists.txt | 79 +++++++++++++++++++++++++++----------------- FindRt.cmake | 19 +++++++++++ serial.pc.in | 12 +++++++ tests/CMakeLists.txt | 37 +++++++++++++++++++-- 4 files changed, 113 insertions(+), 34 deletions(-) create mode 100644 FindRt.cmake create mode 100644 serial.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index f69aa1f7..d67488bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,49 +9,54 @@ else () endif () message(STATUS "Building package ${PKG_NAME}") -# Find catkin -find_package(catkin REQUIRED) +option(DISABLE_CATKIN "Disable build of catkin package and tests" OFF) +if (DISABLE_CATKIN AND "${CATKIN_ENABLE_TESTING}" STREQUAL "" ) + set(CATKIN_ENABLE_TESTING OFF) +endif () set(PROJ_SOVERSION 1) - project(${PKG_NAME} VERSION 1.2.1 DESCRIPTION "Cross-platform, Serial Port library written in C++" HOMEPAGE_URL "http://wjwwood.io/serial/" ) +include(GNUInstallDirs) +if (NOT DISABLE_CATKIN) + find_package(catkin REQUIRED) +endif () configure_file(package.xml.in ${PROJECT_SOURCE_DIR}/package.xml @ONLY) -if(APPLE) - find_library(IOKIT_LIBRARY IOKit) - find_library(FOUNDATION_LIBRARY Foundation) -endif() # Public options and command line configuration option(ENABLE_TEST_PROGRAM "Build test program" OFF) option(CATKIN_ENABLE_TESTING "Enable catkin unit tests" ON) + set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME} CACHE STRING "Installation root for doxygen docs." ) find_path(HAVE_STDINT_H NAMES stdint.h) -if(UNIX AND NOT APPLE) - # If Linux, add rt and pthread - set(rt_LIBRARIES rt) - set(pthread_LIBRARIES pthread) - catkin_package( - LIBRARIES ${PROJECT_NAME} - INCLUDE_DIRS include - DEPENDS rt pthread - ) -else() - # Otherwise normal call +if (NOT DISABLE_CATKIN) + find_library(PTHREAD_LIB NAMES pthread REQUIRED) + if (PTHREAD_LIB) + set(PTHREAD_LIBRARIES ${PTHREAD_LIB}) + endif () + find_package(Rt) + if (RT_FOUND) + set(_RT RT) + endif () + configure_file(package.xml.in ${PROJECT_SOURCE_DIR}/package.xml @ONLY) catkin_package( LIBRARIES ${PROJECT_NAME} INCLUDE_DIRS include + DEPENDS ${_RT} PTHREAD ) -endif() + set(CMAKE_INSTALL_LIBDIR ${CATKIN_PACKAGE_LIB_DESTINATION}) + set(CMAKE_INSTALL_BINDIR ${CATKIN_GLOBAL_BIN_DESTINATION}) + set(CMAKE_INSTALL_INCLUDEDIR ${CATKIN_GLOBAL_INCLUDE_DESTINATION}) +endif () ## Sources set(serial_SRCS src/serial.cc include/serial/serial.h) @@ -91,13 +96,15 @@ if (HAVE_STDINT_H) target_compile_definitions(${PROJECT_NAME} PRIVATE -DHAVE_STDINT_H) endif () -if(APPLE) - target_link_libraries(${PROJECT_NAME} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY}) -elseif(UNIX) - target_link_libraries(${PROJECT_NAME} rt pthread) -else() +if (APPLE) + find_library(IOKIT_LIB IOKit) + find_library(FOUNDATION_LIB Foundation) + target_link_libraries(${PROJECT_NAME} ${FOUNDATION_LIB} ${IOKIT_LIB}) +elseif (UNIX) + target_link_libraries(${PROJECT_NAME} ${RT_LIBRARIES} ${PTHREAD_LIBRARIES}) +else () target_link_libraries(${PROJECT_NAME} setupapi) -endif() +endif () ## Include headers @@ -105,19 +112,29 @@ include_directories(include) ## Install executable install(TARGETS ${PROJECT_NAME} - ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} - RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} - PUBLIC_HEADER DESTINATION - ${CATKIN_GLOBAL_INCLUDE_DESTINATION}/${PROJECT_NAME} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} ) # Other targets: test program, pkg-config and tests. -if(CATKIN_ENABLE_TESTING) +if (CATKIN_ENABLE_TESTING) + include(CTest) + find_package(GTest REQUIRED) + enable_testing() add_subdirectory(tests) endif() +if (DISABLE_CATKIN) + configure_file(serial.pc.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc @ONLY) + install( + FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) +endif() + if (ENABLE_TEST_PROGRAM) add_executable(serial_example examples/serial_example.cc) add_dependencies(serial_example ${PROJECT_NAME}) diff --git a/FindRt.cmake b/FindRt.cmake new file mode 100644 index 00000000..05a6ed4d --- /dev/null +++ b/FindRt.cmake @@ -0,0 +1,19 @@ +# Try to find real time libraries +# Once done, this will define +# +# RT_FOUND - system has rt library +# RT_LIBRARIES - rt libraries directory + +if(RT_LIBRARIES) + set(RT_FIND_QUIETLY TRUE) +endif(RT_LIBRARIES) + +find_library(RT_LIBRARY rt) +set(RT_LIBRARIES ${RT_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set +# RT_FOUND to TRUE if all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Rt DEFAULT_MSG RT_LIBRARY) + +mark_as_advanced(RT_LIBRARY) diff --git a/serial.pc.in b/serial.pc.in new file mode 100644 index 00000000..ca6f25fc --- /dev/null +++ b/serial.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: @PROJECT_NAME@ +Description: C++ portable serial ports communication library +Version: @PROJECT_VERSION@ + +Requires: +Libs: -L${libdir} -l@PROJECT_NAME@ +Cflags: -I${includedir} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e52a4d31..187f2549 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -if(UNIX) +if (UNIX AND NOT DISABLE_CATKIN) catkin_add_gtest(${PROJECT_NAME}-test unix_serial_tests.cc) target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME} ${Boost_LIBRARIES}) if(NOT APPLE) @@ -6,7 +6,38 @@ if(UNIX) endif() if(NOT APPLE) # these tests are unreliable on macOS - catkin_add_gtest(${PROJECT_NAME}-test-timer unit/unix_timer_tests.cc) - target_link_libraries(${PROJECT_NAME}-test-timer ${PROJECT_NAME}) + catkin_add_gtest(${PROJECT_NAME}-test-timer unit/unix_timer_tests.cc) + target_link_libraries(${PROJECT_NAME}-test-timer ${PROJECT_NAME}) endif() +elseif (UNIX) + + add_executable(serial_test + unix_serial_tests.cc + ) + target_link_libraries(serial_test + ${PROJECT_NAME} gtest gtest_main pthread + ) + set_target_properties(serial_test + PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + ) + if (NOT APPLE) + target_link_libraries(serial_test util) + endif () + + add_executable(timer_test + unit/unix_timer_tests.cc + ) + target_link_libraries(timer_test + ${PROJECT_NAME} gtest gtest_main pthread + ) + set_target_properties(timer_test + PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + ) + + add_test(NAME serial_test COMMAND serial_test) + add_test(NAME timer_test COMMAND timer_test) endif() From 13ac389cbef6fc1d830574fe94ba82576ec62db4 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Sun, 27 Sep 2020 21:02:17 +0200 Subject: [PATCH 10/16] cmake: Move options to start, comments, cleanup. --- CMakeLists.txt | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d67488bc..c0d086e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.5.0) +# Public options and command line configuration +option(ENABLE_TEST_PROGRAM "Build test program" OFF) +option(CATKIN_ENABLE_TESTING "Enable catkin unit tests" ON) + option(USE_CXX_SERIAL "build package name cxx-serial" OFF) if (USE_CXX_SERIAL) @@ -9,6 +13,9 @@ else () endif () message(STATUS "Building package ${PKG_NAME}") +set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/${PKG_NAME} + CACHE STRING "Installation root for doxygen docs." +) option(DISABLE_CATKIN "Disable build of catkin package and tests" OFF) if (DISABLE_CATKIN AND "${CATKIN_ENABLE_TESTING}" STREQUAL "" ) set(CATKIN_ENABLE_TESTING OFF) @@ -21,24 +28,17 @@ project(${PKG_NAME} HOMEPAGE_URL "http://wjwwood.io/serial/" ) include(GNUInstallDirs) +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +# Locate packages, headers and libraries if (NOT DISABLE_CATKIN) find_package(catkin REQUIRED) endif () -configure_file(package.xml.in ${PROJECT_SOURCE_DIR}/package.xml @ONLY) - - -# Public options and command line configuration -option(ENABLE_TEST_PROGRAM "Build test program" OFF) -option(CATKIN_ENABLE_TESTING "Enable catkin unit tests" ON) - -set(SERIAL_DOCDIR ${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME} - CACHE STRING "Installation root for doxygen docs." -) find_path(HAVE_STDINT_H NAMES stdint.h) if (NOT DISABLE_CATKIN) + # Build the catkin library find_library(PTHREAD_LIB NAMES pthread REQUIRED) if (PTHREAD_LIB) set(PTHREAD_LIBRARIES ${PTHREAD_LIB}) @@ -65,26 +65,24 @@ if (NOT HAVE_STDINT_H) endif () if(APPLE) - # If OSX list(APPEND serial_SRCS src/impl/unix.cc) list(APPEND serial_SRCS src/impl/list_ports/list_ports_osx.cc) elseif(UNIX) - # If unix + # linux list(APPEND serial_SRCS src/impl/unix.cc) list(APPEND serial_SRCS src/impl/list_ports/list_ports_linux.cc) else() - # If windows + # win32 list(APPEND serial_SRCS src/impl/win.cc) list(APPEND serial_SRCS src/impl/list_ports/list_ports_win.cc) endif() -## Add serial library set(serial_HEADERS include/serial/serial.h) if (NOT HAVE_STDINT_H) list(APPEND serial_HEADERS include/serial/v8stdint.h) endif () -# Build, link and install main library +# Build and link main library add_library(${PROJECT_NAME} ${serial_SRCS}) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} @@ -107,10 +105,7 @@ else () endif () -## Include headers -include_directories(include) - -## Install executable +## Install main library, possibly the catkin one. install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -118,7 +113,6 @@ install(TARGETS ${PROJECT_NAME} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} ) - # Other targets: test program, pkg-config and tests. if (CATKIN_ENABLE_TESTING) include(CTest) From 2070f8ab683af8f4753cc599545f3c79df3a8ff1 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Sun, 27 Sep 2020 12:09:17 +0200 Subject: [PATCH 11/16] tests: Use elapsed time in timer tests (#232). Compute actually elapsed time instead of assuming that usleep() sleeps for exactly the right time, which isn't guaranteed. --- tests/unit/unix_timer_tests.cc | 75 ++++++++++++++++++++-------------- tests/unix_serial_tests.cc | 2 - 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/tests/unit/unix_timer_tests.cc b/tests/unit/unix_timer_tests.cc index 5bbd1edc..6e38ab3e 100644 --- a/tests/unit/unix_timer_tests.cc +++ b/tests/unit/unix_timer_tests.cc @@ -1,13 +1,31 @@ +#include +#include +#include + #include "gtest/gtest.h" #include "serial/impl/unix.h" -#include -#include - using serial::MillisecondTimer; namespace { +typedef std::chrono::high_resolution_clock Clock; + + +template +std::chrono::milliseconds as_milliseconds(T duration) +{ + return std::chrono::duration_cast(duration); +} + + +struct test_timer { + MillisecondTimer timer; + std::chrono::time_point start; + test_timer(unsigned value): start(Clock::now()), timer(value) {} +}; + + /** * Do 100 trials of timing gaps between 0 and 19 milliseconds. * Expect accuracy within one millisecond. @@ -15,48 +33,45 @@ namespace { TEST(timer_tests, short_intervals) { for (int trial = 0; trial < 100; trial++) { - uint32_t ms = rand() % 20; - MillisecondTimer mt(ms); - usleep(1000 * ms); - int32_t r = mt.remaining(); - - // 1ms slush, for the cost of calling usleep. - EXPECT_NEAR(r+1, 0, 1); + int ms = rand() % 20; + auto t1 = Clock::now(); + MillisecondTimer mt(ms); + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); + int elapsed = as_milliseconds(Clock::now() - t1).count(); + EXPECT_NEAR(ms - elapsed, mt.remaining(), 1); } } + TEST(timer_tests, overlapping_long_intervals) { - MillisecondTimer* timers[10]; - // Experimentally determined. Corresponds to the extra time taken by the loops, - // the big usleep, and the test infrastructure itself. - const int slush_factor = 14; + std::vector timers; - // Set up the timers to each time one second, 1ms apart. - for (int t = 0; t < 10; t++) - { - timers[t] = new MillisecondTimer(1000); - usleep(1000); + // Set up the timers to each time one second, 1 ms apart. + while (timers.size() < 10) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + struct test_timer timer(1000); // 1 s + timers.push_back(timer); } - // Check in on them after 500ms. - usleep(500000); - for (int t = 0; t < 10; t++) - { - EXPECT_NEAR(timers[t]->remaining(), 500 - slush_factor + t, 5); + // Check in on them after 500 ms. + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + for (auto& t: timers) { + auto elapsed = as_milliseconds(Clock::now() - t.start).count(); + EXPECT_NEAR(1000 - elapsed, t.timer.remaining(), 1); } - // Check in on them again after another 500ms and free them. - usleep(500000); - for (int t = 0; t < 10; t++) - { - EXPECT_NEAR(timers[t]->remaining(), -slush_factor + t, 5); - delete timers[t]; + // Check in on them again after another 500 ms. + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + for (auto& t: timers) { + auto elapsed = as_milliseconds(Clock::now() - t.start).count(); + EXPECT_NEAR(1000 - elapsed, t.timer.remaining(), 1); } } } // namespace + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/tests/unix_serial_tests.cc b/tests/unix_serial_tests.cc index 26ffde2d..c34868a2 100644 --- a/tests/unix_serial_tests.cc +++ b/tests/unix_serial_tests.cc @@ -20,8 +20,6 @@ void loop() #include #include "gtest/gtest.h" -#include - // Use FRIEND_TEST... its not as nasty, thats what friends are for // // OMG this is so nasty... // #define private public From a56c97e49c9814fa8198b884abdbb90db5a6d594 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Fri, 25 Sep 2020 09:15:59 +0200 Subject: [PATCH 12/16] ci: travis: Update to better match before refactoring. Although this patch better matches the state before the re-factoring, it doesn't mean that much since the build breaks already in the install stage. While on it, fix some yamllint nitpicks. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d626c6e8..d3e508aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,3 +8,4 @@ install: script: - mkdir build && cd build && cmake .. -DPYTHON_EXECUTABLE=$(which python2) && make && make tests && make run_tests - catkin_test_results . + From a459c7cdeefd8535c2fd37a6b77b2a88f7339849 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Thu, 24 Sep 2020 14:37:53 +0200 Subject: [PATCH 13/16] ci: .travis.yml: Refactor, add working focal and xenial builds. The existing targets for precise and osx breaks, both on dependencies. Seems to be about the 'rosdep install' command in the Makefile(?), which is beyond my current scope. Add a new target for Ubuntu focal which works after refactoring the .travis.yml file. Gbp-Pq: Name 0011-ci-.travis.yml-Refactor-add-working-focal-build.patch travis --- .travis.yml | 59 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3e508aa..8b0d8017 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,52 @@ -os: - - linux - - osx +--- language: cpp -install: - - make install_deps - - source setup.bash -script: - - mkdir build && cd build && cmake .. -DPYTHON_EXECUTABLE=$(which python2) && make && make tests && make run_tests - - catkin_test_results . +matrix: + include: + - os: linux + dist: focal + compiler: gcc + script: + - sudo apt update + - > + sudo apt install + build-essential cmake doxygen graphviz googletest libgtest-dev + - mkdir build && cd build + - cmake -DDISABLE_CATKIN=ON .. + - make + - make test + - os: linux + dist: xenial + compiler: gcc + script: + - sudo apt update + - > + sudo apt install + build-essential catkin cmake doxygen graphviz libgtest-dev + - mkdir build && cd build + - cmake -DDISABLE_CATKIN=OFF -DCATKIN_ENABLE_TESTING=OFF .. + - make + +# Does not build, breaks in make install_deps. +# - os: linux +# dist: precise +# compiler: gcc +# install: +# - make install_deps +# - source setup.bash +# script: +# - mkdir build && cd build +# - cmake -DPYTHON_EXECUTABLE=$(which python2) .. +# - make +# - make test + +# - os: osx +# compiler: clang +# install: +# - make install_deps +# - source setup.bash +# script: +# - mkdir build && cd build +# - cmake -DPYTHON_EXECUTABLE=$(which python2) .. +# - make +# - make run_tests From ba8745b9c104bcc3ef5f4a5badb6c6ae7a0ed197 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Sun, 27 Sep 2020 12:43:01 +0200 Subject: [PATCH 14/16] ci: Add a circleci linux and macos builder. --- .circleci/config.yml | 68 ++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 - 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..ae35f656 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,68 @@ +--- +version: 2 +jobs: + build-focal: + docker: + - image: circleci/buildpack-deps:focal-scm + steps: + - checkout + - run: sudo apt install build-essential cmake libcppunit-dev doxygen graphviz + - run: git clone https://github.com/google/googletest + - run: mkdir googletest/build; cd googletest/build; cmake .. + - run: cd googletest/build; make; sudo make install + - run: mkdir build + - run: cd build && cmake -DDISABLE_CATKIN=ON .. + - run: cd build && make && make test + build-macos: + macos: + xcode: "10.0.0" + steps: + - checkout + - restore-cache: + keys: + - 2020-09-29-v1 + - run: brew update + - run: brew upgrade git + - run: > + for p in llvm cmake cppunit doxygen; do + brew list --version $p || brew install $p; + brew link $p; + done + - run: > + brew list --version graphviz + || brew install graphviz || brew install graphviz || :; + brew link graphviz + - run: git clone https://github.com/google/googletest + - run: mkdir googletest/build; cd googletest/build; cmake .. + - run: cd googletest/build; make; sudo make install + - save-cache: + key: 2020-09-29-v1 + paths: + - /usr/local/Homebrew + - /usr/local/Cellar + - run: mkdir build + - run: > + cd build && cmake + -DDISABLE_CATKIN=ON + -DENABLE_CATKIN_TESTING=ON + .. + - run: cd build && make + - run: cd build && ARGS="--verbose" make test + + +workflows: + version: 2 + build_all: + jobs: + - build-focal: + filters: + branches: + only: + - master + - build + - build-macos: + filters: + branches: + only: + - master + - build diff --git a/.gitignore b/.gitignore index d024acab..652da978 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.* .DS_Store *.coverage *.egg-info From 7abad93f33e0a6d7b96911785b4bd64d3541fccb Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Sun, 27 Sep 2020 22:39:25 +0200 Subject: [PATCH 15/16] ci: Add an appveyor windows build script. --- appveyor.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..a76a11f2 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,27 @@ +clone_folder: c:\project\serial +shallow_clone: false +clone_depth: 10 + +image: +- Visual Studio 2017 + +platform: +- Win32 + +configuration: RelWithDebInfo +test: OFF + +install: + - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" + - choco install cmake + +before_build: + - cd c:\project\serial + - mkdir build + - cd build + - cmake -DDISABLE_CATKIN=ON -DCATKIN_ENABLE_TESTING=OFF .. + +build_script: + - cmake build . + - cmake --build . --target install + From 9dcca36b1988c2c45bf1e2214ca508dadbecd8b2 Mon Sep 17 00:00:00 2001 From: Alec Leamas Date: Tue, 29 Sep 2020 14:47:06 +0200 Subject: [PATCH 16/16] README.md: Update. --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3f99507a..05ccdc4b 100644 --- a/README.md +++ b/README.md @@ -16,15 +16,18 @@ API Documentation: http://wjwwood.github.com/serial/doc/1.1.0/index.html ### Dependencies -Required: -* [catkin](http://www.ros.org/wiki/catkin) - cmake and Python based buildsystem +Always required: * [cmake](http://www.cmake.org) - buildsystem + +Required when building the catkin package: +* [catkin](http://www.ros.org/wiki/catkin) - cmake and Python based buildsystem * [Python](http://www.python.org) - scripting language - * [empy](http://www.alcyone.com/pyos/empy/) - Python templating library - * [catkin_pkg](http://pypi.python.org/pypi/catkin_pkg/) - Runtime Python library for catkin +* [empy](http://www.alcyone.com/pyos/empy/) - Python templating library +* [catkin_pkg](http://pypi.python.org/pypi/catkin_pkg/) - Runtime Python library for catkin Optional (for tests): * [Boost](http://www.boost.org/) - Boost C++ librairies +* [Googletest](https://github.com/google/googletest) - Test framework Optional (for documentation): * [Doxygen](http://www.doxygen.org/) - Documentation generation tool