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