From a0f56bb73cc4137fac8e4e98cbe9feb87987c469 Mon Sep 17 00:00:00 2001
From: Axel Farrugia <axel.farrugia@cea.fr>
Date: Fri, 21 Mar 2025 10:43:10 +0100
Subject: [PATCH] [Feat](Exports) Change the kernels_to_copy system

The old system had some limitations :
- Not possible to chose a destination path different from the source path
- The copied kernel would be automatically included in the fwd file, sometime leading to unused includes
---
 aidge_core/export_utils/node_export.py | 61 +++++++++++++++++++++-----
 1 file changed, 49 insertions(+), 12 deletions(-)

diff --git a/aidge_core/export_utils/node_export.py b/aidge_core/export_utils/node_export.py
index c24727adf..3247a7ffb 100644
--- a/aidge_core/export_utils/node_export.py
+++ b/aidge_core/export_utils/node_export.py
@@ -364,9 +364,9 @@ class ExportNodeCpp(ExportNode):
     :var include_list: List of include paths (e.g., "include/toto.hpp") to be added to
         the generated export files. Must be defined before export; raises an error if undefined.
     :vartype include_list: list[str]
-    :var kernels_to_copy: List of paths to kernel files that should be copied during
-        export. The kernels are copied to ``kernels_path``, and are automatically
-        added to the include list.
+    :var kernels_to_copy: A list of dict holding src and dst kernels paths to copy in the export.
+        export. The kernels are copied in dst_path (default : self.kernels_path).
+        They are automatically added to the include list unless the fwd_include option is set to False.
     :vartype kernels_to_copy: list[str]
     :var kernels_path: Path where all kernels are stored in the export, prefixed by the
         `export_root`. Defaults to "include/kernels".
@@ -377,6 +377,12 @@ class ExportNodeCpp(ExportNode):
     :var config_extension: File extension for the configuration files, typically for header
         files. Defaults to "h".
     :vartype config_extension: str
+    :var dev_mode: Wether or not the developer mode is enabled. If enabled, the export files
+        will be symlinks from the aidge export module. Therefore, modifying
+        a file within the export will change the module as well. 
+        The dev_mode flag is also passed to the forward jinja templates to allow export
+        customization (ie. Adding a debug mode for instance).
+    :vartype dev_mode: bool
     """
 
     # Path to the template defining how to export the node definition
@@ -385,16 +391,40 @@ class ExportNodeCpp(ExportNode):
     forward_template: str = None
     # List of includes to add example "include/toto.hpp"
     include_list: list = None
-    # A list of path of kernels to copy in the export
-    # kernels are copied in str(export_folder / "include" / "kernels")
-    # They are automatically added to the include list.
-    kernels_to_copy: list = None
+    # A list of dict holding src and dst kernels paths to copy in the export.
+    # kernels are copied in dst_path (default : self.kernels_path)
+    # They are automatically added to the include list unless the fwd_include option is set to False.
+    kernels_to_copy: list[dict] = None
     # Path where all the kernels are stored in the export (prefixed by export_root)
     kernels_path: str = "include/kernels"
     # Path of config folders
     config_path: str = "include/layers"
     # Config_folder_extension
     config_extension: str = "h"
+    # Dev mode - Symlink copy
+    dev_mode: bool = False
+
+
+    def add_kernel_to_copy(self, kernel_src_path: str, kernel_dst_path: str = kernels_path, fwd_include: bool = True):
+        """ Add a kernel to the kernels_to_copy list of dict.
+        
+        :param kernel_src_path: File path for the kernel to copy within the export module.
+        :type kernel_src_path: str
+        :param kernel_dst_path: File path for the kernel to copy within the generated export. 
+        :type kernel_dst_path: str
+        :param fwd_include: Wether the kernel is included in the generated forward file or not.
+        :type fwd_include: bool
+        """
+
+        if self.kernels_to_copy is None:
+            self.kernels_to_copy = []
+
+        kernel_to_copy: dict = {
+            "src_path": kernel_src_path,
+            "dst_path": kernel_dst_path,
+            "fwd_include": fwd_include
+        }
+        self.kernels_to_copy.append(kernel_to_copy)
 
 
     def export(self, export_folder: str):
@@ -419,13 +449,20 @@ class ExportNodeCpp(ExportNode):
 
         kernel_include_list = []
         for kernel in self.kernels_to_copy:
-            kernel_path = Path(kernel)
+
+            # Copy the kernel file
+            kernel_src_path = Path(kernel["src_path"])
+            kernel_dst_path = Path(kernel["dst_path"])
             code_generation.copy_file(
-                kernel_path,
-                str(export_folder / self.kernels_path)
+                kernel_src_path,
+                str(export_folder / kernel_dst_path),
+                self.dev_mode
             )
-            kernel_include_list.append(
-                self.kernels_path + "/" + kernel_path.stem + kernel_path.suffix)
+
+            # Include the kernel file within the fwd
+            if kernel["fwd_include"]:
+                kernel_include_list.append(
+                    kernel_dst_path / (kernel_src_path.stem + kernel_src_path.suffix))
 
         if self.config_template != "":
             path_to_definition = f"{self.config_path}/{self.attributes['name']}.{self.config_extension}"
-- 
GitLab