-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathINSTALL.linux
More file actions
232 lines (193 loc) · 10.8 KB
/
Copy pathINSTALL.linux
File metadata and controls
232 lines (193 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# Building KAME on Linux
Linux support was dropped when KAME moved from autotools to qmake, and the
tree accumulated a decade of macOS/Windows-only assumptions. It builds and
runs again as of 2026-07.
**Status: unsupported.** What has been verified is that it compiles, links,
installs, starts, loads all 43 driver modules with zero failures, runs BOTH
script engines — the embedded Python/pybind11 one and the Ruby one — and
renders its OpenGL graphs correctly on a real X11 server (see "GUI" below).
No instrument hardware has been exercised. Treat it as a development
platform, not a deployment one.
Verified on Ubuntu 24.04 / Qt 6.4.2 / GCC 13.3 / glibc 2.39, x86-64.
## Dependencies
```bash
sudo apt-get install -y \
qt6-base-dev qt6-base-dev-tools qt6-tools-dev \
qt6-tools-dev-tools libgl1-mesa-dev libglu1-mesa-dev \
libgsl-dev libfftw3-dev libltdl-dev libeigen3-dev zlib1g-dev \
libusb-1.0-0-dev ruby-dev python3-dev python3-pybind11
```
* **Qt 6** needs only `qt6-base-dev` plus `uitools` (`qt6-tools-dev`); Qt 5
works too, minus the Qt 6-only `QT +=` lines in `kame.pri`. `core5compat`
used to be required and no longer is — the only thing that pulled it in was
a dead `#include <QTextCodec>`.
* **Ruby** headers are mandatory — `script/xrubysupport.cpp` is compiled
unconditionally. `kame/kame.pro` asks the interpreter for its header path
via `RbConfig`, so any packaged or rbenv/rvm Ruby works. Verified working
on **Ruby 3.3.6**: the support script and `rubylineshell.rb` both evaluate,
and a `.rb` passed on the command line runs through the Ruby engine and
walks the measurement tree over the C++ node bridge.
* **pybind11** is optional but strongly recommended: without it there is no
Python scripting, no Jupyter/IPython console, no MCP server, and `.kam`
files fall back to the (legacy) Ruby loader. It must be importable by the
interpreter qmake picks — `python3 -m pybind11 --includes` must succeed.
* **Jupyter / IPython** is a separate, runtime-only dependency, and it must be
installed into the interpreter KAME *embeds* (the one qmake reported), not
merely into some python3 on the box:
```bash
python3 -m pip install ipykernel ipython jupyter nest_asyncio numpy
```
`nest_asyncio` is easy to miss — ipykernel's event-loop integration needs it
and without it the kernel starts and then throws `ModuleNotFoundError` from
a tornado callback. `numpy` is not needed by KAME itself but user scripts
expect `np`. With these present the "Script" menu's three Jupyter entries
(Notebook / Console / Qt Console) list every `jupyter` found on `PATH`, and
the embedded kernel writes its connection file to the Jupyter runtime dir.
* **linux-gpib** is optional; when its headers are present `HAVE_LINUX_GPIB`
is defined and the native `XNIGPIBPort` implementation is compiled in.
Without it, `Device = GPIB` falls back to the **usermode NI USB-GPIB
driver** under `modules/charinterface/usermode-linux-gpib/` (needs libusb),
which drives NI USB-B / USB-HS / USB-HS+ / KUSB-488A / MC USB-488 with no
kernel module — the same path macOS and Windows use. `PrologixGPIBUSB`
remains available as a separate `Device` option either way. Note the
shim's `osx_compat.h` keeps its historical name but is plain POSIX; no
Linux-specific compat header is needed.
* **Vendor SDKs.** `modules/nidaq` (NI-DAQmx), `modules/digilentwf`
(WaveForms) and the Euresys eGrabber camera backend now have real Linux
probes: install the vendor package and the drivers appear; without it the
module still builds but registers nothing (rather than registering drivers
whose hardware calls have been compiled away, which is what happened
before). `libdc1394` (IIDC cameras) and `libusb` (Ocean Optics, Thamway
Cypress FX2/FX3) are probed with pkg-config.
* **USB device permissions.** Every USB path goes through libusb from an
unprivileged process, so `/dev/bus/usb` must be writable by the user.
Install the shipped rules:
```bash
sudo install -m 644 kame/70-kame.rules /etc/udev/rules.d/70-kame.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
```
For RS-232 and Prologix GPIB-USB adapters (`/dev/ttyUSB*`, `/dev/ttyACM*`)
add yourself to `dialout` instead: `sudo usermod -aG dialout $USER`.
* **mlock.** KAME pins realtime acquisition buffers. The default
`RLIMIT_MEMLOCK` on systemd distros is 8 MB, which is not enough; KAME now
says so on stderr at startup and disables pinning rather than silently
failing. Raise it (`/etc/security/limits.d/`, or `LimitMEMLOCK=` in a
systemd unit) or pass `--nomlock`.
## Build
```bash
mkdir build && cd build
qmake6 ../kame.pro # or /usr/lib/qt6/bin/qmake
make -j$(nproc)
```
qmake prints which Ruby and which Python it selected; check those lines if
scripting is missing. The executable lands in `build/bin/kame` (not
`build/kame` — that path is the subproject's build directory, and on Linux the
bare target name would collide with it). The deployed script files
(`pythonlineshell.py`, `kame_mcp_server.py`, the manual, …) are copied next to
the binary, which is where `xpythonsupport.py` and `LINESHELL_DIR` look for
them in a build tree.
## Checking the script engines
Both engines are reachable from the command line, which is the easiest way to
confirm they work without a display. `FrmKameMain::runNewScript()` routes by
extension: `.py` and `.kam` go to Python, everything else to Ruby.
```bash
./bin/kame --moduledir "$PWD/mods" /path/to/script.py # Python engine
./bin/kame --moduledir "$PWD/mods" /path/to/script.rb # Ruby engine
```
Note that `xrubysupport.rb` redirects **both** `$stdout` and `$stderr` into
KAME's GUI message pane, so a Ruby test script that prints to either produces
nothing on the terminal even when it ran perfectly. Write to a file instead.
## Running from the build tree
The build now groups the driver modules the way KAME searches for them, under
`build/bin/{coremodules,coremodules2,modules}`, and `build/bin` is
`applicationDirPath()` — which is one of `QApplication::libraryPaths()`. So
the build tree just runs:
```bash
./bin/kame
```
`--moduledir <path>` still overrides the search, and the loader is
order-independent (it retries until no further module opens), so the
coremodules/modules split is a convenience rather than a requirement.
## Installing
```bash
qmake6 ../kame.pro PREFIX=/usr/local
make -j$(nproc) && sudo make install
```
This installs the executable to `$PREFIX/bin`, the driver modules to
`$PREFIX/lib/kame/{coremodules,coremodules2,modules}`, the deployed scripts,
manual, `kame_ja.qm` and Thamway firmware to `$PREFIX/share/kame`, the
`.desktop` entry to `$PREFIX/share/applications`, the icons into the hicolor
theme, and the udev rules to `$PREFIX/lib/udev/rules.d`. `main.cpp` searches
`$PREFIX/lib/kame` and the XDG data dirs in addition to
`QApplication::libraryPaths()`, so an installed KAME finds its drivers with no
`--moduledir`.
## Interface smoke test (no hardware)
`tools/iftest_serial_gpib.py` exercises the serial and GPIB open paths against
a pty pair and a device that cannot exist, so a failed open is proven to be
reported rather than to crash:
```bash
./bin/kame --moduledir "$PWD/mods" ../tools/iftest_serial_gpib.py
cat "${TMPDIR:-/tmp}/kame_iftest.txt"
```
Verified results on this port: SERIAL and Prologix both fail cleanly on a
missing device; SERIAL on a pty opens and completes a `*IDN?` round trip;
`Device = GPIB` reaches the usermode driver's libusb enumeration and fails
cleanly with no adapter attached; `PrologixGPIBUSB` on a pty opens, emits the
full adapter initialisation (`++mode 1`, `++eoi 1`, `++auto 0`, `++ifc`, …)
and completes a `++spoll` / `++read eoi` query round trip.
## Jupyter / IPython
Verified working: KAME's embedded IPython kernel starts, registers a
connection file, and an external client attached to that file drives the live
measurement tree. Executed through the kernel from a separate process —
which is exactly what the menu's `jupyter console --existing` does:
```
Root().getName() -> 'Measurement'
len(Root()['Drivers'].dynamic_cast().typenames()) -> 103
[c.getName() for c in Snapshot(Root()).list(Root())][:4]
-> ['Thermometers', 'ScalarEntries', 'GraphList', 'ChartList']
Root()['Drivers'].dynamic_cast()
.createByTypename('KE2000','JUPTEST').getName() -> 'JUPTEST' (driver created live)
listOfJupyterPrograms() -> ['/usr/local/bin/jupyter']
```
The last line is what fills the menus, so with a `jupyter` on `PATH` all three
entries appear. Creating a driver from the kernel prints "QOpenGLWidget is
not supported on this platform" under `offscreen`; that is the headless QPA,
not the port.
## Known gaps
* **No hardware testing.** Serial, GPIB and TCP are exercised only against
ptys and simulators (see above); no real instrument, and no NI USB-GPIB
adapter, has been attached.
* **Wayland is untested.** The GUI was verified on X11 only (Xvfb, see
below); under a Wayland session the toolbox panes stay docked by design (see
the last bullet). Remaining Linux-specific rendering issues are *not*
fixed, because neither can be judged without real hardware or real image
data:
* `kame/graph/x2dimage.cpp` `applyDisplayGamma()` compensates for the macOS
Metal/sRGB framebuffer applying 1/2.2 automatically. Desktop GL only does
that with `GL_FRAMEBUFFER_SRGB`, which KAME never enables — so camera /
ODMR images are likely to render too dark on Linux.
* `USE_PBO` (`kame/graph/graphpainter.h`) is gated on `__APPLE__`, so the
graph-persistence feature falls back to a per-frame
`glReadPixels`/`glDrawPixels` round trip through host memory. PBOs are
core GL 2.1 and universally available on Linux; the gate is historical.
* Under a **Wayland** session the two toolbox panes stay docked instead of
floating beside the main window (xdg-shell has no client-side window
positioning). X11/XWayland gets the original three-pane layout.
## GUI
Verified on a real X server. No GPU is required — Mesa's llvmpipe software
rasteriser drives `XQGraph`/`QOpenGLWidget` fine, which is also the easiest
way to check the GUI on a headless box:
```bash
sudo apt-get install -y xvfb
Xvfb :99 -screen 0 1600x1000x24 +extension GLX +render &
DISPLAY=:99 QT_QPA_PLATFORM=xcb LIBGL_ALWAYS_SOFTWARE=1 kame
```
What this exercises end to end: the three-pane layout, the driver/graph/
calibration/node-browser toolboxes, `Measure` → create `TestDriver` → start it
from the Interfaces pane, then Graph → New → pick the driver's X/Y scalar
entries. The graph window opens and plots live data; axis tics, tic labels,
the legend box and window resize (`resizeGL`) all render correctly under
software GL.
To capture the result there is no need for a screenshot utility — Qt itself
can grab the root window in ~10 lines
(`QGuiApplication::primaryScreen()->grabWindow(0).save(path)`).