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
9 changes: 7 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,15 @@ jobs:
run: |
mkdir cpp/build
cd cpp/build
cmake -G Ninja -S .. -DHDF5_ROOT="$CONDA_PREFIX"
ninja
cmake -G Ninja -S .. -DHDF5_ROOT="$CONDA_PREFIX" -DCMAKE_INSTALL_PREFIX=../install
ninja install
cd ../..
just run-cpp
- name: Test cpp example
run: |
cd cpp/example
cmake -B build -S . -DCMAKE_PREFIX_PATH=../install
cmake --build build --config Release
- name: Copy LICENSE for deployment
run: |
cp LICENSE.txt python/LICENSE
Expand Down
70 changes: 64 additions & 6 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
# Copyright (C) 2025 UMCG
# Copyright (C) 2023-2026 University College London
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.12.0) # older would work, but could give warnings on policy CMP0074
project(petsird VERSION 0.7.2)
include(GNUInstallDirs)

project(PETSIRD VERSION 0.9.0 LANGUAGES CXX)
set(PETSIRD_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/PETSIRD-0.9")

include(CMakePackageConfigHelpers)

set(CMAKE_CXX_STANDARD 17)
# Not required, as this is set in the yardl-generated file
# set(CMAKE_CXX_STANDARD 17)
# set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(WIN32)
add_compile_options(/W3 /WX)
Expand All @@ -19,10 +30,57 @@ endif()
# sourcesOutputDir: ../cpp/generated/petsird

add_subdirectory(generated/petsird)
# create a petsird library target
# Currently it is just empty, but allows creating target properties which are transitive
add_library(petsird)
target_include_directories(petsird_generated
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/generated>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

# petsird_generated is an OBJECT library. Those are a bit hard
# to handle for external projects, so create a "real" library as well.
# This is the one people should use.
add_library(petsird STATIC)
target_link_libraries(petsird PUBLIC petsird_generated)
target_include_directories(petsird PUBLIC "${PROJECT_SOURCE_DIR}/generated")

add_subdirectory(helpers)

install(TARGETS petsird petsird_generated petsird_helpers
EXPORT PETSIRDTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(EXPORT PETSIRDTargets
NAMESPACE PETSIRD::
DESTINATION ${PETSIRD_CMAKE_DIR}
)

install(
DIRECTORY generated/petsird/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/petsird
)

install(
DIRECTORY helpers/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)


configure_package_config_file(
cmake/PETSIRDConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/PETSIRDConfig.cmake
INSTALL_DESTINATION ${PETSIRD_CMAKE_DIR}
)

write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/PETSIRDConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)

install(FILES
${CMAKE_CURRENT_BINARY_DIR}/PETSIRDConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/PETSIRDConfigVersion.cmake
DESTINATION ${PETSIRD_CMAKE_DIR}
)
22 changes: 6 additions & 16 deletions cpp/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# PETSIRD basic C++ example
# PETSIRD C++ library and example

This directory contains some C++ example code to read/write PETSIRD data. You need to `yardl generate` in the `model` directory first.
This directory builds a library from C++ code to read/write PETSIRD data. You need to `yardl generate` in the `model` directory first.

The C++ code shows writing to and reading from an HDF5 file

1. Compile the code:

```sh
mkdir -p build
cmake -G Ninja -S . -B build -DHDF5_ROOT=$CONDA_PREFIX
ninja
cmake -G Ninja -S . -B build -DHDF5_ROOT=$CONDA_PREFIX -DCMAKE_INSTALL_PREFIX=~/install
cd build
ninja install
```

If you did not use `conda` to install HDF5, do not add the `-DHDF5_ROOT=$CONDA_PREFIX` part of the `cmake` line.
Expand All @@ -20,15 +21,4 @@ The C++ code shows writing to and reading from an HDF5 file

## Using this is a library

Currently, we do not install files yet. You therefore need to do something
like
```cmake
set(PETSIRD_dir ../PETSIRD/cpp/) # or wherever
add_subdirectory(${PETSIRD_dir} PETSIRD)

# only uses petsird
add_executable(your_executable PUBLIC STIR_PETSIRD_convertor.cpp petsird)

# also uses helpers
add_library(your_lib PUBLIC petsird_helpers)
```
See the [example directory](example/README.md)
33 changes: 33 additions & 0 deletions cpp/cmake/PETSIRDConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# CMake Config file for PETSIRD
# This file defines a few targets, but you should only use the following:
# PETSIRD::petsird : library with basic routines for IO (generated via yardl)
# PETSIRD::helpers : library with extra helper functions (depends on PETSIRD::petsird)
#
# Usage:
# find_package(PETSIRD REQUIRED CONFIG)
# add_executable(mine mine.cpp)
# target_link_libraries(mine PUBLIC PETSIRD::helpers)

# Copyright (C) 2025 UMCG
# Copyright (C) 2026 University College London
# SPDX-License-Identifier: Apache-2.0


@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(date)
# We need both xtensor and xtensor-blas
# (the latter doesn't depend on the former, weirdly)
find_dependency(xtensor)
find_dependency(xtensor-blas)
if(@PETSIRD_GENERATED_USE_NDJSON@)
find_dependency(nlohmann_json)
endif()
if(@PETSIRD_GENERATED_USE_HDF5@)
find_dependency(HDF5 COMPONENTS CXX)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/PETSIRDTargets.cmake")
check_required_components(PETSIRD)

# alias that should be future-proof
add_library(PETSIRD::helpers ALIAS PETSIRD::petsird_helpers)
1 change: 1 addition & 0 deletions cpp/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
11 changes: 11 additions & 0 deletions cpp/example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.12.0)
project(PETSIRDTest VERSION 0.1.0)

set(CMAKE_CXX_STANDARD 17)
find_package(PETSIRD REQUIRED CONFIG)
add_executable(PETSIRD_test PETSIRD_test.cpp)
target_link_libraries(PETSIRD_test PUBLIC PETSIRD::petsird)
add_executable(PETSIRD_test_helpers PETSIRD_test_helpers.cpp)
target_link_libraries(PETSIRD_test_helpers PUBLIC PETSIRD::helpers)

# install(TARGETS PETSIRD_test DESTINATION bin)
35 changes: 35 additions & 0 deletions cpp/example/PETSIRD_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <iostream>
#include "petsird/binary/protocols.h"
using petsird::binary::PETSIRDReader;

int
main(int argc, char const* argv[])
{
auto prog_name = argv[0];

std::string filename;
// option processing
while (argc > 1 && (strncmp(argv[1], "-", 1) == 0))
{
if (strcmp(argv[1], "--input") == 0 || strcmp(argv[1], "-i") == 0)
{
filename = argv[2];
++argv;
--argc;
}
else
{
std::cerr << "Wrong options\n";
return 1;
}
++argv;
--argc;
}

// Open the file
PETSIRDReader reader(filename);
petsird::Header header;
reader.ReadHeader(header);

return 0;
}
36 changes: 36 additions & 0 deletions cpp/example/PETSIRD_test_helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <iostream>
#include "petsird/binary/protocols.h"
using petsird::binary::PETSIRDReader;
#include "petsird_helpers/create.h"

int
main(int argc, char const* argv[])
{
auto prog_name = argv[0];

std::string filename;
// option processing
while (argc > 1 && (strncmp(argv[1], "-", 1) == 0))
{
if (strcmp(argv[1], "--input") == 0 || strcmp(argv[1], "-i") == 0)
{
filename = argv[2];
++argv;
--argc;
}
else
{
std::cerr << "Wrong options\n";
return 1;
}
++argv;
--argc;
}

// Open the file
PETSIRDReader reader(filename);
petsird::Header header;
reader.ReadHeader(header);

return 0;
}
18 changes: 18 additions & 0 deletions cpp/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# PETSIRD basic C++ example using PETSIRD

This directory contains some CMake/C++ example code on how to use
the PETSIRD library as an "external" user.

## Usage:

Assuming you installed PETSIRD in `~/install`, you should be able to
run the following from this directory:
```sh
cmake -B build -S . -DCMAKE_PREFIX_PATH=~/install
cmake --build build --config Release
```

If you have multiple versions of PETSIRD, you can be more specific:
```sh
cmake -B build -S . -DPETSIRD_DIR=~/install/lib/cmake/PETSIRD-0.7
```
20 changes: 16 additions & 4 deletions cpp/helpers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,23 @@ find_package(xtensor-blas REQUIRED)
# create a petsird_helpers library target
# Currently it is just empty, but allows creating target properties which are transitive
add_library(petsird_helpers INTERFACE)
target_link_libraries(petsird_helpers INTERFACE petsird xtensor-blas)
target_include_directories(petsird_helpers INTERFACE "${PROJECT_SOURCE_DIR}/helpers/include")
# Future change for when we have sources:
# add_library(petsird_helpers ${PETSIRD_HELPERS_SOURCES})

target_include_directories(petsird_helpers
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(petsird_helpers
INTERFACE
petsird
xtensor-blas
)

add_executable(petsird_generator petsird_generator.cpp)
target_link_libraries(petsird_generator petsird_helpers)
target_link_libraries(petsird_generator PRIVATE petsird_generated petsird_helpers)

add_executable(petsird_analysis petsird_analysis.cpp)
target_link_libraries(petsird_analysis petsird_helpers)
target_link_libraries(petsird_analysis PRIVATE petsird_generated petsird_helpers)
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ dependencies:
- pre-commit=4.0.1
- python>=3.11.3
- shellcheck>=0.8.0
- xtensor>=0.24.2
- xtensor>=0.24.2, < 0.27
- xtensor-blas
Loading