From 0abb165583580e2e3639571b41cccd911b2f64d7 Mon Sep 17 00:00:00 2001
From: Lars Bilke <lars.bilke@ufz.de>
Date: Mon, 5 Sep 2022 13:58:39 +0200
Subject: [PATCH] [py] Module works.

```
pip install .
pytest
```
---
 .gitignore                                    |  1 +
 Applications/CLI/CMakeLists.txt               | 47 -------------------
 Applications/CLI/ogs_python_module.py         | 19 --------
 Applications/CMakeLists.txt                   |  4 ++
 Applications/Python/CMakeLists.txt            | 21 +++++++++
 Applications/Python/OpenGeoSys/__init__.py    |  1 +
 .../{CLI => Python}/ogs_python_module.cpp     |  2 +-
 Tests/Python/test_cli.py                      | 18 +++++++
 pyproject.toml                                | 16 +++++++
 .../cmake/DependenciesExternalProject.cmake   |  2 +-
 setup.py                                      | 19 ++++++--
 11 files changed, 78 insertions(+), 72 deletions(-)
 delete mode 100755 Applications/CLI/ogs_python_module.py
 create mode 100644 Applications/Python/CMakeLists.txt
 create mode 100644 Applications/Python/OpenGeoSys/__init__.py
 rename Applications/{CLI => Python}/ogs_python_module.cpp (99%)
 create mode 100644 Tests/Python/test_cli.py

diff --git a/.gitignore b/.gitignore
index a023a253f49..d3e5862f91c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,4 +42,5 @@ nohup.out
 # Python build
 /_skbuild
 *.egg-info/
+/wheelhouse
 .ipynb_checkpoints
diff --git a/Applications/CLI/CMakeLists.txt b/Applications/CLI/CMakeLists.txt
index 742e4be2a96..4d221c96d5d 100644
--- a/Applications/CLI/CMakeLists.txt
+++ b/Applications/CLI/CMakeLists.txt
@@ -45,31 +45,6 @@ if(OGS_USE_PYTHON)
                $<$<BOOL:${BUILD_SHARED_LIBS}>:PRIVATE
                OGS_BUILD_SHARED_LIBS>
     )
-
-    # Create OpenGeoSys python module
-    # https://pybind11.readthedocs.io/en/stable/compiling.html#building-with-cmake
-    if(OGS_BUILD_PYTHON_MODULE)
-        pybind11_add_module(
-            OpenGeoSys MODULE ogs_python_module.cpp
-            CommandLineArgumentParser.cpp
-        )
-
-        # lld linker strips out PyInit_OpenGeoSys symbol. Use standard linker.
-        get_target_property(_link_options OpenGeoSys LINK_OPTIONS)
-        if(_link_options)
-            list(REMOVE_ITEM _link_options -fuse-ld=lld)
-            set_target_properties(
-                OpenGeoSys PROPERTIES LINK_OPTIONS "${_link_options}"
-            )
-        endif()
-
-        target_link_libraries(
-            OpenGeoSys PRIVATE ApplicationsLib BaseLib GitInfoLib tclap
-                               pybind11::pybind11
-        )
-
-        install(TARGETS OpenGeoSys LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-    endif()
 endif()
 
 ogs_add_executable(ogs ogs.cpp CommandLineArgumentParser.cpp)
@@ -94,28 +69,6 @@ target_link_libraries(
 add_test(NAME ogs_no_args COMMAND ogs)
 set_tests_properties(ogs_no_args PROPERTIES WILL_FAIL TRUE LABELS "default")
 
-if(OGS_BUILD_PYTHON_MODULE AND NOT (WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL
-                                              "Release")
-)
-    # TODO: does not work on Windows Release
-    add_test(
-        NAME ogs_python_module
-        COMMAND
-            ${Python_EXECUTABLE}
-            ${CMAKE_CURRENT_SOURCE_DIR}/ogs_python_module.py
-            ${CMAKE_SOURCE_DIR}/Tests/Data/Parabolic/LiquidFlow/Flux/cube_1e3_calculatesurfaceflux.prj
-    )
-    set_tests_properties(
-        ogs_python_module
-        PROPERTIES
-            LABELS
-            "default"
-            ENVIRONMENT_MODIFICATION
-            PYTHONPATH=path_list_append:$<TARGET_FILE_DIR:OpenGeoSys>:${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
-            DISABLED
-            $<NOT:$<TARGET_EXISTS:LiquidFlow>>
-    )
-endif()
 # ---- Installation ----
 install(TARGETS ogs RUNTIME DESTINATION bin)
 
diff --git a/Applications/CLI/ogs_python_module.py b/Applications/CLI/ogs_python_module.py
deleted file mode 100755
index 8f553584fdd..00000000000
--- a/Applications/CLI/ogs_python_module.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# The OpenGeoSys python library will be created in the lib folder of the build
-# directory
-## export PYTHONPATH=$PYTHONPATH:your-build_directory-here/lib
-
-import sys
-import tempfile
-import OpenGeoSys
-
-arguments = ["", sys.argv[1], "-o " + tempfile.mkdtemp()]
-
-print("Python OpenGeoSys.init ...")
-OpenGeoSys.initialize(arguments)
-print("Python OpenGeoSys.executeSimulation ...")
-OpenGeoSys.executeSimulation()
-print("Python OpenGeoSys.finalize() ...")
-OpenGeoSys.finalize()
-print("Python world.")
diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt
index 386e8b3f40d..ce44d2681a9 100644
--- a/Applications/CMakeLists.txt
+++ b/Applications/CMakeLists.txt
@@ -19,3 +19,7 @@ endif() # OGS_BUILD_CLI
 if(OGS_USE_INSITU)
     add_subdirectory(InSituLib)
 endif()
+
+if(OGS_BUILD_PYTHON_MODULE)
+    add_subdirectory(Python)
+endif()
diff --git a/Applications/Python/CMakeLists.txt b/Applications/Python/CMakeLists.txt
new file mode 100644
index 00000000000..0d6bb59652c
--- /dev/null
+++ b/Applications/Python/CMakeLists.txt
@@ -0,0 +1,21 @@
+# Create OpenGeoSys python module
+# https://pybind11.readthedocs.io/en/stable/compiling.html#building-with-cmake
+pybind11_add_module(
+    _cli MODULE ogs_python_module.cpp ../CLI/CommandLineArgumentParser.cpp
+)
+
+# lld linker strips out PyInit_OpenGeoSys symbol. Use standard linker.
+get_target_property(_link_options _cli LINK_OPTIONS)
+if(_link_options)
+    list(REMOVE_ITEM _link_options -fuse-ld=lld)
+    set_target_properties(_cli PROPERTIES LINK_OPTIONS "${_link_options}")
+endif()
+
+target_link_libraries(_cli PRIVATE ApplicationsLib BaseLib GitInfoLib tclap)
+target_include_directories(_cli PRIVATE ../CLI)
+
+set(_cli_dest ${CMAKE_INSTALL_LIBDIR})
+if(SKBUILD)
+    set(_cli_dest .)
+endif()
+install(TARGETS _cli LIBRARY DESTINATION ${_cli_dest})
diff --git a/Applications/Python/OpenGeoSys/__init__.py b/Applications/Python/OpenGeoSys/__init__.py
new file mode 100644
index 00000000000..2ad97321e99
--- /dev/null
+++ b/Applications/Python/OpenGeoSys/__init__.py
@@ -0,0 +1 @@
+from ._cli import *
diff --git a/Applications/CLI/ogs_python_module.cpp b/Applications/Python/ogs_python_module.cpp
similarity index 99%
rename from Applications/CLI/ogs_python_module.cpp
rename to Applications/Python/ogs_python_module.cpp
index 9abbe7a727d..c3e6f190a87 100644
--- a/Applications/CLI/ogs_python_module.cpp
+++ b/Applications/Python/ogs_python_module.cpp
@@ -122,7 +122,7 @@ void finalize()
 }
 
 /// python module name is OpenGeoSys
-PYBIND11_MODULE(OpenGeoSys, m)
+PYBIND11_MODULE(_cli, m)
 {
     m.doc() = "pybind11 ogs example plugin";
     m.def("initialize", &initOGS, "init OGS");
diff --git a/Tests/Python/test_cli.py b/Tests/Python/test_cli.py
new file mode 100644
index 00000000000..7517dfa739b
--- /dev/null
+++ b/Tests/Python/test_cli.py
@@ -0,0 +1,18 @@
+import OpenGeoSys
+import tempfile
+import os
+
+
+def test_init():
+    arguments = [
+        "",
+        f"{os.path.abspath(os.path.dirname(__file__))}/../Data/Parabolic/LiquidFlow/Flux/cube_1e3_calculatesurfaceflux.prj",
+        "-o " + tempfile.mkdtemp(),
+    ]
+
+    print("Python OpenGeoSys.init ...")
+    OpenGeoSys.initialize(arguments)
+    print("Python OpenGeoSys.executeSimulation ...")
+    OpenGeoSys.executeSimulation()
+    print("Python OpenGeoSys.finalize() ...")
+    OpenGeoSys.finalize()
diff --git a/pyproject.toml b/pyproject.toml
index 5c7d0579bbd..754315d212c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,3 +6,19 @@ requires = [
   "ninja; platform_system!='Windows'",
 ]
 build-backend = "setuptools.build_meta"
+
+[tool.pytest.ini_options]
+testpaths = ["Tests"]
+norecursedirs = ["Tests/Data"]
+
+[tool.cibuildwheel]
+archs = "auto64"
+build = "cp310-*"
+skip = "*musllinux*"
+test-extras = "test"
+test-command = "pytest {project}/Tests/Python"
+build-verbosity = "1"
+
+[tool.cibuildwheel.linux]
+manylinux-x86_64-image = "manylinux2014"
+manylinux-aarch64-image = "manylinux2014"
diff --git a/scripts/cmake/DependenciesExternalProject.cmake b/scripts/cmake/DependenciesExternalProject.cmake
index ec14fe15943..5a9c922131b 100644
--- a/scripts/cmake/DependenciesExternalProject.cmake
+++ b/scripts/cmake/DependenciesExternalProject.cmake
@@ -202,7 +202,7 @@ if(OGS_USE_MPI)
     set(HDF5_PREFER_PARALLEL ON)
     list(APPEND _hdf5_options "-DHDF5_ENABLE_PARALLEL=ON")
 endif()
-if(WIN32)
+if(WIN32 OR HDF5_USE_STATIC_LIBRARIES)
     set(HDF5_USE_STATIC_LIBRARIES ON)
     list(APPEND _hdf5_options "-DBUILD_SHARED_LIBS=OFF")
 endif()
diff --git a/setup.py b/setup.py
index 58e18d9ad73..f709460ae90 100644
--- a/setup.py
+++ b/setup.py
@@ -2,13 +2,24 @@ from skbuild import setup
 from setuptools import find_packages
 
 setup(
-    name="ogs",
+    name="OpenGeoSys",
     version="6.4.2",
     description="OpenGeoSys",
     author="OpenGeoSys Community",
     license="BSD-3-Clause",
-    packages=find_packages(where="."),
-    package_dir={"": "."},
-    cmake_args=["-DOGS_BUILD_PROCESSES=SteadyStateDiffusion", "-DOGS_BUILD_UTILS=OFF"],
+    packages=find_packages(where="Applications/Python"),
+    package_dir={"": "Applications/Python"},
+    cmake_install_dir="Applications/Python/OpenGeoSys",
+    extras_require={"test": ["pytest"]},
+    cmake_args=[
+        "-DOGS_BUILD_PROCESSES=LiquidFlow",
+        "-DOGS_BUILD_UTILS=OFF",
+        "-DHDF5_USE_STATIC_LIBRARIES=ON",
+        "-DOGS_BUILD_HDF5=ON",
+        "-DOGS_USE_PYTHON=OFF",  # not possible because manylinux does not provide libpythonX.Y.so
+        "-DOGS_BUILD_PYTHON_MODULE=ON",
+        "-DOGS_BUILD_TESTING=OFF",
+        "-DOGS_INSTALL_DEPENDENCIES=OFF",  # otherwise auditwheel fails
+    ],
     python_requires=">=3.6",
 )
-- 
GitLab