diff --git a/README.md b/README.md
index 6ff9ec4389e8cd131bd93244b5035a9275454289..246472888762077e64e72f681533098c7e9802f0 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,14 @@ After changes in a python file, no action is required, for changes in .cpp/.h fi
 pip install --no-build-isolation -v -e .
 ```
 
+Or simply use the build backend (generated files in the `build/` directory have been symlinked
+during the first editable install):
+```bash
+make -C build install -j $(nproc)
+# or for instance with ninja backend
+ninja -C build install
+```
+
 In this mode, the C++ compilation build system is located in the local `build/` directory.
 
 Refer to the doc string in `setup.py`for more details on editable mode.
diff --git a/setup.py b/setup.py
index e88e10ef56e55614199e50c7a33cd0cfe5ecbbc0..1101185316c2f80561f25f4bf05d531adc90bd6e 100644
--- a/setup.py
+++ b/setup.py
@@ -47,7 +47,7 @@ Development Status :: 2 - Pre-Alpha
 """
 
 import shutil
-import pathlib
+from pathlib import Path
 import subprocess
 import multiprocessing
 
@@ -57,7 +57,7 @@ from setuptools import setup, Extension
 from setuptools import find_packages
 from setuptools.command.build_ext import build_ext
 
-SETUP_DIR = pathlib.Path(__file__).parent
+SETUP_DIR = Path(__file__).parent
 
 def parse_requirements():
     with open(SETUP_DIR / "requirements.txt", "r") as inf:
@@ -90,19 +90,28 @@ class CMakeBuild(build_ext):
             else:
                 self.editable_mode = False
 
+    def _post_install_copy(self, fname, dst_dir):
+        Path(dst_dir).mkdir(parents=True, exist_ok=True)
+        dst_file = Path(dst_dir) / Path(fname).name
+        if not self.editable_mode:
+            shutil.copy(str(fname), str(dst_file))
+        else:
+            dst_file.unlink(missing_ok=True)
+            os.symlink(str(fname), str(dst_file))
+
     def run(self):
         # This lists the number of processors available on the machine
         # The compilation will use half of them
         # Note that for ninja backend this is not necessary
         max_jobs = str(ceil(multiprocessing.cpu_count() / 2))
 
-        cwd = pathlib.Path().absolute()
+        cwd = 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)
+        build_lib = Path(self.build_lib)
         if not build_lib.exists():
             build_lib.mkdir(parents=True, exist_ok=True)
 
@@ -135,11 +144,11 @@ class CMakeBuild(build_ext):
                 if ((file.endswith('.so') or file.endswith('.pyd')) and
                     root != str(aidge_package) and
                     not root.startswith(str(build_lib))):
-                    currentFile = pathlib.Path(root) / file
-                    shutil.copy(str(currentFile), str(aidge_package))
+                    currentFile = Path(root) / file
+                    self._post_install_copy(currentFile, aidge_package)
 
         # Copy version.txt in aidge_package
-        shutil.copy(str(SETUP_DIR / "version.txt"), str(aidge_package))
+        self._post_install_copy(SETUP_DIR / "version.txt", str(aidge_package))
 
 if __name__ == '__main__':