Skip to content

Commit

Permalink
Add C++ API
Browse files Browse the repository at this point in the history
This adds a C++17 API to the library. Implemented as a single header
without dependencies. It simplifies usage of the library when a
modern C++ compiler is available.

Signed-off-by: Tilman Blumhagen <tilman.blumhagen@googlemail.com>
  • Loading branch information
sternmull authored and pcercuei committed May 16, 2023
1 parent cf1c072 commit 690ab5a
Show file tree
Hide file tree
Showing 11 changed files with 956 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CI/azure/ci-ubuntu.sh
Expand Up @@ -3,6 +3,6 @@ set -x
uname -a
echo "$PWD"
mkdir build && cd build
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DWITH_HWMON=ON -DWITH_SERIAL_BACKEND=ON -DWITH_EXAMPLES=ON -DPYTHON_BINDINGS=ON -DENABLE_PACKAGING=ON -DCPACK_SYSTEM_NAME="${ARTIFACTNAME}"
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DWITH_HWMON=ON -DWITH_SERIAL_BACKEND=ON -DWITH_EXAMPLES=ON -DCPP_BINDINGS=ON -DPYTHON_BINDINGS=ON -DENABLE_PACKAGING=ON -DCPACK_SYSTEM_NAME="${ARTIFACTNAME}"
make
make package
14 changes: 13 additions & 1 deletion CMakeLists.txt
Expand Up @@ -225,6 +225,17 @@ endif()
set(LIBIIO_CFILES backend.c channel.c device.c context.c buffer.c utilities.c scan.c sort.c)
set(LIBIIO_HEADERS iio.h)

set(DOXYGEN_INPUT "${CMAKE_SOURCE_DIR}")
set(DOXYGEN_STRIP_FROM_PATH "${CMAKE_SOURCE_DIR}")

if (CPP_BINDINGS)
list(APPEND LIBIIO_HEADERS bindings/cpp/iiopp.h)
set(DOXYGEN_ENABLED_SECTIONS CPP_BINDINGS)
set(DOXYGEN_INPUT "${DOXYGEN_INPUT} ${CMAKE_SOURCE_DIR}/bindings/cpp/")
set(DOXYGEN_STRIP_FROM_PATH "${CMAKE_SOURCE_DIR}/bindings/cpp/")
set(DOXYGEN_CPP_EXAMPLE_PATH "${CMAKE_SOURCE_DIR}/bindings/cpp/examples")
endif()

if(WITH_USB_BACKEND)
list(APPEND LIBIIO_CFILES usb.c)
list(APPEND LIBS_TO_LINK ${LIBUSB_LIBRARIES})
Expand Down Expand Up @@ -485,7 +496,7 @@ set_target_properties(iio PROPERTIES
VERSION ${VERSION}
SOVERSION ${LIBIIO_VERSION_MAJOR}
FRAMEWORK ${OSX_FRAMEWORK}
PUBLIC_HEADER ${LIBIIO_HEADERS}
PUBLIC_HEADER "${LIBIIO_HEADERS}"
C_STANDARD 99
C_STANDARD_REQUIRED ON
C_EXTENSIONS OFF
Expand Down Expand Up @@ -560,6 +571,7 @@ if(WITH_DOC)
endif()
endif()

option(CPP_BINDINGS "Install C++ bindings" OFF)
option(CSHARP_BINDINGS "Install C# bindings" OFF)
option(PYTHON_BINDINGS "Install Python bindings" OFF)
add_subdirectory(bindings)
Expand Down
11 changes: 6 additions & 5 deletions Doxyfile.in
Expand Up @@ -160,7 +160,7 @@ FULL_PATH_NAMES = YES
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.

STRIP_FROM_PATH =
STRIP_FROM_PATH = @DOXYGEN_STRIP_FROM_PATH@

# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
Expand Down Expand Up @@ -708,7 +708,7 @@ GENERATE_DEPRECATEDLIST= YES
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
# ... \endcond blocks.

ENABLED_SECTIONS =
ENABLED_SECTIONS = @DOXYGEN_ENABLED_SECTIONS@

# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
# initial value of a variable or macro / define can have for it to appear in the
Expand Down Expand Up @@ -854,7 +854,7 @@ WARN_LOGFILE = @CMAKE_BINARY_DIR@/Dox_output_@PROJECT_NAME@
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT = @CMAKE_SOURCE_DIR@
INPUT = @DOXYGEN_INPUT@

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Expand Down Expand Up @@ -939,7 +939,8 @@ EXCLUDE_SYMBOLS =
# command).

EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/tests \
@CMAKE_SOURCE_DIR@/examples
@CMAKE_SOURCE_DIR@/examples \
@DOXYGEN_CPP_EXAMPLE_PATH@

# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
Expand Down Expand Up @@ -2208,7 +2209,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.

PREDEFINED =
PREDEFINED = DOXYGEN

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
Expand Down
4 changes: 2 additions & 2 deletions README_BUILD.md
Expand Up @@ -40,6 +40,7 @@ Cmake Options | Default | Target | Description
---------------------- | ------- | -------| ---------------------------------------------- |
`BUILD_SHARED_LIBS` | ON | All | Build shared libraries |
'COMPILE_WARNING_AS_ERROR' | OFF | All | Make all C warnings into errors |
`CPP_BINDINGS` | OFF | All | Install C++ bindings (C++17 required for examples) |
`PYTHON_BINDINGS` | OFF | All | Install PYTHON bindings |
`WITH_TESTS` | ON | All | Build the test programs (iio-utils) |
`WITH_EXAMPLES` | OFF | All | Build the example programs |
Expand All @@ -57,7 +58,6 @@ Cmake Options | Default | Target | Description
`OSX_FRAMEWORK` | ON | Mac | OS X frameworks provide the interfaces you need to write software for Mac. |
`OSX_PACKAGE` | ON | Mac | Create a OSX package for installation on local and other machines |


Which backends the library supports is dependent on the build system, but can be overridden.
(If cmake finds libusb, it will use it, unless turned off manually)

Expand Down Expand Up @@ -102,7 +102,7 @@ Cmake Options | Default | Description |
```shell
analog@precision:~/libiio$ mkdir build
analog@precision:~/libiio/build$ cd build
analog@precision:~/libiio/build$ cmake ../ -DPYTHON_BINDINGS=ON
analog@precision:~/libiio/build$ cmake ../ -DCPP_BINDINGS=ON -DPYTHON_BINDINGS=ON
analog@precision:~/libiio/build$ make -j$(nproc)
```

Expand Down
6 changes: 3 additions & 3 deletions azure-pipelines.yml
Expand Up @@ -208,23 +208,23 @@ stages:
- script: |
set -e
mkdir build && cd build
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DOSX_PACKAGE=ON -DPYTHON_BINDINGS=ON -DWITH_EXAMPLES=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=OFF
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DOSX_PACKAGE=ON -DCPP_BINDINGS=ON -DPYTHON_BINDINGS=ON -DWITH_EXAMPLES=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=OFF
make
sudo make install
cd ..
displayName: 'Build'
- script: |
set -e
mkdir build_tar && cd build_tar
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON -DPYTHON_BINDINGS=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=OFF -DCPACK_SYSTEM_NAME=${ARTIFACTNAME}
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DOSX_PACKAGE=OFF -DENABLE_PACKAGING=ON -DCPP_BINDINGS=ON -DPYTHON_BINDINGS=ON -DWITH_SERIAL_BACKEND=OFF -DWITH_ZSTD=OFF -DCPACK_SYSTEM_NAME=${ARTIFACTNAME}
make
make package
cd ..
displayName: 'Build tar'
- script: |
set -e
cd build
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DPYTHON_BINDINGS=ON -DWITH_DOC=ON
cmake .. -Werror=dev -DCOMPILE_WARNING_AS_ERROR=ON -DCPP_BINDINGS=ON -DPYTHON_BINDINGS=ON -DWITH_DOC=ON
make
cd ..
displayName: 'Build With Doc'
Expand Down
4 changes: 4 additions & 0 deletions bindings/CMakeLists.txt
@@ -1,3 +1,7 @@
if (CPP_BINDINGS)
add_subdirectory(cpp)
endif()

if (CSHARP_BINDINGS)
add_subdirectory(csharp)
endif()
Expand Down
7 changes: 7 additions & 0 deletions bindings/cpp/CMakeLists.txt
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 2.8.12)

project(iiopp-enum CXX)
add_executable(iiopp-enum examples/iiopp-enum.cpp iiopp.h ${LIBIIO_RC})
target_include_directories(iiopp-enum PRIVATE ./)
set_target_properties(iiopp-enum PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
target_link_libraries(iiopp-enum iio)
103 changes: 103 additions & 0 deletions bindings/cpp/examples/iiopp-enum.cpp
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* libiio - C++ API usage
*
* This example libiio program shows the usage of the C++ API for enumerating
* devices, channels and attributes.
*
* Copyright (c) 2023, DIFITEC GmbH
* Author: Tilman Blumhagen <tilman.blumhagen@difitec.de>
*/

#include <iiopp.h>

#include <iostream>
#include <iomanip>

using namespace iiopp;
using namespace std;

string get(IAttr const & att)
{
char value[1024] = {0}; // Flawfinder: ignore
att.read(value, sizeof(value)); // Flawfinder: ignore
return value;
}

void enumerateIioEntities()
{
cout << boolalpha;

shared_ptr<Context> context = create_default_context();

for (Device device : *context)
{
cout << "Device:" << endl;
cout << " id: " << quoted(string(device.id())) << endl;

cout << " name: ";
if (auto name = device.name())
cout << quoted(string(*name));
cout << endl;

cout << " is trigger: " << device.is_trigger() << endl;

for (auto att : device.attrs)
cout << " attribute " << att.name() << " = " << quoted(get(att)) << endl;

for (auto att : device.debug_attrs)
cout << " debug attribute " << att.name() << " = " << quoted(get(att)) << endl;

for (auto att : device.buffer_attrs)
cout << " buffer attribute " << att.name() << " = " << quoted(get(att)) << endl;

for (Channel channel : device)
{
cout << " Channel: " << channel.id() << endl;

cout << " name: ";
if (auto name = channel.name())
cout << quoted(string(*name));
cout << endl;

cout << " is output: " << channel.is_output() << endl;
cout << " is enabled: " << channel.is_enabled() << endl;

for (auto att : channel.attrs)
cout << " attribute " << quoted(att.name().c_str()) << " = " << quoted(get(att)) << endl;
}
}

shared_ptr<ScanContext> scanCtx = create_scan_context({}, 0);
shared_ptr<ScanContext::InfoList> infoList = scanCtx->info_list();

cout << "scan context info list:" << endl;
for (ContextInfo info : *infoList)
{
cout << " uri: " << quoted(info.uri().c_str()) << endl;
cout << " description: " << quoted(info.desciption().c_str()) << endl;
}

cout << "scan block:" << endl;
shared_ptr<ScanBlock> blk = create_scan_block({}, 0);
for (ContextInfo info : *blk)
{
cout << " uri: " << quoted(info.uri().c_str()) << endl;
cout << " description: " << quoted(info.desciption().c_str()) << endl;
}
}

int main(int argc, char ** argv)
{
try
{
enumerateIioEntities();
}
catch (std::exception & e)
{
cerr << "ERROR: " << e.what() << endl;
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

0 comments on commit 690ab5a

Please sign in to comment.