Skip to content

Add Linux build support (development)#1

Merged
curlh merged 1 commit into
Experimental-Microscopy-Lab:mainfrom
pskeshu:linux-build
Jun 29, 2026
Merged

Add Linux build support (development)#1
curlh merged 1 commit into
Experimental-Microscopy-Lab:mainfrom
pskeshu:linux-build

Conversation

@pskeshu

@pskeshu pskeshu commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Motivation

I came across ScopeOne, and out of curiosity tried building it on Linux. Beyond
the curiosity, cross-platform builds make a project meaningfully easier to
develop on and contribute to — even if production stays on Windows. The
encouraging part is that the hard work is already done: the multi-process core is
built on Qt's cross-platform primitives (QProcess, QSharedMemory,
QLocalServer), so very little of the runtime is actually Windows-specific. The
gap was mostly the build system plus a couple of small spots.

This PR makes ScopeOne build and run on Linux with the demo camera, while
leaving the Windows build path untouched.

What's in this PR (4 files, +74/−39)

Everything platform-specific is guarded behind if(WIN32)/else() so the Windows
build is unchanged:

  • ScopeOneCore/CMakeLists.txt — Linux branch resolves deps via
    find_package (system Qt6, OpenCV [core+imgproc only, to avoid the
    viz→VTK chain], TIFF, ZLIB) and links MMCore as an imported static library
    built from mmCoreAndDevices.
  • CMakeLists.txt — guard the hardcoded C:/Qt/... prefix so it's
    Windows-only.
  • ScopeOneCore/src/RecordingManager.cpp — give SaveBackend::TiffOptions
    an explicit constructor instead of default member initializers; GCC rejects
    = {} as a default argument for the nested aggregate (MSVC accepts it).
    Behavior unchanged.
  • src/ScopeOneLocalApiServer.cpp — guard the Win32
    CreateFileMapping/MapViewOfFile frame export behind #if defined(_WIN32).
    The local API socket server still runs on Linux; only the zero-copy shared-frame
    export is disabled for now (see follow-ups).

Building the Micro-Manager dependency

I built only the minimal pieces from mmCoreAndDevices (no vendor adapters) via
the standard autotools path:

# in a micro-manager checkout (mmCoreAndDevices as submodule)
./autogen.sh && ./configure --without-java
make -C mmCoreAndDevices/MMDevice
make -C mmCoreAndDevices/MMCore
make -C mmCoreAndDevices/DeviceAdapters/DemoCamera

This yields libMMCore.a, libMMDevice.a, and libmmgr_dal_DemoCamera.so.0
(no boost or swig required). Then the usual ScopeOne build, pointing the core
CMake at that checkout via external/mmCoreAndDevices.

Verification

  • Headless smoke test: MMCore loads config/MMConfig_demo.cfg and snapImage()
    returns a 512×512 16-bit frame.
  • GUI launches cleanly.
  • Tested on Manjaro Linux, Qt 6.11.1, OpenCV 4.13, GCC 16, CMake 4.x.
  • I have not been able to test the Windows build; the changes are guarded to
    preserve it, but someone with a Windows setup should confirm.

Scope / non-goals

  • Demo camera only — real device adapters remain Windows-bound by vendor SDKs, as
    expected for Micro-Manager.
  • Dev/CI focus, not production parity.

Known follow-ups (happy to do these if useful)

  1. Multi-camera / agent pathAgentProtocol.h hardcodes
    ScopeOne_Agent.exe; needs a platform-aware name on Linux. The single-camera
    demo uses the native path and is unaffected.
  2. Local-API frame export — port the guarded-out Win32 shared memory to POSIX
    shm_open/mmap (or QSharedMemory) so external clients get zero-copy frames
    on Linux too.
  3. Adapter staging — stage the device-adapter .so next to the binary in
    CMake instead of copying it manually.

Questions for maintainers

  • Would you welcome Linux dev support upstream, or is Windows-only intentional for
    now?
  • How would you prefer the mmCoreAndDevices dependency wired on Linux
    (find-or-fetch in CMake, documented manual build, submodule)? I followed the
    existing external/ layout but kept it flexible.

Thanks for open-sourcing this — it's a clean codebase to work in.

Make the CMake build cross-platform so ScopeOne builds and runs on Linux
(demo camera), while leaving the Windows build path unchanged. All
platform-specific logic is guarded behind if(WIN32)/else().

- ScopeOneCore/CMakeLists.txt: Linux branch uses system Qt6, OpenCV
  (core+imgproc only, avoiding the viz/VTK chain), TIFF and ZLIB via
  find_package, and links MMCore as an imported static library built
  from mmCoreAndDevices.
- CMakeLists.txt: guard the hardcoded Windows Qt prefix path.
- RecordingManager.cpp: give TiffOptions an explicit constructor instead
  of default member initializers (GCC rejects the brace-default argument).
- ScopeOneLocalApiServer.cpp: guard the Win32 CreateFileMapping/
  MapViewOfFile frame export behind _WIN32; the local API socket still
  works on Linux (zero-copy frame export is a follow-up).
@curlh

curlh commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Hi! Thank you for this PR. This is very helpful, and the direction makes sense to me.

I tested the current code on Windows, and the Windows build still compiles successfully on my side. Linux build support for the demo camera and future CI would be very valuable.

For the mmCoreAndDevices dependency, I think the documented manual build using Micro-Manager's Unix build instructions and the existing external/ layout is fine for now. Keeping mmCoreAndDevices under the same external/ style is consistent with the current third-party layout. However, longer term, I would like to move all the third-party dependencies toward submodules where possible. That should make dependency versions more reproducible and make CI easier to set up across Windows/Linux platforms.

The follow-ups you listed all make sense. For local API frame export, I would prefer moving toward QSharedMemory, since the internal agent frame path already uses Qt shared memory and the project already depends heavily on Qt.

I appreciate the contribution. Thank you very much!

@curlh curlh merged commit 9cde474 into Experimental-Microscopy-Lab:main Jun 29, 2026
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