Skip to content

Commit c73aa78

Browse files
committed
chore: implement rudimentary CMake incremental build
We speed-up the build process for local development when CMake sources are not changed in between build runs. This reduces the build time from about 3 minutes to about 20 seconds.
1 parent 3ff7046 commit c73aa78

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

setup.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from pathlib import Path # isort: skip
2525
from pkg_resources import get_build_platform # isort: skip
2626
from distutils.command.clean import clean as CleanCommand # isort: skip
27+
from distutils.dep_util import newer_group
2728

2829

2930
try:
@@ -350,6 +351,35 @@ def build_extension(self, ext):
350351
print(f"WARNING: An error occurred while building the extension: {e}")
351352

352353
def build_extension_cmake(self, ext):
354+
if os.getenv("DD_CMAKE_INCREMENTAL_BUILD", "0").lower() in ("1", "yes", "on", "true"):
355+
# DEV: Rudimentary incremental build support. We copy the logic from
356+
# setuptools' build_ext command, best effort.
357+
full_path = Path(self.get_ext_fullpath(ext.name))
358+
ext_path = Path(ext.source_dir, full_path.name)
359+
360+
# Collect all the source files within the source directory. We exclude
361+
# Python sources and anything that does not have a suffix (most likely
362+
# a binary file), or that has the same name as the extension binary.
363+
sources = (
364+
[
365+
_
366+
for _ in Path(ext.source_dir).rglob("**")
367+
if _.is_file() and _.name != full_path.name and _.suffix and _.suffix not in (".py", ".pyc", ".pyi")
368+
]
369+
if ext.source_dir
370+
else []
371+
)
372+
if not (self.force or newer_group([str(_.resolve()) for _ in sources], str(ext_path.resolve()), "newer")):
373+
print(f"skipping '{ext.name}' CMake extension (up-to-date)")
374+
375+
# We need to copy the binary where setuptools expects it
376+
full_path.parent.mkdir(parents=True, exist_ok=True)
377+
shutil.copy(ext_path, full_path)
378+
379+
return
380+
else:
381+
print(f"building '{ext.name}' CMake extension")
382+
353383
# Define the build and output directories
354384
output_dir = Path(self.get_ext_fullpath(ext.name)).parent.resolve()
355385
extension_basename = Path(self.get_ext_fullpath(ext.name)).name

0 commit comments

Comments
 (0)