CMake Build Help for `pyembree`

654 views Asked by At

I am looking for help building pyembree from source with CMake for Windows. Further details for the history of this question are listed here on GitHub. Windows support for pyembree on conda-forge was just removed, so any help that can be provided would be much appreciated!

Installation Instructions

System

Tested on:

OS: Windows 10 x64 Professional, Build 1909 Python: 3.8.10

Steps

  1. Install Microsoft Visual C++ 14.X and Windows 10 SDK. These are required for building cython code.

(NOTE: The version of Microsoft Visual Studio is not the same as the version of Microsoft Visual C++. Visual Studio 2015, 2017, and 2019 all have MSVCv14X build tools. At the time of this writing, installing the Visual Studio 2019 Build Tools with

MSVCv142 - VS 2019 C++ x64/x86 build tools and Windows 10 SDK (10.0.18362.0)

components will suffice (select the Desktop development with C++ Workload if installing Visual Studio 2019).

  1. Install vcpkg in C:\\vcpkg and add the path to your System Environment Variables:
C:
mkdir vcpkg
cd C:\\vcpkg
git clone https://github.com/Microsoft/vcpkg.git
bootstrap-vcpkg.bat
vcpkg integrate install
  1. Install embree2 64-bit:
vcpkg install embree2:x64-windows

NOTE: To date, pyembree still relies on Embree 2 and has not been updated for Embree 3.

  1. Install cmake.

  2. Create your project folder and initialize a virtual environment with venv (Use Python 3.6 - 3.8). In this example, Python 3.8.5 x64-bit is chosen as it is the Python version used in Miniconda py38_4.9.2.

  3. Install the following packages:

py -m pip install numpy cython cmake ninja scikit-build wheel setuptools pyvista pykdtree
  1. Add the following cmake modules to your system cmake modules folder (e.g. C:\Program Files\CMake\share\cmake-3.21\Modules\).

  2. Navigate to <virtual environment folder>\Lib\site-packages and clone the pyembree repo:

git clone https://github.com/scopatz/pyembree.git
  1. Change directories into the pyembree folder and create the following top-level CMakeLists.txt
cmake_minimum_required(VERSION 3.21.0)
project(pyembree
    VERSION 0.1.6
    LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED True)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()

set(CMAKE_TOOLCHAIN_FILE "C:/vcpkg/scripts/buildsystems/vcpkg.cmake")

find_package(PythonExtensions REQUIRED)
find_package(Cython REQUIRED)
find_package(embree 2 CONFIG REQUIRED)

add_subdirectory(${PROJECT_NAME})
  1. Move to the subfolder pyembree and create the following sub-level CMakeLists.txt:
add_cython_target(mesh_construction.pyx CXX)
add_cython_target(rtcore_scene.pyx CXX)
add_cython_target(rtcore.pyx CXX)
add_cython_target(triangles.pyx CXX)

add_library(${PROJECT_NAME} STATIC ${mesh_construction} ${rtcore_scene} ${rtcore} ${triangles})

target_sources(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

target_include_directories(${PROJECT_NAME}
    PUBLIC "<system python path>/include"
    PUBLIC "C:/vcpkg/installed/x64-windows/include/embree2"
    PUBLIC "<virtual environment folder>/Lib/site-packages/numpy/core/include"
)

target_link_directories(${PROJECT_NAME}
    PUBLIC "<system python path>/libs"
    PUBLIC "C:/vcpkg/installed/x64-windows/lib"
    PUBLIC "C:/vcpkg/installed/x64-windows/bin"
    PUBLIC "<virtual environment folder>/Lib/site-packages/numpy/core/lib"
)

target_link_libraries(${PROJECT_NAME}
    embree
)

python_extension_module(${PROJECT_NAME})

install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)

replacing <system python path> (e.g. C:/Program Files/Python38) and <virtual environment folder> accordingly.

  1. Move back to the top-level pyembree folder and create the following setup.py file:
from setuptools import find_packages
from skbuild import setup

import numpy as np
from Cython.Build import cythonize

include_path = [np.get_include()]

ext_modules = cythonize('pyembree/*.pyx', language_level=3, include_path=include_path)
for ext in ext_modules:
    ext.include_dirs = include_path
    ext.libraries = [
        "C:/vcpkg/installed/x86-windows/lib/embree",
        "C:/vcpkg/installed/x86-windows/lib/tbb",
        "C:/vcpkg/installed/x86-windows/lib/tbbmalloc",
        "C:/vcpkg/installed/x86-windows/lib/tbbmalloc_proxy",
]

setup(
    name="pyembree",
    version='0.1.6',
    ext_modules=ext_modules,
    zip_safe=False,
    packages=find_packages(),
    include_package_data=True
)
  1. Add the following line to the top of every *.pyx and *.pxd file in pyembree:
# distutils: language=c++
  1. Build and install pyembree by running the following from the top-level pyembree folder:
py setup.py build
py setup.py install
  1. Finally, install rtree and trimesh:
py -m pip install rtree trimesh

Current Challenge

I am stuck at py setup.py build.

  1. Currently, I need to copy and paste the embree headers and libraries (.lib and .dll) to the source folder (<virtual environment folder>/Lib/site-packages/pyembree) and generated build folder (<virtual environment folder>\Lib\site-packages\pyembree\_skbuild\win-amd64-3.8\cmake-build\pyembree)

Is there a copy files command I can use in CMake?

  1. When running py setup.py build, I get LNK201: unresolved external symbol linker errors for __imp_rtcMapBuffer, __imp_rtc_NewTriangleMesh, and __imp_rtcUnmapBuffer. I believe __imp_ is a DLL construct though, which is only available for the C-Language and shared libraries (not static libraries), so I'm a bit confused.

Any help on this error would be appreciated too!

Creating library _skbuild\win-amd64-3.8\setuptools\temp.win-amd64-3.8\Release\pyembree\mesh_construction.cp38-win_amd64.lib and object _skbuild\win-amd64-3.8\setuptools\temp.win-amd64-3.8\Release\pyembree\mesh_construction.cp38-win_amd64.exp
mesh_construction.obj : error LNK2001: unresolved external symbol __imp_rtcMapBuffer
mesh_construction.obj : error LNK2001: unresolved external symbol __imp_rtcNewTriangleMesh
mesh_construction.obj : error LNK2001: unresolved external symbol __imp_rtcUnmapBuffer
_skbuild\win-amd64-3.8\setuptools\lib.win-amd64-3.8\pyembree\mesh_construction.cp38-win_amd64.pyd : fatal error LNK1120: 3 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\link.exe' failed with exit status 1120
1

There are 1 answers

0
adam.hendry On BEST ANSWER

CMake is actually not required. For complete instructions, please see my solution on Install pyembree on Windows without Conda #468.