Skip to content

Commit

Permalink
refactor: modernize python bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Curve committed Mar 17, 2024
1 parent aa693ce commit 8fe5057
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 318 deletions.
33 changes: 21 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
project(
ViennaLS
LANGUAGES CXX
VERSION 3.0.0)
VERSION 3.1.0)

# --------------------------------------------------------------------------------------------------------
# Library options
Expand All @@ -16,23 +16,28 @@ option(VIENNALS_STATIC_BUILD "Build dependencies as static libraries" OFF)
option(VIENNALS_ENABLE_SANITIZER "Enable Sanitizer for debug buidlds" OFF)
option(VIENNALS_USE_SANITIZER "Enable Sanitizer (Requires GCC or Clang)" OFF)

option(VIENNALS_BUILD_PYTHON "Build python bindings" OFF)
option(VIENNALS_BUILD_EXAMPLES "Build examples" OFF)
option(VIENNALS_BUILD_TESTS "Build tests" OFF)

# --------------------------------------------------------------------------------------------------------
# Conditional Library options
# Global CMake Configuration └ See:
# https://github.com/ViennaTools/ViennaPS/blob/c76e371817a797dfe2800691f00cb93317b731fa/CMakeLists.txt#L30
# --------------------------------------------------------------------------------------------------------

include(CMakeDependentOption)

cmake_dependent_option(VIENNALS_BUILD_PYTHON "Build for Python (>=3)" OFF "VIENNALS_USE_VTK" OFF)
set(CMAKE_PLATFORM_NO_VERSIONED_SONAME ${VIENNALS_BUILD_PYTHON})

# --------------------------------------------------------------------------------------------------------
# Configuration
# --------------------------------------------------------------------------------------------------------

include("cmake/openmp.cmake")

if(VIENNALS_BUILD_PYTHON)
message(STATUS "[ViennaLS] Using VTK for python bindings")
set(VIENNALS_USE_VTK ON)
endif()

if(VIENNALS_STATIC_BUILD)
message(STATUS "[ViennaLS] Enabling precompiled headers for static build")
set(VIENNALS_PRECOMPILE_HEADERS ON)
Expand Down Expand Up @@ -90,12 +95,14 @@ include("cmake/vtk.cmake")
CPMAddPackage(
NAME PackageProject
VERSION 1.11.1
GIT_REPOSITORY "https://github.com/TheLartians/PackageProject.cmake")
GIT_REPOSITORY "https://github.com/TheLartians/PackageProject.cmake"
EXCLUDE_FROM_ALL ${VIENNALS_BUILD_PYTHON})

CPMFindPackage(
NAME ViennaHRLE
VERSION 0.4.0
GIT_REPOSITORY "https://github.com/ViennaTools/ViennaHRLE")
GIT_REPOSITORY "https://github.com/ViennaTools/ViennaHRLE"
EXCLUDE_FROM_ALL ${VIENNALS_BUILD_PYTHON})

find_package(OpenMP REQUIRED)
target_link_libraries(${PROJECT_NAME} INTERFACE OpenMP::OpenMP_CXX ViennaHRLE)
Expand All @@ -113,6 +120,7 @@ if(VIENNALS_USE_VTK)
GIT_TAG 99bd602bdbe8024c55e8382f7cf1013d42a14601
VERSION 9.0.0
GIT_REPOSITORY "https://gitlab.kitware.com/vtk/vtk"
EXCLUDE_FROM_ALL ${VIENNALS_BUILD_PYTHON}
OPTIONS "VTK_LEGACY_REMOVE ON"
"VTK_SMP_IMPLEMENTATION_TYPE \"OpenMP\""
"VTK_GROUP_ENABLE_Rendering NO"
Expand Down Expand Up @@ -169,12 +177,12 @@ if(VIENNALS_PRECOMPILE_HEADERS)
set(VIENNALS_LINKAGE STATIC)
endif()

add_library(${PROJECT_NAME}_Lib ${VIENNALS_LINKAGE})
add_library(${PROJECT_NAME}::Lib ALIAS ${PROJECT_NAME}_Lib)
add_library(${PROJECT_NAME}Lib ${VIENNALS_LINKAGE})
add_library(${PROJECT_NAME}::Lib ALIAS ${PROJECT_NAME}Lib)

target_link_libraries(${PROJECT_NAME}_Lib PUBLIC ${PROJECT_NAME})
target_sources(${PROJECT_NAME}_Lib PUBLIC "lib/specialisations.cpp")
set_target_properties(${PROJECT_NAME}_Lib PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
target_link_libraries(${PROJECT_NAME}Lib PUBLIC ${PROJECT_NAME})
target_sources(${PROJECT_NAME}Lib PUBLIC "lib/specialisations.cpp")
set_target_properties(${PROJECT_NAME}Lib PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

# --------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -204,6 +212,7 @@ endif()
if(VIENNALS_BUILD_PYTHON)
message(STATUS "[ViennaLS] Building Python Bindings")
add_subdirectory(python)
return()
endif()

# --------------------------------------------------------------------------------------------------------
Expand Down
21 changes: 21 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[build-system]
requires = ["scikit-build-core", "pybind11"]
build-backend = "scikit_build_core.build"

[project]
version = "3.1.0"
name = "ViennaLS_Python"
readme = "README.md"
license = {file = "LICENSE"}
description = "A high performance sparse level set library"
dependencies = ['vtk >= 9.0.0, < 10']

[project.urls]
Homepage = "https://viennatools.github.io/ViennaLS/"
Documentation = "https://viennatools.github.io/ViennaLS/"
Repository = "https://github.com/ViennaTools/ViennaLS"
Issues = "https://github.com/ViennaTools/ViennaLS/issues"

[tool.scikit-build]
build-dir = "build"
cmake.args = ["-DVIENNALS_BUILD_PYTHON=ON"]
70 changes: 25 additions & 45 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ project(ViennaLS_Python LANGUAGES CXX)

add_custom_target(${PROJECT_NAME} ALL)

# --------------------------------------------------------------------------------------------------------
# Global CMake Configuration └ See:
# https://github.com/ViennaTools/ViennaPS/blob/c76e371817a797dfe2800691f00cb93317b731fa/python/CMakeLists.txt#L8
# --------------------------------------------------------------------------------------------------------

set(CMAKE_MACOSX_RPATH ON)

list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN")
list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN/../vtkmodules")

# --------------------------------------------------------------------------------------------------------
# Setup Dependencies
# --------------------------------------------------------------------------------------------------------

include("../cmake/cpm.cmake")

set(PYBIND11_FINDPYTHON ON)
set(PYBIND11_PYTHON_VERSION
3
CACHE STRING "Python version")

CPMFindPackage(
NAME pybind11
Expand All @@ -32,55 +39,28 @@ if(CMAKE_LIBRARY_OUTPUT_DIRECTORY)
endif()

# --------------------------------------------------------------------------------------------------------
# VTK-Setup
# Binding macro
# --------------------------------------------------------------------------------------------------------

include("../cmake/vtk.cmake")
macro(setup_binding NAME FLAGS)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${VIENNALS_LIBRARY_OUTPUT_DIR}/${NAME})
set(MODULE_NAME "_${NAME}")

if(WIN32 AND NOT VIENNALS_SYSTEM_VTK)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${PROJECT_BINARY_DIR}/vtk_env>)
setup_vtk_env(${PROJECT_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
pybind11_add_module("${MODULE_NAME}" "pyWrap.cpp")
add_dependencies(${PROJECT_NAME} ${MODULE_NAME})

if(NOT VIENNALS_SYSTEM_VTK)
message(STATUS "[ViennaLS] Setting VTK_DIR to previously created environment")
# We set `VTK_DIR` to the previously setup environment to ensure that the python script can find
# the library files
set(VTK_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
endif()
target_link_libraries(${MODULE_NAME} PUBLIC ViennaLS)
target_compile_definitions(${MODULE_NAME} PRIVATE ${FLAGS} -DVIENNALS_MODULE_NAME=${MODULE_NAME})

# --------------------------------------------------------------------------------------------------------
# Setup 2D-Bindings
# --------------------------------------------------------------------------------------------------------

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${VIENNALS_LIBRARY_OUTPUT_DIR}/viennals2d)
set(VIENNALS_PYTHON_MODULE_NAME_2D "_${VIENNALS_PYTHON_MODULE_NAME}2d")

pybind11_add_module("${VIENNALS_PYTHON_MODULE_NAME_2D}" "pyWrap.cpp")
add_dependencies(${PROJECT_NAME} ${VIENNALS_PYTHON_MODULE_NAME_2D})

target_link_libraries(${VIENNALS_PYTHON_MODULE_NAME_2D} PUBLIC ViennaLS)
target_compile_definitions(
${VIENNALS_PYTHON_MODULE_NAME_2D}
PRIVATE -DVIENNALS_PYTHON_DIMENSION=2 -DVIENNALS_MODULE_NAME=${VIENNALS_PYTHON_MODULE_NAME_2D})
configure_file(__init__.py.in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/__init__.py)

set(MODULE_NAME ${VIENNALS_PYTHON_MODULE_NAME_2D})
configure_file(__init__.py.in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/__init__.py)
install(TARGETS ${MODULE_NAME} LIBRARY DESTINATION ${NAME})
install(DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/" DESTINATION ${NAME})
endmacro()

# --------------------------------------------------------------------------------------------------------
# Setup 3D-Bindings
# Setup Bindings
# --------------------------------------------------------------------------------------------------------

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${VIENNALS_LIBRARY_OUTPUT_DIR}/viennals3d)
set(VIENNALS_PYTHON_MODULE_NAME_3D "_${VIENNALS_PYTHON_MODULE_NAME}3d")

pybind11_add_module("${VIENNALS_PYTHON_MODULE_NAME_3D}" "pyWrap.cpp")
add_dependencies(${PROJECT_NAME} ${VIENNALS_PYTHON_MODULE_NAME_3D})

target_link_libraries(${VIENNALS_PYTHON_MODULE_NAME_3D} PUBLIC ViennaLS)
target_compile_definitions(
${VIENNALS_PYTHON_MODULE_NAME_3D}
PRIVATE -DVIENNALS_PYTHON_DIMENSION=3 -DVIENNALS_MODULE_NAME=${VIENNALS_PYTHON_MODULE_NAME_3D})

set(MODULE_NAME ${VIENNALS_PYTHON_MODULE_NAME_3D})
configure_file(__init__.py.in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/__init__.py)
setup_binding(viennals2d -DVIENNALS_PYTHON_DIMENSION=2)
setup_binding(viennals3d -DVIENNALS_PYTHON_DIMENSION=3)
30 changes: 7 additions & 23 deletions python/__init__.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,15 @@ tailored towards scientific simulations. ViennaLS can also be used for
visualisation applications, although this is not the main design target.
"""

import os
import sys
from .@MODULE_NAME@ import *

extra_dll_dir = os.path.dirname(__file__)

if sys.platform == 'win32' and os.path.isdir(extra_dll_dir):
# Add the VTK dll directory

vtk_path = "@VTK_DIR@".replace("/lib/cmake/vtk", "")

if vtk_path:
os.add_dll_directory(os.path.abspath("@VTK_DIR@"))
else:
os.add_dll_directory(os.path.join(os.path.abspath("@VTK_DIR@".replace("/lib/cmake/vtk", "")), "bin"))

# Add the directory of the python bindings
def _windows_dll_path():

os.add_dll_directory(extra_dll_dir)

# Remove internal symbols

del vtk_path

from .@MODULE_NAME@ import *
import os
import vtk

# Remove internal symbols
os.add_dll_directory(vtk.__path__)

del extra_dll_dir
if sys.platform == "win32":
_windows_dll_path()
1 change: 0 additions & 1 deletion requirements.txt

This file was deleted.

Loading

0 comments on commit 8fe5057

Please sign in to comment.