Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions .github/workflows/compile-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
compile:
name: Compile
runs-on: ubuntu-24.04
timeout-minutes: 120
timeout-minutes: 180

steps:
- name: Check out ScopeOne
Expand All @@ -39,15 +39,20 @@ jobs:
autoconf-archive \
pkg-config \
libboost-all-dev \
libopencv-dev \
libtiff-dev \
zlib1g-dev

- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.11.0'
cache: true
ninja-build curl zip unzip \
libgl-dev libegl-dev libopengl-dev libx11-dev libx11-xcb-dev libxrender-dev \
libxcb1-dev libxcb-cursor-dev libxcb-icccm4-dev libxcb-util-dev libxcb-image0-dev \
libxcb-keysyms1-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-shape0-dev \
libxcb-shm0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xkb-dev libxcb-xinput-dev \
libxcb-glx0-dev libxkbcommon-dev libxkbcommon-x11-dev

- name: Set up vcpkg
shell: bash
run: |
git clone https://github.com/microsoft/vcpkg.git "$RUNNER_TEMP/scopeone-vcpkg"
git -C "$RUNNER_TEMP/scopeone-vcpkg" checkout "$(jq -r '."builtin-baseline"' vcpkg.json)"
"$RUNNER_TEMP/scopeone-vcpkg/bootstrap-vcpkg.sh" -disableMetrics
echo "VCPKG_ROOT=$RUNNER_TEMP/scopeone-vcpkg" >> "$GITHUB_ENV"

- name: Compile mmCoreAndDevices and ScopeOne
shell: bash
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
!/CMakeLists.txt
!/README.md
!/VERSION
!/vcpkg.json

!/.gitignore

/build/
/vcpkg_installed/
/ref/
**/.DS_Store
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ set(ScopeOneCore_ROOT
"${CMAKE_SOURCE_DIR}/ScopeOneCore/install"
CACHE PATH "ScopeOneCore install prefix"
)
if (WIN32)
list(PREPEND CMAKE_PREFIX_PATH "C:/Qt/6.11.0/msvc2022_64")
endif ()
list(PREPEND CMAKE_PREFIX_PATH "${ScopeOneCore_ROOT}")

file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include")
Expand Down
131 changes: 46 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ There is an example dual-camera .cfg file in the config folder, just change the

- [CMake](https://cmake.org/download/) 4.1.0
- [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) (MSVC v143 toolset)
- [Qt](https://www.qt.io/development/download-qt-installer-oss) 6.9.1 (msvc2022_64)
- OpenCV 4.12.0
- [vcpkg](https://github.com/microsoft/vcpkg) for Qt 6.11.2, OpenCV 4.14.0, and ScopeWriter's libtiff, zlib, zstd and crc32c
- mmCoreAndDevices

Clone ScopeOne and initialize all submodules with:
Expand All @@ -79,11 +78,10 @@ ScopeOne/
include/scopeone/ Core API and external plugin contracts
external/
mmCoreAndDevices/
opencv-4.12.0/
ScopeWriter/
```

ScopeWriter contains its filesystem Zarr V3 writer and carries libtiff, zlib, zstd and crc32c under its own `third_party` directory. It builds these dependencies from source without downloading packages during CMake configuration.
ScopeWriter contains its filesystem Zarr V3 writer. It uses libtiff, zlib, zstd and crc32c from vcpkg; ScopeOne lists them in its root `vcpkg.json`, and ScopeWriter declares the same dependencies in its own `vcpkg.json` for standalone builds.

### Plugin layout

Expand All @@ -102,129 +100,92 @@ The Image Processing panel can process all live cameras or one selected camera.

**Windows Build Steps:**

1. Build and install `ScopeOneCore`:
Set up vcpkg once outside the ScopeOne repository:

```powershell
cmake -S ScopeOneCore -B ScopeOneCore/build
cmake --build ScopeOneCore/build --config Release --parallel
cmake --install ScopeOneCore/build --config Release
git clone https://github.com/microsoft/vcpkg.git C:/dev/vcpkg
C:/dev/vcpkg/bootstrap-vcpkg.bat
$env:VCPKG_ROOT = "C:/dev/vcpkg"
```

2. Build the GUI application:
For an existing vcpkg checkout, run `git -C $env:VCPKG_ROOT pull --ff-only` and rerun its `bootstrap-vcpkg.bat` before migrating.

Build Core, plugins, and GUI with the repository script:

```powershell
.\scripts\build.ps1 --configure
```

When migrating an existing build, use `--clean --configure` once to replace the old CMake caches. Later builds only need `.\scripts\build.ps1`.

The root `vcpkg.json` pins Qt and OpenCV and provides ScopeWriter's libtiff, zlib, zstd and crc32c. Core, GUI, and plugins share `vcpkg_installed/`; the build scripts select `x64-windows`, `x64-linux-dynamic`, `arm64-osx-dynamic`, or another supported host triplet. Linux and macOS use the dynamic triplets so Qt is shared between the GUI, ScopeOneCore, and plugins. CMake installs dependencies on the first configure, and the Windows GUI uses vcpkg's `windeployqt` to deploy Qt plugins. Micro-Manager, CUDA, and ONNX Runtime retain their existing dependency setup.

For a direct Core CMake configure:

```powershell
cmake -S . -B build
cmake --build build --config Release --parallel
cmake -S ScopeOneCore -B ScopeOneCore/build `
"-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" `
"-DVCPKG_MANIFEST_DIR=$PWD" `
"-DVCPKG_INSTALLED_DIR=$PWD/vcpkg_installed" `
-DVCPKG_TARGET_TRIPLET=x64-windows
```

3. Run:
Run the built application:

```powershell
.\build\Release\ScopeOne.exe
```

**Linux and macOS Build Steps (experimental):**

Linux and macOS use the same native build flow. Use the top-level `micro-manager` repository to configure the native build, then compile `MMDevice`, `MMCore`, and the required device adapters. Create a symlink so ScopeOne can find the `mmCoreAndDevices` tree at the path expected by the current CMake files.

Run `./scripts/build-unix.sh` from the ScopeOne repository root on Linux or macOS to automate the complete sequence below.
Linux and macOS use vcpkg for Qt, OpenCV, and ScopeWriter's dependencies. Micro-Manager is built from its own checkout because its native core and device adapters are not vcpkg dependencies.

1. Install common build dependencies.
1. Install the system build tools.

Linux:

```bash
sudo apt install \
git subversion build-essential cmake autoconf automake libtool autoconf-archive \
pkg-config libboost-all-dev qt6-base-dev libopencv-dev libtiff-dev zlib1g-dev
pkg-config ninja-build curl zip unzip libboost-all-dev
sudo apt install --no-upgrade \
libgl-dev libegl-dev libopengl-dev libx11-dev libx11-xcb-dev libxrender-dev \
libxcb1-dev libxcb-cursor-dev libxcb-icccm4-dev libxcb-util-dev libxcb-image0-dev \
libxcb-keysyms1-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-shape0-dev \
libxcb-shm0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xkb-dev libxcb-xinput-dev \
libxcb-glx0-dev libxkbcommon-dev libxkbcommon-x11-dev
```

The second command installs the X11 and OpenGL development files that vcpkg's `qtbase` port expects from the system; it is not a system Qt installation. It uses the glvnd `libgl-dev`/`libegl-dev` packages instead of `libgl1-mesa-dev`/`libegl1-mesa-dev`, so `--no-upgrade` can install it without upgrading the installed Mesa drivers.

macOS:

```bash
xcode-select --install
brew install \
git subversion cmake autoconf automake libtool autoconf-archive \
pkg-config boost qt opencv libtiff zlib
```

2. Clone Micro-Manager and create the `mmCoreAndDevices` symlink:

```bash
cd /path/to/ScopeOne/ScopeOneCore
mkdir -p external
cd external

git clone --recurse-submodules https://github.com/micro-manager/micro-manager.git micro-manager
ln -s micro-manager/mmCoreAndDevices mmCoreAndDevices

cd micro-manager
git submodule update --init --recursive
pkg-config ninja boost
```

3. Configure Micro-Manager without the Java application layer:
2. Install and bootstrap vcpkg:

```bash
./autogen.sh
./configure --without-java --enable-static
git clone https://github.com/microsoft/vcpkg.git "$HOME/vcpkg"
"$HOME/vcpkg/bootstrap-vcpkg.sh"
export VCPKG_ROOT="$HOME/vcpkg"
```

4. Build the native core components:
3. Build from the ScopeOne repository root:

```bash
# Adjust `-j4` to match your CPU cores
make -C mmCoreAndDevices/MMDevice -j4
make -C mmCoreAndDevices/MMCore -j4
./scripts/build-unix.sh
```

5. Build the adapters required by the demo configuration. You can build additional adapters as needed.
The script initializes the submodules, clones Micro-Manager into `ScopeOneCore/external/micro-manager` and links `mmCoreAndDevices`, builds MMDevice, MMCore and the DemoCamera and Utilities adapters, builds and installs ScopeOneCore, builds the GUI, and copies the demo adapters next to the executable. It selects the `x64-linux-dynamic`, `arm64-linux-dynamic`, `x64-osx-dynamic`, or `arm64-osx-dynamic` triplet from the host. Set `JOBS` to limit parallel jobs and `BUILD_TYPE` to change the CMake build type (default `Release`).

```bash
make -C mmCoreAndDevices/DeviceAdapters/DemoCamera -j4
make -C mmCoreAndDevices/DeviceAdapters/Utilities -j4
```
Pass `--clean` once when migrating from a build that used system Qt or OpenCV, or from an earlier static `x64-linux` triplet build.

6. Build and install `ScopeOneCore`:

```bash
cd /path/to/ScopeOne
cmake -S ScopeOneCore -B ScopeOneCore/build -DCMAKE_BUILD_TYPE=Release
cmake --build ScopeOneCore/build --parallel
cmake --install ScopeOneCore/build
```

7. Build the GUI application:

```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
```

The Linux or macOS executable is expected at:

```text
build/ScopeOne
```

To run `config/MMConfig_demo.cfg`, copy its runtime adapters next to the ScopeOne executable.

Linux:

```bash
cp -L \
ScopeOneCore/external/mmCoreAndDevices/DeviceAdapters/DemoCamera/.libs/libmmgr_dal_DemoCamera.so.0 \
ScopeOneCore/external/mmCoreAndDevices/DeviceAdapters/Utilities/.libs/libmmgr_dal_Utilities.so.0 \
build/
```

macOS uses an extensionless Mach-O bundle rather than the static `.a` file:

```bash
cp \
ScopeOneCore/external/mmCoreAndDevices/DeviceAdapters/DemoCamera/.libs/libmmgr_dal_DemoCamera \
ScopeOneCore/external/mmCoreAndDevices/DeviceAdapters/Utilities/.libs/libmmgr_dal_Utilities \
build/
```
The executable is `build/ScopeOne`, and `config/MMConfig_demo.cfg` runs with the copied demo adapters. It loads Qt and OpenCV from `vcpkg_installed/<triplet>/lib`, so run it from the build tree; there is no Linux or macOS deployment step yet.

## 🤖 Automation and AI Agents

Expand Down
24 changes: 10 additions & 14 deletions ScopeOneCore/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ include(CMakePackageConfigHelpers)
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/install" CACHE PATH "Install path" FORCE)
endif ()
if (WIN32)
list(PREPEND CMAKE_PREFIX_PATH "C:/Qt/6.11.0/msvc2022_64")
endif ()

set(MMCORE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/mmCoreAndDevices")
set(MMCORE_INCLUDE_DIR "${MMCORE_DIR}/MMCore")
set(MMDEVICE_INCLUDE_DIR "${MMCORE_DIR}/MMDevice")

find_package(Qt6 COMPONENTS Core Gui Network Concurrent REQUIRED)
find_package(OpenCV CONFIG REQUIRED COMPONENTS core imgproc imgcodecs)

set(SCOPEWRITER_BUILD_TESTS OFF)
add_subdirectory(external/ScopeWriter)
Expand All @@ -29,15 +27,11 @@ set(CMAKE_AUTOMOC ON)
if (WIN32)
set(MMCORE_BIN_DIR "${MMCORE_DIR}/build/Release/x64")

set(OpenCV_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/opencv-4.12.0/build")

find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs)
set(SCOPEONE_OPENCV_LIBRARIES opencv_world)

file(GLOB MMCORE_RUNTIME_DLLS "${MMCORE_BIN_DIR}/*.dll")
file(GLOB VCPKG_RUNTIME_DLLS "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin/*.dll")

set(SCOPEONE_RUNTIME_DLLS
$<TARGET_FILE:opencv_world>
${VCPKG_RUNTIME_DLLS}
${MMCORE_RUNTIME_DLLS}
)

Expand All @@ -48,11 +42,9 @@ if (WIN32)
endif ()
endforeach ()
else ()
# Linux/Unix: use system OpenCV and link the MMCore static libraries
# Linux/Unix: link the MMCore static libraries
# built from the sibling micro-manager checkout (symlinked into
# external/mmCoreAndDevices). No runtime DLLs to stage.
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs)
set(SCOPEONE_OPENCV_LIBRARIES ${OpenCV_LIBS})
set(MMCORE_BIN_DIR "")

add_library(MMCore STATIC IMPORTED GLOBAL)
Expand Down Expand Up @@ -176,6 +168,7 @@ if (UNIX AND NOT APPLE)
set_target_properties(ScopeWriter ScopeOneCore PROPERTIES
BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN"
INSTALL_RPATH_USE_LINK_PATH TRUE
)
endif ()
set_target_properties(ScopeOnePluginSDK PROPERTIES EXPORT_NAME PluginSDK)
Expand All @@ -192,7 +185,9 @@ target_link_libraries(ScopeOneCore
MMCore
Qt::Network
Qt::Concurrent
${SCOPEONE_OPENCV_LIBRARIES}
opencv_core
opencv_imgproc
opencv_imgcodecs
ScopeWriter::ScopeWriter
)
target_compile_definitions(ScopeOneCore PRIVATE
Expand Down Expand Up @@ -253,7 +248,8 @@ add_executable(ScopeOne_DriverHost
if (UNIX AND NOT APPLE)
set_target_properties(ScopeOne_DriverHost PROPERTIES
BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN/../lib"
INSTALL_RPATH "$ORIGIN/../lib;$ORIGIN"
INSTALL_RPATH_USE_LINK_PATH TRUE
)
endif ()
target_link_libraries(ScopeOne_DriverHost
Expand Down
2 changes: 1 addition & 1 deletion ScopeOneCore/external/ScopeWriter
Submodule ScopeWriter updated 1983 files
1 change: 1 addition & 0 deletions ScopeOneCore/include/scopeone/ScopeOneCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ namespace scopeone::core
static QString getVersion();
static QString getMMCoreVersion();
static QString getOpenCVVersion();
static QString getScopeWriterVersion();
static QString getLibTiffVersion();
static QString getZlibVersion();
static QString rawLayerKey(const QString& cameraId);
Expand Down
5 changes: 5 additions & 0 deletions ScopeOneCore/src/ScopeOneCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,11 @@ namespace scopeone::core
}

// Return the ScopeWriter libtiff version
QString ScopeOneCore::getScopeWriterVersion()
{
return QString::fromStdString(scopewriter::version());
}

QString ScopeOneCore::getLibTiffVersion()
{
return QString::fromStdString(scopewriter::libTiffVersion());
Expand Down
2 changes: 1 addition & 1 deletion plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(CMAKE_AUTOMOC ON)

find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
find_package(ScopeOneCore CONFIG REQUIRED)
find_package(OpenCV REQUIRED COMPONENTS core imgcodecs imgproc)
find_package(OpenCV CONFIG REQUIRED COMPONENTS core imgcodecs imgproc)
find_program(SCOPEONE_CUDA_NVCC_EXECUTABLE nvcc)

function(scopeone_add_plugin target kind)
Expand Down
Loading
Loading