Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci-build-test-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
CARGO_TERM_COLOR: always
CMAKE_BUILD_PARALLEL_LEVEL: 2
steps:
- name: Checkout (with submodules)
- name: Checkout (with tempoch submodule)
uses: actions/checkout@v4
with:
submodules: recursive
Expand Down Expand Up @@ -39,6 +39,10 @@ jobs:
libssl-dev \
graphviz

- name: Install official qtty-cpp package
shell: bash
run: scripts/install-official-cpp-deps.sh

- name: Install Doxygen 1.16.1
shell: bash
run: |
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
CARGO_TERM_COLOR: always
CMAKE_BUILD_PARALLEL_LEVEL: 2
steps:
- name: Checkout (with submodules)
- name: Checkout (with tempoch submodule)
uses: actions/checkout@v4
with:
submodules: recursive
Expand All @@ -30,6 +30,10 @@ jobs:
libssl-dev \
gcovr

- name: Install official qtty-cpp package
shell: bash
run: scripts/install-official-cpp-deps.sh

- name: Set up Rust (stable)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
env:
CARGO_TERM_COLOR: always
steps:
- name: Checkout (with submodules)
- name: Checkout (with tempoch submodule)
uses: actions/checkout@v4
with:
submodules: recursive
Expand All @@ -26,6 +26,10 @@ jobs:
ninja-build \
clang-tidy

- name: Install official qtty-cpp package
shell: bash
run: scripts/install-official-cpp-deps.sh

- name: Install clang-format 18
shell: bash
run: |
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
CARGO_TERM_COLOR: always
CMAKE_BUILD_PARALLEL_LEVEL: 2
steps:
- name: Checkout (with submodules)
- name: Checkout (with tempoch submodule)
uses: actions/checkout@v4
with:
submodules: recursive
Expand All @@ -30,6 +30,10 @@ jobs:
libssl-dev \
rpm

- name: Install official qtty-cpp package
shell: bash
run: scripts/install-official-cpp-deps.sh

- name: Set up Rust (stable)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@
path = tempoch
url = git@github.com:Siderust/tempoch.git
branch = helpers
[submodule "qtty-cpp"]
path = qtty-cpp
url = https://github.com/Siderust/qtty-cpp.git
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.5] - 2026-06-14

### Added

- Added tests covering qtty-backed encoded-time arithmetic, period boundary
helpers, and FFI status/error translation paths.
- Added `scripts/install-official-cpp-deps.sh` for installing the official
`qtty-cpp` package on DEB/RPM systems.

### Changed

- Production builds now require the official `qtty-cpp >= 0.4.5` CMake package
via `find_package(qtty_cpp 0.4.5 REQUIRED)`.
- CI and Docker now install the official `qtty-cpp` package before configuring
tempoch-cpp.
- DEB/RPM package metadata now declares `qtty-cpp >= 0.4.5`.

### Removed

- Removed the vendored `qtty-cpp` submodule from the repository and build path.

## [0.5.4] - 2026-06-13

### Added
Expand Down
18 changes: 10 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.15)
project(tempoch_cpp VERSION 0.5.4 LANGUAGES CXX)
project(tempoch_cpp VERSION 0.5.5 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -73,10 +73,12 @@ endif()
add_dependencies(tempoch_ffi build_tempoch_ffi)

# qtty-cpp integration (provides unit types for duration<>)
if(NOT TARGET qtty_cpp)
set(QTTY_BUILD_DOCS OFF CACHE BOOL "Disable qtty-cpp docs when vendored by tempoch-cpp" FORCE)
add_subdirectory(qtty-cpp)
find_package(qtty_cpp 0.4.5 REQUIRED)
get_target_property(QTTY_CPP_INCLUDE_DIRS qtty::qtty_cpp INTERFACE_INCLUDE_DIRECTORIES)
if(NOT QTTY_CPP_INCLUDE_DIRS)
set(QTTY_CPP_INCLUDE_DIRS "")
endif()
string(REPLACE ";" " " QTTY_CPP_DOXYGEN_INCLUDE_PATHS "${QTTY_CPP_INCLUDE_DIRS}")

# Header-only C++ wrapper library
add_library(tempoch_cpp INTERFACE)
Expand All @@ -87,8 +89,7 @@ target_include_directories(tempoch_cpp INTERFACE
)
target_link_libraries(tempoch_cpp INTERFACE
tempoch_ffi
$<BUILD_INTERFACE:qtty_cpp>
$<INSTALL_INTERFACE:qtty::qtty_cpp>
qtty::qtty_cpp
)
add_dependencies(tempoch_cpp build_tempoch_ffi)

Expand Down Expand Up @@ -186,6 +187,7 @@ set(TEST_SOURCES
tests/test_constants.cpp
tests/test_data_status.cpp
tests/test_gnss_week.cpp
tests/test_context.cpp
)

add_executable(test_tempoch ${TEST_SOURCES})
Expand Down Expand Up @@ -287,14 +289,14 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(CPACK_DEBIAN_PACKAGE_NAME "tempoch-cpp")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "VPRamon <vallespuigramon@gmail.com>")
set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17), libstdc++6 (>= 9), qtty-cpp (>= 0.4.2)")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17), libstdc++6 (>= 9), qtty-cpp (>= 0.4.5)")
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)

# -- RPM -----------------------------------------------------------------------
set(CPACK_RPM_PACKAGE_NAME "tempoch-cpp")
set(CPACK_RPM_PACKAGE_LICENSE "AGPL-3.0")
set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
set(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.17, libstdc++ >= 9, qtty-cpp >= 0.4.2")
set(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.17, libstdc++ >= 9, qtty-cpp >= 0.4.5")
set(CPACK_RPM_FILE_NAME RPM-DEFAULT)

set(CPACK_GENERATOR "DEB;RPM")
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --pr
WORKDIR /workspace
COPY . /workspace

RUN scripts/install-official-cpp-deps.sh

RUN test -f tempoch/Cargo.toml && \
test -f tempoch/tempoch-ffi/Cargo.toml

Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,30 @@ The C++ wrapper intentionally mirrors the current `tempoch-ffi` surface. Rust-on
- CMake 3.15+
- C++17 compiler (GCC 8+, Clang 7+, MSVC 2019+)
- Rust/Cargo (builds `tempoch-ffi`)
- Installed `qtty-cpp >= 0.4.5` package, or a local staged install passed
through `CMAKE_PREFIX_PATH`

## Build and Test

```bash
git clone --recurse-submodules <repo-url>
git clone <repo-url>
cd tempoch-cpp
git submodule update --init tempoch

# Debian/RPM systems can install the official qtty-cpp package with:
./scripts/install-official-cpp-deps.sh

cmake -S . -B build
cmake --build build --parallel
ctest --test-dir build --output-on-failure
./build/01_quickstart
```

If you cloned without submodules:
For local qtty-cpp development, install qtty-cpp to a staging prefix and pass it
to CMake:

```bash
git submodule update --init --recursive
cmake -S . -B build -DCMAKE_PREFIX_PATH=/path/to/qtty-stage
```

## Usage
Expand Down Expand Up @@ -132,6 +139,7 @@ std::cout << dt.to<qtty::Hour>() << "\n";
### Add as a Subdirectory

```cmake
find_package(qtty_cpp 0.4.5 REQUIRED)
add_subdirectory(path/to/tempoch-cpp)
target_link_libraries(your_target PRIVATE tempoch_cpp)
```
Expand Down
2 changes: 1 addition & 1 deletion cmake/tempoch_cppConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

include(CMakeFindDependencyMacro)

find_dependency(qtty_cpp REQUIRED)
find_dependency(qtty_cpp 0.4.5 REQUIRED)

# Include the targets file
include("${CMAKE_CURRENT_LIST_DIR}/tempoch_cppTargets.cmake")
Expand Down
3 changes: 2 additions & 1 deletion docs/Doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ MACRO_EXPANSION = NO
SKIP_FUNCTION_MACROS = YES
INCLUDE_PATH = \
"@CMAKE_CURRENT_SOURCE_DIR@/include" \
"@CMAKE_CURRENT_SOURCE_DIR@/tempoch/tempoch-ffi/include"
"@CMAKE_CURRENT_SOURCE_DIR@/tempoch/tempoch-ffi/include" \
@QTTY_CPP_DOXYGEN_INCLUDE_PATHS@

SOURCE_BROWSER = YES
INLINE_SOURCES = NO
Expand Down
4 changes: 3 additions & 1 deletion docs/mainpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ FFI `tempoch_status_t` codes are translated into typed C++ exceptions:
## Building

```bash
git clone --recurse-submodules <url>
git clone <url>
cd tempoch-cpp
git submodule update --init tempoch
./scripts/install-official-cpp-deps.sh

cmake -S . -B build
cmake --build build --parallel
Expand Down
1 change: 0 additions & 1 deletion qtty-cpp
Submodule qtty-cpp deleted from 35a679
2 changes: 1 addition & 1 deletion scripts/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ ensure_repo_root
header "Submodule check"
git submodule status --recursive || true
if [[ ! -f tempoch/Cargo.toml ]]; then
fail "tempoch submodule missing (run: git submodule update --init --recursive)"
fail "tempoch submodule missing (run: git submodule update --init tempoch)"
exit 1
fi
ok "tempoch submodule present"
Expand Down
48 changes: 48 additions & 0 deletions scripts/install-official-cpp-deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -euo pipefail

QTTY_CPP_VERSION="${QTTY_CPP_VERSION:-0.4.5}"
SIDERUST_PACKAGE_BASE_URL="${SIDERUST_PACKAGE_BASE_URL:-https://siderust.org}"

tmp_dir="$(mktemp -d)"
cleanup() {
rm -rf "${tmp_dir}"
}
trap cleanup EXIT

run_privileged() {
if [[ "$(id -u)" -eq 0 ]]; then
"$@"
elif command -v sudo >/dev/null 2>&1; then
sudo "$@"
else
echo "This installer needs root privileges or sudo to install system packages." >&2
return 1
fi
}

download() {
local url="$1"
local output="$2"
echo "Downloading ${url}"
curl -fsSL "${url}" -o "${output}"
}

if command -v apt-get >/dev/null 2>&1 && command -v dpkg >/dev/null 2>&1; then
qtty_pkg="${tmp_dir}/qtty-cpp_${QTTY_CPP_VERSION}_amd64.deb"
download "${SIDERUST_PACKAGE_BASE_URL}/apt/qtty-cpp_${QTTY_CPP_VERSION}_amd64.deb" "${qtty_pkg}"
run_privileged apt-get install -y --no-install-recommends "${qtty_pkg}"
elif command -v rpm >/dev/null 2>&1; then
qtty_pkg="${tmp_dir}/qtty-cpp-${QTTY_CPP_VERSION}-1.x86_64.rpm"
download "${SIDERUST_PACKAGE_BASE_URL}/rpm/qtty-cpp-${QTTY_CPP_VERSION}-1.x86_64.rpm" "${qtty_pkg}"
if command -v dnf >/dev/null 2>&1; then
run_privileged dnf install -y "${qtty_pkg}"
elif command -v yum >/dev/null 2>&1; then
run_privileged yum install -y "${qtty_pkg}"
else
run_privileged rpm -Uvh "${qtty_pkg}"
fi
else
echo "Unsupported package manager. Install qtty-cpp manually, then pass its prefix through CMAKE_PREFIX_PATH if needed." >&2
exit 1
fi
26 changes: 26 additions & 0 deletions tests/test_context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <gtest/gtest.h>
#include <tempoch/tempoch.hpp>

using namespace tempoch;

TEST(FfiCore, CheckStatusTranslatesKnownErrors) {
EXPECT_NO_THROW(check_status(TEMPOCH_STATUS_T_OK, "ok"));
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_NULL_POINTER, "op"), NullPointerError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_UTC_CONVERSION_FAILED, "op"), UtcConversionError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_INVALID_PERIOD, "op"), InvalidPeriodError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_NO_INTERSECTION, "op"), NoIntersectionError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_INVALID_SCALE_ID, "op"), InvalidScaleIdError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_INVALID_DURATION_UNIT, "op"),
InvalidDurationUnitError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_CONVERSION_FAILED, "op"), ConversionFailedError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_INVALID_FORMAT_ID, "op"), InvalidFormatIdError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_INTERNAL_PANIC, "op"), InternalPanicError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_UT1_HORIZON_EXCEEDED, "op"), Ut1HorizonExceededError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_PERIOD_LIST_UNSORTED, "op"), PeriodListUnsortedError);
EXPECT_THROW(check_status(TEMPOCH_STATUS_T_PERIOD_LIST_OVERLAPPING, "op"),
PeriodListOverlappingError);

const auto unknown_status =
static_cast<tempoch_status_t>(9999); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
EXPECT_THROW(check_status(unknown_status, "op"), TempochException);
}
Loading
Loading