Skip to main content

Installation

C#

Install via NuGet:

dotnet add package rfIDEAS.ReaderIntegrationKit

Or via Package Manager Console:

Install-Package rfIDEAS.ReaderIntegrationKit

Requirements: .NET 8.0 or later (the package targets .NET 8.0 and .NET 10.0) on a supported runtime identifier (Windows x64, Linux x64, Linux ARM64, Linux ARMhf, macOS x64, or macOS ARM64)

note

The NuGet package includes native libraries for Windows x64, Linux x64, Linux ARM64, Linux ARMhf, and macOS (Intel + Apple Silicon, Monterey 12+). They are automatically placed in the correct runtime directory at build time.

Minimal Project

MyApp.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64;linux-x64;linux-arm64;linux-arm;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="rfIDEAS.ReaderIntegrationKit" Version="*" />
</ItemGroup>
</Project>
note

Linux ARM64 includes two optimized variants: Raspberry Pi 5 and generic ARM64. At runtime the package selects the variant using the RIK_ARM_VARIANT environment variable when set (pi5 or generic); otherwise it inspects /proc/device-tree/model and falls back to generic. No build-time configuration is required.

macOS

The NuGet package includes a universal dylib staged under both runtimes/osx-x64/native/ and runtimes/osx-arm64/native/. An additional copy is present at runtimes/osx-universal/native/libReaderIntegrationKit.dylib and is used as a fallback by the runtime loader (NativeLibraryLocator) when a RID-specific path is not found. Including osx-x64 and osx-arm64 in <RuntimeIdentifiers> is sufficient -- no osx-universal RID is required in consumer projects.


Python

Install from PyPI with a single command. pip automatically selects the correct platform-tagged wheel for your operating system and CPU architecture:

pip install reader-integration-kit
Platform / ArchitectureWheel tag
Linux x86_64manylinux_*_x86_64
Linux ARM64 (generic aarch64 and Raspberry Pi 5)manylinux_*_aarch64
Linux 32-bit ARM hard-float (ARMhf / armv7)manylinux_*_armv7l
Windows x86_64win_amd64
macOS (Intel + Apple Silicon, 12.0+)macosx_12_0_universal2

The wheel bundles the native shared library for your platform. The Python import name is the same on every platform:

import reader_integration_kit
Raspberry Pi 5

The Linux ARM64 wheel bundles both the Raspberry Pi 5-optimized and the generic ARM64 native library. The correct variant is selected automatically at import time: the package inspects /proc/device-tree/model, and you can override the choice with the RIK_ARM_VARIANT environment variable (pi5 or generic). No package choice is required at install time.

Upgrading from older package names

Earlier releases published per-platform packages (for example reader-integration-kit-linux-x86-64). Those names still resolve: they are now thin redirect packages that depend on the unified reader-integration-kit, so existing requirements.txt entries continue to work without changes.

Requirements: Python 3.8+

Verify Installation

from reader_integration_kit.facade import AbstractReader
info = AbstractReader.get_library_info()
print(f"RIK version: {info.get('VersionString')}")
tip

If the import succeeds and prints a version, the native shared library was loaded correctly.


C++

RIK for C++ is distributed as prebuilt libraries with headers for Windows x64, Linux x64, Linux ARM64, Linux ARMhf, and macOS (universal binary covering Intel and Apple Silicon). Two linking variants are available (shared and static). On Linux ARM64, two CPU builds are published:

Linux ARM targetPrebuilt package
Raspberry Pi 5 (optimized)ARM64 package labeled for Raspberry Pi 5
Generic ARM64 (aarch64)ARM64 package labeled for generic / non–Pi 5 boards
32-bit ARM hard-float (ARMhf)ARMhf package

Download the shared or static archive whose platform name matches your target from the rf IDEAS download portal. Package names follow the pattern ReaderIntegrationKit-<version>-<platform>-shared.zip (or -static.zip). On macOS, the platform token is Darwin-AppleClang-universal and a single archive covers both Intel and Apple Silicon (universal binary).

For each platform, two linking variants are available:

VariantFileBest for
Shared (default).dll / .so / .dylibMost projects. Smaller executable, simpler updates.
Static.lib / .aSelf-contained deployment with no runtime dependencies on the RIK library file.

Both variants ship the same headers. The CMake find_package integration works identically for both -- your CMakeLists.txt does not need to change. Just point CMAKE_PREFIX_PATH at whichever package you extracted.

Shared vs Static: Which Should I Use?

Use the shared library if you are building a desktop application, service, or prototype. It is the simplest path -- your executable stays small, and you can update the RIK library independently by swapping the .dll, .so, or .dylib file. This is the recommended default.

Use the static library if you need a single self-contained binary with no external library files. This is common for embedded deployments, appliance software, or environments where distributing a separate .dll, .so, or .dylib is inconvenient. The static library is a "fat archive" that bundles all internal dependencies (protocol, transport, and third-party libraries) into one file, so you only need the .lib/.a and the headers. On macOS, the static library requires linking system frameworks IOKit, CoreFoundation, and AppKit (the CMake find_package integration handles this automatically).

Windows Static Library: Release Mode Only

On Windows, the static library is built with the MSVC static Release runtime (/MT). This means your project must also build in Release mode when linking the static library. Debug builds (/MDd) will fail with LNK2038 runtime library mismatch errors.

If you need Debug builds during development, use the shared library instead -- it works in both Debug and Release because the DLL has its own runtime internally.

This is a standard MSVC constraint that applies to all static C++ libraries, not specific to RIK.

Linux Static Library

On Linux, the static library works in both Debug and Release builds. There is no CRT mismatch issue. The fat archive includes all dependencies, but your final executable must still link the system libraries pthread and udev. The CMake package config handles this automatically when you use find_package.

macOS Static Library

On macOS, the static archive works in both Debug and Release builds. The fat archive includes all internal RIK dependencies. Your final executable must link the system frameworks IOKit, CoreFoundation, and AppKit. The CMake find_package config handles this automatically. If using a Makefile, add:

LDFLAGS += -framework IOKit -framework CoreFoundation -framework AppKit

Package Layout

Shared package:

ReaderIntegrationKit-<version>-<platform>-shared/
├── include/ # Header files
├── lib/ # Import library (.lib on Windows), .so symlinks (Linux),
│ # .dylib (macOS), CMake config
├── bin/ # Shared library (.dll on Windows; not present on Linux or macOS)
├── examples/ # Example projects
└── rfIDEAS_EULA.txt

On Linux and macOS, the shared library (.so / .dylib) is in lib/, not bin/.

Static package:

ReaderIntegrationKit-<version>-<platform>-static/
├── include/ # Header files (same as shared)
├── lib/ # Static archive (.lib / .a) and CMake config
├── examples/ # Example projects
└── rfIDEAS_EULA.txt

Extract the RIK release archive, then configure CMake to find it. This works for both shared and static packages.

CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(MyApp)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Point CMake to the RIK package
find_package(ReaderIntegrationKit REQUIRED
HINTS ${CMAKE_SOURCE_DIR}/lib/cmake/ReaderIntegrationKit)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE ReaderIntegrationKit::ReaderIntegrationKit)

Configure and build:

cmake -B build -DCMAKE_PREFIX_PATH=/path/to/rik-release -DCMAKE_BUILD_TYPE=Release
cmake --build build
tip

You can pass CMAKE_PREFIX_PATH on the command line (as shown above) or use HINTS in find_package. Either approach works. CMAKE_PREFIX_PATH is more flexible when you want to keep your CMakeLists.txt portable.

Shared library on Windows -- copy the DLL:

When using the shared library on Windows, the DLL must be next to your executable at runtime. Add a post-build copy step:

CMakeLists.txt
add_custom_command(TARGET my_app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_SOURCE_DIR}/bin/ReaderIntegrationKit.dll"
$<TARGET_FILE_DIR:my_app>)

This step is not needed for the static library (there is no DLL).

Static library on Windows -- match the runtime:

When using the static library on Windows with MSVC, ensure your project uses the static Release runtime:

CMakeLists.txt
# Required when linking the RIK static library on Windows
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")

Option 2: Zip Package (Manual)

  1. Download and extract the RIK release zip (shared or static)
  2. Add include paths and link libraries manually in your build system
  3. For the shared variant, ensure the .dll, .so, or .dylib is available at runtime (see platform notes below)

Option 3: Traditional Makefile (Linux and macOS)

This pattern also works on macOS with clang++ and .dylib in place of .so. For static linking on macOS, add -framework IOKit -framework CoreFoundation -framework AppKit to LDFLAGS (see the macOS Static Library note below).

With the shared library:

Makefile
# Paths to the extracted RIK shared package
RIK_DIR := /path/to/rik-release
RIK_INCLUDE := $(RIK_DIR)/include
RIK_LIB := $(RIK_DIR)/lib

CXX := g++
CXXFLAGS := -std=c++17 -I$(RIK_INCLUDE)
LDFLAGS := -L$(RIK_LIB) -lReaderIntegrationKit -Wl,-rpath,$(RIK_LIB)

TARGET := my_app
SRCS := main.cpp

$(TARGET): $(SRCS)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

clean:
rm -f $(TARGET)
make
./my_app

With the static library:

Makefile
# Paths to the extracted RIK static package
RIK_DIR := /path/to/rik-release-static
RIK_INCLUDE := $(RIK_DIR)/include
RIK_LIB := $(RIK_DIR)/lib

CXX := g++
CXXFLAGS := -std=c++17 -I$(RIK_INCLUDE)
# Link the static archive and required system libraries
LDFLAGS := $(RIK_LIB)/libReaderIntegrationKit.a -lpthread -ludev

TARGET := my_app
SRCS := main.cpp

$(TARGET): $(SRCS)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

clean:
rm -f $(TARGET)
make
./my_app # No LD_LIBRARY_PATH needed -- everything is statically linked
note

The static archive bundles all internal RIK dependencies. You only need to link pthread and udev as system libraries. The resulting executable has no runtime dependency on any RIK library file.

C++ Headers

Both the shared and static packages include the same set of headers:

HeaderPurpose
Reader/AbstractReader.hBase class, instance management, metadata
Reader/Reader.hReader operations
Reader/Reader_C.hC-compatible API for FFI
ErrorHandling/ReaderException.hException type

Platform Notes

Linux

glibc Requirement

The RIK native library is built on Ubuntu 24.04 and requires glibc 2.38 or later. This applies to all language bindings (C++, C, C#, Python) since they all load the same native shared library.

Distributions that meet this requirement include:

  • Ubuntu 24.04+ (glibc 2.39)
  • Fedora 39+ (glibc 2.38)
  • Debian 13 (Trixie)+ (glibc 2.38)

Older distributions such as Ubuntu 22.04 (glibc 2.35) and Debian 12 (glibc 2.36) are not supported.

If you see an error like:

GLIBC_2.38 not found (required by libReaderIntegrationKit.so)

your system's glibc is too old. Check your version with ldd --version.

note

USB readers require udev rules for non-root access. See Supported Readers for setup instructions.

ARM64 and ARMhf Support

Linux ARM64 packages include two builds: Raspberry Pi 5-optimized and generic ARM64. For C++, download the prebuilt zip that matches your board (see the table above). For Python, the single ARM64 wheel bundles both builds and selects the correct one at runtime using RIK_ARM_VARIANT or device-tree detection. For C#, the NuGet package selects the ARM64 native library using RIK_ARM_VARIANT or device-tree detection (see the C# section above). The udev rules requirement for USB access applies equally on ARM platforms.

  • Shared library: The .so file must be in the linker's search path at runtime. Use LD_LIBRARY_PATH, an -rpath link flag, or install it to a standard system library directory.
  • Static library: No runtime library path is needed. The pthread and udev system libraries are the only external link dependencies. Install libudev-dev (Debian/Ubuntu) or systemd-devel (Fedora/RHEL) if not already present. Note: the static library still links glibc dynamically -- the glibc 2.38+ requirement applies to both variants.
  • Both Debug and Release builds work with either variant.

Windows

note

USB drivers typically install automatically. If needed, download drivers from rfideas.com/support.

  • Shared library: The .dll must be in the same directory as your executable, or on the system PATH. Works with both Debug and Release builds, and with either /MD or /MT in your project. The RIK DLL statically links its own MSVC runtime, so it does not require the Visual C++ Redistributable on the target machine.
  • Static library: No DLL is needed. Release mode with /MT only -- the static library is built with the MSVC static Release runtime (/MT), so your project must also use /MT in Release mode. Debug builds or /MD builds will fail with LNK2038 runtime library mismatch errors. If you need Debug builds or /MD during development, use the shared library instead.

macOS

  • Minimum version: macOS 12.0 (Monterey) and later, Intel (x86_64) and Apple Silicon (arm64).
  • Universal binary: The C++ package (Darwin-AppleClang-universal) ships a single universal binary. There are no separate Intel and Apple Silicon download archives.
  • Shared library: libReaderIntegrationKit.dylib is located in lib/. At runtime, ensure the dylib is findable via DYLD_LIBRARY_PATH, an -rpath link flag, or by installing it to a standard library directory (e.g., /usr/local/lib).
  • Static library: No runtime library path configuration is needed. Link the system frameworks IOKit, CoreFoundation, and AppKit (CMake find_package handles this automatically).
  • USB HID readers: Accessed via IOKit/HIDAPI. No extra drivers are required for standard HID-class readers (and no Linux-style udev rules apply on macOS).
  • Permissions: No root / sudo and no App Sandbox HID/USB entitlements are required for CLI or non-sandboxed apps. Discovery does not require Input Monitoring; opening a keyboard-class HID collection may. See macOS USB Permissions for details, including keystroking behavior, Input Monitoring, and App Sandbox guidance.
  • Serial readers: Use standard macOS device nodes. Prefer /dev/cu.* for programmatic use (e.g., /dev/cu.usbserial-1410); /dev/tty.usbserial-* nodes are also accepted.

Gatekeeper

If macOS Gatekeeper blocks a downloaded .dylib, allow it in System Settings > Privacy & Security, or clear the quarantine attribute with:

xattr -d com.apple.quarantine libReaderIntegrationKit.dylib

This applies to unsigned local builds and downloaded binaries that have not been notarized.