diff --git a/CMakeLists.txt b/CMakeLists.txt index eef0e63bf398cffb2c15b3af56ec0bf02d6590a9..6f5a8cbfcf7076256beef5e636d8c594b9df27e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}") # Note : project name is ${CMAKE_PROJECT_NAME} and python module name is also ${CMAKE_PROJECT_NAME} set(module_name _${CMAKE_PROJECT_NAME}) # target name +set(pybind_module_name ${CMAKE_PROJECT_NAME}) # name of submodule for python bindings ############################################## # Define options @@ -69,9 +70,12 @@ set_property(TARGET ${module_name} PROPERTY POSITION_INDEPENDENT_CODE ON) # PYTHON BINDING if (PYBIND) - # Handles Python + pybind11 headers dependencies + # Python binding lib is by default installed in <prefix>/python_packages/<package>/ + # When installed from python, setup.py should set it to the python package dir + set(PYBIND_INSTALL_PREFIX python_packages/${pybind_module_name} CACHE PATH "Python package install prefix") + include(PybindModuleCreation) - generate_python_binding(${CMAKE_PROJECT_NAME} ${module_name}) + generate_python_binding(${pybind_module_name} ${module_name}) target_link_libraries(${module_name} PUBLIC @@ -128,6 +132,12 @@ install(TARGETS ${module_name} EXPORT ${CMAKE_PROJECT_NAME}-targets ) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +if (PYBIND) + install(TARGETS ${pybind_module_name} + DESTINATION ${PYBIND_INSTALL_PREFIX} + ) +endif() + #Export the targets to a script install(EXPORT ${CMAKE_PROJECT_NAME}-targets FILE "${CMAKE_PROJECT_NAME}-targets.cmake" diff --git a/README.md b/README.md index ed44c2eaaee074f17c8d7edad059c0891473f272..96283603759f03415b7dc1b99f3905550427f633 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,23 @@ Those operators can be used on any machine with an Linux OS. pip install . -v ``` > **TIPS :** Use environment variables to change compilation options : -> - `AIDGE_INSTALL` : to set the installation folder. Defaults to /usr/local/lib. :warning: This path must be identical to aidge_core install path. -> - `AIDGE_PYTHON_BUILD_TYPE` : to set the compilation mode to **Debug** or **Release** -> - `AIDGE_BUILD_GEN` : to set the build backend with +> - `AIDGE_INSTALL` : to set the installation folder. Defaults to `<python_prefix>/lib/libAidge`. :warning: This path must be identical to aidge_core install path. +> - `AIDGE_PYTHON_BUILD_TYPE` : to set the compilation mode to **Debug** or **Release** or "" (for default flags). Defaults to **Release**. +> - `AIDGE_BUILD_GEN` : to set the build backend (for development mode) or "" for the cmake default. Default to "". + +## Pip installation for development + +To setup using pip in development (or editable mode), use the `--no-build-isolation -e` options to pip. + +For instance run the following command in your python environnement for a typical setup : +``` bash +export AIDGE_PYTHON_BUILD_TYPE= # default flags (no debug info but fastest build time) +export AIDGE_PYTHON_BUILD_TYPE=Debug # or if one really need to debug the C++ code +pip install -U pip setuptools setuptools_scm[toml] cmake # Pre-install build requirements (refer to the pyproject.toml [build-system] section) +pip install -v --no-build-isolation -e . +``` + +Refer to `aidge_core/README.md` for more details on development build options. ### Standard C++ Compilation diff --git a/pyproject.toml b/pyproject.toml index aa43189d3f4f7d3796009c2646175635382796bf..ff7a17363963ca511f26e3f3bbbcafa5e2870dd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,8 +17,7 @@ dynamic = ["version"] # defined in tool.setuptools_scm requires = [ "setuptools>=64", "setuptools_scm[toml]==7.1.0", - "cmake>=3.15.3.post1", - "toml" + "cmake>=3.15.3.post1" ] build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index 35520fd344c505bf38a60fcd5484c28517b0d2bd..a2b50c38faa1dc832e6ffe60b528f146e4287da3 100644 --- a/setup.py +++ b/setup.py @@ -8,17 +8,13 @@ import multiprocessing from math import ceil -import toml - from setuptools import setup, Extension from setuptools.command.build_ext import build_ext -def get_project_name() -> str: - with open(pathlib.Path().absolute() / "pyproject.toml", "r") as file: - project_toml = toml.load(file) - return project_toml["project"]["name"] +PROJECT_NAME = "aidge_backend_cpu" +SETUP_DIR = pathlib.Path(__file__).parent class AidgeBuildExtension(Extension): def __init__(self, name): @@ -26,6 +22,15 @@ class AidgeBuildExtension(Extension): class AidgePkgBuild(build_ext): + def __init__(self, dist, *args, **kwargs): + super().__init__(dist, *args, **kwargs) + # Detect editable_mode for old versions of setuptools + if not hasattr(self, "editable_mode"): + if hasattr(dist, "commands"): + self.editable_mode = "develop" in dist.commands + else: + self.editable_mode = False + def run(self): #################################### # BUILD PACKAGE @@ -43,36 +48,34 @@ class AidgePkgBuild(build_ext): if not build_lib.exists(): build_lib.mkdir(parents=True, exist_ok=True) - os.chdir(str(build_temp)) + package_prefix = build_lib if not self.editable_mode else SETUP_DIR + pybind_install_prefix = (package_prefix / PROJECT_NAME).absolute() - compile_type = ( - "Release" - if "AIDGE_PYTHON_BUILD_TYPE" not in os.environ - else os.environ["AIDGE_PYTHON_BUILD_TYPE"] - ) + os.chdir(str(build_temp)) + compile_type = os.environ.get("AIDGE_PYTHON_BUILD_TYPE", "Release") install_path = ( os.path.join(sys.prefix, "lib", "libAidge") if "AIDGE_INSTALL" not in os.environ else os.environ["AIDGE_INSTALL"] ) - - # using ninja as default build system to build faster and with the same compiler as on windows - build_gen = ( - ["-G", os.environ["AIDGE_BUILD_GEN"]] - if "AIDGE_BUILD_GEN" in os.environ + build_gen = os.environ.get("AIDGE_BUILD_GEN", "") + build_gen_opts = ( + ["-G", build_gen] + if build_gen else [] ) self.spawn( [ "cmake", - *build_gen, + *build_gen_opts, str(cwd), "-DTEST=OFF", f"-DCMAKE_INSTALL_PREFIX:PATH={install_path}", f"-DCMAKE_BUILD_TYPE={compile_type}", "-DPYBIND=ON", + f"-DPYBIND_INSTALL_PREFIX:PATH={pybind_install_prefix}", "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", "-DCOVERAGE=OFF", ] @@ -85,25 +88,11 @@ class AidgePkgBuild(build_ext): self.spawn(["cmake", "--install", ".", "--config", compile_type]) os.chdir(str(cwd)) - aidge_package = build_lib / (get_project_name()) - - # Get "aidge core" package - # ext_lib = build_temp - print(build_temp.absolute()) - # 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) - shutil.copy(currentFile, str(aidge_package.absolute())) - if __name__ == "__main__": setup( include_package_data=True, - ext_modules=[AidgeBuildExtension(get_project_name())], + ext_modules=[AidgeBuildExtension(PROJECT_NAME)], cmdclass={ "build_ext": AidgePkgBuild, },