From ce13c06ec49f9b9e2ae16391d8360b8b2c1daed1 Mon Sep 17 00:00:00 2001
From: thibault allenet <thibault.allenet@cea.fr>
Date: Tue, 14 May 2024 14:34:09 +0000
Subject: [PATCH] DEV - Initial commit on cmake adjustments, manifest.in, toml,
 script building aidge_core

---
 ...uildwheel_build_deps_before_build_wheel.sh | 28 ++++++
 CMakeLists.txt                                | 14 +--
 MANIFEST.in                                   |  7 ++
 cmake/PybindModuleCreation.cmake              | 51 ++++++----
 pyproject.toml                                | 61 ++++++++++++
 setup.py                                      | 99 ++++++++++---------
 6 files changed, 180 insertions(+), 80 deletions(-)
 create mode 100644 .gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh
 create mode 100644 MANIFEST.in
 create mode 100644 pyproject.toml

diff --git a/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh b/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh
new file mode 100644
index 0000000..dde9ca9
--- /dev/null
+++ b/.gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+set -x
+set -e
+echo $AIDGE_DEPENDENCIES
+if [[ $AIDGE_DEPENDENCIES ==  "" ]]; then # case for aidge_ core
+  mkdir -p build # creating build if its not already there to hold the build of cpp files
+  rm -rf build/* # build from scratch
+else 
+  for repo in $AIDGE_DEPENDENCIES ; do # case for other projects
+    REPO_PATH=$(find /host/data1/is156025/tb256203/dev/eclipse_aidge/aidge_latest/ -type d -name $repo \
+                                -not -path '*install*' \
+                                -not -path '*.git*' \
+                                -not -path '*miniconda*' \
+                                -not -path '*conda*' \
+                                -not -path '*.local*' \
+                                -not -path "*lib*" \
+                                -not -path "*/$repo/$repo" \
+                                -print -quit) 
+
+    cd $REPO_PATH
+    mkdir -p build # creating build if its not already there to hold the build of cpp files
+    rm -rf build/* # build from scratch
+    pip install . -v
+    cd -
+  done
+fi
+set +x
+set +e
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 89926ea..27c40f2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,7 +14,7 @@ project(${project})
 
 ##############################################
 # Define options
-option(PYBIND "python binding" ON)
+option(PYBIND "python binding" OFF)
 option(WERROR "Warning as error" OFF)
 option(TEST "Enable tests" ON)
 option(COVERAGE "Enable coverage" OFF)
@@ -22,7 +22,6 @@ option(COVERAGE "Enable coverage" OFF)
 ##############################################
 # Import utils CMakeLists
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
-include(PybindModuleCreation)
 
 if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE)
     Include(CodeCoverage)
@@ -63,15 +62,8 @@ target_include_directories(${module_name}
 
 # PYTHON BINDING
 if (PYBIND)
-    generate_python_binding(${project} ${module_name})
-
-    # Handles Python + pybind11 headers dependencies
-    target_link_libraries(${module_name}
-        PUBLIC 
-            pybind11::pybind11
-        PRIVATE
-            Python::Python
-        )
+    include(PybindModuleCreation)
+    generate_python_binding()
 endif()
 
 target_compile_features(${module_name} PRIVATE cxx_std_14)
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..c08fcf0
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,7 @@
+recursive-include aidge_backend_opencv *.py 
+recursive-exclude aidge_backend_opencv/unit_tests *.py
+
+recursive-include include *
+recursive-include src *
+recursive-exclude unit_tests *
+
diff --git a/cmake/PybindModuleCreation.cmake b/cmake/PybindModuleCreation.cmake
index 18f4abc..32f67e0 100644
--- a/cmake/PybindModuleCreation.cmake
+++ b/cmake/PybindModuleCreation.cmake
@@ -1,23 +1,32 @@
-function(generate_python_binding name target_to_bind) 
-    if (PYBIND)
-        add_definitions(-DPYBIND)
-        Include(FetchContent)
+macro(generate_python_binding )
+    add_definitions(-DPYBIND)
+    Include(FetchContent)
 
-        FetchContent_Declare(
-        PyBind11
-        GIT_REPOSITORY https://github.com/pybind/pybind11.git
-        GIT_TAG        v2.10.4 # or a later release
-        )
-
-        # Use the New FindPython mode, recommanded. Requires CMake 3.15+
-        find_package(Python COMPONENTS Interpreter Development)
-        FetchContent_MakeAvailable(PyBind11)
+    # Use the New FindPython mode, recommanded. Requires CMake 3.15+
+    find_package(Python 3.7.0
+                    COMPONENTS Interpreter Development.Module 
+                    REQUIRED)
+    set(PYBIND11_FINDPYTHON ON)
+    set(PYBIND_VERSION v2.10.4)
+    message(STATUS "Retrieving pybind ${PYBIND_VERSION} from git")
+    FetchContent_Declare(
+    PyBind11
+    GIT_REPOSITORY https://github.com/pybind/pybind11.git
+    GIT_TAG        ${PYBIND_VERSION} # or a later release
+    )
+    FetchContent_MakeAvailable(PyBind11)
+    
+    message(STATUS "Creating binding for module ${project}")
+    file(GLOB_RECURSE pybind_src_files "python_binding/*.cpp")
 
-        message(STATUS "Creating binding for module ${name}")
-        file(GLOB_RECURSE pybind_src_files "python_binding/*.cpp")
-
-        pybind11_add_module(${name} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA recquired for pip install
-        target_include_directories(${name} PUBLIC "python_binding")
-        target_link_libraries(${name} PUBLIC ${target_to_bind})        
-    endif()
-endfunction()
+    pybind11_add_module(${project} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA required for pip install
+    target_include_directories(${project} PUBLIC "python_binding" ${pybind11_INCLUDE_DIRECTORIES})
+    # Handles Python + pybind11 headers dependencies
+    target_link_libraries(${module_name}
+        PRIVATE
+            Python::Module 
+        PUBLIC
+            pybind11::pybind11
+        )
+    target_link_libraries(${project} PUBLIC ${module_name})
+endmacro()
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..4c0d4fd
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,61 @@
+[project]
+name = "aidge_backend_opencv"
+description="Opencv implementations of the operators and tensor of aidge framework"
+dependencies = [
+    "numpy>=1.21.6",
+    "opencv-python",
+]
+requires-python = ">= 3.7"
+# dynamic = ["version"] # defined in tool.setuptools_scm
+version = "0.1"
+readme = "README.md"
+license = { file = "LICENSE" }
+classifiers = [ 
+    "Development Status :: 2 - Pre-Alpha",
+    "Programming Language :: Python :: 3"
+    ]
+
+[build-system]
+requires = [
+    "setuptools>=64",
+    "setuptools_scm[toml]==7.1.0",
+    "cmake>=3.29",
+    "toml",
+    "opencv-python",
+]
+build-backend = "setuptools.build_meta"
+
+#####################################################
+# SETUPTOOLS
+[tool.setuptools]
+[tool.setuptools.packages.find]
+where = ["."]  # list of folders that contain the packages (["."] by default)
+include = ["aidge_backend_opencv*"]  # package names should match these glob patterns (["*"] by default)
+exclude = ["aidge_backend_opencv.unit_tests*"]  # exclude packages matching these glob patterns (empty by default)
+namespaces = false  # to disable scanning PEP 420 namespaces (true by default)
+# SETUPTOOLS_SCM
+# [tool.setuptools_scm]
+# write_to = "aidge_backend_opencv/_version.py"
+
+#####################################################
+# CIBUILDWHEEL
+[tool.cibuildwheel]
+build=["cp38-manylinux_x86_64"] # , "cp39-manylinux_x86_64","cp310-manylinux_x86_64"]
+build-frontend = "build"
+### AIDGE DEPENDENCIES DECLARATION
+# aidge_core do not rely on any aidge dependency, hence this string is empty
+[tool.cibuildwheel.linux.environment]
+AIDGE_DEPENDENCIES = "aidge_core" # format => "dep_1 dep_2 ... dep_n"
+AIDGE_INSTALL="/host/AIDGE_INSTALL_CIBUILDWHEEL"
+[tool.cibuildwheel.windows.environment]
+AIDGE_DEPENDENCIES = "aidge_core" # format => "dep_1","dep_2", ... ,"dep_n"
+AIDGE_INSTALL="../AIDGE_INSTALL_CIBUILDWHEEL/"
+
+[tool.cibuildwheel.linux]
+before-build = [
+    "bash .gitlab/ci/cibuildwheel_build_deps_before_build_wheel.sh "
+]
+[tool.cibuildwheel.windows]
+before-build = [
+    "powershell -File .\\.gitlab\\ci\\cibuildwheel_build_deps_before_build_wheel.ps1"
+]
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 168007e..44d40d4 100644
--- a/setup.py
+++ b/setup.py
@@ -1,42 +1,24 @@
-#!/usr/bin/env python3
-""" Aidge
-
-#TODO To change
-POC of the next framework named Aidge
-"""
-
-DOCLINES = (__doc__ or '').split("\n")
-
 import sys
 import os
-
-# Python supported version checks
-if sys.version_info[:2] < (3, 7):
-    raise RuntimeError("Python version >= 3.7 required.")
-
-
-CLASSIFIERS = """\
-Development Status :: 2 - Pre-Alpha
-"""
-
 import shutil
 import pathlib
 import subprocess
 import multiprocessing
 
+import sysconfig
+
 from math import ceil
 
+import toml
+
 from setuptools import setup, Extension
 from setuptools import find_packages
 from setuptools.command.build_ext import build_ext
 
 def get_project_name() -> str:
-    return open(pathlib.Path().absolute() / "project_name.txt", "r").read()
-
-def get_project_version() -> str:
-    aidge_root = pathlib.Path().absolute()
-    version = open(aidge_root / "version.txt", "r").read().strip()
-    return version
+    with  open(pathlib.Path().absolute() / "pyproject.toml", "r") as file :
+        project_toml = toml.load(file)
+        return project_toml["project"]["name"]
 
 
 class CMakeExtension(Extension):
@@ -62,17 +44,46 @@ class CMakeBuild(build_ext):
 
         os.chdir(str(build_temp))
 
-        # Impose to use the executable of the python
-        # used to launch setup.py to setup PythonInterp
-        param_py = "-DPYTHON_EXECUTABLE=" + sys.executable
-
-        compile_type = 'Debug'
-        install_path = os.path.join(sys.prefix, "lib", "libAidge")  if "AIDGE_INSTALL" not in os.environ else os.environ["AIDGE_INSTALL"]
+        python_executable = sys.executable 
+        python_include_dirs = sysconfig.get_path('include') 
+        python_library = sysconfig.get_config_var('LIBDIR') 
+        python_prefix = sys.exec_prefix 
+        print(f"python\texecutable\t{python_executable}") 
+        print(f"\t\t\tinclude\tdirs {python_include_dirs}") 
+        print(f"-DPYTHON_INCLUDE_DIRS={sysconfig.get_config_var('INCLUDEPY')}") 
+        print(f"\t\t\tlibrary\t{python_library}") 
+        print(f"-DPYTHON_LIBRARIES={sysconfig.get_config_var('LIBDEST')}") 
+        print(f"\t\t\tprefix\t{python_prefix}") 
+
+        # Impose to use the executable of the python                                                                                                                                                  
+        # used to launch setup.py to setup PythonInterp                                                                                                                                                   
+        python_executable = sys.executable                                                                                                                                                                
+        print(f"python executable :\t{python_executable}")                                                                                                                                                   
+        compile_type = "Debug"
+        install_path = (
+            os.path.join(sys.prefix, "lib", "libAidge")
+            if "AIDGE_INSTALL" not in os.environ
+            else os.environ["AIDGE_INSTALL"]
+        )
+        self.spawn(
+            [
+                "cmake",
+                str(cwd),
+                f"-DPYTHON_EXECUTABLE={sys.executable}",
+                "-DTEST=OFF",
+                f"-DCMAKE_INSTALL_PREFIX:PATH={install_path}",
+                f"-DCMAKE_BUILD_TYPE={compile_type}",
+                "-DPYBIND=ON",
+                "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
+                "-DCOVERAGE=OFF"
+            ]
+        )
 
-        self.spawn(['cmake', str(cwd), param_py, '-DTEST=OFF', f'-DCMAKE_INSTALL_PREFIX:PATH={install_path}', f'-DCMAKE_BUILD_TYPE={compile_type}'])
         if not self.dry_run:
-            self.spawn(['cmake', '--build', '.', '--config', compile_type, '-j', max_jobs])
-            self.spawn(['cmake', '--install', '.', '--config', compile_type])
+            self.spawn(
+                ["cmake", "--build", ".", "--config", compile_type, "-j", max_jobs]
+            )
+            self.spawn(["cmake", "--install", ".", "--config", compile_type])
         os.chdir(str(cwd))
 
         aidge_package = build_lib / (get_project_name())
@@ -83,32 +94,24 @@ class CMakeBuild(build_ext):
         # Copy all shared object files from build_temp/lib to aidge_package
         for root, _, files in os.walk(build_temp.absolute()):
             for file in files:
-                if (file.endswith('.so') or file.endswith('.pyd')) and (root != str(aidge_package.absolute())):
-                    currentFile=os.path.join(root, file)
+                if (file.endswith(".so") or file.endswith(".pyd")) and (
+                    root != str(aidge_package.absolute())
+                ):
+                    currentFile = os.path.join(root, file)
                     shutil.copy(currentFile, str(aidge_package.absolute()))
 
         # Copy version.txt in aidge_package
         os.chdir(os.path.dirname(__file__))
-        shutil.copy("version.txt", str(aidge_package.absolute()))    
+        shutil.copy("version.txt", str(aidge_package.absolute()))  
 
 
 if __name__ == '__main__':
 
     setup(
-        name=get_project_name(),
-        version=get_project_version(),
-        python_requires='>=3.7',
-        description=DOCLINES[0],
-        long_description_content_type="text/markdown",
-        long_description="\n".join(DOCLINES[2:]),
-        classifiers=[c for c in CLASSIFIERS.split('\n') if c],
-        packages=find_packages(where="."),
         include_package_data=True,
         ext_modules=[CMakeExtension(get_project_name())],
         cmdclass={
-            'build_ext': CMakeBuild,
+            "build_ext": CMakeBuild,
         },
-        install_requires=['aidge_core'],
         zip_safe=False,
-
     )
-- 
GitLab