Inspiration

Porting Linux C/C++ code to QNX fails in predictable places: epoll, timerfd/signalfd, prctl, sched_setaffinity, <linux/...> headers, /proc/cpuinfo parsing, -lrt/-ldl in the build, sockets without libsocket. Each one costs a compile → fix → recompile loop with qcc. I wanted to see all of them before the first build.

What it does

qnx-port-check is a host tool (Linux, macOS, Windows; Python 3.8+) that scans a C/C++ project and reports everything that will not build or run on QNX SDP 8.0, with the QNX replacement for each finding: poll() or ionotify() with pulses, timer_create() with SIGEV_PULSE, ThreadCtl(_NTO_TCTL_RUNMASK), pthread_setname_np(), sysconf/SYSPAGE_ENTRY, linking libsocket.

  • 23 rules for C/C++ sources and CMake/Make/Meson build files, each with a concrete fix.
  • Preprocessor-aware: code under #ifdef __linux__, other-OS branches and branches after an existing #if defined(__QNX__) is not reported; feature-guarded code is downgraded to info.
  • CMake-aware: if(APPLE) branches and the else() after elseif(QNX) stay quiet.
  • Skips files built only for other OSes and lists them.
  • With QNX_TARGET set, every system #include is checked against the SDP headers, so missing headers become verified errors.
  • Output: terminal, Markdown porting report with an effort estimate, JSON, SARIF 2.1.0 for GitHub code scanning, plus a GitHub Action.
  • qnx-port-check toolchain --arch aarch64le|x86_64 writes a CMake toolchain file for qcc/q++.

How I built it

Pure Python, no dependencies. Rules map each Linux-only construct to its QNX 8.0 replacement, cross-checked with QNX's porting guide and the io-sock migration guide. A small preprocessor tracker follows #if/#elif/#else stacks, and a CMake tracker follows if/elseif/else, so only code that QNX would actually compile is reported. The SDP module reads QNX_TARGET and verifies headers for the chosen arch.

QNX version, target and toolchain

QNX SDP 8.0. Targets analysed: aarch64le and x86_64. Toolchain: qcc/q++ (gcc_ntoaarch64le, gcc_ntox86_64) through the generated CMake toolchain file with CMAKE_SYSROOT=$QNX_TARGET.

Build and run:

pip install git+https://github.com/yurij12211-ship-it/qnx-port-check
qnx-port-check scan path/to/project
source ~/qnx800/qnxsdp-env.sh && qnx-port-check scan path/to/project   # verify headers against the SDP
qnx-port-check toolchain --arch aarch64le > qnx-aarch64le.cmake
cmake -B build -DCMAKE_TOOLCHAIN_FILE=qnx-aarch64le.cmake && cmake --build build

Results on real projects

  • examples/event-server (in the repo): 14 errors, 4 warnings before the port, 0 / 0 after.
  • libuv: 0 errors, 4 warnings; 65 OS-specific files correctly skipped.
  • eclipse-mosquitto: 0 errors, 3 warnings (already supports QNX).
  • ninja: 0 errors, 0 warnings.

Challenges

Avoiding false positives. A plain grep flags hundreds of lines in libuv that QNX never compiles. Tracking preprocessor branches and skipping OS-specific files brought libuv from 41 errors to 0 while still catching real issues.

Bonus: codelab

docs/codelab.md walks through porting a Linux event server to QNX 8.0 step by step with the tool.

What's next

Parse qcc build logs and map compiler errors back to rules; more io-sock rules; a VS Code extension using the SARIF output.

Built With

Share this project:

Updates

Submission history