# Gui Module Build Integration The `FreeCADGui` shared library is the main GUI module. It contains the origin system, toolbar widgets, 3D viewport, command dispatch, and the Python bridge layer. This page explains how it is built, what it links against, and how to add new source files. ## Target overview ```cmake add_library(FreeCADGui SHARED) ``` Built when `BUILD_GUI=ON` (the default). The output is a shared library installed to `${CMAKE_INSTALL_LIBDIR}`. **CMake file:** `src/Gui/CMakeLists.txt` ## Dependency chain ``` FreeCADGui (SHARED) ├── FreeCADApp (core application module) ├── libfastsignals (STATIC, from src/3rdParty/FastSignals/) ├── Qt6::Core, Widgets, OpenGL, OpenGLWidgets, Network, │ PrintSupport, Svg, SvgWidgets, UiTools, Xml ├── Coin3D / Quarter (3D scene graph) ├── PySide6 / Shiboken6 (Python-Qt bridge, if FREECAD_USE_PYSIDE=ON) ├── PyCXX (C++-Python interop, header-only) ├── Boost (various components) ├── OpenGL ├── yaml-cpp ├── ICU (Unicode) └── (optional) 3Dconnexion, Tracy profiler, VR ``` ### fastsignals fastsignals is built as a **static library** with position-independent code: ``` src/3rdParty/FastSignals/ └── libfastsignals/ ├── CMakeLists.txt # builds libfastsignals.a (STATIC, -fPIC) ├── include/fastsignals/ # public headers (INTERFACE include dir) └── src/ # implementation ``` Linked into FreeCADGui via: ```cmake target_link_libraries(FreeCADGui ... libfastsignals ...) target_include_directories(FreeCADGui SYSTEM PRIVATE ${FastSignals_INCLUDE_DIRS}) ``` The `fastsignals/signal.h` header is also included in `src/Gui/PreCompiled.h` so it is available without explicit `#include` in any Gui source file. ## Source file organisation Source files are grouped into named blocks in `CMakeLists.txt`. Each group becomes a Visual Studio filter / IDE source group. | Group variable | Contains | Origin system files in this group | |----------------|----------|-----------------------------------| | `Command_CPP_SRCS` | Command classes | `CommandOrigin.cpp` | | `Widget_CPP_SRCS` | Toolbar/dock widgets | `OriginSelectorWidget.h/.cpp` | | `Workbench_CPP_SRCS` | Workbench infrastructure | `OriginManager.h/.cpp`, `OriginManagerDialog.h/.cpp` | | `FreeCADGui_CPP_SRCS` | Core Gui classes | `FileOrigin.h/.cpp`, `FileOriginPython.h/.cpp` | All groups are collected into `FreeCADGui_SRCS` and added to the target: ```cmake target_sources(FreeCADGui PRIVATE ${FreeCADGui_SRCS}) ``` ## Adding new source files 1. Create your `.h` and `.cpp` files in `src/Gui/`. 2. Add them to the appropriate source group in `src/Gui/CMakeLists.txt`. For origin system code, follow the existing pattern: - Widget → `Widget_CPP_SRCS` - Command → `Command_CPP_SRCS` - Manager/infrastructure → `Workbench_CPP_SRCS` - Core class → `FreeCADGui_CPP_SRCS` ```cmake SET(FreeCADGui_CPP_SRCS ... MyNewOrigin.cpp MyNewOrigin.h ... ) ``` 3. If the file has a `Q_OBJECT` macro, CMake's `AUTOMOC` handles MOC generation automatically. No manual steps needed. 4. If adding Python bindings via PyCXX, add the `.pyi` stub and register it: ```cmake generate_from_py(MyNewOrigin) ``` 5. If linking a new external library: ```cmake list(APPEND FreeCADGui_LIBS MyNewLibrary) ``` 6. Reconfigure and build: ```bash pixi run configure pixi run build ``` No changes are needed to `CommandOrigin.cpp`, `OriginSelectorWidget.cpp`, or `Workbench.cpp` when adding a new origin — those modules discover origins dynamically through `OriginManager` at runtime. ## Qt integration ### Modules linked QtCore, QtWidgets, QtOpenGL, QtOpenGLWidgets, QtPrintSupport, QtSvg, QtSvgWidgets, QtNetwork, QtUiTools, QtXml. Qt version `>=6.8,<6.9` is specified in `pixi.toml`. ### MOC (Meta Object Compiler) Handled automatically by CMake's `AUTOMOC` for any header containing `Q_OBJECT`. Exception: `GraphvizView` has manual MOC commands due to moc-from-cpp requirements. ### UI files ~100 `.ui` files are compiled by Qt's `uic` into C++ headers. Declared in the `Gui_UIC_SRCS` block. ### Resources Icons are embedded via `Icons/resource.qrc`. Translations use Qt Linguist (`.ts` → `.qm`) with auto-generated resource files. ## Theme and stylesheet build Stylesheets are **copied, not compiled**. The canonical stylesheet is `src/Gui/Stylesheets/KindredCreate.qss`. `src/Gui/Stylesheets/CMakeLists.txt` defines a custom target that copies `.qss` files and SVG/PNG images to the build tree: ```cmake fc_copy_sources(Stylesheets_data "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Gui/Stylesheets" ${Stylesheets_Files} ${Images_Files} ...) ``` `src/Gui/PreferencePacks/CMakeLists.txt` copies the same stylesheet into the preference pack directory using `configure_file(... COPYONLY)`, avoiding a duplicate source: ```cmake configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../Stylesheets/KindredCreate.qss ${CMAKE_BINARY_DIR}/.../PreferencePacks/KindredCreate/KindredCreate.qss COPYONLY) ``` Edit only the canonical file in `Stylesheets/` — the preference pack copy is generated. ## Version constants Defined in the top-level `CMakeLists.txt` and injected as compiler definitions: ```cmake set(KINDRED_CREATE_VERSION "0.1.5") set(FREECAD_VERSION "1.0.0") add_definitions(-DKINDRED_CREATE_VERSION="${KINDRED_CREATE_VERSION}") add_definitions(-DFREECAD_VERSION="${FREECAD_VERSION}") ``` Available in C++ code as preprocessor macros. The Python update checker uses `version.py` generated from `version.py.in` at build time with `configure_file()`. ## Precompiled headers Controlled by `FREECAD_USE_PCH` (off by default in conda builds): ```cmake if(FREECAD_USE_PCH) target_precompile_headers(FreeCADGui PRIVATE $<$:"PreCompiled.h">) endif() ``` `PreCompiled.h` includes ``, all Qt headers (via `QtAll.h`), Coin3D headers, Boost, and Xerces. QSint and Quarter sources are excluded from PCH via `SKIP_PRECOMPILE_HEADERS`. ## Build presets Defined in `CMakePresets.json`: | Preset | Platform | Build type | |--------|----------|------------| | `conda-linux-debug` | Linux | Debug | | `conda-linux-release` | Linux | Release | | `conda-macos-debug` | macOS | Debug | | `conda-macos-release` | macOS | Release | | `conda-windows-debug` | Windows | Debug | | `conda-windows-release` | Windows | Release | All presets use the conda/pixi environment for dependency resolution. ## ccache Enabled by default (`FREECAD_USE_CCACHE=ON`). CMake searches the system PATH for `ccache` at configure time and sets it as the compiler launcher: ```cmake set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") ``` Disable with `-DFREECAD_USE_CCACHE=OFF` if needed. Clear the cache with `ccache -C`. ## Pixi tasks Common build workflow: ```bash pixi run initialize # git submodule update --init --recursive pixi run configure # cmake --preset conda-linux-debug (or platform equivalent) pixi run build # cmake --build build/debug pixi run install # cmake --install build/debug pixi run freecad # launch the built binary pixi run test-kindred # run Kindred addon tests (no build needed) ``` Release variants: `configure-release`, `build-release`, `install-release`, `freecad-release`. ## Key CMake variables | Variable | Default | Effect | |----------|---------|--------| | `BUILD_GUI` | ON | Build FreeCADGui at all | | `FREECAD_USE_CCACHE` | ON | Compiler caching | | `FREECAD_USE_PCH` | OFF (conda) | Precompiled headers | | `FREECAD_USE_PYSIDE` | auto | PySide6 Python-Qt bridge | | `FREECAD_USE_SHIBOKEN` | auto | Shiboken6 binding generator | | `BUILD_VR` | OFF | Oculus VR support | | `BUILD_TRACY_FRAME_PROFILER` | OFF | Tracy profiler integration | ## See also - [Build System](./build-system.md) — general build instructions - [Signal Architecture](../architecture/signal-architecture.md) — how fastsignals integrates at runtime - [Creating a Custom Origin (C++)](../reference/cpp-custom-origin-guide.md) — what to link when adding an origin