Skip to content

Commit 5d4a922

Browse files
add C++ modules support and CMake (#1)
1 parent e86754e commit 5d4a922

17 files changed

Lines changed: 395 additions & 44 deletions

.github/workflows/test.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ jobs:
2424
sudo apt install -y g++ cmake libasio-dev socat qt6-base-dev qt6-serialport-dev
2525
2626
- name: Configure CMake
27-
run: cmake -S test -B test/build
27+
run: cmake -S . -B build -DPROTOCOMM_BUILD_TESTS=ON -DPROTOCOMM_BUILD_ASIO=ON -DPROTOCOMM_BUILD_QT=ON
2828

2929
- name: Build
30-
run: cmake --build test/build
30+
run: cmake --build build
3131

3232
- name: Run
3333
run: |
3434
echo "Starting virtual serial port loopback..."
3535
sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11 &
3636
echo "Waiting for ports to initialize..."
3737
sleep 2
38-
echo "Running test..."
39-
sudo test/build/ProtoCommTest
38+
echo "Running tests..."
39+
cd build && sudo ctest --output-on-failure
4040
4141
clang:
4242
runs-on: ubuntu-latest
@@ -61,16 +61,16 @@ jobs:
6161
env:
6262
CC: /usr/bin/clang-18
6363
CXX: /usr/bin/clang++-18
64-
run: cmake -S test -B test/build
64+
run: cmake -S . -B build -DPROTOCOMM_BUILD_TESTS=ON -DPROTOCOMM_BUILD_ASIO=ON -DPROTOCOMM_BUILD_QT=ON
6565

6666
- name: Build
67-
run: cmake --build test/build
67+
run: cmake --build build
6868

6969
- name: Run
7070
run: |
7171
echo "Starting virtual serial port loopback..."
7272
sudo socat -d -d pty,raw,echo=0,link=/dev/ttyS10 pty,raw,echo=0,link=/dev/ttyS11 &
7373
echo "Waiting for ports to initialize..."
7474
sleep 2
75-
echo "Running test..."
76-
sudo test/build/ProtoCommTest
75+
echo "Running tests..."
76+
cd build && sudo ctest --output-on-failure

CMakeLists.txt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
cmake_minimum_required(VERSION 3.28)
2+
3+
project(ProtoComm
4+
VERSION 1.0.0
5+
DESCRIPTION "A header-only modern C++ library for message-based communication"
6+
LANGUAGES CXX
7+
)
8+
9+
# Set C++20 as the standard
10+
set(CMAKE_CXX_STANDARD 20)
11+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
12+
set(CMAKE_CXX_EXTENSIONS OFF)
13+
14+
# Options for building optional components
15+
option(PROTOCOMM_BUILD_ASIO "Build Asio protocol implementations" OFF)
16+
option(PROTOCOMM_BUILD_QT "Build Qt protocol implementations" OFF)
17+
option(PROTOCOMM_BUILD_MODULES "Build C++20 modules" OFF)
18+
option(PROTOCOMM_BUILD_TESTS "Build tests" OFF)
19+
option(PROTOCOMM_BUILD_EXAMPLES "Build examples" OFF)
20+
21+
# Add subdirectories
22+
add_subdirectory(include)
23+
add_subdirectory(src)
24+
25+
# C++20 Modules (experimental)
26+
if(PROTOCOMM_BUILD_MODULES)
27+
add_subdirectory(modules)
28+
endif()
29+
30+
# Tests
31+
if(PROTOCOMM_BUILD_TESTS)
32+
enable_testing()
33+
add_subdirectory(test)
34+
endif()
35+
36+
# Examples
37+
if(PROTOCOMM_BUILD_EXAMPLES)
38+
add_subdirectory(docs/examples)
39+
endif()
40+
41+
# Installation
42+
include(GNUInstallDirs)
43+
include(CMakePackageConfigHelpers)
44+
45+
# Install targets (handled in subdirectories)
46+
47+
# Generate and install CMake config files
48+
write_basic_package_version_file(
49+
"${CMAKE_CURRENT_BINARY_DIR}/ProtoCommConfigVersion.cmake"
50+
VERSION ${PROJECT_VERSION}
51+
COMPATIBILITY AnyNewerVersion
52+
)
53+
54+
configure_package_config_file(
55+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/ProtoCommConfig.cmake.in"
56+
"${CMAKE_CURRENT_BINARY_DIR}/ProtoCommConfig.cmake"
57+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ProtoComm
58+
)
59+
60+
install(EXPORT ProtoCommTargets
61+
FILE ProtoCommTargets.cmake
62+
NAMESPACE ProtoComm::
63+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ProtoComm
64+
)
65+
66+
install(FILES
67+
"${CMAKE_CURRENT_BINARY_DIR}/ProtoCommConfig.cmake"
68+
"${CMAKE_CURRENT_BINARY_DIR}/ProtoCommConfigVersion.cmake"
69+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ProtoComm
70+
)
71+
72+
# Export targets for build tree usage
73+
export(EXPORT ProtoCommTargets
74+
FILE "${CMAKE_CURRENT_BINARY_DIR}/ProtoCommTargets.cmake"
75+
NAMESPACE ProtoComm::
76+
)

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ A header-only modern C++ library designed for message-based communication with h
3434

3535
- **Optional Implementations:** Get started immediately with optional protocol implementations for ``asio`` and ``Qt``.
3636

37+
- **Modules support:** Use modules with C++20 and later.
3738

3839
## Dependencies
3940

@@ -52,8 +53,12 @@ The protocol implementations are optional and require the respective libraries.
5253

5354
A collection of examples demonstrating how to implement your own messages, protocols, and frame handlers can be found in the [docs/examples](docs/examples) directory.
5455

55-
56-
56+
The following options can be toggled in `CMakeLists.txt`:
57+
- `PROTOCOMM_BUILD_ASIO`, for building Asio protocol implementations
58+
- `PROTOCOMM_BUILD_QT`, for building Qt protocol implementations
59+
- `PROTOCOMM_BUILD_MODULES`, for building the C++ modules
60+
- `PROTOCOMM_BUILD_TESTS`, for building library tests
61+
- `PROTOCOMM_BUILD_EXAMPLES`, for building library examples
5762

5863
## Roadmap
5964

cmake/ProtoCommConfig.cmake.in

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@PACKAGE_INIT@
2+
3+
include(CMakeFindDependencyMacro)
4+
5+
# Find dependencies based on what was built
6+
if(@PROTOCOMM_BUILD_ASIO@)
7+
find_dependency(asio QUIET)
8+
if(NOT asio_FOUND)
9+
find_dependency(Boost QUIET COMPONENTS system)
10+
endif()
11+
endif()
12+
13+
if(@PROTOCOMM_BUILD_QT@)
14+
find_dependency(Qt6 COMPONENTS Core SerialPort)
15+
endif()
16+
17+
# Include the targets file
18+
include("${CMAKE_CURRENT_LIST_DIR}/ProtoCommTargets.cmake")
19+
20+
check_required_components(ProtoComm)

docs/examples/CMakeLists.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ProtoComm Examples
2+
3+
# NMEA Parser Example (synchronous)
4+
add_executable(nmea_parser
5+
nvea-parser.cpp
6+
)
7+
8+
target_link_libraries(nmea_parser PRIVATE
9+
ProtoComm::ProtoComm
10+
)
11+
12+
target_include_directories(nmea_parser PRIVATE
13+
${PROJECT_SOURCE_DIR}/include
14+
)
15+
16+
# NMEA Parser Example (asynchronous with futures)
17+
add_executable(nmea_parser_async
18+
nvea-parser-async.cpp
19+
)
20+
21+
target_link_libraries(nmea_parser_async PRIVATE
22+
ProtoComm::ProtoComm
23+
)
24+
25+
target_include_directories(nmea_parser_async PRIVATE
26+
${PROJECT_SOURCE_DIR}/include
27+
)
28+
29+
# Optional: Install examples
30+
install(TARGETS nmea_parser nmea_parser_async
31+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/ProtoComm/examples
32+
)
33+
34+
# Optional: Install example source files for reference
35+
install(FILES
36+
nvea-parser.cpp
37+
nvea-parser-async.cpp
38+
message.md
39+
protocols.md
40+
frame-handlers.md
41+
DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples
42+
)

include/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Header-only core library
2+
add_library(ProtoComm INTERFACE)
3+
add_library(ProtoComm::ProtoComm ALIAS ProtoComm)
4+
5+
target_include_directories(ProtoComm INTERFACE
6+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
7+
$<INSTALL_INTERFACE:include>
8+
)
9+
10+
target_compile_features(ProtoComm INTERFACE cxx_std_20)
11+
12+
# Installation
13+
install(TARGETS ProtoComm
14+
EXPORT ProtoCommTargets
15+
)
16+
17+
install(FILES
18+
ProtoComm.hpp
19+
AsioProtocols.hpp
20+
QtProtocols.hpp
21+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ProtoComm
22+
)
File renamed without changes.
File renamed without changes.

modules/AsioProtocols.cppm

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module;
2+
3+
#ifdef PROTOCOMM_BUILD_ASIO
4+
#include "AsioProtocols.hpp"
5+
#endif
6+
7+
export module ProtoComm:AsioProtocols;
8+
9+
export namespace ProtoComm {
10+
#ifdef PROTOCOMM_BUILD_ASIO
11+
using ProtoComm::AsioSerialProtocol;
12+
using ProtoComm::AsioTcpClient;
13+
using ProtoComm::AsioTcpServer;
14+
#endif
15+
}

0 commit comments

Comments
 (0)