Windows MSYS2 构建安装 PyMesh

  • Post author:
  • Post category:其他




1. 前言



关于PyMesh


PyMesh

is a code base developed by Qingnan Zhou for his PhD research at New York University. It is a rapid prototyping platform focused on geometry processing.

PyMesh

is written with both C++ and Python, where computational intensive functionalities are realized in C++, and Python is used for creating minimalistic and easy to use interfaces.

PyMesh GitHub仓库:

GitHub – PyMesh/PyMesh: Geometry Processing Library for Python

在Linux和MacOS中,PyMesh可以使用

setup.py

完成一键安装,但由于依赖库及编译环境所限,在Windows中使用该脚本会导致许多错误,而无法完成编译和安装。

经过多次踩坑,我成功地在Windows中安装运行了PyMesh,在此进行记录。



系统环境

  • Windows 10 20H2
  • MSYS2



2. 环境配置

PyMesh安装指南中涉及到一些系统依赖,这些依赖需要单独安装:

  • Python
  • NumPy
  • SciPy
  • GMP
  • MPFR
  • Boost

本次编译在

MSYS2

环境下进行。开发软件包选择

mingw-w64-x86_64-*

,因此编译产品可以直接在Windows原生环境中运行。

  1. 运行

    MSYS2 MinGW x64

    终端,并运行以下命令安装所需工具:

    # 安装必需的dev库和工具
    pacman -S base-devel msys2-devel
    # 安装MinGW工具链
    pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja
    # 安装Python和依赖库
    pacman -S mingw-w64-x86_64-python3 mingw-w64-x86_64-python-pip mingw-w64-x86_64-python-numpy mingw-w64-x86_64-python-scipy
    # 安装GMP和MPFR所需的m4依赖
    pacman -S m4
    
    # 我的环境配置如下
    $ which make gcc g++ gfortran cmake ninja
    /mingw64/bin/make
    /mingw64/bin/gcc
    /mingw64/bin/g++
    /mingw64/bin/gfortran
    /mingw64/bin/cmake
    /mingw64/bin/ninja
    
  2. 克隆PyMesh仓库。此处建议使用

    FastGit

    代理来加速完整仓库和子模块的克隆。

    git clone https://github.com/PyMesh/PyMesh.git
    cd PyMesh
    git submodule update --init
    
  3. 前往

    pymesh/

    以外的文件夹,在

    Boost

    网站下载、解压、安装Boost。本案例使用

    boost_1_78_0

    演示。

    # 根据自己路径确定
    cd ~/Projects
    wget https://boostorg.jfrog.io/artifactory/main/release/1.78.0/source/boost_1_78_0.zip
    unzip boost_1_78_0.zip
    # 初始化
    cd boost_1_78_0
    ./bootstrap.bat  # 双击运行即可
    # 安装至/usr
    ./b2 --build-dir=./tmp --build-type=complete threading=multi link=static toolset=gcc stage install --prefix=/usr
    
  4. 前往

    pymesh/

    以外的文件夹,下载

    GMP



    MPFR

    的源码。也可以使用CGAL提供的Windows预编译库文件。

    wget https://gmplib.org/download/gmp/gmp-6.2.1.tar.xz
    tar xvf gmp-6.2.1.tar.xz
    wget https://www.mpfr.org/mpfr-current/mpfr-4.1.0.tar.xz
    tar xvf mpfr-4.1.0.tar.xz
    

    (可选)安装MPFR补丁文件:

    cd mpfr-4.1.0/
    wget https://www.mpfr.org/mpfr-current/allpatches
    pacman -S patch
    patch -N -Z -p1 < allpatches
    
  5. 建立临时的库目录来构建GMP和MPFR,也可以使用

    /usr

    作为安装目录。

    mkdir ~/Projects/c
    

至此,环境配置完成。



3. 编译依赖库

第三方依赖库需编译为静态链接库(.lib)。编译过程分为系统依赖库和

PyMesh/third-party

中的第三方依赖库。

在全部编译的过程中,我们尽量很少地使用

setup.py

提供的代码,否则会带来一些麻烦。



编译GMP

cd /path/to/your/gmp
./configure --prefix=~/Projects/c --enable-cxx
make
make check   # 可选,该过程非常耗时
make install



编译MPFR

注意,编译MPFR需要指定GMP的安装路径。

cd /path/to/your/mpfr
./configure --prefix=~/Projects/c --with-gmp=~/Projects/c --disable-shared
make && make install



编译third_party依赖

根据

setup.py

中设置的编译命令,咱们需要编译以下的库:

cgal eigen triangle clipper qhull cork draco tetgen tbb mmg json

。这些库使用

third_party/build.py

进行编译。

在此之前,部分代码文件需要进行修改。以下代码内容中的行号提示,均以完全没有修改过的最最最原始的文件为准。



修改

build.py

# Line 35
# 在build_generic方法中修改build_flags变量,添加一个选项。路径改为自己的
# 环境变量缺啥加啥就行
    build_flags = build_flags + " -DBoost_INCLUDE_DIR=X:/path/to/boost_1_78_0/"

# Line 43
# 为cmake cmd添加一个生成MinGW Makefiles的选项。这个选项不能直接加到字符串里,否则会被split()分开。
    cmdsplit = cmd.split()
    cmdsplit.append('-G "MinGW Makefiles"')
    # subprocess.check_call(cmd.split(), cwd=build_dir);
    subprocess.check_call(cmdsplit, cwd=build_dir);



修改

third_party/cork/src/util/prelude.h

// Line 33
// 添加M_PI的定义
#define M_PI 3.14159265358979323846



修改

third_party/cork/src/isct/fixint.h

// Line 50
// 使用gmp.h代替mpir.h

#ifdef _WIN32
// #include <mpir.h>
#include <gmp.h>



修改

third_party/cork/src/isct/gmpext4.h

// Line 31
// 使用gmp.h代替mpir.h

//#include <mpirxx.h>
#include <gmpxx.h>



修改

third_party/cork/src/mesh/mesh.isct.tpp

// Line 636

// Vec3d raw = mesh->verts[v->ref].pos;
Vec3d raw = TopoCache::mesh->verts[v->ref].pos;



修改

third_party/draco/src/draco/io/parser_utils.cc

// Line 21
// 添加两个头文件

#include <stdexcept>
#include <limits>



修改

third_party/draco/src/draco/core/cycle_timer.h

// Line 22
// 更改timeval结构体定义头

// #include <windows.h>
// typedef LARGE_INTEGER timeval;
#include <sys/time.h>



修改

third_party/draco/src/draco/core/cycle_timer.cc

// Line 19 27 35
// 删除所有 #ifdef _WIN32的宏定义

#ifdef _WIN32
  QueryPerformanceCounter(&tv_end);
  ......
#else
  gettimeofday(&tv_end, NULL);
  ......
#endif

  |
  V

  gettimeofday(&tv_end, NULL);
  ......



修改

third_party/mmg/CMakeLists.txt

# Line 24
# 添加 -fcommon 的CMAKE_C_FLAGS

SET(CMAKE_C_FLAGS " -fcommon ${CMAKE_C_FLAGS}")

完成修改后,执行

./build.py <libname>

进行编译。

./build.py cgal
./build.py eigen
./build.py triangle
./build.py clipper
./build.py qhull
./build.py cork
./build.py draco
./build.py tetgen
./build.py tbb
./build.py mmg
./build.py json



4. 编译安装PyMesh

修改

setup.py

,由于第3步已经完成了第三方依赖的编译安装,因此不需要再次编译了。

# Line 102
# 注释掉编译第三方的代码

#        self.build_third_party()

修改后执行:

./setup.py build

此时命令会报错。

编辑

build_3.x/build.ninja

文件进行排错。这里可以使用记事本的替换功能进行。

  • 将所有

    /wd4251

    字符串删除;

  • 检查

    libgmp



    libmpfr

    的路径是否有错;

  • 查找

    Link the shared library ..\python\pymesh\lib\libPyMesh-CGAL.dll

    字符串,在

    LINK_LIBRARIES

    后添加链接

    -lgmp -lmpfr

      LINK_LIBRARIES = ../python/pymesh/lib/libPyMesh-Mesh.dll.a  ../python/pymesh/third_party/lib/libtbb.dll.a  ../python/pymesh/third_party/lib/libtbbmalloc.dll.a  D:/msys64/usr/lib/libboost_atomic-mgw11-mt-x64-1_78.a  .....  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -lgmp -lmpfr
    
  • 查找

    Link the shared library ..\python\pymesh\lib\libPyMesh-Boolean.dll

    字符串,在

    LINK_LIBRARIES

    后添加链接

    -lgmp -lmpfr

    ,并删除

    LINK_LIBRARIES

    后的GMP与MPFR路径。

编辑完毕后,执行如下命令进行编译:

cd build_3.x
cmake --build . -j <Jobs> --config Release --

修改

setup.py

,由于已经完成了PyMesh的编译,因此不需要再次编译了。

# Line 103
# 注释掉编译PyMesh的代码

#        self.build_pymesh()

修改后执行:

./setup.py install

即完成PyMesh的安装。

遇到其他问题,参考第5部分Notes。



5. Notes



选择GMP还是MPIR?

MPIR是Windows平台兼容GMP的库。一些第三方依赖库在预定义头中判断了当前系统,如果为WIN32则使用

mpir.h

头文件。GMP可以在Windows平台成功编译安装,因此本文选择使用GMP,并对第三方依赖库的源代码进行部分修改。



Cygwin/CMD/Powershell能否完成这些工作?

不能,或者很难,所以另请高明(MSYS)。

许多使用

make

进行编译源码,需要执行

./configure

进行配置,而CMD/Powershell不能像Shell一样执行这些脚本,因此无法进行。




import pymesh

时提示DLL加载错误?

请不要脱离

msys

环境来运行PyMesh。并且记得在

$PATH

中或

$PYTHONPATH

里添加

python/pymesh/lib

路径。PyMesh需要加载

PyMesh-cpython-xxx.pyd

这个库。




pymesh.test()

一共跑了0个测试?

至少在我的机器上是这样,但不影响正常使用。



版权声明:本文为jshazsj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。