Files
OrcaSlicer/CMakeLists.txt
T
a5413efc37 refactor: printer agent infrastructure changes to work with other printer agents aside from bambu (#15710)
* Add developer flag for printer agents

* Parse user print info on the UI thread to prevent heap corruption (#119)

get_user_print_info()'s HTTP fetch can run on a worker thread (e.g. BindJob),
but parse_user_print_info() mutates userMachineList (insert/erase/delete
MachineObject). on_machine_alive (SSDP) mutates the same maps on the UI thread
without locking, so parsing off-thread races the map and frees MachineObjects
out from under it -> heap corruption.

Keep all device-list mutation on the UI thread: parse inline when already on
the main thread, otherwise marshal via CallAfter so it stays serialized with
on_machine_alive.

* Prevent loss of user access code on LAN reselect

Keep user access code intact to maintain access rights even if
device slot is unpopulated, ensuring continuous connection
and status message reception.

* Harden send flow and separate upload failure recovery (#111)

* fix(send): harden FT send path + IP pre-flight UX

* Remove early returns

* Working Moonraker and Qidi printer agent transport (#104)

Folds the Qidi AMS box-mapping print
overrides (apply_box_mapping +
start_* wrappers) that the transport
fix builds on.

* Add support for runtime error status in plugins

Distinguish a loaded plugin whose
capability errored (RuntimeError,
warn-styled, stays checked) from a
load-time Error. Status now derives
via resolve_plugin_status(); enum
ordinal keeps dialog sort priority.
Unloading clears stale errors.

* Resolve duplicate agent ID conflicts

Reject a printer-agent capability
whose agent ID is already owned by
another capability or built-in:
flag the plugin error, disable the
capability, and warn the user
instead of silently ignoring it.

* fix: checkbox should depend on plugin is_loaded status

* Replace fake-enum printer agent dropdown (#121)

A dedicated PrinterAgentChoice field
reads rows straight from the live
agent registry and stores the agent
id string, replacing the fake-coEnum
index mapping. The field moves to
TabPrinter and registers with the
searcher so UnsavedChanges renders
it; the PhysicalPrinterDialog copy
and its update hook are removed
(#125). switch_printer_agent now
resolves ids via
resolve_printer_agent_id.

* Reset device selection on agent swap or unload (#124)

set_live_printer_agent centralizes
the swap: deselect the machine,
clear stale sidebar state and the
previous agent's Other Devices, then
install the new agent (or null when
its provider vanished). Plugin
load/unload callbacks refresh the
dropdown and re-run agent selection.
load_last_machine no longer falls
back to the first available machine.

* Gate agent mode behind use_printer_agents toggle

Replace per-printer auto-activation
(is_current_printer_agent_plugin)
with a global experimental AppConfig
toggle, default off: legacy
print-host behavior is unchanged
until the user opts in. The toggle
drives device-tab routing, print
button defaults, connect-button
visibility and sidebar layout, and
dedups machine-select dialog opens.

* Track BBLPrinterAgentPlugin.py

* Add printer-agent and plugin status tests

Ports the agent lifecycle, duplicate
agent-id, built-in-id clash and
status-resolution tests. The loader
runs on a detached worker thread, so
the lifecycle tests live in their own
executable. Tests install the
production unload-side registry
wiring themselves (no GUI in the
test binary) and register agents
manually so concurrent loads stay
deterministic.

* fix: pin HTTP to prevent connection refusal

Set `use_ssl` to false to ensure Moonraker
connectivity, as the service uses HTTP rather
than HTTPS, preventing connection issues. Initialize
device info early for reliable name resolution.

* Bring Moonraker device panel to feature parity

The monitor panel showed wrong or missing
data for Moonraker printers, and its
controls did nothing.

Push payload now carries layer number and
total layers. Remaining time replaces the
wrong total_duration - print_duration
formula. The chamber light toggle maps to
Klipper SET_PIN / SET_LED, and pause,
resume and stop post to
/printer/print/{action}. Task thumbnails
resolve via /server/files/thumbnails onto
a new MachineObject thumbnail url.

Filament sync switches to pull mode so the
agent is queried on demand.

Not compiled or run.

* Stop blocking print on unreported nozzle data

* fix: make Klipper macro lamp control reliable

* Surface Moonraker webcams and gate unrunnable controls

* Keep Bambu AMS dialect out of the agent waist

M620 is Bambu firmware dialect, not a
neutral command. Composing it in
MachineObject let non-Bambu agents
(Moonraker/Klipper) forward it and
report success on firmware that
cannot run it.

Agents now own the dialect: the
default refusal on IPrinterAgent
returns not-supported so the UI
can say so; BBLPrinterAgent keeps
the byte-identical composition.

* Fix multi-color filament logic

Reuse color decoding across functions to improve
code readability and maintain consistency in
multi-color filament handling.

* Move Moonraker commands off the UI thread

Pause/resume/stop, g-code sends, temps, and
light ran synchronous HTTP on the UI thread,
freezing the app up to 10s per click on slow
or unreachable printers.

Run them on a single agent-owned FIFO worker
so g-code ordering is preserved, while command
translation stays synchronous so unsupported-
command dialogs still work.

Add a pending-disabled state to the pause,
resume, and abort buttons for Moonraker-family
printers: the icon only flips once the
WebSocket reports the real state, which also
rules out double-click races.

* Show Snapmaker U1 camera in Device tab

The U1 exposes no /server/webcams/list entry;
its camera only captures after an explicit
camera.start_monitor RPC, which the Moonraker
websocket executes unauthenticated but only
answers over MQTT - so the call is fire and
forget.

Start the camera when the camera view is
shown and renew every 300 s: the printer
retires the capture task at ~362 s and
stop_monitor is accepted but ineffective,
so teardown is simply to stop renewing.

Frames land in monitor.jpg as still JPEGs
(~2 fps at interval 0), so the webview loads
a local HTML wrapper that repolls with a
cache buster.

* fix: start stream when camera URL changes

* fix: stop Qidi slot parse throwing on null

* Keep printer-agent progress in sync

Keep the shared task progress aligned with agent
reports that lack Bambu cloud task identity.

Release the lazily allocated task during reset to
avoid leaks when machine objects reconnect.

* docs: document the printer-agent subsystem

* fix: merge access codes into one

* Reconcile implementation split with PR tip

* feat: abstract remaining gcode commands in devicemanager

* refactor: abstract bambu specific protocol to printer agent

* refactor: push bbl workflows to bbl printer agent

* remove unused

* fix: default impl

* fix callback error

* fix: remove redundant cache

* specify api for getting file transfer url

* revert file transfer abstraction

* fix: ams filament mapping workflow

* feat: update qidi to use subscription based filament sync mode

* fix: resolve stubgen byte header conflict

* fix: ams sync info and periodic ams sync via subscription workflow

* fix: skip filament sync dialog if filamentSyncMode is none

* feat: parse nozzle information for qidi and moonraker printer agents

* fix: extend access code requirements t 0, 8 or more characters.

* remove irrelevant docs

* fix: remove heavy includes from IPrinterAgent

* fix: defer filesystem and camera abstractions

* fix: remote do_fetch_filament_info from tests

* cleanup moonraker and snapmaker printer agents

* fix: access codes regression

* fix: tests

* fix: printer agent switching on preset change

* fix: remove unused variable

* fix: snapmaker U1 SelectMachineDialog blocking print

* fix: merge artifact

* fix: clear up some unrelated changes

* feat: connect to cloud printer and monitor

* feat: connect to cloud printer and monitor

* feat: generic camera stream support for http snapshot and rtsp

* fix: build & access code UI

* feat: generic camera stream support for http snapshot and rtsp

* fix: build & access code UI

* feat: connect to cloud printer and monitor

* feat: connect to cloud printer and monitor

* fix: build errors

* feat: camera via webrtc

* fix: build

* fix: cmake

* feat: remove frame assembler and change config to set protocol

* fix: orcaprinteragent refactor

* fix: LAN paths and camera stream

* feat: use ffmpeg to render http camera stream

* fix: make model_id/dev_type optional instead of blocking

* fix: connect via ip dialog

* feat: LAN impl for Orca Printer Agent

* fix: model_id resolution method for non bambu printers

* fix: ffmpeg http camera stream jittering due to incomplete frames

* fix: revert sdcard check

* feat: check printer storage status before sending

* fix: moonraker printer agent hang on printer power cut

* fix: shim layer for any compatibiliity changes

* fix: cloud printers were using the wrong MQTT endpoint

* feat: cloud download via HTTP

* temp: doc for intended change

* fix: warnings

* fix: warnings

* fix: camera auto-play on startup

* fix: split infra from impl

* fix: uninitialized ams state blocking print

* Fixes nullptr deref

* Log first before std::move

* fix: printer agent virutal optional functions

* fix: parameterize orcaslicer_copy_test_dlls() for printer_agent_plugin_tests

* Revert "fix: parameterize orcaslicer_copy_test_dlls() for printer_agent_plugin_tests"

This reverts commit 2f566e3779.

* Guard libdatachannel. Remove unused code

* fix: unit tests & unused variables

* fix(ci): deps build order for datachannel

* Resolve printer agent first before getting cloud printer agent

* fix(ci): set depends openssl

* fix: re-include apply header guarded by ifdef __APPLE__

* fix(ci): add libdatachannel to flatpak manifest

* fix: add internal_developer_mode chekc back to MediaPlayCtrl::load()

* fix: invoke js clearInterval on WebMediaController::stop

* fix: change rtc log level

* fix: inject provider, agent id and generation to get_user_print_info to ensure correct metadata

* fix: revert moonraker specific behavior

* fix: remove stale comment

* fix: use ORCA_CLOUD_PROVIDER instead of hardcoded string

* fix: remove hardcoded ICE servers

* feat: enable https camera stream mode

* fix: move non-mandatory printer agent function stubs to IPrinterAgent

* fix: dedupe compatible printer type check

* fix: stop the correct media controller

* fix: scope get_my_machine_list to printers listed under the current printer agent

* fix: move printer agent plugin tests into test_plugin_lifecycle.cpp

* fix: always build bundled DataChannel dep

* fix: disable unused DataChannel media support

* revert: filament sync work

* fix: wrap command_* with small wrapper

* fix: regression bug, connecting to bambu needs bblp username

* fix: default impl for vendor agnostic gcode commansd

* refactor: media controller playback routing and ownership

* fix: bump libdatachannel ver & update flatpak to use tar instead

* fix: stop flatpak DataChannel build from re-cloning over the sandboxed network

* fix: update windows ffmpeg prebuild

* fix: update printer agent plugin API

* fix: shift camera signaling channel to network agent

* fix: follow external-packages for flatpak libdatachannel deps & add flatpak path to use source_dir

* feat: add printer-agent.md doc to HLSD

* fix: guard DeviceManager command dispatch when no printer agent is bound

* fix: port BBL implementations from #15711

* refactor: connect_printer api and dialog

* fix(tests): make omitted printer agent operations answer like a missing agent

* fix: preserve printer agent defaults in PrinterAgentPluginCapabilityTrampoline

* test: cover printer agent default command dispatch

* fix: validate windows FFmpeg avformat library

* feat: extend optional printer model warnings to calibration & ams workflows

* fix: handle malformed printer progress values safely

* fix: clear webview document on stop

* chore: reduce diagnostic logging level to trace

* refactor: centralize printer compatibility checks

* tests: add device manager integration coverage

* tests: cover WebMediaController lifecycle with wxWebView stub

* fix: make integration tests headless

* refactor: collapse command_ams_refresh_rfid and command_ams_refresh_rfid2

* refactor: make printer connection SSL agent-specific

* fix: persist input printer host and port

* fix: use correct device id for Moonraker connections

* fix: make moonraker gcode commands asynchronous

* fix: preserve moonraker device names

* fix: add include for non BBL_RELEASE_TO_PUBLIC path in BBLPrinterAgent

---------

Co-authored-by: Andrew <159703254+andrewsoonqn@users.noreply.github.com>
Co-authored-by: SoftFever <softfeverever@gmail.com>
Co-authored-by: Lam Wei Lun <weilun.lam@gmail.com>
2026-10-01 00:30:44 +08:00

1387 lines
59 KiB
CMake

if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "4.0")
set(CMAKE_POLICY_VERSION_MINIMUM 3.13 CACHE STRING "" FORCE)
endif()
cmake_minimum_required(VERSION 3.13)
if(POLICY CMP0177)
cmake_policy(SET CMP0177 NEW)
endif()
# The following line used to be in tests/CMakeLists.txt
# Having it there causes rebuilds of all targets on any CMakeLists.txt change under tests/
# It has no effect on how code is compiled or linked.
# It just lets you later do `set_property(TARGET foo PROPERTY FOLDER "bar")`
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
if (WIN32)
# Detect known CI environments
set(IS_CI FALSE)
if(DEFINED ENV{CI})
set(IS_CI TRUE)
elseif(DEFINED ENV{GITHUB_ACTIONS})
set(IS_CI TRUE)
elseif(DEFINED ENV{GITLAB_CI})
set(IS_CI TRUE)
elseif(DEFINED ENV{TF_BUILD})
set(IS_CI TRUE)
elseif(DEFINED ENV{BUILD_NUMBER}) # Jenkins
set(IS_CI TRUE)
endif()
# Detect common misconfiguration (Strawberry Perl in PATH before CMake)
# We use ENV to check the PATH order
string(REPLACE "\\" "/" ENV_PATH "$ENV{PATH}")
string(FIND "${ENV_PATH}" "Strawberry/c/bin" STRAWBERRY_POS)
string(FIND "${ENV_PATH}" "Program Files/CMake/bin" CMAKE_POS)
if (STRAWBERRY_POS GREATER -1 AND CMAKE_POS GREATER -1 AND STRAWBERRY_POS LESS CMAKE_POS)
set(_warning_text "
#############################################################
Detected Strawberry Perl's 'c/bin' appearing before CMake in PATH.
This is known to cause CMake to misbehave (e.g., missing modules).
Please adjust your PATH so that:
C:\\Program Files\\CMake\\bin
appears before:
C:\\Strawberry\\c\\bin
You can do this in Environment Variables settings.
#############################################################
")
if(NOT IS_CI)
message(FATAL_ERROR "${_warning_text}")
endif()
endif()
endif ()
if (APPLE)
# if CMAKE_OSX_DEPLOYMENT_TARGET is not set, set it to 12.0 (the lowest Xcode 27 accepts)
if (NOT CMAKE_OSX_DEPLOYMENT_TARGET)
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum OS X deployment version" FORCE)
endif ()
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif ()
# Keep MSVC's default /W3 out of CMAKE_<LANG>_FLAGS so it can be applied to our own
# targets only. Silencing a bundled target would otherwise override a warning level,
# which cl reports as D9025 for every file it compiles.
if (POLICY CMP0092)
cmake_policy(SET CMP0092 NEW)
endif ()
# project() reads this, so set it first.
set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_CURRENT_LIST_DIR}/cmake/modules/ClangClShowIncludes.cmake")
project(OrcaSlicer)
# Backward compatibility for old CMake versions
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_VERSION VERSION_LESS "3.25")
set(LINUX ON CACHE BOOL "" FORCE)
endif ()
include("version.inc")
include(GNUInstallDirs)
include(CMakeDependentOption)
set(SLIC3R_RESOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resources")
file(TO_NATIVE_PATH "${SLIC3R_RESOURCES_DIR}" SLIC3R_RESOURCES_DIR_WIN)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Release)" FORCE)
endif()
if (DEFINED BBL_RELEASE_TO_PUBLIC)
add_compile_definitions("BBL_RELEASE_TO_PUBLIC=${BBL_RELEASE_TO_PUBLIC}")
if (BBL_RELEASE_TO_PUBLIC)
add_compile_definitions(WXINSPECTOR_DISABLE)
endif ()
else ()
add_compile_definitions("BBL_RELEASE_TO_PUBLIC=$<CONFIG:Release>")
add_compile_definitions("$<$<CONFIG:Release>:WXINSPECTOR_DISABLE>")
endif ()
if(DEFINED ENV{SLIC3R_STATIC})
set(SLIC3R_STATIC_INITIAL $ENV{SLIC3R_STATIC})
else()
set(SLIC3R_STATIC_INITIAL 1)
endif()
option(SLIC3R_STATIC "Compile OrcaSlicer with static libraries (Boost, TBB)" ${SLIC3R_STATIC_INITIAL})
option(SLIC3R_GUI "Compile OrcaSlicer with GUI components (OpenGL, wxWidgets)" 1)
option(SLIC3R_CAD "Compile OrcaSlicer with the parametric Design/CAD tab (needs OCCT ModelingAlgorithms)" 1)
option(SLIC3R_FHS "Assume OrcaSlicer is to be installed in a FHS directory structure" 0)
option(SLIC3R_PROFILE "Compile OrcaSlicer with an invasive Shiny profiler" 0)
option(SLIC3R_PCH "Use precompiled headers" 1)
option(SLIC3R_WARNINGS "Emit compiler warnings for OrcaSlicer sources" 1)
option(SLIC3R_BUNDLED_WARNINGS "Emit compiler warnings for bundled third-party sources" 0)
option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
option(SLIC3R_RELATIVE_DEBUG_PATHS "Record a relative compilation directory in debug info (clang-cl)" 0)
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
# Python stubgen module
option(ORCA_BUILD_PYTHON_STUBGEN_MODULE "Build importable Python module for pybind11-stubgen" ON)
set(ORCA_BUNDLED_UV_EXECUTABLE "" CACHE FILEPATH "Path to a uv executable to bundle for Python package installation. Leave empty to auto-download.")
# Auto-download uv if not provided by the user.
# uv is pinned: the executable ships inside the signed app, so the build must
# be reproducible and the download verified. To upgrade, bump ORCA_UV_VERSION
# and refresh every hash below from the release's .sha256 assets, e.g.:
# curl -sL https://github.com/astral-sh/uv/releases/download/<ver>/uv-<triple>.tar.gz.sha256
set(ORCA_UV_VERSION "0.11.21")
set(ORCA_UV_SHA256_aarch64-apple-darwin "1f921d491ba5ffeea774eb04d6681ecee379101341cbb1500394993b541bf3f4")
set(ORCA_UV_SHA256_x86_64-apple-darwin "f3c8e5708a84b920c18b691214d54d2b0da6b984789caae95d47c95120cb7765")
set(ORCA_UV_SHA256_aarch64-unknown-linux-gnu "88e800834007cc5efd4675f166eb2a51e7e3ad19876d85fa8805a6fb5c922397")
set(ORCA_UV_SHA256_x86_64-unknown-linux-gnu "8c88519b0ef0af9801fcdee419bbb12116bd9e6b18e162ae093c932d8b264050")
set(ORCA_UV_SHA256_x86_64-pc-windows-msvc "ace861f360c6de2babedc1607d0f454b6b09a820dbc8182dc15af927e4df9589")
# Version-scoped cache dir so a version bump invalidates the cached binary.
set(ORCA_UV_DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/.uv/${ORCA_UV_VERSION}")
set(ORCA_UV_BINARY "${ORCA_UV_DOWNLOAD_DIR}/uv")
if(WIN32)
set(ORCA_UV_BINARY "${ORCA_UV_DOWNLOAD_DIR}/uv.exe")
endif()
# Older configures FORCE-cached the auto-downloaded path; any cache entry
# under .uv/ is that legacy value -- clear it so auto-download re-resolves
# (user-provided paths never live under .uv/).
if(ORCA_BUNDLED_UV_EXECUTABLE MATCHES "/\\.uv/")
set(ORCA_BUNDLED_UV_EXECUTABLE "" CACHE FILEPATH "Path to the auto-downloaded uv executable" FORCE)
endif()
if(NOT ORCA_BUNDLED_UV_EXECUTABLE)
if(NOT EXISTS "${ORCA_UV_BINARY}")
# Select uv by TARGET arch. On macOS universal builds each leg sets a single
# CMAKE_OSX_ARCHITECTURES (and the x86_64 leg cross-builds on an arm64 runner),
# so prefer it over the host CMAKE_SYSTEM_PROCESSOR -- otherwise both legs fetch
# the same arch and the later universal lipo merge of tools/uv/uv fails.
set(_orca_uv_proc "${CMAKE_SYSTEM_PROCESSOR}")
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
set(_orca_uv_proc "${CMAKE_OSX_ARCHITECTURES}")
endif()
# All release archives are tar.gz except the Windows zip.
set(ORCA_UV_EXT "tar.gz")
if(_orca_uv_proc MATCHES "x86_64|AMD64|amd64")
if(WIN32)
set(ORCA_UV_ARCH "x86_64-pc-windows-msvc")
set(ORCA_UV_EXT "zip")
elseif(APPLE)
set(ORCA_UV_ARCH "x86_64-apple-darwin")
else()
set(ORCA_UV_ARCH "x86_64-unknown-linux-gnu")
endif()
elseif(_orca_uv_proc MATCHES "aarch64|arm64|ARM64")
if(APPLE)
set(ORCA_UV_ARCH "aarch64-apple-darwin")
else()
set(ORCA_UV_ARCH "aarch64-unknown-linux-gnu")
endif()
else()
message(WARNING "Unsupported architecture for auto-downloading uv: ${_orca_uv_proc}")
endif()
if(ORCA_UV_ARCH)
set(ORCA_UV_URL "https://github.com/astral-sh/uv/releases/download/${ORCA_UV_VERSION}/uv-${ORCA_UV_ARCH}.${ORCA_UV_EXT}")
set(ORCA_UV_ARCHIVE "${ORCA_UV_DOWNLOAD_DIR}/uv-archive.${ORCA_UV_EXT}")
file(MAKE_DIRECTORY "${ORCA_UV_DOWNLOAD_DIR}")
message(STATUS "Downloading uv ${ORCA_UV_VERSION} from ${ORCA_UV_URL} ...")
file(DOWNLOAD "${ORCA_UV_URL}" "${ORCA_UV_ARCHIVE}" STATUS ORCA_UV_DL_STATUS TLS_VERIFY ON)
list(GET ORCA_UV_DL_STATUS 0 ORCA_UV_DL_CODE)
list(GET ORCA_UV_DL_STATUS 1 ORCA_UV_DL_MSG)
if(NOT ORCA_UV_DL_CODE EQUAL 0)
# Network failure keeps the historical graceful degradation (uv is
# optional at build time) -- but a hash mismatch below is fatal.
message(WARNING "Failed to download uv: ${ORCA_UV_DL_MSG}")
file(REMOVE "${ORCA_UV_ARCHIVE}")
else()
file(SHA256 "${ORCA_UV_ARCHIVE}" _orca_uv_actual_sha256)
if(NOT _orca_uv_actual_sha256 STREQUAL "${ORCA_UV_SHA256_${ORCA_UV_ARCH}}")
file(REMOVE "${ORCA_UV_ARCHIVE}")
message(FATAL_ERROR
"uv archive checksum mismatch for ${ORCA_UV_ARCH} ${ORCA_UV_VERSION}:\n"
" expected ${ORCA_UV_SHA256_${ORCA_UV_ARCH}}\n"
" actual ${_orca_uv_actual_sha256}\n"
"Possible tampering or a stale pin; refusing to bundle.")
endif()
message(STATUS "Extracting uv ...")
file(ARCHIVE_EXTRACT INPUT "${ORCA_UV_ARCHIVE}" DESTINATION "${ORCA_UV_DOWNLOAD_DIR}")
file(REMOVE "${ORCA_UV_ARCHIVE}")
# Pinned archives have a fixed layout: the tarballs hold
# uv-<triple>/uv, the Windows zip holds uv.exe at the root
# (already at ORCA_UV_BINARY). A layout change implies a new
# archive, hence a hash bump -- and RENAME fails loudly.
if(NOT WIN32)
file(RENAME "${ORCA_UV_DOWNLOAD_DIR}/uv-${ORCA_UV_ARCH}/uv" "${ORCA_UV_BINARY}")
file(REMOVE_RECURSE "${ORCA_UV_DOWNLOAD_DIR}/uv-${ORCA_UV_ARCH}")
endif()
endif()
endif()
endif()
if(EXISTS "${ORCA_UV_BINARY}")
# Plain set (shadows the empty cache entry for this configure run):
# the version-scoped path re-derives every configure, so a version
# bump takes effect in warm build dirs without cache surgery.
set(ORCA_BUNDLED_UV_EXECUTABLE "${ORCA_UV_BINARY}")
endif()
endif()
# Resolve ORCA_BUNDLED_UV_EXECUTABLE -> ORCA_BUNDLED_UV_EXECUTABLE_CONFIG / ORCA_BUNDLED_UV_FILENAME
# Must run before add_subdirectory(src) so target_compile_definitions sees it.
if(ORCA_BUNDLED_UV_EXECUTABLE)
if(EXISTS "${ORCA_BUNDLED_UV_EXECUTABLE}")
file(TO_CMAKE_PATH "${ORCA_BUNDLED_UV_EXECUTABLE}" ORCA_BUNDLED_UV_EXECUTABLE_CONFIG)
get_filename_component(ORCA_BUNDLED_UV_FILENAME "${ORCA_BUNDLED_UV_EXECUTABLE}" NAME)
else()
message(WARNING "ORCA_BUNDLED_UV_EXECUTABLE does not exist: ${ORCA_BUNDLED_UV_EXECUTABLE}")
set(ORCA_BUNDLED_UV_EXECUTABLE "")
set(ORCA_BUNDLED_UV_EXECUTABLE_CONFIG "")
set(ORCA_BUNDLED_UV_FILENAME "")
endif()
else()
set(ORCA_BUNDLED_UV_EXECUTABLE_CONFIG "")
set(ORCA_BUNDLED_UV_FILENAME "")
endif()
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, othrewise variable.
CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow performing desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0)
set(OPENVDB_FIND_MODULE_PATH "" CACHE PATH "Path to OpenVDB installation's find modules.")
set(SLIC3R_GTK "3" CACHE STRING "GTK version to use with wxWidgets on Linux")
set(IS_CROSS_COMPILE FALSE)
option (COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF)
if (${COLORED_OUTPUT})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_compile_options (-fdiagnostics-color=always)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options (-fcolor-diagnostics)
endif ()
endif ()
if (APPLE)
list(LENGTH CMAKE_OSX_ARCHITECTURES _arch_len)
if (_arch_len GREATER 1)
message(FATAL_ERROR "OrcaSlicer only supports building for one architecture at a time. Please make sure only one architecture is specified in CMAKE_OSX_ARCHITECTURES")
endif ()
set(CMAKE_FIND_FRAMEWORK LAST)
set(CMAKE_FIND_APPBUNDLE LAST)
list(FIND CMAKE_OSX_ARCHITECTURES ${CMAKE_SYSTEM_PROCESSOR} _arch_idx)
if (CMAKE_OSX_ARCHITECTURES AND _arch_idx LESS 0)
set(IS_CROSS_COMPILE TRUE)
endif ()
if (CMAKE_MACOSX_BUNDLE)
set(CMAKE_INSTALL_RPATH @executable_path/../Frameworks)
endif()
SET(CMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.orcaslicer.OrcaSlicer")
# The macOS CI jobs build with Ninja (build_release_macos.sh -x), so the Xcode generator
# is not covered. Xcode adds -Wshorten-64-to-32 by default ("Implicit Conversion to 32 Bit
# Type"); Ninja/-Wall does not, and under -Werror it fails Xcode builds on code CI accepts.
set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION "NO")
message(STATUS "Orca: IS_CROSS_COMPILE: ${IS_CROSS_COMPILE}")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_INSTALL_RPATH "$ORIGIN")
endif ()
# Proposal for C++ unit tests and sandboxes
option(SLIC3R_BUILD_SANDBOXES "Build development sandboxes" OFF)
option(BUILD_TESTS "Build unit tests" OFF)
option(ORCA_TOOLS "Build Orca tools" OFF)
if (FLATPAK)
set(SLIC3R_FHS ON CACHE BOOL "" FORCE)
set(SLIC3R_DESKTOP_INTEGRATION OFF CACHE BOOL "" FORCE)
endif ()
if (IS_CROSS_COMPILE)
message("Detected cross compilation setup. Tests and encoding checks will be forcedly disabled!")
set(BUILD_TESTS OFF CACHE BOOL "" FORCE)
endif ()
# Print out the SLIC3R_* cache options
get_cmake_property(_cache_vars CACHE_VARIABLES)
list (SORT _cache_vars)
foreach (_cache_var ${_cache_vars})
if("${_cache_var}" MATCHES "^SLIC3R_")
message(STATUS "${_cache_var}: ${${_cache_var}}")
endif ()
endforeach()
if (SLIC3R_GUI)
add_definitions(-DSLIC3R_GUI)
endif ()
if (SLIC3R_CAD)
add_definitions(-DSLIC3R_CAD)
endif ()
if(SLIC3R_DESKTOP_INTEGRATION)
add_definitions(-DSLIC3R_DESKTOP_INTEGRATION)
endif ()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
message(STATUS "Automatically setting CMAKE_INSTALL_PREFIX")
set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE "${CMAKE_BINARY_DIR}/OrcaSlicer")
endif()
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set(IS_CLANG_CL TRUE)
# clang-cl can interpret SYSTEM header paths if -imsvc is used
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-imsvc")
else ()
set(IS_CLANG_CL FALSE)
endif ()
if (MSVC)
# CMP0092 only applies when the cache is created; an existing tree keeps its /W3,
# which a silenced bundled target would then override (D9025, once per file).
string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# /MP only matters for the VS generators, where CMake turns it into the
# MultiProcessorCompilation property. Ninja parallelises on its own, and
# clang-cl warns "argument unused" if the flag reaches it.
if (SLIC3R_MSVC_COMPILE_PARALLEL AND CMAKE_GENERATOR MATCHES "Visual Studio")
add_compile_options(/MP)
endif ()
# Parse lambdas the way the standard says, as clang and GCC already do. Without it
# MSVC keeps its legacy lambda processor under /std:c++17 and rejects reading a
# constexpr constant inside a lambda that does not capture it (C3493), which no
# other compiler requires. Implied by /std:c++20 and /permissive-, so it is only
# needed while we are on C++17. clang-cl is conforming already and does not take
# the flag. Requires VS2019 16.8 or newer.
if (NOT IS_CLANG_CL)
# cl.exe only warns (D9002) about an unknown /Zc: option, so without this the
# flag would be dropped and the first lambda reading a constexpr constant would
# fail with C3493 far from the cause.
if (MSVC_VERSION LESS 1928)
message(FATAL_ERROR "Visual Studio 2019 16.8 (MSVC 19.28) or newer is required; detected MSVC ${MSVC_VERSION}.")
endif ()
add_compile_options(/Zc:lambda)
endif ()
# /bigobj (Increase Number of Sections in .Obj file)
add_compile_options(-bigobj)
# error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm90' or greater
# Generate symbols at every build target, even for the release.
# -Zm520 fixes error C3859 but forces the compiler to pre-allocate that memory for every translation unit regardless
# combining /Zi with /FS frees up a significant amount of memory pressure across all parallel compile jobs and makes /MP faster overall.
if (SLIC3R_MSVC_PDB)
add_compile_options(/Zi /FS)
endif ()
# Disable STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17.
#FIXME Remove this line after eigen library adapts to the new C++17 adaptor rules.
add_compile_options(-D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING)
# Disable warnings on conversion from unsigned to signed (possible loss of data)
# C4244: 'conversion' conversion from 'type1' to 'type2', possible loss of data. An integer type is converted to a smaller integer type.
# C4267: The compiler detected a conversion from size_t to a smaller type.
add_compile_options(/wd4244 /wd4267)
# Disable warnings on comparison of unsigned and signed
# C4018: signed/unsigned mismatch
add_compile_options(/wd4018)
# Prevent linker restart when TBB (or other deps) built with /GL are linked
# Make your full (clean) build slower because it enables link-time code generation across all translation units.
# helps incremental builds by preventing the double-link restart from TBB
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LTCG")
endif ()
# Without this every object names its build directory and two worktrees never
# share cache entries. The linker still writes absolute paths into the PDB.
if (SLIC3R_RELATIVE_DEBUG_PATHS)
if (IS_CLANG_CL)
add_compile_options(-ffile-compilation-dir=.)
else ()
message(WARNING "SLIC3R_RELATIVE_DEBUG_PATHS is only implemented for clang-cl")
endif ()
endif ()
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang" AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER 15)
add_compile_definitions(BOOST_NO_CXX98_FUNCTION_BASE _HAS_AUTO_PTR_ETC=0)
endif()
if (MINGW)
add_compile_options(-Wa,-mbig-obj)
endif ()
if (NOT MSVC)
# ARMs (Raspberry PI) use an unsigned char by default. Let's make it consistent for OrcaSlicer on all platforms.
add_compile_options(-fsigned-char)
endif ()
if ("${DEP_BUILD_DIR}" STREQUAL "")
get_filename_component(BIN_DIR_NAME ${CMAKE_BINARY_DIR} NAME)
if (APPLE AND BIN_DIR_NAME STREQUAL "${CMAKE_OSX_ARCHITECTURES}")
file(RELATIVE_PATH BIN_DIR_NAME ${CMAKE_BINARY_DIR}/../.. ${CMAKE_BINARY_DIR})
endif ()
set(DEP_BUILD_DIR "${CMAKE_SOURCE_DIR}/deps/${BIN_DIR_NAME}" CACHE PATH "Path to dependencies build directory" FORCE)
message(STATUS "DEP_BUILD_DIR: ${DEP_BUILD_DIR} (generated automatically and saved to cache)")
set(AUTOGENERATED_DEP_BUILD_DIR ${DEP_BUILD_DIR} CACHE PATH "Provides the last autogenerated DEP_BUILD_DIR" FORCE)
else ()
message(STATUS "DEP_BUILD_DIR: ${DEP_BUILD_DIR} (from cache or command line)")
endif ()
if ("${CMAKE_PREFIX_PATH}" STREQUAL "" OR "${CMAKE_PREFIX_PATH}" STREQUAL "${AUTOGENERATED_PREFIX_PATH}")
if (DEFINED AUTOGENERATED_DEP_BUILD_DIR AND NOT "${DEP_BUILD_DIR}" STREQUAL "${AUTOGENERATED_DEP_BUILD_DIR}")
message(STATUS "CMAKE_PREFIX_PATH is being re-generated due to DEP_BUILD_DIR being manually updated")
set(REGEN_DESTDIR TRUE)
unset(AUTOGENERATED_DEP_BUILD_DIR CACHE)
endif ()
else ()
unset(AUTOGENERATED_PREFIX_PATH CACHE)
endif ()
# Display and check CMAKE_PREFIX_PATH
if ("${CMAKE_PREFIX_PATH}" STREQUAL "" OR REGEN_DESTDIR)
set(CMAKE_PREFIX_PATH "${DEP_BUILD_DIR}/OrcaSlicer_dep/usr/local" CACHE PATH "Path to dependencies install directory" FORCE)
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH} (generated automatically and saved to cache)")
set(AUTOGENERATED_PREFIX_PATH ${CMAKE_PREFIX_PATH} CACHE STRING "Provides the last autogenerated CMAKE_PREFIX_PATH" FORCE)
unset(REGEN_DESTDIR CACHE)
else ()
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH} (from cache or command line)")
endif ()
set(PREFIX_PATH_CHECK ${CMAKE_PREFIX_PATH})
# the CMAKE_PREFIX_PATH environment variable is separate from the CMAKE_PREFIX_PATH cache variable and provides additional paths to search for libraries.
if (NOT "$ENV{CMAKE_PREFIX_PATH}" STREQUAL "")
message(STATUS "CMAKE_PREFIX_PATH: $ENV{CMAKE_PREFIX_PATH} (from environment)")
list(APPEND PREFIX_PATH_CHECK $ENV{CMAKE_PREFIX_PATH})
endif ()
# Check all directories in CMAKE_PREFIX_PATH variables
foreach (DIR ${PREFIX_PATH_CHECK})
if (NOT EXISTS "${DIR}")
message(WARNING "CMAKE_PREFIX_PATH element doesn't exist: ${DIR}")
endif ()
endforeach ()
if (APPLE)
set(CMAKE_MACOSX_RPATH ON CACHE BOOL "")
set(CMAKE_MACOSX_BUNDLE ON CACHE BOOL "")
endif ()
if (APPLE AND CMAKE_MACOSX_RPATH AND "${CMAKE_INSTALL_RPATH}" STREQUAL "")
set(CMAKE_INSTALL_RPATH ${CMAKE_PREFIX_PATH})
endif ()
# Add our own cmake module path.
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules/)
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
enable_testing ()
# Enable C++17 language standard.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT WIN32)
# Add DEBUG flags to debug builds.
add_compile_definitions("$<IF:$<CONFIG:Debug>,DEBUG,NDEBUG>")
endif()
# To be able to link libslic3r with the Perl XS module.
# Once we get rid of Perl and libslic3r is linked statically, we can get rid of -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# WIN10SDK_PATH is used to point CMake to the WIN10 SDK installation directory.
# We pick it from environment if it is not defined in another way
# ORCA: Removed Netfabb STL fixing service support in favor of CGAL.
# if(WIN32)
# if(NOT DEFINED WIN10SDK_PATH)
# if(DEFINED ENV{WIN10SDK_PATH})
# set(WIN10SDK_PATH "$ENV{WIN10SDK_PATH}")
# endif()
# endif()
# if(DEFINED WIN10SDK_PATH)
# #BBS: modify win10sdk_path
# if (EXISTS "${WIN10SDK_PATH}/winrt/windows.graphics.printing3d.h")
# set(WIN10SDK_INCLUDE_PATH "${WIN10SDK_PATH}")
# else()
# message("WIN10SDK_PATH is invalid: ${WIN10SDK_PATH}")
# message("${WIN10SDK_PATH}/winrt/windows.graphics.printing3d.h was not found")
# message("STL fixing by the Netfabb service will not be compiled")
# unset(WIN10SDK_PATH)
# endif()
# else()
# # Try to use the default Windows 10 SDK path.
# if (DEFINED ENV{WindowsSdkDir} AND DEFINED ENV{WindowsSDKVersion})
# set(WIN10SDK_INCLUDE_PATH "$ENV{WindowsSdkDir}/Include/$ENV{WindowsSDKVersion}")
# else ()
# set(WIN10SDK_INCLUDE_PATH "C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0")
# endif ()
# if (NOT EXISTS "${WIN10SDK_INCLUDE_PATH}/winrt/windows.graphics.printing3d.h")
# message("${WIN10SDK_INCLUDE_PATH}/winrt/windows.graphics.printing3d.h was not found")
# message("STL fixing by the Netfabb service will not be compiled")
# unset(WIN10SDK_INCLUDE_PATH)
# endif()
# endif()
# if(WIN10SDK_INCLUDE_PATH)
# message("Building with Win10 Netfabb STL fixing service support")
# add_definitions(-DHAS_WIN10SDK)
# include_directories(SYSTEM "${WIN10SDK_INCLUDE_PATH}")
# else()
# message("Building without Win10 Netfabb STL fixing service support")
# endif()
# endif()
if (APPLE)
message("OS X SDK Path: ${CMAKE_OSX_SYSROOT}")
if (CMAKE_OSX_DEPLOYMENT_TARGET)
message("OS X Deployment Target: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
else ()
message("OS X Deployment Target: (default)")
endif ()
endif ()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(PkgConfig REQUIRED)
# Boost on Raspberry-Pi does not link to pthreads.
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(DBus REQUIRED)
include_directories(SYSTEM ${DBUS_INCLUDE_DIRS})
endif()
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX)
# Adding -fext-numeric-literals to enable GCC extensions on definitions of quad float literals, which are required by Boost.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals" )
endif()
if ((NOT MSVC OR IS_CLANG_CL) AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
if (IS_CLANG_CL)
# clang-cl reads -Wall as MSVC /Wall, which clang maps to -Weverything. /W4 is
# its -Wall -Wextra and, unlike /clang:-Wall, is ordered with the -Wno-* below
# instead of after them. The -Wextra-only warnings are dropped again so the set
# matches what -Wall gives the GNU/Clang builds.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" )
add_compile_options(-Wno-unused-parameter -Wno-ignored-qualifiers -Wno-missing-field-initializers)
elseif (NOT MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
endif ()
# Every warning is an error unless it appears in one of the two lists below.
# disabled - never wanted. Off everywhere, so it never warns or errors.
# demoted - wanted, not cleared yet. Still warns, does not error.
# Disabled.
set(warnings_disabled
reorder # members initialised in an order we chose
sign-compare # signed/unsigned comparisons throughout
misleading-indentation # false positives on mixed tabs and spaces
switch # unhandled enum value in a switch
unused-function # commented-out or conditionally compiled code
unused-variable # commented-out or conditionally compiled code
unused-but-set-variable # commented-out or conditionally compiled code
unused-label # commented-out or conditionally compiled code
unused-local-typedefs # commented-out or conditionally compiled code
)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(APPEND warnings_disabled deprecated-declarations) # legacy OpenGL calls
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0)
list(APPEND warnings_disabled ignored-attributes) # from Eigen headers marked SYSTEM
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND warnings_disabled unknown-pragmas) # igl pragmas, GCC bug 66943
endif ()
foreach (w IN LISTS warnings_disabled)
add_compile_options(-Wno-${w})
endforeach ()
# GCC is not built in CI, so don't throw errors CI won't catch.
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Werror=return-type)
else ()
# Turn everything else into an error. Dependency headers are exempt because the
# SYSTEM include flag (-imsvc on clang-cl, -isystem elsewhere) keeps their
# diagnostics out.
add_compile_options(-Werror)
endif ()
# Demoted. Remove a name once its category is cleared on every compiler.
set(warnings_demoted)
if (APPLE)
list(APPEND warnings_demoted
# MacDarkMode.mm makes two calls to AppKit's private titlebarViewController
# and one to a wxWidgets category on NSTableColumn whose header is not
# imported. Clearing it means declaring the private selectors ourselves, which
# needs a macOS build to verify.
objc-method-access
)
endif ()
if (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
list(APPEND warnings_demoted
# About two dozen GetProcAddress casts, most in the vendored dark_mode.hpp,
# retype FARPROC to a real signature. The __stdcall typedefs are identical to
# FARPROC on x64, so only arm64 reports them. Clearing them is a separate
# sweep.
cast-function-type-mismatch
)
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(APPEND warnings_demoted
# enum-constexpr-conversion is a Clang warning that defaults to an error,
# present through clang 20 and gone in clang 21.
enum-constexpr-conversion
)
endif ()
# The list mixes names not every compiler has, so add each exception only where the
# compiler knows the warning. Probe with the positive -W<name>, which an unknown
# warning fails on both compilers (GCC errors, Clang reports unknown-warning-option).
# An option that takes a =N argument rejects the bare -W<name>, so fall back to
# -W<name>=1 and demote with the trailing =.
include(CheckCXXCompilerFlag)
foreach (category IN LISTS warnings_demoted)
string(MAKE_C_IDENTIFIER "ORCA_HAS_W_${category}" _orca_has_w)
check_cxx_compiler_flag("-W${category}" ${_orca_has_w})
if (${_orca_has_w})
add_compile_options(-Wno-error=${category})
else ()
check_cxx_compiler_flag("-W${category}=1" ${_orca_has_w}_arg)
if (${${_orca_has_w}_arg})
add_compile_options(-Wno-error=${category}=)
endif ()
endif ()
endforeach ()
# Compress the debug info with zstd to save space in Flatpak CI builds
if(FLATPAK)
if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 13.0) OR
("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0))
add_compile_options(-gz=zstd)
endif()
endif()
endif()
if (SLIC3R_ASAN)
# ASAN should be available on MSVC starting with Visual Studio 2019 16.9
# https://devblogs.microsoft.com/cppblog/address-sanitizer-for-msvc-now-generally-available/
add_compile_options(-fsanitize=address)
if (NOT MSVC)
add_compile_options(-fno-omit-frame-pointer)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fsanitize=address")
else()
add_compile_definitions(_DISABLE_STRING_ANNOTATION=1 _DISABLE_VECTOR_ANNOTATION=1)
endif ()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lasan")
endif ()
endif ()
if (APPLE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new")
endif ()
if(MSVC)
# Ignore truncating casts in initializers & constructors
# https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4305
add_compile_options(/wd4305)
endif()
# Where all the bundled libraries reside?
set(LIBDIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(LIBDIR_BIN ${CMAKE_CURRENT_BINARY_DIR}/src)
message(STATUS "LIBDIR: ${LIBDIR}")
message(STATUS "LIBDIR_BIN: ${LIBDIR_BIN}")
# For the bundled boost libraries (boost::nowide)
include_directories(SYSTEM ${LIBDIR})
# For generated header files
include_directories(SYSTEM ${LIBDIR_BIN}/dev-utils/platform)
# For ligigl
include_directories(SYSTEM ${LIBDIR}/libigl)
if(WIN32)
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
if(MSVC)
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x602 -DBOOST_SYSTEM_USE_UTF8 )
# Force the source code encoding to UTF-8. See OrcaSlicer GH pull request #5583
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
endif(MSVC)
endif(WIN32)
add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE -DWXINTL_NO_GETTEXT_MACRO)
# Disable unsafe implicit wxString to const char* / std::string and vice versa. This implicit conversion breaks the UTF-8 encoding quite often.
add_definitions(-DwxNO_UNSAFE_WXSTRING_CONV)
if (SLIC3R_PROFILE)
message("OrcaSlicer will be built with a Shiny invasive profiler")
add_definitions(-DSLIC3R_PROFILE)
endif ()
# Disable optimization for RelWithDebInfo
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES "/O2")
string(REGEX REPLACE "/O2" "/Od" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endif()
if(CMAKE_CXX_FLAGS_RELWITHDEBINFO MATCHES "/O2")
string(REGEX REPLACE "/O2" "/Od" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES "-O2")
string(REGEX REPLACE "-O2" "-O0" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endif()
if(CMAKE_CXX_FLAGS_RELWITHDEBINFO MATCHES "-O2")
string(REGEX REPLACE "-O2" "-O0" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()
endif()
if(MSVC)
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES "/Ob1")
string(REGEX REPLACE "/Ob1" "/Ob0" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endif()
if(CMAKE_CXX_FLAGS_RELWITHDEBINFO MATCHES "/Ob1")
string(REGEX REPLACE "/Ob1" "/Ob0" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif()
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /RTC1")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /RTC1")
endif()
list(REMOVE_DUPLICATES CMAKE_C_FLAGS_RELWITHDEBINFO)
list(REMOVE_DUPLICATES CMAKE_CXX_FLAGS_RELWITHDEBINFO)
# Find and configure boost
if(SLIC3R_STATIC)
# Use static boost libraries.
set(Boost_USE_STATIC_LIBS ON)
# Use boost libraries linked statically to the C++ runtime.
# set(Boost_USE_STATIC_RUNTIME ON)
else()
add_definitions(-DBOOST_LOG_DYN_LINK)
endif()
#set(Boost_DEBUG ON)
# set(Boost_COMPILER "-mgw81")
# boost::process was introduced first in version 1.64.0,
# boost::beast::detail::base64 was introduced first in version 1.66.0
if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()
set(Boost_NO_SYSTEM_PATHS TRUE)
find_package(Boost 1.83.0 REQUIRED COMPONENTS system filesystem thread log log_setup locale regex chrono atomic date_time iostreams program_options nowide)
# Find and configure Eigen3
find_package(Eigen3 5.0.1 REQUIRED)
add_library(boost_libs INTERFACE)
add_library(boost_headeronly INTERFACE)
if (APPLE)
# BOOST_ASIO_DISABLE_KQUEUE : prevents a Boost ASIO bug on OS X: https://svn.boost.org/trac/boost/ticket/5339
target_compile_definitions(boost_headeronly INTERFACE BOOST_ASIO_DISABLE_KQUEUE)
endif()
if(NOT SLIC3R_STATIC)
target_compile_definitions(boost_headeronly INTERFACE BOOST_LOG_DYN_LINK)
endif()
function(slic3r_remap_configs targets from_Cfg to_Cfg)
if(MSVC)
string(TOUPPER ${from_Cfg} from_CFG)
foreach(tgt ${targets})
if(TARGET ${tgt})
set_target_properties(${tgt} PROPERTIES MAP_IMPORTED_CONFIG_${from_CFG} ${to_Cfg})
endif()
endforeach()
endif()
endfunction()
target_include_directories(boost_headeronly SYSTEM INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(boost_libs INTERFACE boost_headeronly ${Boost_LIBRARIES})
# Find and configure intel-tbb
if(SLIC3R_STATIC)
set(TBB_STATIC 1)
endif()
set(TBB_DEBUG 1)
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO RelWithDebInfo Release "")
find_package(TBB REQUIRED)
# include_directories(SYSTEM ${TBB_INCLUDE_DIRS})
# add_definitions(${TBB_DEFINITIONS})
# if(MSVC)
# # Suppress implicit linking of the TBB libraries by the Visual Studio compiler.
# add_definitions(-D__TBB_NO_IMPLICIT_LINKAGE)
# endif()
# The Intel TBB library will use the std::exception_ptr feature of C++11.
# add_definitions(-DTBB_USE_CAPTURED_EXCEPTION=0)
find_package(OpenSSL REQUIRED)
find_package(CURL REQUIRED)
find_package(Freetype REQUIRED)
if (SLIC3R_GUI)
# LibDataChannel's installed export references its bundled dependencies,
# but does not install their CMake targets. Recreate those targets from
# the same dependency prefix before loading the LibDataChannel config.
if (NOT TARGET Usrsctp::usrsctp)
find_library(_ORCA_USRSCTP_LIBRARY NAMES usrsctp
PATHS "${CMAKE_PREFIX_PATH}/lib" NO_DEFAULT_PATH)
if (_ORCA_USRSCTP_LIBRARY)
add_library(Usrsctp::usrsctp UNKNOWN IMPORTED GLOBAL)
set_target_properties(Usrsctp::usrsctp PROPERTIES
IMPORTED_LOCATION "${_ORCA_USRSCTP_LIBRARY}"
IMPORTED_LINK_INTERFACE_LANGUAGES C
INTERFACE_LINK_LIBRARIES "Threads::Threads")
endif()
endif()
if (NOT TARGET LibJuice::LibJuice)
find_library(_ORCA_LIBJUICE_LIBRARY NAMES juice
PATHS "${CMAKE_PREFIX_PATH}/lib" NO_DEFAULT_PATH)
if (_ORCA_LIBJUICE_LIBRARY)
add_library(LibJuice::LibJuice UNKNOWN IMPORTED GLOBAL)
set_target_properties(LibJuice::LibJuice PROPERTIES
IMPORTED_LOCATION "${_ORCA_LIBJUICE_LIBRARY}"
IMPORTED_LINK_INTERFACE_LANGUAGES C
INTERFACE_LINK_LIBRARIES "Threads::Threads")
endif()
endif()
find_package(LibDataChannel CONFIG REQUIRED)
endif()
add_library(libcurl INTERFACE)
target_link_libraries(libcurl INTERFACE CURL::libcurl)
find_package(ZLIB REQUIRED)
target_link_libraries(libcurl INTERFACE ZLIB::ZLIB)
# Fixing curl's cmake config script bugs
if (NOT WIN32)
# Required by libcurl
#find_package(ZLIB REQUIRED)
#target_link_libraries(libcurl INTERFACE ZLIB::ZLIB)
#find_package(Libssh2 REQUIRED)
#target_link_libraries(libcurl INTERFACE Libssh2::libssh2)
else()
target_link_libraries(libcurl INTERFACE crypt32)
endif()
if (SLIC3R_STATIC AND NOT SLIC3R_STATIC_EXCLUDE_CURL)
if (NOT APPLE)
# libcurl is always linked dynamically to the system libcurl on OSX.
# On other systems, libcurl is linked statically if SLIC3R_STATIC is set.
target_compile_definitions(libcurl INTERFACE CURL_STATICLIB)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
# As of now, our build system produces a statically linked libcurl,
# which links the OpenSSL library dynamically.
find_package(OpenSSL REQUIRED)
message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}")
message("OpenSSL libraries: ${OPENSSL_LIBRARIES}")
target_include_directories(libcurl SYSTEM INTERFACE ${OPENSSL_INCLUDE_DIR})
target_link_libraries(libcurl INTERFACE ${OPENSSL_LIBRARIES})
endif()
endif()
## OPTIONAL packages
# Find expat or use bundled version
# Always use the system libexpat on Linux.
find_package(EXPAT)
if (NOT EXPAT_FOUND)
add_library(expat STATIC
${LIBDIR}/expat/xmlparse.c
${LIBDIR}/expat/xmlrole.c
${LIBDIR}/expat/xmltok.c
)
set(EXPAT_FOUND 1)
set(EXPAT_INCLUDE_DIRS ${LIBDIR}/expat/)
set(EXPAT_LIBRARIES expat)
endif ()
find_package(PNG REQUIRED)
set(OpenGL_GL_PREFERENCE "LEGACY")
find_package(OpenGL REQUIRED)
if(APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL "4.0")
set(OPENGL_LIBRARIES "-framework OpenGL" CACHE STRING "OpenGL framework" FORCE)
endif()
find_package(glfw3 REQUIRED)
# Find the Cereal serialization library
find_package(cereal REQUIRED)
if (NOT TARGET cereal::cereal)
set_target_properties(cereal PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(cereal::cereal ALIAS cereal)
else ()
set_target_properties(cereal::cereal PROPERTIES IMPORTED_GLOBAL TRUE)
endif ()
# l10n
set(L10N_DIR "${SLIC3R_RESOURCES_DIR}/i18n")
set(BBL_L18N_DIR "${CMAKE_CURRENT_SOURCE_DIR}/localization/i18n")
add_custom_target(gettext_make_pot
COMMAND xgettext --keyword=L --keyword=_L --keyword=_u8L --keyword=L_CONTEXT:1,2c --keyword=_L_CONTEXT:1,2c --keyword=_u8L_CONTEXT:1,2c --keyword=_L_PLURAL:1,2 --add-comments=TRN --from-code=UTF-8 --no-location --debug --boost
-f "${BBL_L18N_DIR}/list.txt"
-o "${BBL_L18N_DIR}/OrcaSlicer.pot"
COMMAND hintsToPot ${SLIC3R_RESOURCES_DIR} ${BBL_L18N_DIR}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Generate pot file from strings in the source tree"
)
add_custom_target(gettext_merge_po_with_pot
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Merge localization po with new generated pot file"
)
file(GLOB BBL_L10N_PO_FILES "${BBL_L18N_DIR}/*/OrcaSlicer*.po")
foreach(po_file ${BBL_L10N_PO_FILES})
GET_FILENAME_COMPONENT(po_dir "${po_file}" DIRECTORY)
SET(po_new_file "${po_dir}/OrcaSlicer_.po")
add_custom_command(
TARGET gettext_merge_po_with_pot PRE_BUILD
COMMAND msgmerge -N -o ${po_file} ${po_file} "${BBL_L18N_DIR}/OrcaSlicer.pot"
)
endforeach()
add_custom_target(gettext_po_to_mo
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Generate localization po files (binary) from mo files (texts)"
)
file(GLOB L10N_PO_FILES "${BBL_L18N_DIR}/*/OrcaSlicer*.po")
foreach(po_file ${BBL_L10N_PO_FILES})
GET_FILENAME_COMPONENT(SECOND_FOLDER_ABSOLUTE ${po_file} DIRECTORY)
string(REGEX REPLACE ".*/(.*)" "\\1" po_dir "${SECOND_FOLDER_ABSOLUTE}" )
SET(mo_file "${L10N_DIR}/${po_dir}/OrcaSlicer.mo")
add_custom_command(
TARGET gettext_po_to_mo PRE_BUILD
COMMAND msgfmt ARGS --check-format -o ${mo_file} ${po_file}
#COMMAND msgfmt ARGS --check-compatibility -o ${mo_file} ${po_file}
)
endforeach()
find_package(NLopt 1.4 REQUIRED)
# Use bundled Python from deps instead of system Python
set(_bundled_python_version "3.12.13")
set(_bundled_python_abi "312")
string(REGEX REPLACE "^([0-9]+\\.[0-9]+)\\..*$" "\\1" _bundled_python_version_short "${_bundled_python_version}")
set(_bundled_python_root "${CMAKE_PREFIX_PATH}/libpython")
set(Python3_ROOT_DIR "${_bundled_python_root}" CACHE PATH "Root directory for bundled Python" FORCE)
set(Python3_USE_STATIC_LIBS OFF)
set(Python3_FIND_STRATEGY LOCATION)
set(Python3_FIND_IMPLEMENTATIONS CPython)
if(WIN32)
set(_bundled_python_executable "${_bundled_python_root}/python.exe")
set(_bundled_python_library "${_bundled_python_root}/libs/python${_bundled_python_abi}.lib")
if(EXISTS "${_bundled_python_root}/python_d.exe")
set(_bundled_python_executable "${_bundled_python_root}/python_d.exe")
endif()
if(EXISTS "${_bundled_python_root}/libs/python${_bundled_python_abi}_d.lib")
set(_bundled_python_library "${_bundled_python_root}/libs/python${_bundled_python_abi}_d.lib")
endif()
set(Python3_FIND_REGISTRY NEVER)
set(Python3_EXECUTABLE "${_bundled_python_executable}" CACHE FILEPATH "Bundled Python executable" FORCE)
set(Python3_INCLUDE_DIR "${_bundled_python_root}/include" CACHE PATH "Bundled Python include directory" FORCE)
set(Python3_LIBRARY "${_bundled_python_library}" CACHE FILEPATH "Bundled Python embed import library" FORCE)
elseif(APPLE)
set(Python3_FIND_FRAMEWORK NEVER)
find_program(_bundled_python_executable
NAMES python${_bundled_python_version_short} python3
PATHS "${_bundled_python_root}/bin"
NO_DEFAULT_PATH
)
find_path(_bundled_python_include_dir
NAMES Python.h
PATHS
"${_bundled_python_root}/include/python${_bundled_python_version_short}"
"${_bundled_python_root}/include"
NO_DEFAULT_PATH
)
find_library(_bundled_python_library
NAMES python${_bundled_python_version_short} libpython${_bundled_python_version_short}
PATHS "${_bundled_python_root}/lib"
NO_DEFAULT_PATH
)
if(NOT _bundled_python_executable)
message(FATAL_ERROR "Bundled Python executable not found under ${_bundled_python_root}/bin")
endif()
if(NOT _bundled_python_include_dir)
message(FATAL_ERROR "Bundled Python headers not found under ${_bundled_python_root}/include")
endif()
if(NOT _bundled_python_library)
message(FATAL_ERROR "Bundled Python library not found under ${_bundled_python_root}/lib")
endif()
set(Python3_EXECUTABLE "${_bundled_python_executable}" CACHE FILEPATH "Bundled Python executable" FORCE)
set(Python3_INCLUDE_DIR "${_bundled_python_include_dir}" CACHE PATH "Bundled Python include directory" FORCE)
set(Python3_LIBRARY "${_bundled_python_library}" CACHE FILEPATH "Bundled Python embed library" FORCE)
endif()
find_package(Python3 ${_bundled_python_version} EXACT REQUIRED
COMPONENTS Interpreter Development.Embed
)
# Provide a minimal pybind11::embed target sourced from deps_src/pybind11 headers.
set(PYBIND11_SOURCE_DIR "${CMAKE_SOURCE_DIR}/deps_src/pybind11")
if(NOT EXISTS "${PYBIND11_SOURCE_DIR}/include/pybind11/pybind11.h")
message(FATAL_ERROR "pybind11 headers not found in ${PYBIND11_SOURCE_DIR}. Did you initialize submodules?")
endif()
add_library(pybind11_headers INTERFACE)
target_include_directories(pybind11_headers INTERFACE "${PYBIND11_SOURCE_DIR}/include")
add_library(pybind11::headers ALIAS pybind11_headers)
add_library(pybind11::pybind11 ALIAS pybind11_headers)
add_library(pybind11_embed INTERFACE)
target_link_libraries(pybind11_embed INTERFACE pybind11_headers Python3::Python)
target_compile_definitions(pybind11_embed INTERFACE PYBIND11_SIMPLE_GIL_MANAGEMENT)
add_library(pybind11::embed ALIAS pybind11_embed)
if(SLIC3R_STATIC)
set(OPENVDB_USE_STATIC_LIBS ON)
set(USE_BLOSC TRUE)
endif ()
find_package(OpenVDB 5.0 COMPONENTS openvdb)
if(OpenVDB_FOUND)
slic3r_remap_configs(IlmBase::Half RelWithDebInfo Release)
slic3r_remap_configs(Blosc::blosc RelWithDebInfo Release)
else ()
message(FATAL_ERROR "OpenVDB could not be found with the bundled find module. "
"You can try to specify the find module location of your "
"OpenVDB installation with the OPENVDB_FIND_MODULE_PATH cache variable.")
endif ()
find_path(SPNAV_INCLUDE_DIR spnav.h)
if (SPNAV_INCLUDE_DIR)
find_library(SPNAV_LIB NAMES libspnav.a) # Force linking libspnav statically
if (SPNAV_LIB)
add_definitions(-DHAVE_SPNAV)
message(STATUS "SPNAV library found")
else()
message(STATUS "SPNAV library NOT found, Spacenavd not supported")
endif()
else()
message(STATUS "SPNAV library NOT found, Spacenavd not supported")
endif()
set(TOP_LEVEL_PROJECT_DIR ${PROJECT_SOURCE_DIR})
function(orcaslicer_copy_dlls target config postfix output_dlls)
if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
set(_arch "x64")
elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "X86")
set(_arch "x86")
elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
set(_arch "arm64")
else ()
message(FATAL_ERROR "Unable to detect architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif ()
get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
get_target_property(_alt_out_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
if (_alt_out_dir)
set (_out_dir "${_alt_out_dir}")
message ("set out_dir to _alt_out_dir: ${_out_dir}")
elseif (_is_multi)
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}/${config}")
message ("set out_dir to CMAKE_CURRENT_BINARY_DIR/config: ${_out_dir}")
else ()
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
message ("set out_dir to CMAKE_CURRENT_BINARY_DIR: ${_out_dir}")
endif ()
file(COPY ${TOP_LEVEL_PROJECT_DIR}/deps/GMP/gmp/lib/win-${_arch}/libgmp-10.dll
${TOP_LEVEL_PROJECT_DIR}/deps/MPFR/mpfr/lib/win-${_arch}/libmpfr-4.dll
${TOP_LEVEL_PROJECT_DIR}/deps/WebView2/lib/win-${_arch}/WebView2Loader.dll
DESTINATION ${_out_dir})
# Stage the OCCT toolkits libslic3r links (published as OCCT_LIBS), not whatever the
# deps prefix happens to hold, and fail the configure if one of them is missing.
if (NOT OCCT_LIBS)
message(FATAL_ERROR "OCCT_LIBS is not set; libslic3r must be configured first.")
endif ()
set(_occt_bin "${CMAKE_PREFIX_PATH}/bin/occt")
set(_occt_dlls "")
set(_occt_staged "")
set(_missing_occt "")
foreach (_tk IN LISTS OCCT_LIBS)
if (EXISTS "${_occt_bin}/${_tk}.dll")
list(APPEND _occt_dlls "${_occt_bin}/${_tk}.dll")
list(APPEND _occt_staged "${_out_dir}/${_tk}.dll")
else ()
list(APPEND _missing_occt "${_tk}.dll")
endif ()
endforeach ()
if (_missing_occt)
message(FATAL_ERROR
"OCCT DLLs missing from ${_occt_bin}/: ${_missing_occt}\n"
"Rebuild the dependencies (build_release_vs2022.bat deps) with the same "
"SLIC3R_CAD setting as this project.")
endif ()
file(COPY ${_occt_dlls}
${CMAKE_PREFIX_PATH}/bin/freetype.dll
${CMAKE_PREFIX_PATH}/bin/avformat-61.dll
${CMAKE_PREFIX_PATH}/bin/avcodec-61.dll
${CMAKE_PREFIX_PATH}/bin/swresample-5.dll
${CMAKE_PREFIX_PATH}/bin/swscale-8.dll
${CMAKE_PREFIX_PATH}/bin/avutil-59.dll
DESTINATION ${_out_dir})
set(_dll_list
${_out_dir}/libgmp-10.dll
${_out_dir}/libmpfr-4.dll
${_out_dir}/WebView2Loader.dll
${_out_dir}/freetype.dll
${_out_dir}/avformat-61.dll
${_out_dir}/avcodec-61.dll
${_out_dir}/swresample-5.dll
${_out_dir}/swscale-8.dll
${_out_dir}/avutil-59.dll
)
list(APPEND _dll_list ${_occt_staged})
set(${output_dlls} ${_dll_list} PARENT_SCOPE)
endfunction()
function(orcaslicer_copy_sos target config postfix output_sos)
get_property(_is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
get_target_property(_alt_out_dir ${target} RUNTIME_OUTPUT_DIRECTORY)
if (_alt_out_dir)
set(_out_dir "${_alt_out_dir}")
elseif (_is_multi)
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}/${config}")
else ()
set(_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
endif ()
file(COPY ${CMAKE_PREFIX_PATH}/lib/libavformat.so
${CMAKE_PREFIX_PATH}/lib/libavformat.so.61
${CMAKE_PREFIX_PATH}/lib/libavformat.so.61.1.100
${CMAKE_PREFIX_PATH}/lib/libavcodec.so
${CMAKE_PREFIX_PATH}/lib/libavcodec.so.61
${CMAKE_PREFIX_PATH}/lib/libavcodec.so.61.3.100
${CMAKE_PREFIX_PATH}/lib/libavutil.so
${CMAKE_PREFIX_PATH}/lib/libavutil.so.59
${CMAKE_PREFIX_PATH}/lib/libavutil.so.59.8.100
${CMAKE_PREFIX_PATH}/lib/libswscale.so
${CMAKE_PREFIX_PATH}/lib/libswscale.so.8
${CMAKE_PREFIX_PATH}/lib/libswscale.so.8.1.100
${CMAKE_PREFIX_PATH}/lib/libswresample.so
${CMAKE_PREFIX_PATH}/lib/libswresample.so.5
${CMAKE_PREFIX_PATH}/lib/libswresample.so.5.1.100
DESTINATION ${_out_dir})
set(${output_sos}
${_out_dir}/libavformat.so
${_out_dir}/libavformat.so.61
${_out_dir}/libavformat.so.61.1.100
${_out_dir}/libavcodec.so
${_out_dir}/libavcodec.so.61
${_out_dir}/libavcodec.so.61.3.100
${_out_dir}/libavutil.so
${_out_dir}/libavutil.so.59
${_out_dir}/libavutil.so.59.8.100
${_out_dir}/libswscale.so
${_out_dir}/libswscale.so.8
${_out_dir}/libswscale.so.8.1.100
${_out_dir}/libswresample.so
${_out_dir}/libswresample.so.5
${_out_dir}/libswresample.so.5.1.100
PARENT_SCOPE
)
endfunction()
# Bundled sources set their own warning flags, and a plain -Wall there means /Wall
# (= -Weverything) under clang-cl. Target options are applied after the ones a target
# set on itself, so these win. Targets are discovered rather than listed so a newly
# bundled library needs no maintenance here.
function(orcaslicer_silence_third_party_warnings _dir)
get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
foreach (_subdir IN LISTS _subdirs)
orcaslicer_silence_third_party_warnings("${_subdir}")
endforeach ()
get_property(_targets DIRECTORY "${_dir}" PROPERTY BUILDSYSTEM_TARGETS)
foreach (_target IN LISTS _targets)
get_target_property(_type ${_target} TYPE)
if (NOT _type STREQUAL "INTERFACE_LIBRARY" AND NOT _type STREQUAL "UTILITY")
if (MSVC AND NOT IS_CLANG_CL)
# Drop any level the target set for itself, or -w overrides it and cl
# reports D9025 once per file.
get_target_property(_opts ${_target} COMPILE_OPTIONS)
if (_opts)
string(REGEX REPLACE "/W[0-4]|/Wall" "" _opts "${_opts}")
string(REGEX REPLACE ";;+" ";" _opts "${_opts}")
set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${_opts}")
endif ()
# CMake maps a level into the VS generator's WarningLevel element, while a
# bare -w stays on the command line and trips D9025 there, once per file.
target_compile_options(${_target} PRIVATE /W0)
else ()
target_compile_options(${_target} PRIVATE -w)
endif ()
endif ()
endforeach ()
endfunction()
# libslic3r, OrcaSlicer GUI and the OrcaSlicer executable.
add_subdirectory(deps_src)
if (NOT SLIC3R_BUNDLED_WARNINGS)
orcaslicer_silence_third_party_warnings("${CMAKE_CURRENT_SOURCE_DIR}/deps_src")
endif ()
# Warning level for the targets added below: our sources, plus glad and libvgcode,
# which are vendored but live under src/. The deps_src libraries were configured just
# above. CMP0092 left MSVC without a default level, so it is set here.
if (NOT SLIC3R_WARNINGS)
add_compile_options(-w)
elseif (MSVC AND NOT IS_CLANG_CL)
# /we4715 is C4715, no return from a non-void function, an error on the GNU/Clang
# builds under -Werror. MSVC is not in that model, so this stays a single promoted
# warning.
add_compile_options(/W3 /we4715)
endif ()
add_subdirectory(src)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT OrcaSlicer_app_gui)
add_dependencies(gettext_make_pot hintsToPot)
if(SLIC3R_BUILD_SANDBOXES)
add_subdirectory(sandboxes)
endif()
if(BUILD_TESTS)
add_subdirectory(tests)
if (NOT SLIC3R_BUNDLED_WARNINGS)
# Catch2 is vendored under tests/ and sets its own warning flags too.
orcaslicer_silence_third_party_warnings("${CMAKE_CURRENT_SOURCE_DIR}/tests/catch2")
endif ()
endif()
if (NOT WIN32 AND NOT APPLE)
set(SLIC3R_APP_CMD "orca-slicer")
configure_file(${LIBDIR}/dev-utils/platform/unix/build_appimage.sh.in ${CMAKE_CURRENT_BINARY_DIR}/build_appimage.sh USE_SOURCE_PERMISSIONS @ONLY)
endif()
# Resources install target, configure fhs.hpp on UNIX
if (WIN32)
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "./resources")
if(ORCA_BUNDLED_UV_EXECUTABLE)
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "./resources/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
endif()
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
include(InstallRequiredSystemLibraries)
install (PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ".")
elseif (SLIC3R_FHS)
# CMAKE_INSTALL_FULL_DATAROOTDIR: read-only architecture-independent data root (share)
set(SLIC3R_FHS_RESOURCES "${CMAKE_INSTALL_FULL_DATAROOTDIR}/OrcaSlicer")
install(DIRECTORY ${SLIC3R_RESOURCES_DIR}/ DESTINATION ${SLIC3R_FHS_RESOURCES}
PATTERN "*/udev" EXCLUDE
)
if(ORCA_BUNDLED_UV_EXECUTABLE)
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "${SLIC3R_FHS_RESOURCES}/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
endif()
install(FILES src/dev-utils/platform/unix/com.orcaslicer.OrcaSlicer.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
foreach(SIZE 32 128 192)
install(FILES ${SLIC3R_RESOURCES_DIR}/images/OrcaSlicer_${SIZE}px.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}x${SIZE}/apps RENAME OrcaSlicer.png
)
endforeach()
elseif (CMAKE_MACOSX_BUNDLE)
# install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/OrcaSlicer.app/Contents/resources")
if(ORCA_BUNDLED_UV_EXECUTABLE)
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "${CMAKE_INSTALL_PREFIX}/OrcaSlicer.app/Contents/Resources/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
endif()
else ()
install(FILES src/dev-utils/platform/unix/com.orcaslicer.OrcaSlicer.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/resources/applications)
install(DIRECTORY "${SLIC3R_RESOURCES_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources")
if(ORCA_BUNDLED_UV_EXECUTABLE)
install(PROGRAMS "${ORCA_BUNDLED_UV_EXECUTABLE}" DESTINATION "${CMAKE_INSTALL_PREFIX}/resources/tools/uv" RENAME "${ORCA_BUNDLED_UV_FILENAME}")
endif()
endif ()
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LIBRARY_FILES
${LIBDIR_BIN}/libavformat.so.61
${LIBDIR_BIN}/libavformat.so.61.1.100
${LIBDIR_BIN}/libavcodec.so.61
${LIBDIR_BIN}/libavcodec.so.61.3.100
${LIBDIR_BIN}/libavutil.so.59
${LIBDIR_BIN}/libavutil.so.59.8.100
${LIBDIR_BIN}/libswresample.so.5
${LIBDIR_BIN}/libswresample.so.5.1.100
${LIBDIR_BIN}/libswscale.so.8
${LIBDIR_BIN}/libswscale.so.8.1.100
)
install(FILES ${LIBRARY_FILES} DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endif ()
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.txt DESTINATION ".")
configure_file(${LIBDIR}/dev-utils/platform/unix/fhs.hpp.in ${LIBDIR_BIN}/dev-utils/platform/unix/fhs.hpp)
set (CPACK_PACKAGE_NAME "OrcaSlicer")
set (CPACK_PACKAGE_VENDOR "SoftFever")
set (CPACK_PACKAGE_VERSION_MAJOR "${ORCA_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${ORCA_VERSION_MINOR}")
set (CPACK_PACKAGE_VERSION_PATCH "${ORCA_VERSION_PATCH}")
set (CPACK_PACKAGE_FILE_NAME "OrcaSlicer_Windows_Installer_V${SoftFever_VERSION}")
# Suffix the Windows installer with its target arch so the x64 and arm64 builds
# produce distinct filenames (matches ARCH_SUFFIX in build_orca.yml). Same
# CMAKE_SYSTEM_PROCESSOR mapping used by orcaslicer_copy_dlls() above.
if (WIN32)
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
string (APPEND CPACK_PACKAGE_FILE_NAME "_arm64")
else ()
string (APPEND CPACK_PACKAGE_FILE_NAME "_x64")
endif ()
endif ()
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Orca Slicer is an open source slicer for FDM printers")
set (CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/OrcaSlicer/OrcaSlicer")
set (CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set (CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources/images\\\\OrcaSlicer.ico")
set (CPACK_NSIS_MUI_ICON "${CPACK_PACKAGE_ICON}")
set (CPACK_NSIS_MUI_UNIICON "${CPACK_PACKAGE_ICON}")
set (CPACK_NSIS_INSTALLED_ICON_NAME "$INSTDIR\\\\orca-slicer.exe")
set (CPACK_PACKAGE_CHECKSUM SHA256)
set (CPACK_PACKAGE_INSTALL_REGISTRY_KEY "OrcaSlicer")
set (CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set (CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
# set (CPACK_NSIS_MODIFY_PATH "ON")
set(CPACK_PACKAGE_EXECUTABLES "orca-slicer;OrcaSlicer")
set(CPACK_CREATE_DESKTOP_LINKS "orca-slicer")
set (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt) # must also include in install command
set(CPACK_WIX_UPGRADE_GUID "058245e8-20e0-4a95-9ab7-1acfe17ad511")
set(CPACK_GENERATOR NSIS)
include(CPack)