From 2e76f3d9938a2d42878d4b7054ba0fffabc93026 Mon Sep 17 00:00:00 2001 From: Nickolai Belakovski Date: Thu, 11 Jan 2024 18:02:07 -0800 Subject: [PATCH] scikit-build-core appears to work Next step is to add a yml using cibuildwheel, and then we can flesh out the tests --- .gitignore | 4 +++ CMakeLists.txt | 30 +++++++++++------ pyproject.toml | 19 ++++------- python/CMakeLists.txt | 41 +++++++++++------------- python/{ => prima}/__init__.py | 2 +- python/{ => prima}/_bounds.py | 0 python/{ => prima}/_linearconstraints.py | 0 python/{ => prima}/_nlconstraints.py | 0 8 files changed, 51 insertions(+), 45 deletions(-) rename python/{ => prima}/__init__.py (99%) rename python/{ => prima}/_bounds.py (100%) rename python/{ => prima}/_linearconstraints.py (100%) rename python/{ => prima}/_nlconstraints.py (100%) diff --git a/.gitignore b/.gitignore index ccc044fb7c..cda60f75f7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ install/ build/ include/ !c/include/ +!python/pybind11/include/ lib/ mod/ @@ -227,3 +228,6 @@ cython_debug/ # Mac files .DS_Store + +# Version file +_version.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 0addaae024..52c96388c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,21 +64,33 @@ endif () # Get the version number find_package(Git) +set(IS_REPO FALSE) if(GIT_EXECUTABLE) # --always means git describe will output the commit hash if no tags are found # This is usually the case for forked repos since they do not clone tags by default. execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE PRIMA_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) -else() - # If git is not available, that may indicate we are building on macports which - # downloads the bundle from github (which uses git archive) and so the version - # number should be in .git-archival.txt - file(STRINGS .git-archival.txt PRIMA_VERSION) - if(PRIMA_VERSION MATCHES "describe") - message(WARNING "No git detected and .git-archival.txt does not contain a version number") - set(PRIMA_VERSION "unknown") + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_RESULT ERROR_QUIET) + if (GIT_RESULT EQUAL 0) + set(IS_REPO TRUE) + endif() +endif() +if(NOT GIT_EXECUTABLE OR NOT IS_REPO) + # If git is not available, or this isn't a repo, that may indicate we are building + # on macports which downloads the bundle from github (which uses git archive) and + # so the version number should be in .git-archival.txt. + # Alternatively it might mean that we're building the Python bindings, in which case + # the version is output in _version.txt. I know, it's complicated. I don't make the rules. + if(EXISTS _version.txt) + file(STRINGS _version.txt PRIMA_VERSION) + else() + file(STRINGS .git-archival.txt PRIMA_VERSION) + if(PRIMA_VERSION MATCHES "describe") + message(WARNING "No git detected and .git-archival.txt does not contain a version number") + set(PRIMA_VERSION "unknown") + endif() endif() endif() diff --git a/pyproject.toml b/pyproject.toml index 167feaa4a1..f3e8acb570 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["scikit-build-core", "pybind11", "numpy"] +requires = ["scikit-build-core", "numpy"] build-backend = "scikit_build_core.build" [project] @@ -8,17 +8,10 @@ dependencies = ["numpy"] dynamic = ["version"] [tool.scikit-build] -cmake.targets = ["prima_pybind"] - - -# VERSION OPTION 1 -# [tool.scikit-build.metadata.version] -# provider = "scikit_build_core.metadata.regex" -# input = "VERSION.txt" -# regex = '(?P[0-9.]+)' -# VERSION OPTION 2 +cmake.targets = ["_prima"] metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" -sdist.include = ["pyVERSION.txt"] +sdist.include = [".git-archival.txt"] +install.components = ["Prima_Python_C_Extension"] + [tool.setuptools_scm] # Section required -version_file = "pyVERSION.txt" -# END VERSION OPTIONS \ No newline at end of file +version_file = "_version.txt" diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index c2c36a635f..b66b2c0345 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -17,35 +17,32 @@ if (NOT _IMPORT_NUMPY EQUAL 0) return() endif () -# This section is cribbed from scipy/meson.build -if(WIN32 AND (CMAKE_C_COMPILER_ID MATCHES "GNU")) - message("MinGW detected, adding compiler and linker flags") - add_link_options(-lucrt -static) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-double-64 -D__USE_MINGW_ANSI_STDIO=1") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__USE_MINGW_ANSI_STDIO=1") -endif() - -if (WIN32) - set (PYTHON_SITE_PACKAGES Lib/site-packages) -else () - set (PYTHON_SITE_PACKAGES ${CMAKE_INSTALL_LIBDIR}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages) -endif () +set(PYBIND11_NEWPYTHON ON) add_subdirectory(pybind11) pybind11_add_module(_prima _prima.cpp) target_include_directories(_prima PRIVATE ${CMAKE_SOURCE_DIR}/c/include) target_link_libraries(_prima PRIVATE primac primaf) target_compile_definitions(_prima PRIVATE VERSION_INFO=${PRIMA_VERSION}) -install (TARGETS _prima DESTINATION ${PYTHON_SITE_PACKAGES}/prima/) -install (FILES __init__.py DESTINATION ${PYTHON_SITE_PACKAGES}/prima/) -install (FILES _nlconstraints.py DESTINATION ${PYTHON_SITE_PACKAGES}/prima/) -install (FILES _linearconstraints.py DESTINATION ${PYTHON_SITE_PACKAGES}/prima/) -install (FILES _bounds.py DESTINATION ${PYTHON_SITE_PACKAGES}/prima/) +# This section is cribbed from scipy/meson.build +if(WIN32 AND (CMAKE_C_COMPILER_ID MATCHES "GNU")) + message(STATUS "MinGW detected, adding compiler and linker flags") + target_link_options(_prima PUBLIC -lucrt -static) + target_compile_options(_prima PUBLIC $<$:-mlong-double-64 -D__USE_MINGW_ANSI_STDIO=1>) + target_compile_options(_prima PUBLIC $<$:-D__USE_MINGW_ANSI_STDIO=1>) +endif() + +install (TARGETS _prima DESTINATION prima/ COMPONENT Prima_Python_C_Extension) +# The following are not added to the component because scikit-build-core automatically +# detects files in python/ and adds them to the wheel. These commands +# are here in case one is building via cmake directory and not via scikit-build-core +file(GLOB SUPPORTING_PY_FILES "${CMAKE_CURRENT_SOURCE_DIR}/prima/*.py") +install (FILES ${SUPPORTING_PY_FILES} DESTINATION prima) macro (prima_add_py_test name) - add_test (NAME example_${name}_python COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/examples/example_${name}.py) - set_tests_properties (example_${name}_python PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_INSTALL_PREFIX}/${PYTHON_SITE_PACKAGES}") + add_test (NAME example_${name}_python COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/examples/${name}_example.py) + # set_tests_properties (example_${name}_python PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_INSTALL_PREFIX}/${PYTHON_SITE_PACKAGES}") if (WIN32) file(TO_NATIVE_PATH "${PROJECT_BINARY_DIR}/bin" _BIN_PATH) set_property(TEST example_${name}_python APPEND PROPERTY ENVIRONMENT "PATH=${_BIN_PATH}\\;$ENV{PATH}") @@ -66,6 +63,6 @@ add_test (NAME python-tests COMMAND ${Python_EXECUTABLE} -m pytest --capture=no WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests ) -set_tests_properties(python-tests - PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_INSTALL_PREFIX}/${PYTHON_SITE_PACKAGES}") +#set_tests_properties(python-tests + #PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_INSTALL_PREFIX}/${PYTHON_SITE_PACKAGES}") diff --git a/python/__init__.py b/python/prima/__init__.py similarity index 99% rename from python/__init__.py rename to python/prima/__init__.py index 1ea3a0d633..98f579a425 100644 --- a/python/__init__.py +++ b/python/prima/__init__.py @@ -1,4 +1,4 @@ -from ._prima import minimize as _minimize +from ._prima import minimize as _minimize, __version__ from ._nlconstraints import NonlinearConstraint, process_single_nl_constraint, process_multiple_nl_constraints from ._linearconstraints import LinearConstraint, process_single_linear_constraint, process_multiple_linear_constraints from ._bounds import process_bounds diff --git a/python/_bounds.py b/python/prima/_bounds.py similarity index 100% rename from python/_bounds.py rename to python/prima/_bounds.py diff --git a/python/_linearconstraints.py b/python/prima/_linearconstraints.py similarity index 100% rename from python/_linearconstraints.py rename to python/prima/_linearconstraints.py diff --git a/python/_nlconstraints.py b/python/prima/_nlconstraints.py similarity index 100% rename from python/_nlconstraints.py rename to python/prima/_nlconstraints.py