diff --git a/.gitignore b/.gitignore index 3199dfd..cac322b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,4 @@ MANIFEST .project .pydevproject *.so - +.idea/* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..622524d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 3.15) +project(prosail_model_fortran LANGUAGES Fortran C) # Langages utilisés + +# Trouvez Python +find_package(Python COMPONENTS Interpreter Development REQUIRED) + +# Obtenir le répertoire des en-têtes NumPy en exécutant un script Python +execute_process( + COMMAND ${Python_EXECUTABLE} -c "import numpy; print(numpy.get_include())" + OUTPUT_VARIABLE NumPy_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _numpy_include_result + ERROR_QUIET # Pour ne pas afficher d'erreur si numpy n'est pas là, on le gère après +) + +if(NOT _numpy_include_result EQUAL "0" OR NOT NumPy_INCLUDE_DIR) + message(FATAL_ERROR "Impossible d'obtenir le répertoire d'inclusion de NumPy via Python. Assurez-vous que NumPy est installé dans l'environnement de build. Output: ${NumPy_INCLUDE_DIR}") +endif() + +message(STATUS "Répertoire d'inclusion NumPy trouvé : ${NumPy_INCLUDE_DIR}") # Pour le débogage + +# Ajoutez le répertoire d'inclusion de NumPy aux chemins d'inclusion de CMake +# Ceci est utile si vous avez du code C/C++ qui inclut directement des en-têtes NumPy +# ou si f2py a besoin d'un indice, bien que f2py le trouve souvent par lui-même. +include_directories(${NumPy_INCLUDE_DIR}) + +# Obtenir le suffixe d'extension Python (ex: .cpython-312-darwin.so) +execute_process( + COMMAND ${Python_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))" + OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _python_ext_suffix_result + ERROR_QUIET +) +if(NOT _python_ext_suffix_result EQUAL "0" OR NOT PYTHON_EXTENSION_SUFFIX) + message(FATAL_ERROR "Impossible d'obtenir le suffixe d'extension Python via sysconfig. Output: ${PYTHON_EXTENSION_SUFFIX}") +endif() +message(STATUS "Suffixe d'extension Python trouvé : ${PYTHON_EXTENSION_SUFFIX}") + +# Définition des fichiers source Fortran +set(FORTRAN_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/MODULE_PRO4SAIL.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/dataSpec_P5B.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/LIDF.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/dladgen.f + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/PRO4SAIL.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/prospect_5B.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/tav_abs.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/volscatt.f90 + ${CMAKE_CURRENT_SOURCE_DIR}/pyprosail/PyPROSAIL.f90 +) + +# Nom du module (doit correspondre à -m _prosail_model) +set(MODULE_NAME _prosail_model) + +# Définir le chemin attendu pour le module compilé +set(F2PY_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +file(MAKE_DIRECTORY ${F2PY_WORKING_DIRECTORY}) +set(COMPILED_MODULE_PATH ${F2PY_WORKING_DIRECTORY}/${MODULE_NAME}${PYTHON_EXTENSION_SUFFIX}) + +# Commande f2py +add_custom_command( + OUTPUT ${COMPILED_MODULE_PATH} + COMMAND ${Python_EXECUTABLE} -m numpy.f2py -c + -m ${MODULE_NAME} + ${FORTRAN_SOURCES} + --build-dir ${CMAKE_CURRENT_BINARY_DIR}/f2py_build_temp + DEPENDS ${FORTRAN_SOURCES} + WORKING_DIRECTORY ${F2PY_WORKING_DIRECTORY} + COMMENT "Construction du module Fortran ${MODULE_NAME} avec f2py" + VERBATIM +) + +# La cible personnalisée dépend du chemin de sortie mis à jour +add_custom_target(f2py_build ALL DEPENDS ${COMPILED_MODULE_PATH}) + +# Installer le module depuis CMAKE_CURRENT_SOURCE_DIR vers le paquet pyprosail +install(FILES ${COMPILED_MODULE_PATH} + DESTINATION pyprosail + COMPONENT Runtime) + +message(STATUS "Chemin attendu du module compilé : ${COMPILED_MODULE_PATH}") \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..723f50b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,50 @@ +[build-system] +requires = [ + "scikit-build-core>=0.10.0", + "numpy", + "setuptools", + "meson", + "ninja" +] +build-backend = "scikit_build_core.build" + +[project] +name = "pyprosail" +version = "1.1.2" +authors = [ + { name = "Robin Wilson", email = "robin@rtwilson.com" }, + { name = "Lukas Valentin Graf" } +] +description = "PyProSAIL is a Python interface to the ProSAIL combined leaf and canopy optical model." +readme = "README.md" +requires-python = ">=3.8" +license = { file = "COPYING" } +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Atmospheric Science", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Software Development :: Libraries :: Python Modules", + "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "numpy", +] + +[project.urls] +Repository = "https://github.com/EOA-team/PyProSAIL" +Documentation = "https://pyprosail.readthedocs.io/en/latest/" + +[tool.scikit-build] +wheel.packages = ["pyprosail"] +build-dir = "build/{wheel_tag}" +install.components = ["Runtime", "Development"] +cmake.build-type = "Release" +cmake.minimum-version = "3.15" +cmake.verbose = true diff --git a/pyprosail.egg-info/.gitignore b/pyprosail.egg-info/.gitignore deleted file mode 100644 index a777665..0000000 --- a/pyprosail.egg-info/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/PKG-INFO -/SOURCES.txt -/dependency_links.txt -/top_level.txt diff --git a/pyprosail/__init__.py b/pyprosail/__init__.py index 4ea070d..4fdc7ac 100644 --- a/pyprosail/__init__.py +++ b/pyprosail/__init__.py @@ -23,7 +23,7 @@ from __future__ import annotations import numpy as np -from _prosail_model import run as run_fortran +from ._prosail_model import run as run_fortran # Common leaf distributions Planophile = (1, 0) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..53b5d41 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +cmake==4.0.0 +meson==1.8.0 +ninja==1.11.1.4 +numpy==2.2.5 +setuptools==78.1.1 +scikit_build_core==0.11.2 diff --git a/setup.py b/setup.py deleted file mode 100644 index 4d82768..0000000 --- a/setup.py +++ /dev/null @@ -1,40 +0,0 @@ - -import setuptools - -from numpy.distutils.core import setup, Extension -from numpy.distutils.misc_util import Configuration - - -# define PROSAIL Fortran library -prosail_fortran_lib = Extension( - name='_prosail_model', - sources = [ - './pyprosail/MODULE_PRO4SAIL.f90', - './pyprosail/dataSpec_P5B.f90', - './pyprosail/LIDF.f90', - './pyprosail/dladgen.f', - './pyprosail/PRO4SAIL.f90', - './pyprosail/prospect_5B.f90', - './pyprosail/tav_abs.f90', - './pyprosail/volscatt.f90', - './pyprosail/PyPROSAIL.f90' - ] -) - -# define Python package setup -setup( - name='pyprosail', - packages=['pyprosail'], - version='1.0.2', - author='Robin Wilson', - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Science/Research", - "Topic :: Scientific/Engineering :: Atmospheric Science", - "Topic :: Scientific/Engineering :: Physics", - "Topic :: Software Development :: Libraries :: Python Modules", - "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", - "Programming Language :: Python3" - ], - ext_modules=[prosail_fortran_lib] -)