phase 1: copy Kindred-only files onto upstream/main (FreeCAD 1.2.0-dev)

Wholesale copy of all Kindred Create additions that don't conflict with
upstream FreeCAD code:

- kindred-icons/ (1444 Catppuccin Mocha SVG icon overrides)
- src/Mod/Create/ (Kindred Create workbench)
- src/Gui/ Kindred source files (FileOrigin, OriginManager,
  OriginSelectorWidget, CommandOrigin, BreadcrumbToolBar, EditingContext)
- src/Gui/Icons/ (Kindred branding and silo icons)
- src/Gui/PreferencePacks/KindredCreate/
- src/Gui/Stylesheets/ (KindredCreate.qss, images_dark-light/)
- package/ (rattler-build recipe)
- docs/ (architecture, guides, specifications)
- .gitea/ (CI workflows, issue templates)
- mods/silo, mods/ztools submodules
- .gitmodules (Kindred submodule URLs)
- resources/ (kindred-create.desktop, kindred-create.xml)
- banner-logo-light.png, CONTRIBUTING.md
This commit is contained in:
forbes
2026-02-13 14:03:58 -06:00
parent 5d81f8ac16
commit 87a0af0b0f
1566 changed files with 32071 additions and 6155 deletions

400
package/debian/build-deb.sh Executable file
View File

@@ -0,0 +1,400 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# Build a .deb package from the installed build directory
#
# This script creates a Debian binary package following Debian Policy Manual guidelines.
# See: https://www.debian.org/doc/debian-policy/
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
# Parse arguments
INSTALL_DIR="${1:-}"
OUTPUT_DIR="${2:-}"
VERSION="${3:-}"
if [ -z "$INSTALL_DIR" ] || [ -z "$OUTPUT_DIR" ]; then
echo "Usage: $0 <install-dir> <output-dir> [version]"
echo " install-dir: Directory containing installed build (e.g., build/release/install)"
echo " output-dir: Directory to write the .deb file"
echo " version: Package version (default: from git describe)"
exit 1
fi
# Validate install directory exists
if [ ! -d "$INSTALL_DIR" ]; then
echo "Error: Install directory does not exist: $INSTALL_DIR"
exit 1
fi
# Get version from git if not provided
if [ -z "$VERSION" ]; then
VERSION=$(cd "$PROJECT_ROOT" && git describe --tags --always 2>/dev/null || echo "0.1.0")
fi
# Convert version to Debian-compatible format
# Debian Policy Manual 5.6.12: version must start with a digit
# Format: [epoch:]upstream_version[-debian_revision]
convert_to_debian_version() {
local ver="$1"
# Remove leading 'v' if present (common in git tags)
ver="${ver#v}"
# Replace hyphens with dots (hyphens have special meaning in Debian versions)
ver="${ver//-/.}"
# If version starts with a letter (e.g., 'weekly'), prefix with '0~'
# The ~ character sorts before anything else, ensuring:
# 0~weekly.2025.01.01 < 0.1.0 < 1.0.0
if [[ "$ver" =~ ^[a-zA-Z] ]]; then
ver="0~${ver}"
fi
echo "$ver"
}
VERSION=$(convert_to_debian_version "$VERSION")
PACKAGE_NAME="kindred-create"
ARCH="amd64"
# Debian package naming: <name>_<version>_<arch>.deb
DEB_NAME="${PACKAGE_NAME}_${VERSION}_${ARCH}"
echo "========================================"
echo "Building Debian package"
echo "========================================"
echo " Package: ${PACKAGE_NAME}"
echo " Version: ${VERSION}"
echo " Arch: ${ARCH}"
echo " Source: ${INSTALL_DIR}"
echo " Output: ${OUTPUT_DIR}/${DEB_NAME}.deb"
echo "========================================"
# Create staging directory
STAGING_DIR=$(mktemp -d)
trap "rm -rf ${STAGING_DIR}" EXIT
# Create debian package structure following Filesystem Hierarchy Standard
mkdir -p "${STAGING_DIR}/DEBIAN"
mkdir -p "${STAGING_DIR}/opt/${PACKAGE_NAME}"
mkdir -p "${STAGING_DIR}/usr/bin"
mkdir -p "${STAGING_DIR}/usr/share/applications"
mkdir -p "${STAGING_DIR}/usr/share/icons/hicolor/scalable/apps"
mkdir -p "${STAGING_DIR}/usr/share/icons/hicolor/48x48/apps"
mkdir -p "${STAGING_DIR}/usr/share/icons/hicolor/256x256/apps"
mkdir -p "${STAGING_DIR}/usr/share/mime/packages"
mkdir -p "${STAGING_DIR}/usr/share/metainfo"
mkdir -p "${STAGING_DIR}/usr/share/doc/${PACKAGE_NAME}"
# Copy installed files
echo "Copying installed files..."
cp -a "${INSTALL_DIR}"/* "${STAGING_DIR}/opt/${PACKAGE_NAME}/"
# Create wrapper scripts in /usr/bin that set up the environment
# The binaries need LD_LIBRARY_PATH to find bundled libraries
cat > "${STAGING_DIR}/usr/bin/kindred-create" << 'WRAPPER'
#!/bin/bash
export KINDRED_CREATE_HOME="/opt/kindred-create"
export LD_LIBRARY_PATH="${KINDRED_CREATE_HOME}/lib:${LD_LIBRARY_PATH:-}"
export QT_PLUGIN_PATH="${KINDRED_CREATE_HOME}/lib/qt6/plugins:${QT_PLUGIN_PATH:-}"
export QT_QPA_PLATFORM_PLUGIN_PATH="${KINDRED_CREATE_HOME}/lib/qt6/plugins/platforms:${QT_QPA_PLATFORM_PLUGIN_PATH:-}"
export PYTHONHOME="${KINDRED_CREATE_HOME}"
export PYTHONPATH="${KINDRED_CREATE_HOME}/lib/python3.11:${KINDRED_CREATE_HOME}/lib/python3.11/site-packages:${PYTHONPATH:-}"
export XDG_DATA_DIRS="${KINDRED_CREATE_HOME}/share:${XDG_DATA_DIRS:-/usr/share}"
export GI_TYPELIB_PATH="${KINDRED_CREATE_HOME}/lib/girepository-1.0:${GI_TYPELIB_PATH:-}"
# XKB keyboard configuration - use bundled data to avoid hardcoded CI paths in libxkbcommon
export XKB_CONFIG_ROOT="${KINDRED_CREATE_HOME}/share/X11/xkb"
# Fontconfig - use bundled configuration to avoid missing default config
export FONTCONFIG_FILE="${KINDRED_CREATE_HOME}/etc/fonts/fonts.conf"
export FONTCONFIG_PATH="${KINDRED_CREATE_HOME}/etc/fonts"
# Qt Wayland fractional scaling — force integer rounding to avoid blurry text
export QT_SCALE_FACTOR_ROUNDING_POLICY=RoundPreferFloor
export QT_ENABLE_HIGHDPI_SCALING=1
# Use system CA certificates so bundled Python trusts internal CAs (e.g. FreeIPA)
# The bundled openssl has a hardcoded cafile from the build environment which
# does not exist on the target system.
if [ -z "${SSL_CERT_FILE:-}" ]; then
for ca in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$ca" ]; then
export SSL_CERT_FILE="$ca"
break
fi
done
fi
# Try different binary names (FreeCAD or freecad depending on build)
if [ -x "${KINDRED_CREATE_HOME}/bin/FreeCAD" ]; then
exec "${KINDRED_CREATE_HOME}/bin/FreeCAD" "$@"
elif [ -x "${KINDRED_CREATE_HOME}/bin/freecad" ]; then
exec "${KINDRED_CREATE_HOME}/bin/freecad" "$@"
else
echo "Error: Cannot find FreeCAD binary in ${KINDRED_CREATE_HOME}/bin/" >&2
exit 1
fi
WRAPPER
chmod 755 "${STAGING_DIR}/usr/bin/kindred-create"
cat > "${STAGING_DIR}/usr/bin/kindred-create-cmd" << 'WRAPPER'
#!/bin/bash
export KINDRED_CREATE_HOME="/opt/kindred-create"
export LD_LIBRARY_PATH="${KINDRED_CREATE_HOME}/lib:${LD_LIBRARY_PATH:-}"
export PYTHONHOME="${KINDRED_CREATE_HOME}"
export PYTHONPATH="${KINDRED_CREATE_HOME}/lib/python3.11:${KINDRED_CREATE_HOME}/lib/python3.11/site-packages:${PYTHONPATH:-}"
# Use system CA certificates (see kindred-create wrapper for details)
if [ -z "${SSL_CERT_FILE:-}" ]; then
for ca in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt; do
if [ -f "$ca" ]; then
export SSL_CERT_FILE="$ca"
break
fi
done
fi
# Try different binary names (FreeCADCmd or freecadcmd depending on build)
if [ -x "${KINDRED_CREATE_HOME}/bin/FreeCADCmd" ]; then
exec "${KINDRED_CREATE_HOME}/bin/FreeCADCmd" "$@"
elif [ -x "${KINDRED_CREATE_HOME}/bin/freecadcmd" ]; then
exec "${KINDRED_CREATE_HOME}/bin/freecadcmd" "$@"
else
echo "Error: Cannot find FreeCADCmd binary in ${KINDRED_CREATE_HOME}/bin/" >&2
exit 1
fi
WRAPPER
chmod 755 "${STAGING_DIR}/usr/bin/kindred-create-cmd"
# Create desktop entry following freedesktop.org specification
cat > "${STAGING_DIR}/usr/share/applications/kindred-create.desktop" << 'EOF'
[Desktop Entry]
Version=1.1
Type=Application
Name=Kindred Create
GenericName=CAD Application
Comment=Engineering-focused parametric 3D CAD platform
Exec=/usr/bin/kindred-create %F
Icon=kindred-create
Terminal=false
Categories=Graphics;Science;Engineering;
MimeType=application/x-extension-fcstd;application/x-freecad;
Keywords=CAD;3D;modeling;engineering;design;parametric;FreeCAD;
StartupNotify=true
StartupWMClass=FreeCAD
EOF
# Copy Kindred branding icons (prefer Kindred logo over FreeCAD default)
if [ -f "${PROJECT_ROOT}/resources/branding/kindred-logo.svg" ]; then
cp "${PROJECT_ROOT}/resources/branding/kindred-logo.svg" \
"${STAGING_DIR}/usr/share/icons/hicolor/scalable/apps/kindred-create.svg"
elif [ -f "${INSTALL_DIR}/share/icons/hicolor/scalable/apps/org.freecad.FreeCAD.svg" ]; then
cp "${INSTALL_DIR}/share/icons/hicolor/scalable/apps/org.freecad.FreeCAD.svg" \
"${STAGING_DIR}/usr/share/icons/hicolor/scalable/apps/kindred-create.svg"
fi
# Generate PNG icons from the Kindred SVG for better desktop integration
if command -v rsvg-convert > /dev/null 2>&1 && \
[ -f "${STAGING_DIR}/usr/share/icons/hicolor/scalable/apps/kindred-create.svg" ]; then
for size in 48 256; do
rsvg-convert -w "$size" -h "$size" \
"${STAGING_DIR}/usr/share/icons/hicolor/scalable/apps/kindred-create.svg" \
-o "${STAGING_DIR}/usr/share/icons/hicolor/${size}x${size}/apps/kindred-create.png" \
2>/dev/null || true
done
else
# Fallback: copy FreeCAD PNGs if available
for size in 48 256; do
if [ -f "${INSTALL_DIR}/share/icons/hicolor/${size}x${size}/apps/org.freecad.FreeCAD.png" ]; then
cp "${INSTALL_DIR}/share/icons/hicolor/${size}x${size}/apps/org.freecad.FreeCAD.png" \
"${STAGING_DIR}/usr/share/icons/hicolor/${size}x${size}/apps/kindred-create.png"
fi
done
fi
# Create MIME type definition for .fcstd files
cat > "${STAGING_DIR}/usr/share/mime/packages/kindred-create.xml" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-freecad">
<comment>FreeCAD Document</comment>
<glob pattern="*.fcstd"/>
<glob pattern="*.FCStd"/>
<icon name="kindred-create"/>
</mime-type>
</mime-info>
EOF
# Create AppStream metainfo for software centers
cat > "${STAGING_DIR}/usr/share/metainfo/kindred-create.metainfo.xml" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>kindred-create</id>
<name>Kindred Create</name>
<summary>Engineering-focused parametric 3D CAD platform</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1-or-later</project_license>
<description>
<p>
Kindred Create is an engineering-focused parametric 3D CAD platform
built on FreeCAD 1.0+. It provides a streamlined interface for
mechanical engineering and product design.
</p>
<p>Features include:</p>
<ul>
<li>Parametric modeling with constraint-based sketcher</li>
<li>Part Design workbench for solid modeling</li>
<li>Assembly workbench for multi-part designs</li>
<li>TechDraw workbench for 2D technical drawings</li>
<li>FEM workbench for finite element analysis</li>
<li>CAM workbench for CNC machining</li>
</ul>
</description>
<launchable type="desktop-id">kindred-create.desktop</launchable>
<url type="homepage">https://gitea.kindred.internal/kindred/create</url>
<url type="bugtracker">https://gitea.kindred.internal/kindred/create/issues</url>
<provides>
<binary>kindred-create</binary>
<binary>kindred-create-cmd</binary>
</provides>
<content_rating type="oars-1.1"/>
<releases>
<release version="${VERSION}" date="$(date +%Y-%m-%d)"/>
</releases>
</component>
EOF
# Create basic copyright file (required by Debian policy)
cat > "${STAGING_DIR}/usr/share/doc/${PACKAGE_NAME}/copyright" << 'EOF'
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Kindred Create
Upstream-Contact: Kindred Team <team@kindred.internal>
Source: https://gitea.kindred.internal/kindred/create
Files: *
Copyright: 2024-2026 Kindred
2001-2024 FreeCAD Contributors
License: LGPL-2.1-or-later
License: LGPL-2.1-or-later
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
.
On Debian systems, the complete text of the GNU Lesser General Public
License can be found in `/usr/share/common-licenses/LGPL-2.1'.
EOF
# Generate control file with actual version
sed "s/\${VERSION}/${VERSION}/" "${SCRIPT_DIR}/control" > "${STAGING_DIR}/DEBIAN/control"
# Calculate and append installed size (in KiB, as required by Debian policy)
INSTALLED_SIZE=$(du -sk "${STAGING_DIR}" | cut -f1)
echo "Installed-Size: ${INSTALLED_SIZE}" >> "${STAGING_DIR}/DEBIAN/control"
# Create postinst script for post-installation setup
cat > "${STAGING_DIR}/DEBIAN/postinst" << 'EOF'
#!/bin/sh
set -e
case "$1" in
configure)
# Update desktop database
if command -v update-desktop-database > /dev/null 2>&1; then
update-desktop-database -q /usr/share/applications 2>/dev/null || true
fi
# Update icon cache
if command -v gtk-update-icon-cache > /dev/null 2>&1; then
gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor 2>/dev/null || true
fi
# Update MIME database
if command -v update-mime-database > /dev/null 2>&1; then
update-mime-database /usr/share/mime 2>/dev/null || true
fi
;;
esac
exit 0
EOF
chmod 755 "${STAGING_DIR}/DEBIAN/postinst"
# Create postrm script for post-removal cleanup
cat > "${STAGING_DIR}/DEBIAN/postrm" << 'EOF'
#!/bin/sh
set -e
case "$1" in
remove|purge)
# Update desktop database
if command -v update-desktop-database > /dev/null 2>&1; then
update-desktop-database -q /usr/share/applications 2>/dev/null || true
fi
# Update icon cache
if command -v gtk-update-icon-cache > /dev/null 2>&1; then
gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor 2>/dev/null || true
fi
# Update MIME database
if command -v update-mime-database > /dev/null 2>&1; then
update-mime-database /usr/share/mime 2>/dev/null || true
fi
;;
esac
exit 0
EOF
chmod 755 "${STAGING_DIR}/DEBIAN/postrm"
# Set proper permissions following Debian policy
# Directories: 755, Files: 644, Executables: 755
echo "Setting file permissions..."
find "${STAGING_DIR}" -type d -exec chmod 755 {} \;
find "${STAGING_DIR}/opt" -type f -exec chmod 644 {} \;
# Make binaries executable
if [ -d "${STAGING_DIR}/opt/${PACKAGE_NAME}/bin" ]; then
find "${STAGING_DIR}/opt/${PACKAGE_NAME}/bin" -type f -exec chmod 755 {} \;
fi
# Make shared libraries executable (required for proper loading)
find "${STAGING_DIR}/opt/${PACKAGE_NAME}" -name "*.so" -type f -exec chmod 755 {} \;
find "${STAGING_DIR}/opt/${PACKAGE_NAME}" -name "*.so.*" -type f -exec chmod 755 {} \;
# Ensure DEBIAN scripts have correct permissions (must be 0555 to 0775)
chmod 755 "${STAGING_DIR}/DEBIAN/postinst"
chmod 755 "${STAGING_DIR}/DEBIAN/postrm"
# Build the .deb package
# --root-owner-group ensures all files are owned by root:root (standard practice)
# -Zxz with -z1 uses fast compression (large packages can take very long with default settings)
mkdir -p "${OUTPUT_DIR}"
echo "Building package (this may take a few minutes for large packages)..."
echo "Staging directory size: $(du -sh "${STAGING_DIR}" | cut -f1)"
dpkg-deb -Zxz -z1 --build --root-owner-group "${STAGING_DIR}" "${OUTPUT_DIR}/${DEB_NAME}.deb"
# Verify the package
echo "Verifying package..."
dpkg-deb --info "${OUTPUT_DIR}/${DEB_NAME}.deb"
# Generate checksums
cd "${OUTPUT_DIR}"
sha256sum "${DEB_NAME}.deb" > "${DEB_NAME}.deb.sha256"
echo ""
echo "========================================"
echo "Package built successfully!"
echo "========================================"
echo " File: ${OUTPUT_DIR}/${DEB_NAME}.deb"
echo " Size: $(ls -lh "${DEB_NAME}.deb" | awk '{print $5}')"
echo " SHA256: $(cat "${DEB_NAME}.deb.sha256" | cut -d' ' -f1)"
echo "========================================"
echo ""
echo "Install with: sudo dpkg -i ${DEB_NAME}.deb"
echo " sudo apt-get install -f # to resolve dependencies"

23
package/debian/control Normal file
View File

@@ -0,0 +1,23 @@
Package: kindred-create
Version: ${VERSION}
Section: science
Priority: optional
Architecture: amd64
Maintainer: Kindred Team <team@kindred.internal>
Homepage: https://gitea.kindred.internal/kindred/create
Description: Engineering-focused parametric 3D CAD platform
Kindred Create is an engineering-focused parametric 3D CAD platform
built on FreeCAD 1.0+. It provides a streamlined interface for
mechanical engineering and product design.
.
Features include:
* Parametric modeling with constraint-based sketcher
* Part Design workbench for solid modeling
* Assembly workbench for multi-part designs
* TechDraw workbench for 2D technical drawings
* FEM workbench for finite element analysis
* CAM workbench for CNC machining
* Import/export of STEP, IGES, STL, and other formats
Depends: libc6 (>= 2.31), libstdc++6 (>= 10), libgl1, libglu1-mesa, libx11-6, libxcb1, libxext6, libxi6, libxmu6, libxrender1, libfreetype6, libfontconfig1
Recommends: calculix-ccx, gmsh, graphviz
Suggests: openscad, povray