Skip to content

feat(linux): drive LabVIEW for Linux - #9

Open
Flydroid wants to merge 12 commits into
mainfrom
claude/lvpm-linux-build-ke4hoh
Open

Flydroid wants to merge 12 commits into
mainfrom
claude/lvpm-linux-build-ke4hoh

Conversation

@Flydroid

Copy link
Copy Markdown
Owner

Measured against LabVIEW 2026 Q3 in NI's Linux container image; each of
these broke install, relink, hooks, refresh or venvs there:

  • targets: find installs via /etc/natinst and /usr/local/natinst, require
    the labview executable, read the minor version from readme/UNINSTALL
  • preferences: ~/natinst/.config/LabVIEW-/labview.conf instead of
    /LabVIEW.ini; absent until first launch, and VI Server is off
    by default there
  • PTH0: decode Linux paths as rooted /usr/..., not usr\...
  • relink: send the folder with forward slashes; backslashed, the relink
    VI walked nothing and reported success
  • refresh: join the refresh VI paths a component at a time
  • <OS ...> tokens: map to what Get System Directory.vi returns on Linux;
    keep global install records in /var/lib/lvpm, the cache in ~/.cache
  • Target Dir tails: accept either separator
  • launch: LF ini, own process group, and wait out TIME_WAIT on the VI
    Server port: a LabVIEW started while it lasts never serves VI Server
  • stage the relink VI in a per-user directory, not the shared /tmp

The platform is chosen at compile time: each change is a cfg(windows) /
cfg(not(windows)) pair whose Windows half is the previous code. Visible
on Windows: two error messages name the full file path, and an expanded
Target Dir uses backslashes throughout (the same path). Tests that pin
Windows behaviour are cfg(windows), with Linux counterparts.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf

Measured against LabVIEW 2026 Q3 in NI's Linux container image; each of
these broke install, relink, hooks, refresh or venvs there:

- targets: find installs via /etc/natinst and /usr/local/natinst, require
  the `labview` executable, read the minor version from readme/UNINSTALL
- preferences: ~/natinst/.config/LabVIEW-<year>/labview.conf instead of
  <install>/LabVIEW.ini; absent until first launch, and VI Server is off
  by default there
- PTH0: decode Linux paths as rooted `/usr/...`, not `usr\...`
- relink: send the folder with forward slashes; backslashed, the relink
  VI walked nothing and reported success
- refresh: join the refresh VI paths a component at a time
- `<OS ...>` tokens: map to what Get System Directory.vi returns on Linux;
  keep global install records in /var/lib/lvpm, the cache in ~/.cache
- Target Dir tails: accept either separator
- launch: LF ini, own process group, and wait out TIME_WAIT on the VI
  Server port: a LabVIEW started while it lasts never serves VI Server
- stage the relink VI in a per-user directory, not the shared /tmp

The platform is chosen at compile time: each change is a cfg(windows) /
cfg(not(windows)) pair whose Windows half is the previous code. Visible
on Windows: two error messages name the full file path, and an expanded
Target Dir uses backslashes throughout (the same path). Tests that pin
Windows behaviour are cfg(windows), with Linux counterparts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
scripts/linux-e2e.sh builds test packages from tools/*.vi and checks
detection, a headless install with relink and hooks, refresh, relink,
run-hooks, uninstall and a venv whose LVAddons overlay is proven by a
caller that runs on the venv's LabVIEW and is broken on a fresh plain
one. LVPM= uses a prebuilt static lvpm instead of building one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
After nominal-io/reqwest-labview's build workflow: one job per platform
on its own runner (windows-latest MSVC, ubuntu-latest static musl), each
running cargo test and a release build and uploading its executable; a
collect job putting both in one artifact named for version and commit;
and linux-e2e running scripts/linux-e2e.sh in
nationalinstruments/labview:2026q3-linux.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
docs/linux.md: building, how Windows stays as it was, the Windows/Linux
differences and what lvpm does about each, the <OS ...> token table,
LabVIEWCLI on Linux, what was verified, CI, and what Linux still needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
scripts/linux-packages.sh installs eleven OpenG libraries and the JKI
State Machine from the public indexes into NI's Linux container: a
headless install that must start no LabVIEW, a LabVIEWCLI mass compile
of every folder they own that must report no bad VI, relink --all, an
uninstall that must leave the LabVIEW tree as it was, and a venv relink.
The linux-packages job runs it with the Linux executable from the build
job and keeps the logs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
What carries over from the Linux port, what needs a macOS branch and a
Mac to measure it on, and why CI cannot cover it yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
What holds only for LabVIEW on Linux (install location, executable,
preferences file, version file, <OS ...> roots, /var/lib records, rooted
PTH0 paths, the missing-ini default) is now cfg(target_os = "linux")
instead of cfg(not(windows)). Separators, line ends and the per-user
cache stay not(windows): they hold on any POSIX system. Any other
platform stops with a compile_error!, so macOS cannot build and then
look in the wrong places. The Linux build is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
Pushes to any branch now build, test and publish the executables, so a
feature branch is integration-tested before it is merged; tags stay out.
A pull request from a branch of this repository is skipped, since the
push that updated the branch already ran; one from a fork still runs. A
newer push cancels a branch's run in progress, except on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
- Hand the container's root-owned files back before cleanup: on a CI
  runner's user the final rm failed and failed both jobs, all checks
  passed or not.
- Count as bad only the VIs the packages installed, each once: folders
  a package shares with LabVIEW hold LabVIEW's own files too.
- A package with nothing to relink stays unmarked; the relink checks
  now read the manifests instead of `lvpm list`.
- The uninstall check allows the .aliases, .lvlps and .UserState files
  LabVIEW writes beside a project it opens, and says how many.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
- linux-packages installs astemes_lib_lunit and dataflow_g_lib_g_image
  with --hooks (G-Image needs its PostInstall), and checks that every
  hook ran. The checks are the plain ones again: any bad VI, any
  unrelinked package, any change to the LabVIEW tree fails.
- Logs are written inside the work directory and copied to OUT, so the
  cleanup changes the owner of nothing but its own files.
- linux-e2e: `grep -c relinked` also counted "NOT relinked" lines.
- Pull requests run again: skipping those from this repository left a
  branch without the workflow with no CI at all. On main each commit has
  a concurrency group of its own, so no queued run is dropped.
- The VI Server default and the headless log path are per-OS constants,
  so another platform fails to compile instead of taking Linux's values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
LUnit is the reference package, and its Basic Example ships Test
Broken.vi to show how a broken test is reported. The mass compile check
now sets exactly that file aside (exit 3 with no other bad VI counts as
compiled); any other bad VI still fails it.

Roadmap: integration test VIs made for lvpm, so its checks stop
depending on third-party packages; and the lvpm issues the first public
package runs found (relink walks folders LabVIEW shares, uninstall leaves
LabVIEW's project files, relink --all never marks a package with nothing
to relink).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
The mass compile in linux-packages tested the packages and LabVIEW, not
lvpm. Its only failures were LUnit's VI broken on purpose and NI's
templates beside LUnit's project provider. The compile also writes
.aliases and .UserState files beside each project, and those made the
uninstall check fail.

Instead:
- every file in the install records must be on disk after
  install --hooks;
- after uninstall, no file in the LabVIEW tree may be added, gone or
  changed; the check compared names only;
- the venv flow must leave the LabVIEW tree alone.

The changed-file check finds what the name check missed: relink saves
LabVIEW's own files when a package file lies directly in a folder
LabVIEW fills. With one test VI in resource/Framework/Providers, relink
saved 44 of LabVIEW's files. LUnit's provider library lies there, so
linux-packages stays red until relink is fixed (roadmap).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrYr5p1UVnscR92E5K9ZKf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants