Fix watch if compilation fails, update README
This commit is contained in:
parent
64c31f6211
commit
ce74e6135e
2 changed files with 20 additions and 10 deletions
|
|
@ -10,6 +10,8 @@ The advantages of this tool are :
|
||||||
|
|
||||||
* hash system to avoid time check issues (same file content, remote files problems, etc)
|
* hash system to avoid time check issues (same file content, remote files problems, etc)
|
||||||
|
|
||||||
|
* watch option to recompile whenever a source is changed
|
||||||
|
|
||||||
|
|
||||||
## Use
|
## 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`.
|
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 :
|
**Example :** from the root folder of a project :
|
||||||
|
|
||||||
```
|
```
|
||||||
git submodule add https://gitlab.com/corentin-pro/umake.git && cp umake/make* .
|
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
|
## How it works
|
||||||
|
|
||||||
|
|
|
||||||
23
umake.py
23
umake.py
|
|
@ -128,18 +128,18 @@ class Builder:
|
||||||
|
|
||||||
def make(self):
|
def make(self):
|
||||||
self._populate_todo_dict()
|
self._populate_todo_dict()
|
||||||
self._compile_sources()
|
|
||||||
|
|
||||||
if self._config.WATCH:
|
if self._config.WATCH:
|
||||||
from watch import Watcher, WatchFlag # pylint: disable=import-outside-toplevel
|
from watch import Watcher, WatchFlag # pylint: disable=import-outside-toplevel
|
||||||
|
|
||||||
def callback(path: Path, _flags: WatchFlag):
|
def callback(path: Path, _flags: WatchFlag):
|
||||||
source_hash = get_hash(path)
|
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}')
|
print(f'{ConsoleColor.ORANGE}Source file changed : {path} {ConsoleColor.ENDCOLOR}')
|
||||||
self._populate_todo_dict()
|
self._populate_todo_dict()
|
||||||
self._compile_sources()
|
self._compile_sources()
|
||||||
|
|
||||||
|
self._compile_sources()
|
||||||
watcher = Watcher()
|
watcher = Watcher()
|
||||||
for source_path in self._compile_dict:
|
for source_path in self._compile_dict:
|
||||||
watcher.register(source_path, WatchFlag.MODIFY, callback)
|
watcher.register(source_path, WatchFlag.MODIFY, callback)
|
||||||
|
|
@ -147,6 +147,8 @@ class Builder:
|
||||||
watcher.watch()
|
watcher.watch()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print('\rExit')
|
print('\rExit')
|
||||||
|
elif not self._compile_sources():
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def _populate_todo_dict(self):
|
def _populate_todo_dict(self):
|
||||||
"""Check source file and generate compilation commands to execute."""
|
"""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,
|
return ' '.join([self._config.CC, self._config.COMMON_FLAGS, self._config.COMPILE_FLAGS,
|
||||||
str(source_path), '-c', '-o', str(object_path)])
|
str(source_path), '-c', '-o', str(object_path)])
|
||||||
|
|
||||||
def _compile_sources(self):
|
def _compile_sources(self) -> bool:
|
||||||
if not self._todo_dict and all(
|
if not self._todo_dict and all(
|
||||||
(self._config.BIN_DIR / app_path).exists()
|
(self._config.BIN_DIR / app_path).exists()
|
||||||
for app_path in self._config.APPS if app_path not in self._config.IGNORE_APPS):
|
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}')
|
print(f'{ConsoleColor.GREEN}Nothing to do{ConsoleColor.ENDCOLOR}')
|
||||||
return
|
return True
|
||||||
|
|
||||||
# Running compilation processes
|
# Running compilation processes
|
||||||
if not os.path.exists(self._config.OBJECT_DIR):
|
if not os.path.exists(self._config.OBJECT_DIR):
|
||||||
|
|
@ -194,11 +196,13 @@ class Builder:
|
||||||
oldest_job.wait()
|
oldest_job.wait()
|
||||||
if oldest_job.returncode != 0:
|
if oldest_job.returncode != 0:
|
||||||
error_paths.append((job_path, oldest_job.stdout.read() + oldest_job.stderr.read()))
|
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
|
break
|
||||||
# Update hash if no error
|
# Update hash if no error
|
||||||
for dependency_path in self._dependency_dict[str(job_path)]:
|
for dependency_path in self._dependency_dict[str(job_path)]:
|
||||||
self._hash_dict[str(dependency_path)] = get_hash(dependency_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:
|
for source_path in completed_paths:
|
||||||
del self._todo_dict[source_path]
|
del self._todo_dict[source_path]
|
||||||
|
|
||||||
|
|
@ -206,6 +210,8 @@ class Builder:
|
||||||
job.wait()
|
job.wait()
|
||||||
if job.returncode != 0:
|
if job.returncode != 0:
|
||||||
error_paths.append((job_path, job.stdout.read() + job.stderr.read()))
|
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:
|
else:
|
||||||
# Update hash if no error
|
# Update hash if no error
|
||||||
for dependency_path in self._dependency_dict[str(job_path)]:
|
for dependency_path in self._dependency_dict[str(job_path)]:
|
||||||
|
|
@ -219,6 +225,8 @@ class Builder:
|
||||||
universal_newlines=True, shell=True)
|
universal_newlines=True, shell=True)
|
||||||
if job.returncode != 0:
|
if job.returncode != 0:
|
||||||
error_paths.append((source_path, job.stdout + job.stderr))
|
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
|
break
|
||||||
# Update hash if no error
|
# Update hash if no error
|
||||||
for dependency_path in self._dependency_dict[str(source_path)]:
|
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)
|
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:
|
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))
|
hash_file.write(json.dumps(self._hash_dict, indent=1))
|
||||||
sys.exit(1)
|
return False
|
||||||
|
|
||||||
# Running linking processes
|
# Running linking processes
|
||||||
if not self._config.BIN_DIR.exists():
|
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)
|
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:
|
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))
|
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:
|
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))
|
hash_file.write(json.dumps(self._hash_dict, indent=1))
|
||||||
|
|
||||||
print(f'{ConsoleColor.GREEN}Compilation done{ConsoleColor.ENDCOLOR}')
|
print(f'{ConsoleColor.GREEN}Compilation done{ConsoleColor.ENDCOLOR}')
|
||||||
|
return True
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue