问题描述
如何设置嵌入了 FreeCAD 库的 Python 虚拟环境以启用作为模块导入到脚本中的功能?
How do I setup a Python virtual environment with the FreeCAD library embedded as to enable import as a module into scripts?
在使用使用 FreeCAD 库来创建和修改 3D 几何的 Python 脚本时,我想避免使用 FreeCAD GUI 以及依赖于在系统上安装 FreeCAD.我希望 Python 虚拟环境可以使这成为可能.
I would like to avoid using the FreeCAD GUI as well as being dependent on having FreeCAD installed on the system, when working with Python scripts that use FreeCAD libraries to create and modify 3D geometry. I hope a Python virtual environment can make that possible.
我正在 PyCharm 2021.1.1 和 Python 3.8 在 Debian 10 上的 virtualenv 中工作.
I am working in PyCharm 2021.1.1 with Python 3.8 in virtualenv on Debian 10.
我开始使用 FreeCAD 文档作为嵌入脚本的基础:
I started out with FreeCAD documentation for embedding in scripts as a basis:
https://wiki.freecadweb.org/Embedding_FreeCAD
在一次尝试中,我从 Debian 下载并解压了 .deb 包,注意获取每个依赖项所需的正确版本.在另一次尝试中,我复制了 FreeCAD flatpak 安装的内容,因为它应该包含 FreeCAD 依赖的所有库.
In one attempt, I downloaded and unpacked .deb packages from Debian, taking care to get the correct versions required by each dependency. In another attempt, I copied the contents of a FreeCAD flatpak install, as it should contain all the libraries that FreeCAD depends on.
将要导入的库放入虚拟机加工文件夹后,我在各种尝试中使用 sys.path.append() 以及 PyCharm 的 Project Structure 工具指向它们.在这两种情况下,虚拟环境都会检测到 FreeCAD.so 所在的位置,但无法找到其任何依赖项,即使位于同一文件夹中也是如此.显式导入这些依赖项时,每个依赖项都有相同的问题.当导入失败时,这会导致死胡同,因为它没有根据 Python 定义模块导出函数:
After placing the libraries to be imported in the virtual maching folder, I have pointed to them with sys.path.append() as well as PyCharm's Project Structure tool in various attempts. In both cases the virtual environment detects where FreeCAD.so is located, but fails to find any of its dependencies, even when located in the same folder. When importing these dependencies explicitly, each of them have the same issue. This leads to a dead end when an import fails because it does not define a module export function according to Python:
ImportError: dynamic module does not define module export function (PyInit_libnghttp2)
我似乎正在查看一长串损坏的依赖项,即使我提供了所需的库并通知 Python 它们所在的位置.
I seem to be looking at a very long chain of broken dependencies, even though I make the required libraries available and inform Python where they are located.
我很感激有关如何执行此操作的直接说明或指向描述在 Python 虚拟环境中导入 FreeCAD 库的文档的指针,因为我还没有遇到任何具体的内容.
I would appreciate either straight up instructions for how to do this or pointers to documentation that describes importing FreeCAD libraries in Python virtual environments, as I have not come across anything that specific yet.
我之前遇到过几个似乎有类似意图的问题,但没有答案:
I came across a few prior questions which seemed to have similar intent, but no answers:
是否可以嵌入Blender/Python 程序中的 Freecad?
Conda 的类似问题侧重于从主机系统导入库而不是将它们嵌入到虚拟环境中:
Similar questions for Conda focus on importing libraries from the host system rather than embedding them in the virtual environment:
仅在系统路径中包含 FreeCAD一个 conda 虚拟环境
其他人在 FreeCAD 论坛上的问题没有得到解答:
Other people's questions on FreeCAD forums went unanswered:
https://forum.freecadweb.org/viewtopic.php?t=27929
弄清楚这一点是一次很棒的学习经历.将依赖项拼凑在一起的问题在于,要使这种方法奏效,从 FreeCAD 及其依赖项到 Python 解释器及其依赖项的所有内容似乎都需要构建在它们所依赖的相同版本的库上,以避免导致分割使一切陷入瘫痪的故障.这意味着从 Flatpak 安装中获取它所依赖的 FreeCAD 模块和库的想法在理论上并不可怕,因为所有部件都是使用相同的库版本构建在一起的.我只是无法解决它,大概是由于包含的库的位置以及难以识别包含的 Python 解释器的可执行文件.最后,我查看了 FreeCAD AppImage 的内容,结果发现在一个文件夹结构中包含了所需的一切,该结构似乎对 PyCharm 和 Python 对模块和库的期望非常友好.
Figuring this out was a great learning experience. The problem with piecing dependencies together is that for that approach to work out, everything from the FreeCAD and its dependencies to the Python interpreter and its dependencies seems to need to be built on the same versions of the libraries that they depend on to avoid causing segmentation faults that brings everything to a crashing halt. This means that the idea of grabbing FreeCAD modules and libraries it depends on from a Flatpak installation is in theory not horrible, as all parts are built together using the same library versions. I just couldn't make it work out, presumably due to how the included libraries are located and difficulty identifying an executable for the included Python interpreter. In the end, I looked into the contents of the FreeCAD AppImage, and that turned out to have everything needed in a folder structure that appears to be very friendly to what PyCharm and Python expects from modules and libraries.
推荐答案
这是我为让 FreeCAD 与 PyCharm 和 virtualenv 一起工作所做的工作:
This is what I did to get FreeCAD to work with PyCharm and virtualenv:
下载 FreeCAD AppImage
Download FreeCAD AppImage
https://www.freecadweb.org/downloads.php
使 AppImage 可执行
Make AppImage executable
chmod -v +x ~/Downloads/FreeCAD_*.AppImage
创建用于提取 AppImage 的文件夹
Create folder for extracting AppImage
mkdir -v ~/Documents/freecad_appimage
从文件夹中提取 AppImage(注意:这会扩展到接近 30000 个文件,需要超过 2 GB 的磁盘空间)
Extract AppImage from folder (note: this expands to close to 30000 files requiring in excess of 2 GB disk space)
cd ~/Documents/freecad_appimage
~/Downloads/./FreeCAD_*.AppImage --appimage-extract
为 PyCharm 项目创建文件夹
Create folder for PyCharm project
mkdir -v ~/Documents/pycharm_freecad_project
使用 Python 解释器从提取的 AppImage 中创建 pycharm 项目
Create pycharm project using Python interpreter from extracted AppImage
Location: ~/Documents/pycharm_freecad_project
New environment using: Virtualenv
Location: ~/Documents/pycharm_freecad_project/venv
Base interpreter: ~/Documents/freecad_appimage/squashfs-root/usr/bin/python
Inherit global site-packages: False
Make available to all projects: False
将包含 FreeCAD.so 库的文件夹作为内容根添加到 PyCharm 项目结构并标记为源(这样做,您不必设置 PYTHONPATH 或 sys.path 值,因为 PyCharm 向解释器提供模块位置信息)
Add folder containing FreeCAD.so library as Content Root to PyCharm Project Structure and mark as Sources (by doing so, you shouldn't have to set PYTHONPATH or sys.path values, as PyCharm provides module location information to the interpreter)
File: Settings: Project: Project Structure: Add Content Root
~/Documents/freecad_appimage/squashfs-root/usr/lib
此后 PyCharm 忙于索引文件一段时间.
After this PyCharm is busy indexing files for a while.
在 PyCharm 中打开 Python 控制台并运行命令以检查基本功能
Open Python Console in PyCharm and run command to check basic functioning
import FreeCAD
使用示例功能创建 python 脚本
Create python script with example functionality
import FreeCAD
vec = FreeCAD.Base.Vector(0, 0, 0)
print(vec)
运行脚本
调试脚本
到目前为止,我在脚本中使用的所有 FreeCAD 功能都有效.然而,一个问题似乎是 FreeCAD 模块需要在 Path 模块之前导入.否则 Python 解释器会以代码 139 退出(被信号 11:SIGSEGV 中断).
All FreeCAD functionality I have used in my scripts so far has worked. However, one kink seems to be that the FreeCAD module needs to be imported before the Path module. Otherwise the Python interpreter exits with code 139 (interrupted by signal 11: SIGSEGV).
PyCharm 有几个问题:它在导入名称下显示一条红色波浪线,并声称由于没有名为‘FreeCAD’的模块"而发生错误,即使脚本运行正常.此外,PyCharm 无法在代码视图中提供代码完成,即使它设法在其 Python 控制台中这样做.我正在创建新问题来解决这些问题,如果找到解决方案,我会在此处更新信息.
There are a couple of issues with PyCharm: It is showing a red squiggly line under the import name and claiming that an error has happened because "No module named 'FreeCAD'", even though the script is running perfectly. Also, PyCharm fails to provide code completion in the code view, even though it manages to do so in it's Python Console. I am creating new questions to address those issues and will update info here if I find a solution.
这篇关于如何在 Python 虚拟环境中嵌入 FreeCAD?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!