From 214cc8a213e27777a376fa7c98f5f563762d2f14 Mon Sep 17 00:00:00 2001
From: cmoineau <cyril.moineau@cea.fr>
Date: Thu, 3 Aug 2023 13:38:58 +0000
Subject: [PATCH] Add setup.py and project_name.txt file.

---
 CMakeLists.txt                   |  16 +++--
 README.md                        |  54 ++++++++++-----
 aidge_core/__init__.py           |   1 +
 cmake/PybindModuleCreation.cmake |   2 +-
 project_name.txt                 |   1 +
 setup.py                         | 111 +++++++++++++++++++++++++++++++
 6 files changed, 165 insertions(+), 20 deletions(-)
 create mode 100644 aidge_core/__init__.py
 create mode 100644 project_name.txt
 create mode 100644 setup.py

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 73891e774..3e490964d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,15 @@
 cmake_minimum_required(VERSION 3.11)
 
-set(project aidge_core)      # This will also be python module name 
+file(READ "${CMAKE_SOURCE_DIR}/version.txt" version)
+file(READ "${CMAKE_SOURCE_DIR}/project_name.txt" project)
+
+message(STATUS "Project name: ${project}")
+message(STATUS "Project version: ${version}")
+
+# Note : project name is {project} and python module name is also {project} 
 set(module_name _${project}) # target name
 
 
-set(version 2.0.0)
 project(${project})
 
 ##############################################
@@ -16,6 +21,7 @@ include(PybindModuleCreation)
 # Define options
 option(PYBIND "python binding" ON)
 option(WERROR "Warning as error" OFF)
+option(TEST "Enable tests" ON)
 
 ##############################################
 # Find system dependencies
@@ -126,5 +132,7 @@ export(EXPORT ${project}-targets
 
 ##############################################
 ## Add test
-enable_testing()
-add_subdirectory(unit_tests)
+if(TEST)
+    enable_testing()
+    add_subdirectory(unit_tests)
+endif()
\ No newline at end of file
diff --git a/README.md b/README.md
index 70ca91e42..8c4e52ad8 100644
--- a/README.md
+++ b/README.md
@@ -4,25 +4,49 @@ You can find here the C++ code of the Core library of Aidge.
 
 ## Compilation
 
-To only compile the Core library, run
-```
-make core_only
-```
 
-To compile the Core library + the associated unitary tests, run
-```
-make core_tests
-```
+Create two directories ``build`` and ``ìnstall``.
 
-To compile the Core library with the python binding, run
-```
-make core_with_pybind
-```
-Important: this command can also be run with `make`.
 
+Then **inside** ``build`` :
+
+```bash
+
+cmake -DCMAKE_INSTALL_PREFIX:PATH=$(path_to_install_folder) $(CMAKE PARAMETERS) $(projet_root)
+
+make all install
 
-To compile the Core library with the python binding + the associated unitary tests, run
 ```
-make core_with_pybind_tests
+
+
+**Compilation options**
+
+
+|   Option   | Value type | Description |
+
+|:----------:|:----------:|:-----------:|
+
+| *-DCMAKE_INSTALL_PREFIX:PATH* | ``str``  | Path to the install folder |
+
+| *-DCMAKE_BUILD_TYPE*          | ``str``  | If ``Debug``, compile in debug mode, ``Release`` compile with highest optimisations, default= ``Release`` |
+
+| *-DWERROR*                    | ``bool`` | If ``ON`` show warning as error during compilation phase, default=``OFF`` |
+
+| *-DPYBIND*                    | ``bool`` | If ``ON`` activate python binding, default=``ON`` |
+
+If you have compiled with PyBind you can find at the root of the ``build`` file the python lib ``aidge_core.cpython*.so``
+
+## Run tests
+
+### CPP
+
+Inside of the build file run:
+
+```bash
+
+ctest --output-on-failure
+
 ```
 
+### Python
+
diff --git a/aidge_core/__init__.py b/aidge_core/__init__.py
new file mode 100644
index 000000000..3b9dbbf8f
--- /dev/null
+++ b/aidge_core/__init__.py
@@ -0,0 +1 @@
+from .aidge_core import * # import so generated by PyBind
\ No newline at end of file
diff --git a/cmake/PybindModuleCreation.cmake b/cmake/PybindModuleCreation.cmake
index c54f1c87e..a80b594bc 100644
--- a/cmake/PybindModuleCreation.cmake
+++ b/cmake/PybindModuleCreation.cmake
@@ -12,7 +12,7 @@ function(generate_python_binding name target_to_bind)
         FetchContent_MakeAvailable(PyBind11)
         message(STATUS "Creating binding for module ${name}")
         file(GLOB_RECURSE pybind_src_files "python_binding/*.cpp")
-        pybind11_add_module(${name} MODULE ${pybind_src_files})
+        pybind11_add_module(${name} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA recquired for pip install
         target_include_directories(${name} PUBLIC ${pybind11_INCLUDE_DIRS} "python_binding")
         target_link_libraries(${name} PUBLIC ${target_to_bind})
         
diff --git a/project_name.txt b/project_name.txt
new file mode 100644
index 000000000..66bd7db76
--- /dev/null
+++ b/project_name.txt
@@ -0,0 +1 @@
+aidge_core
\ No newline at end of file
diff --git a/setup.py b/setup.py
new file mode 100644
index 000000000..7dbde6a0a
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,111 @@
+#!/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
+
+from math import ceil
+
+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
+
+
+class CMakeExtension(Extension):
+    def __init__(self, name):
+        super().__init__(name, sources=[])
+
+class CMakeBuild(build_ext):
+
+    def run(self):
+        # This lists the number of processors available on the machine
+        # The compilation will use half of them
+        max_jobs = str(ceil(multiprocessing.cpu_count() / 2))
+
+        cwd = pathlib.Path().absolute()
+
+        build_temp = cwd / "build"
+        if not build_temp.exists():
+            build_temp.mkdir(parents=True, exist_ok=True)
+
+        build_lib = pathlib.Path(self.build_lib)
+        if not build_lib.exists():
+            build_lib.mkdir(parents=True, exist_ok=True)
+
+        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
+
+        self.spawn(['cmake', str(cwd), param_py, '-DTEST=OFF', f'-DCMAKE_INSTALL_PREFIX:PATH={build_temp}/install'])
+        
+        if not self.dry_run:
+            self.spawn(['make', 'all', 'install', '-j', max_jobs])
+        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') 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()))    
+
+
+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],
+        platforms=["Linux"],
+        packages=find_packages(where="."),
+        include_package_data=True,
+        # exclude_package_data={"aidge": ["_Core/*", "_CPU/*"]},
+        ext_modules=[CMakeExtension('aidge_core')],
+        cmdclass={
+            'build_ext': CMakeBuild,
+        },
+
+    )
-- 
GitLab