Scripting FreeCAD from an AppImage
Introduction
AppImages are another packaging methods for distributing code with all dependencies included. It’s one of the simpler approaches, there’s no package manager for it, you download the image and go. The FreeCAD AppImages (here) work great and is my typical approach to installation.
One of FreeCADs strengths is the scripting interface. The GUI maps button clicks to commands meaning you can script everything out of the gate (mostly, it’s better than most). AppImages make this only a bit more complicated than native installations.
Credit to Stack Overflow user tompi for the guide: https://stackoverflow.com/questions/67325416/how-to-embed-freecad-in-a-python-virtual-environment
Updated 2025-03-13
- Extract the AppImage into a known location:
> mkdir ${HOME}/.FreeCAD && cd ${HOME}/.FreeCAD
> FreeCAD_1.0.0-conda-Linux-x86_64-py311.AppImage --appimage-extract
- Add FreeCAD.so to the path:
> PYTHONPATH=${PYTHONPATH}:${HOME}/.FreeCAD/squashfs-root/usr/lib
Option 1: Use the included FreeCAD python
FreeCAD.so is compiled as a CPython library so is imported exactly like a normal module. This tripped me up when getting going with the paths.
- Use the FreeCAD python interpreter to make calls:
> ${HOME}/.FreeCAD/squashfs-root/usr/bin/python -c "print('Hello World')"
Hello World
- Link other python libraries by extending the PYTHONPATH. Here I have a virtual environment setup for FreeCAD where I install packages to use with FreeCAD.
> PYTHONPATH=${PYTHONPATH}:${HOME}/.freecad_venv/lib/python3.11/site-packages
Option 2: Setup Paths with a different python environment
I like to use Anaconda to manage binaries, python versions, and virtual environments. To use this method make sure you’re using the same version of python as the app image. When using 3.12 with the 3.11 image I got the following error:
ImportError: ${HOME}.FreeCAD/squashfs-root/usr/lib/./libFreeCADBase.so: undefined symbol:_Py_PackageContext
This means the Python interpreter you’re using is a different ABI version than the one FreeCAD was built with. Stick to the exact Python version used in the AppImage or even use the interpretor in the AppImage.
- Set the PATH_TO_FREECAD_LIBDIR:
export PATH_TO_FREECAD_LIBDIR=${HOME}/.FreeCAD/squashfs-root/usr/lib/
If you skip this step you’ll see:
import FreeCAD as app
ModuleNotFoundError: No module named 'FreeCAD'
Example
${HOME}/.FreeCAD/squashfs-root/usr/bin/python
import FreeCAD
doc = FreeCAD.newDocument()
box = FreeCAD.ActiveDocument.addObject("Part::Box", "TheBox")
FreeCAD.ActiveDocument.recompute()
print("Box created:", box)
doc.saveAs("TheBox.FCStd")
End
One project I’ve built with this makes an SVG into an object which can be used as a cutting tool or embedded into a part. It makes visualization easy and allows rendering the object using the render workbench. There will probably be a write-up coming for that. https://github.com/snhobbs/inkscape-freecad-labels.