docs(dev): Gui module build integration
All checks were successful
Build and Test / build (pull_request) Successful in 1h20m55s

Covers FreeCADGui target definition, dependency chain (fastsignals,
Qt6, Coin3D, PySide6, PyCXX), source file organisation and how to
add new files, theme/stylesheet build-time copying, version constants,
precompiled headers, CMake presets, ccache, and pixi tasks.

Closes #138
This commit is contained in:
2026-02-10 08:36:50 -06:00
parent 5774f42876
commit 779e32e24a
2 changed files with 240 additions and 0 deletions

View File

@@ -27,6 +27,7 @@
- [Code Quality](./development/code-quality.md)
- [Repository Structure](./development/repo-structure.md)
- [Build System](./development/build-system.md)
- [Gui Module Build](./development/gui-build-integration.md)
# Silo Server

View File

@@ -0,0 +1,239 @@
# 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.0")
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
$<$<COMPILE_LANGUAGE:CXX>:"PreCompiled.h">)
endif()
```
`PreCompiled.h` includes `<fastsignals/signal.h>`, 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