diff --git a/README.md b/README.md index cc59fb2..9bd0296 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ The advantages of this tool are : * hash system to avoid time check issues (same file content, remote files problems, etc) +* watch option to recompile whenever a source is changed + ## Use @@ -25,15 +27,14 @@ This repository is meant to be used as a submodule of a C/C++ project. By default 3 targets can be used `make` (or `make all` as usual default of makefiles), `make debug` and `make clean`. -**Be careful** : `clean` will delete the object and binary output directories defined in `make.py`. - - **Example :** from the root folder of a project : ``` git submodule add https://gitlab.com/corentin-pro/umake.git && cp umake/make* . ``` +Then change the configuration in `make.py` and a simple `make` command will build your project! + ## How it works diff --git a/umake.py b/umake.py index ba5cafe..a2bf31f 100755 --- a/umake.py +++ b/umake.py @@ -128,18 +128,18 @@ class Builder: def make(self): self._populate_todo_dict() - self._compile_sources() if self._config.WATCH: from watch import Watcher, WatchFlag # pylint: disable=import-outside-toplevel def callback(path: Path, _flags: WatchFlag): source_hash = get_hash(path) - if source_hash != self._hash_dict[str(path)]: + if str(path) not in self._hash_dict or source_hash != self._hash_dict[str(path)]: print(f'{ConsoleColor.ORANGE}Source file changed : {path} {ConsoleColor.ENDCOLOR}') self._populate_todo_dict() self._compile_sources() + self._compile_sources() watcher = Watcher() for source_path in self._compile_dict: watcher.register(source_path, WatchFlag.MODIFY, callback) @@ -147,6 +147,8 @@ class Builder: watcher.watch() except KeyboardInterrupt: print('\rExit') + elif not self._compile_sources(): + sys.exit(1) def _populate_todo_dict(self): """Check source file and generate compilation commands to execute.""" @@ -170,12 +172,12 @@ class Builder: return ' '.join([self._config.CC, self._config.COMMON_FLAGS, self._config.COMPILE_FLAGS, str(source_path), '-c', '-o', str(object_path)]) - def _compile_sources(self): + def _compile_sources(self) -> bool: if not self._todo_dict and all( (self._config.BIN_DIR / app_path).exists() for app_path in self._config.APPS if app_path not in self._config.IGNORE_APPS): print(f'{ConsoleColor.GREEN}Nothing to do{ConsoleColor.ENDCOLOR}') - return + return True # Running compilation processes if not os.path.exists(self._config.OBJECT_DIR): @@ -194,11 +196,13 @@ class Builder: oldest_job.wait() if oldest_job.returncode != 0: error_paths.append((job_path, oldest_job.stdout.read() + oldest_job.stderr.read())) + if str(job_path) in self._hash_dict: + del self._hash_dict[str(job_path)] break # Update hash if no error for dependency_path in self._dependency_dict[str(job_path)]: self._hash_dict[str(dependency_path)] = get_hash(dependency_path) - completed_paths.append(source_path) + completed_paths.append(job_path) for source_path in completed_paths: del self._todo_dict[source_path] @@ -206,6 +210,8 @@ class Builder: job.wait() if job.returncode != 0: error_paths.append((job_path, job.stdout.read() + job.stderr.read())) + if str(job_path) in self._hash_dict: + del self._hash_dict[str(job_path)] else: # Update hash if no error for dependency_path in self._dependency_dict[str(job_path)]: @@ -219,6 +225,8 @@ class Builder: universal_newlines=True, shell=True) if job.returncode != 0: error_paths.append((source_path, job.stdout + job.stderr)) + if str(source_path) in self._hash_dict: + del self._hash_dict[str(source_path)] break # Update hash if no error for dependency_path in self._dependency_dict[str(source_path)]: @@ -232,7 +240,7 @@ class Builder: print(ConsoleColor.RED + f'Error compiling {error_path}:\n' + ConsoleColor.ENDCOLOR + error_text) with open(self._config.OBJECT_DIR / 'hash.json', 'w', encoding='utf-8') as hash_file: hash_file.write(json.dumps(self._hash_dict, indent=1)) - sys.exit(1) + return False # Running linking processes if not self._config.BIN_DIR.exists(): @@ -288,9 +296,10 @@ class Builder: print(ConsoleColor.RED + f'Error linking {error_path}:\n' + ConsoleColor.ENDCOLOR + error_text) with open(os.path.join(self._config.OBJECT_DIR, 'hash.json'), 'w', encoding='utf-8') as hash_file: hash_file.write(json.dumps(self._hash_dict, indent=1)) - sys.exit(1) + return False with open(self._config.OBJECT_DIR / 'hash.json', 'w', encoding='utf-8') as hash_file: hash_file.write(json.dumps(self._hash_dict, indent=1)) print(f'{ConsoleColor.GREEN}Compilation done{ConsoleColor.ENDCOLOR}') + return True