diff --git a/.github/workflows/test.yml b/.github/workflows/build.yml similarity index 65% rename from .github/workflows/test.yml rename to .github/workflows/build.yml index 659f4618..fd5690fa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/build.yml @@ -11,9 +11,16 @@ jobs: fail-fast: false matrix: - config: [Release, Debug] + config: + - Release + - Debug + + os: + - macos-latest + - ubuntu-latest + - windows-latest + vtk-system: [true, false] - os: [ubuntu-latest, windows-latest, macos-latest] exclude: - os: macos-latest @@ -25,7 +32,7 @@ jobs: runs-on: ${{ matrix.os }} container: ${{ matrix.os == 'ubuntu-latest' && 'fedora:38' || null }} - name: '๐Ÿงช Test on ${{ matrix.os }} [Config: "${{ matrix.config }}", VTK installed: "${{ matrix.vtk-system }}"]' + name: '๐Ÿงช Test on ${{ matrix.os }} ["${{ matrix.config }}", VTK: "${{ matrix.vtk-system }}"]' steps: - name: ๐Ÿ“ฅ Checkout @@ -40,13 +47,11 @@ jobs: - name: ๐Ÿฆฅ Cache Dependencies uses: actions/cache@v3 with: - key: ${{ matrix.os }}-${{ matrix.config }}-cache - path: | - deps-cache - build + key: test-${{ matrix.os }}-${{ matrix.config }}-${{ matrix.vtk-system }} + path: build - name: ๐Ÿ—๏ธ Compile - run: cmake -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCPM_SOURCE_CACHE=deps-cache -DVIENNALS_BUILD_TESTS=ON -B build && cmake --build build + run: cmake -DVIENNALS_BUILD_TESTS=ON -B build && cmake --build build --config ${{ matrix.config }} - name: ๐Ÿงช Test run: ctest -E "Benchmark|Performance" -C ${{ matrix.config }} --test-dir build diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 4414eb34..3467e948 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -11,20 +11,12 @@ jobs: fail-fast: false matrix: - vtk-system: [true, false] os: [ubuntu-latest, windows-latest, macos-latest] - exclude: - - os: macos-latest - vtk-system: true - - - os: windows-latest - vtk-system: true - runs-on: ${{ matrix.os }} container: ${{ matrix.os == 'ubuntu-latest' && 'fedora:38' || null }} - name: '๐Ÿ Build Bindings on ${{ matrix.os }} [VTK installed: "${{ matrix.vtk-system }}"]' + name: "๐Ÿ Build Bindings on ${{ matrix.os }}" steps: - name: ๐Ÿ“ฅ Checkout @@ -34,7 +26,31 @@ jobs: uses: ./.github/actions/setup with: container: ${{ matrix.os }} - install-vtk: ${{ matrix.vtk-system }} + install-vtk: false - - name: ๐Ÿ Build Python Module - run: pip3 install --user . -v + - name: ๐Ÿฆฅ Cache Dependencies + uses: actions/cache@v3 + with: + key: python-${{ matrix.os }} + path: build + + - name: ๐Ÿ Build and check Python Module (Windows) + if: ${{ matrix.os == 'windows-latest' }} + run: | + python3 -m venv venv + ./venv/Scripts/activate.bat + pip install . + python3 -c "import viennals2d; print(viennals2d.__doc__)" + + - name: ๐Ÿ Build and check Python Module (Other) + if: ${{ matrix.os != 'windows-latest' }} + run: | + python3 -m venv venv + ./venv/bin/pip install . + ./venv/bin/python -c "import viennals2d; print(viennals2d.__doc__)" + + - name: ๐Ÿ“ฆ Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: Pre-Built (${{ matrix.os }}) + path: venv diff --git a/CMakeLists.txt b/CMakeLists.txt index 05d04d0d..c74268b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 @@ -16,16 +16,18 @@ 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) +if(VIENNALS_BUILD_PYTHON) + set(CMAKE_PLATFORM_NO_VERSIONED_SONAME ON) +endif() # -------------------------------------------------------------------------------------------------------- # Configuration @@ -33,6 +35,11 @@ cmake_dependent_option(VIENNALS_BUILD_PYTHON "Build for Python (>=3)" OFF "VIENN 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) @@ -90,12 +97,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) @@ -104,7 +113,9 @@ if(VIENNALS_USE_VTK) enable_language(C) find_package(VTK QUIET) - set(VIENNALS_SYSTEM_VTK ${VTK_FOUND}) + set(VIENNALS_SYSTEM_VTK + ${VTK_FOUND} + CACHE INTERNAL "") CPMFindPackage( NAME VTK @@ -113,6 +124,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" @@ -169,12 +181,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() # -------------------------------------------------------------------------------------------------------- @@ -204,6 +216,7 @@ endif() if(VIENNALS_BUILD_PYTHON) message(STATUS "[ViennaLS] Building Python Bindings") add_subdirectory(python) + return() endif() # -------------------------------------------------------------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..b8d26331 --- /dev/null +++ b/pyproject.toml @@ -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"] diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 1bad547b..c9191239 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -3,6 +3,24 @@ 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) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) + +if(NOT APPLE) + list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN") + list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN/../vtkmodules") + list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN/../viennals.libs") +else() + list(APPEND CMAKE_INSTALL_RPATH "@loader_path") + list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../vtkmodules") + list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../viennals.libs") +endif() + # -------------------------------------------------------------------------------------------------------- # Setup Dependencies # -------------------------------------------------------------------------------------------------------- @@ -10,9 +28,6 @@ add_custom_target(${PROJECT_NAME} ALL) include("../cmake/cpm.cmake") set(PYBIND11_FINDPYTHON ON) -set(PYBIND11_PYTHON_VERSION - 3 - CACHE STRING "Python version") CPMFindPackage( NAME pybind11 @@ -32,55 +47,35 @@ if(CMAKE_LIBRARY_OUTPUT_DIRECTORY) endif() # -------------------------------------------------------------------------------------------------------- -# VTK-Setup +# Binding macro # -------------------------------------------------------------------------------------------------------- -include("../cmake/vtk.cmake") - -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() - -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() - -# -------------------------------------------------------------------------------------------------------- -# Setup 2D-Bindings -# -------------------------------------------------------------------------------------------------------- +macro(setup_binding NAME FLAGS) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${VIENNALS_LIBRARY_OUTPUT_DIR}/${NAME}) + set(MODULE_NAME "_${NAME}") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${VIENNALS_LIBRARY_OUTPUT_DIR}/viennals2d) -set(VIENNALS_PYTHON_MODULE_NAME_2D "_${VIENNALS_PYTHON_MODULE_NAME}2d") + pybind11_add_module("${MODULE_NAME}" "pyWrap.cpp") + add_dependencies(${PROJECT_NAME} ${MODULE_NAME}) -pybind11_add_module("${VIENNALS_PYTHON_MODULE_NAME_2D}" "pyWrap.cpp") -add_dependencies(${PROJECT_NAME} ${VIENNALS_PYTHON_MODULE_NAME_2D}) + target_link_libraries(${MODULE_NAME} PUBLIC ViennaLS) + target_compile_definitions(${MODULE_NAME} PRIVATE ${FLAGS} -DVIENNALS_MODULE_NAME=${MODULE_NAME}) -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}) +setup_binding(viennals2d -DVIENNALS_PYTHON_DIMENSION=2) +setup_binding(viennals3d -DVIENNALS_PYTHON_DIMENSION=3) -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(VIENNALS_LIB_FOLDER "${VIENNALS_LIBRARY_OUTPUT_DIR}/viennals.libs") -set(MODULE_NAME ${VIENNALS_PYTHON_MODULE_NAME_3D}) -configure_file(__init__.py.in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/__init__.py) +if(WIN32 AND NOT VIENNALS_SYSTEM_VTK) + setup_vtk_env(${MODULE_NAME} "${VIENNALS_LIB_FOLDER}") + install(DIRECTORY "${VIENNALS_LIB_FOLDER}" DESTINATION .) +endif() diff --git a/python/__init__.py.in b/python/__init__.py.in index 608ef32c..6c0ff048 100644 --- a/python/__init__.py.in +++ b/python/__init__.py.in @@ -8,31 +8,26 @@ tailored towards scientific simulations. ViennaLS can also be used for visualisation applications, although this is not the main design target. """ -import os import sys -extra_dll_dir = os.path.dirname(__file__) - -if sys.platform == 'win32' and os.path.isdir(extra_dll_dir): - # Add the VTK dll directory +def _windows_dll_path(): - vtk_path = "@VTK_DIR@".replace("/lib/cmake/vtk", "") + import os + import 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")) + vtk_path = vtk.__path__[0] - # Add the directory of the python bindings - - os.add_dll_directory(extra_dll_dir) + additional_paths = [ + vtk_path, + os.path.join(os.path.dirname(vtk_path), 'vtk.libs'), + os.path.join(os.path.dirname(os.path.dirname(__file__)), 'viennals.libs') + ] - # Remove internal symbols + for path in additional_paths: + os.add_dll_directory(path) + os.environ["PATH"] = path + os.pathsep + os.environ["PATH"] - del vtk_path +if sys.platform == "win32": + _windows_dll_path() from .@MODULE_NAME@ import * - -# Remove internal symbols - -del extra_dll_dir diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 7482041e..00000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -mypy \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 64ac22df..00000000 --- a/setup.py +++ /dev/null @@ -1,237 +0,0 @@ -# Original Copyright Notice: -# -# Copyright (c) 2016 The Pybind Development Team, All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# You are under no obligation whatsoever to provide any bug fixes, patches, or -# upgrades to the features, functionality or performance of the source code -# ("Enhancements") to anyone; however, if you choose to make your Enhancements -# available either publicly, or directly to the author of this software, without -# imposing a separate written license agreement for such Enhancements, then you -# hereby grant the following license: a non-exclusive, royalty-free perpetual -# license to install, use, modify, prepare derivative works, incorporate into -# other computer software, distribute, and sublicense such enhancements or -# derivative works thereof, in binary and source code form. - -import os -import re -import shutil -import subprocess -import sys -from pathlib import Path - -from setuptools import Extension, setup -from setuptools.command.build_ext import build_ext - -# Convert distutils Windows platform specifiers to CMake -A arguments -PLAT_TO_CMAKE = { - "win32": "Win32", - "win-amd64": "x64", - "win-arm32": "ARM", - "win-arm64": "ARM64", -} - - -# A CMakeExtension needs a sourcedir instead of a file list. -# The name must be the _single_ output extension from the CMake build. -# If you need multiple extensions, see scikit-build. -class CMakeExtension(Extension): - - def __init__(self, name: str) -> None: - super().__init__(name, sources=[]) - self.sourcedir = os.fspath(Path("").resolve()) - - -class CMakeBuild(build_ext): - - def build_extension(self, ext: CMakeExtension) -> None: - # Must be in this form due to bug in .resolve() only fixed in Python 3.10+ - ext_fullpath = Path.cwd() / self.get_ext_fullpath(ext.name) - extdir = ext_fullpath.parent.resolve() - - # Using this requires trailing slash for auto-detection & inclusion of - # auxiliary "native" libs - - debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug - cfg = "Debug" if debug else "Release" - - # CMake lets you override the generator - we need to check this. - # Can be set with Conda-Build, for example. - cmake_generator = os.environ.get("CMAKE_GENERATOR", "") - - # Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON - # EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code - # from Python. - cmake_args = [ - f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}{os.sep}", - f"-DPYTHON_EXECUTABLE={sys.executable}", - f"-DCMAKE_BUILD_TYPE={cfg}", # not used on MSVC, but no harm - "-DVIENNALS_BUILD_PYTHON=ON", - ] - - build_args = [] - # Adding CMake arguments set as environment variable - # (needed e.g. to build for ARM OSx on conda-forge) - if "CMAKE_ARGS" in os.environ: - cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item] - - if self.compiler.compiler_type != "msvc": - # Using Ninja-build since it a) is available as a wheel and b) - # multithreads automatically. MSVC would require all variables be - # exported for Ninja to pick it up, which is a little tricky to do. - # Users can override the generator with CMAKE_GENERATOR in CMake - # 3.15+. - if not cmake_generator or cmake_generator == "Ninja": - try: - import ninja - - ninja_executable_path = Path(ninja.BIN_DIR) / "ninja" - cmake_args += [ - "-GNinja", - f"-DCMAKE_MAKE_PROGRAM:FILEPATH={ninja_executable_path}", - ] - except ImportError: - pass - - else: - # Single config generators are handled "normally" - single_config = any(x in cmake_generator for x in {"NMake", "Ninja"}) - - # CMake allows an arch-in-generator style for backward compatibility - contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"}) - - # Specify the arch if using MSVC generator, but only if it doesn't - # contain a backward-compatibility arch spec already in the - # generator name. - if not single_config and not contains_arch: - cmake_args += ["-A", PLAT_TO_CMAKE[self.plat_name]] - - # Multi-config generators have a different way to specify configs - if not single_config: - cmake_args += [f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{cfg.upper()}={extdir}"] - build_args += ["--config", cfg] - - if sys.platform.startswith("darwin"): - # Cross-compile support for macOS - respect ARCHFLAGS if set - archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", "")) - if archs: - cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))] - for var in os.environ: - if var.startswith("OpenMP_"): - cmake_args += [f"-D{var}='{os.environ[var]}'"] - - # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level - # across all generators. - if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ: - # self.parallel is a Python 3 only way to set parallel jobs by hand - # using -j in the build_ext call, not supported by pip or PyPA-build. - if hasattr(self, "parallel") and self.parallel: - # CMake 3.12+ only. - build_args += [f"-j{self.parallel}"] - - build_temp = Path(self.build_temp) / ext.name - if not build_temp.exists(): - build_temp.mkdir(parents=True) - - # Configure the project - subprocess.run(["cmake", ext.sourcedir, *cmake_args], cwd=build_temp, check=True) - - # Build dependencies if neccesary - subprocess.run(["cmake", "--build", ".", *build_args], cwd=build_temp, check=True) - - # Build python bindings - subprocess.run(["cmake", "--build", ".", *build_args], cwd=build_temp, check=True) - - # On windows move the generated pyd (dll in disguise) files to the corresponding - # folders. Ideally this should be done in CMake, but we have not yet implemented - # this. - if sys.platform == "win32": - pyd_files = [f for f in os.listdir(extdir) if f.endswith(".pyd")] - for f in pyd_files: - if f.startswith("_viennals2d"): - shutil.move(src=os.path.join(extdir, f), - dst=os.path.join(extdir, "viennals2d", f)) - elif f.startswith("_viennals3d"): - shutil.move(src=os.path.join(extdir, f), - dst=os.path.join(extdir, "viennals3d", f)) - - # Generate stubs (*.pyi files) for autocompletion and type hints - try: - import mypy.stubgen as stubgen - - # Make sure that the extdir is in sys.path so that - # stubgen can be run on packages defined there. - sys.path.insert(0, str(extdir)) - - # Don't create __pycache__ directory - sys.dont_write_bytecode = True - - # Initialize the stubgen parser options - options = stubgen.parse_options([ - "-o", - str(os.path.abspath(extdir)), "-p", "viennals2d", "-p", "viennals3d" - ]) - - # Generate the stubs - stubgen.generate_stubs(options) - - # Remove mypy_cache, if it exists - if os.path.exists(os.path.join(extdir, ".mypy_cache")): - shutil.rmtree(os.path.join(extdir, ".mypy_cache")) - except ModuleNotFoundError: - pass - except ImportError: - pass - - -# The information here can also be placed in setup.cfg - better separation of -# logic and declaration, and simpler if you include description/version in a file. -setup( - name="ViennaLS", - version="2.1.0", - author="Institute for Microelectronics", - author_email="viennals@iue.tuwien.ac.at", - license="MIT", - url="https://github.com/ViennaTools/ViennaLS", - description="A high performance sparse level set library", - long_description= - "ViennaLS is a header-only C++ level set library developed for high performance " - "topography simulations. The main design goals are simplicity and efficiency, " - "tailored towards scientific simulations. ViennaLS can also be used for " - "visualisation applications, although this is not the main design target.", - ext_modules=[CMakeExtension("viennals")], - cmdclass={"build_ext": CMakeBuild}, - zip_safe=False, - setup_requires=[ - 'mypy', - ], - requires=[ - 'vtk', - ], - # extras_require={"test": ["pytest>=6.0"]}, - python_requires=">=3.7", -)