What it does
open62541 on QNX 8.0 ports the open-source OPC UA stack open62541 (v1.5.1) to QNX SDP 8.0 (x86_64) — and proves it works on a real QNX target, not just that it cross-compiles.
OPC UA is the industrial interoperability standard: factories, vehicles, and medical devices speak it. QNX runs in exactly those places. Yet the QNX Open-Source Dashboard listed no open62541 package at all, and upstream v1.5.1 did not compile for QNX 8.0. This project closes that gap: a clean port (four small fixes + a CMake toolchain file), on-target verification under QEMU, an OPC UA demo server exposing simulated production-line sensors, and a step-by-step codelab that teaches the whole porting loop.
The gap — verified, not assumed
Upstream carries a Tier-3 QNX entry (PR #6967, 25 lines, 2025) — no CI, no arch/qnx/ directory; QNX builds as posix. A direct qcc build fails in three places, each proven by a build probe:
- G1:
arch/posix/eventloop_posix.hincludes glibc-only<bits/stdio_lim.h>(absent on QNX). Fix: exclude__QNX__from the include (FILENAME_MAXalready comes from QNX<stdio.h>). - G2: The bundled
open62541_queue.his skipped on QNX, but nothing includes the system header, soLIST_ENTRY/LIST_HEADare undefined. Fix:#include <sys/queue.h>on the__QNX__path. - G3: Links
-lpthread -lrt, which do not exist as separate libraries on QNX (both are in libc). Fix: QNX exclusion inCMakeLists.txt. - G4: Socket API (
socket,getaddrinfo, …) lives in a separatelibsocketon QNX, not in libc. Fix: linksocketon QNX (win32 precedent:ws2_32).
The whole upstream delta is ~10 lines plus the toolchain file. The engineering depth is everything around it.
How I built it
- Week 1 — target first. Installed SDP 8.0, cross-compiled a hello-world using the QNX-only
ClockTime()API, and built a minimal headless QEMU image (mkqnximage --type=qemu, 1 CPU, 256 MB) that boots in ~100 s under QEMU's pure emulation (no KVM) and answers over SSH. Two stock-image defects were found and fixed along the way (an RSA host key that segfaultssshd; a missingsshd-authbinary). - Week 2 — the port. New public repo (not a fork), patches G1–G4 as clean diffs vs v1.5.1, a QNX CMake toolchain file, and build scripts. Clean build from the repo alone — no shims:
libopen62541.a(116 objects, genuine QNX ELF) and the 6.7 MB single-file amalgamation both build underqcc. - Week 3 — proof + encryption. On-target tests, demo polish, and a verified encrypted build (see below).
Verification — on target, not just cross-compiled
All tests run on QNX 8.0 under QEMU (Haswell, 256 MB, no KVM):
test_types_roundtrip— 10/10 PASS (Variant binary round-trips, NodeId equality).test_eventloop— ALL PASS — the POSIX eventloop'sselect()fallback fires timers on QNX (100 ms timer 20–21×, 250 ms timer 8× over ~2.1 s). No epoll on QNX; the fallback is automatic.test_server_client— ALL PASS — a real OPC UA handshake on target (SecureChannel None, session created,TestValueread back as 42).- Demo server + host client — ALL PASS. The server (
examples/server_qnx_sensors.c) exposes six nodes — Temperature, Vibration, Count, Setpoint (writable), FanSpeed (writable), Alarm — with a first-order-lag process model. The host client reads all six nodes, writes Setpoint 24.0 and FanSpeed 75.0 with read-back, and collects 10 Temperature + 10 Count subscription notifications in 5 s. - Encrypted round-trip — ALL PASS (stretch goal). With
UA_ENABLE_ENCRYPTION=OPENSSL(SDP-bundled OpenSSL 3.0.20), a secure-only server (Basic256Sha256, SignAndEncrypt, no None endpoint) and a client read a value back over the encrypted channel on target. The demo server itself still ships security None; the encrypted build is a separate, verified configuration — stated plainly in the README.
Upstream's check_* suite is not run on target: it needs the libcheck framework, which is not available for QNX 8.0. The tests above cover the same API surface without it, and the README says so.
Upstream contribution
The G2+G3+G4 fixes are offered upstream as PR #8717 ("fix(arch): build the POSIX architecture on QNX 8.0 (1.5 backport)", base 1.5). Stated honestly: this is a backport to the 1.5 maintenance line — upstream master fixed the equivalent QNX 8.0 build on 2026-11-11, and G1 was already on 1.5 via upstream 2c9beadfc. The entry's value is the verified v1.5.1 port, the on-target proof, the demo, and the codelab — not a claim to be the first to fix the build.
The codelab (Best Codelab bonus)
"Port a POSIX C Library to QNX 8.0 under QEMU" — https://buahrasa01-hub.github.io/open62541-qnx/codelab/port-open62541-qnx.html
Nine steps, ~60 minutes, in the official QNX codelab format: licence and SDP install, the qcc toolchain, a cross-compiled hello, a minimal headless QEMU image, reading the library's build system, the toolchain file and defects G1–G4 (each shown as error → cause → patch), on-target proof, packaging the port, plus an optional encryption section. Every command is copy-pasteable; every expected output shown is real, captured from the 2026-11-13 run.
What's next
Demo video recorded in week 5 (early, 2026-11-13): 2:18, built with the proven text-video pipeline from real captured output of the fresh-clone run — the live run's timings under TCG made live terminal footage impractical, and every line on screen is verbatim output from that run (build, tests, server log, host client, encryption test). The codelab is written to be reusable for the next library: the same loop — dashboard check, build-system read, fix the defects the build surfaces in order, prove it on target, offer the fixes upstream — works for any POSIX C library.
Repo layout (for the judges)
patches/— G1 + G2 + G3 + G4 as clean diffs vs upstream v1.5.1cmake/toolchain-qnx-x86_64.cmakescripts/build.sh— clone v1.5.1 -> apply patches -> build lib + amalgamationscripts/build-encryption.sh— same, with UA_ENABLE_ENCRYPTION=OPENSSL + test_encryptionscripts/build-target.sh— build demo server + on-target tests with qccscripts/build-host-client.sh— build the host client (native gcc + amalgamation)examples/server_qnx_sensors.c— demo OPC UA server (sensors + writable setpoint/fan)tests-on-target/— on-target tests (no libcheck dependency), incl. test_encryption.ctools/host_client.c— host client: read / write / subscribedocs/codelab/— codelab source (official QNX codelab format)
Build from the repo alone: the only upstream input is the v1.5.1 tag. Licence: MPL-2.0 (same as upstream).
Built With
- c
- cmake
- open62541
- openssl
- qemu
- qnx
- sdp