cppmake 127.0.13__py3-none-any.whl → 127.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. cppmake-127.0.16.dist-info/METADATA +191 -0
  2. cppmake-127.0.16.dist-info/RECORD +55 -0
  3. {cppmake-127.0.13.dist-info → cppmake-127.0.16.dist-info}/WHEEL +1 -1
  4. cppmake-127.0.16.dist-info/entry_points.txt +3 -0
  5. cppmake-127.0.16.dist-info/top_level.txt +3 -0
  6. cppmaked.py +2 -0
  7. cppmakelib/__init__.py +32 -0
  8. cppmakelib/basic/config.py +50 -0
  9. cppmakelib/basic/context.py +39 -0
  10. cppmakelib/builder/cmake.py +71 -0
  11. cppmakelib/builder/include.py +15 -0
  12. cppmakelib/builder/makefile.py +68 -0
  13. cppmakelib/compiler/all.py +26 -0
  14. cppmakelib/compiler/clang.py +196 -0
  15. cppmakelib/compiler/emcc.py +79 -0
  16. cppmakelib/compiler/gcc.py +237 -0
  17. cppmakelib/compiler/msvc.py +24 -0
  18. cppmakelib/error/config.py +5 -0
  19. cppmakelib/error/logic.py +6 -0
  20. cppmakelib/error/subprocess.py +9 -0
  21. cppmakelib/executor/operation.py +15 -0
  22. cppmakelib/executor/run.py +84 -0
  23. cppmakelib/executor/scheduler.py +91 -0
  24. cppmakelib/logger/compile_commands.py +30 -0
  25. cppmakelib/logger/make_progress.py +0 -0
  26. cppmakelib/logger/module_mapper.py +6 -0
  27. cppmakelib/logger/unit_status.py +224 -0
  28. cppmakelib/system/all.py +25 -0
  29. cppmakelib/system/linux.py +26 -0
  30. cppmakelib/system/macos.py +26 -0
  31. cppmakelib/system/windows.py +26 -0
  32. cppmakelib/unit/binary.py +26 -0
  33. cppmakelib/unit/code.py +62 -0
  34. cppmakelib/unit/dynamic.py +12 -0
  35. cppmakelib/unit/executable.py +35 -0
  36. cppmakelib/unit/header.py +63 -0
  37. cppmakelib/unit/module.py +69 -0
  38. cppmakelib/unit/object.py +71 -0
  39. cppmakelib/unit/package.py +87 -0
  40. cppmakelib/unit/precompiled.py +6 -0
  41. cppmakelib/unit/preparsed.py +6 -0
  42. cppmakelib/unit/preprocessed.py +3 -0
  43. cppmakelib/unit/source.py +64 -0
  44. cppmakelib/utility/algorithm.py +44 -0
  45. cppmakelib/utility/color.py +14 -0
  46. cppmakelib/utility/decorator.py +120 -0
  47. cppmakelib/utility/filesystem.py +71 -0
  48. cppmakelib/utility/import_.py +21 -0
  49. cppmakelib/utility/remote/client.py +2 -0
  50. cppmakelib/utility/remote/protocol.py +32 -0
  51. cppmakelib/utility/remote/remote.py +43 -0
  52. cppmakelib/utility/remote/server.py +0 -0
  53. cppmakelib/utility/time.py +1 -0
  54. cppmakelib/utility/version.py +65 -0
  55. cppmake-127.0.13.dist-info/METADATA +0 -9
  56. cppmake-127.0.13.dist-info/RECORD +0 -6
  57. cppmake-127.0.13.dist-info/entry_points.txt +0 -2
  58. cppmake-127.0.13.dist-info/top_level.txt +0 -1
  59. /cppmake/__main__.py → /cppmake.py +0 -0
@@ -0,0 +1,91 @@
1
+ from cppmakelib.basic.config import config
2
+ from cppmakelib.utility.decorator import member
3
+ import asyncio
4
+ import typing
5
+
6
+ class Scheduler:
7
+ def __init__(self, value: int = config.parallel) -> None : ...
8
+ def schedule(self, value: int = 1) -> typing.AsyncContextManager[None]: ...
9
+ max: int
10
+
11
+ class _ContextManager:
12
+ def __init__ (self, scheduler: Scheduler, value: int) -> None: ...
13
+ async def __aenter__(self) -> None: ...
14
+ async def __aexit__ (self, *args: typing.Any, **kwargs: typing.Any) -> None: ...
15
+ _scheduler: Scheduler
16
+ _value : int
17
+ class _NotifyFailedError(RuntimeError):
18
+ pass
19
+ async def _acquire (self, value: int = 1) -> None: ...
20
+ def _release (self, value: int = 1) -> None: ...
21
+ def _notify_one(self) -> None: ...
22
+ _value : int
23
+ _waiters: dict[asyncio.Future[None], int]
24
+
25
+ scheduler: Scheduler
26
+
27
+
28
+
29
+ @member(Scheduler)
30
+ def __init__(self: Scheduler, value: int = config.parallel) -> None:
31
+ assert value >= 0
32
+ self.max = value
33
+ self._value = value
34
+ self._waiters = {}
35
+
36
+ @member(Scheduler)
37
+ def schedule(self: Scheduler, value: int = 1) -> typing.AsyncContextManager[None]:
38
+ return Scheduler._ContextManager(self, value)
39
+
40
+ @member(Scheduler._ContextManager)
41
+ def __init__(self: Scheduler._ContextManager, scheduler: Scheduler, value: int):
42
+ self._scheduler = scheduler
43
+ self._value = value
44
+
45
+ @member(Scheduler._ContextManager)
46
+ async def __aenter__(self: Scheduler._ContextManager) -> None:
47
+ return await self._scheduler._acquire(self._value)
48
+
49
+ @member(Scheduler._ContextManager)
50
+ async def __aexit__(self: Scheduler._ContextManager, *args: typing.Any, **kwargs: typing.Any) -> None:
51
+ self._scheduler._release(self._value)
52
+
53
+ @member(Scheduler)
54
+ async def _acquire(self: Scheduler, value: int = 1) -> None:
55
+ if self._value >= value and all(not waiter.cancelled() for waiter in self._waiters.keys()):
56
+ self._value -= value
57
+ return
58
+ future = asyncio.get_event_loop().create_future()
59
+ self._waiters[future] = value
60
+ try:
61
+ try:
62
+ await future
63
+ finally:
64
+ self._waiters.pop(future)
65
+ except asyncio.CancelledError:
66
+ if future.done() and not future.cancelled():
67
+ self._value += value
68
+ raise
69
+ finally:
70
+ while self._value > 0:
71
+ try:
72
+ self._notify_one()
73
+ except Scheduler._NotifyFailedError:
74
+ break
75
+ return
76
+
77
+ @member(Scheduler)
78
+ def _release(self: Scheduler, value: int = 1) -> None:
79
+ self._value += value
80
+ self._notify_one()
81
+
82
+ @member(Scheduler)
83
+ def _notify_one(self: Scheduler) -> None:
84
+ for future in self._waiters.keys():
85
+ if not future.done() and self._value >= self._waiters[future]:
86
+ self._value -= self._waiters[future]
87
+ future.set_result(None)
88
+ return
89
+ raise Scheduler._NotifyFailedError('no waiters notified')
90
+
91
+ scheduler = Scheduler()
@@ -0,0 +1,30 @@
1
+ from cppmakelib.utility.filesystemimport absolute_path, parent_path, create_dir
2
+ from cppmakelib.utility.decorator import member
3
+ import json
4
+
5
+ class CompileCommandsLogger:
6
+ def __init__(self):
7
+ self.file = 'binary/.cache/compile_commands.json'
8
+ try:
9
+ self._content = json.load(open(self.file, 'r'))
10
+ except:
11
+ self._content = []
12
+
13
+ def __del__(self):
14
+ if len(self._content) > 0:
15
+ create_dir(parent_path(self.file))
16
+ json.dump(self._content, open(self.file, 'w'), indent=4)
17
+
18
+ def log_command(self, command, file):
19
+ for entry in self._content:
20
+ if entry['file'] == file:
21
+ self._content.remove(entry)
22
+ self._content.append({
23
+ 'directory': absolute_path('.'),
24
+ 'file' : file,
25
+ 'command' : ' '.join(command)
26
+ })
27
+
28
+
29
+
30
+ compile_commands_logger = CompileCommandsLogger()
File without changes
@@ -0,0 +1,6 @@
1
+ from cppmakelib.utility.filesystem import path
2
+
3
+ class ModuleMapperLogger:
4
+ def mapper_file_of(self, import_dir: path) -> path: ...
5
+
6
+ module_mapper_logger: ModuleMapperLogger
@@ -0,0 +1,224 @@
1
+ from cppmakelib.compiler.all import compiler
2
+ from cppmakelib.error.logic import LogicError
3
+ from cppmakelib.executor.operation import when_all
4
+ from cppmakelib.unit.code import Code
5
+ from cppmakelib.unit.module import Module
6
+ from cppmakelib.unit.object import Object
7
+ from cppmakelib.unit.source import Source
8
+ from cppmakelib.utility.filesystem import path
9
+ from cppmakelib.utility.decorator import member
10
+ import json
11
+ import re
12
+ import typing
13
+
14
+ class UnitStatusLogger:
15
+ # ========
16
+ def __init__ (self, build_cache_dir: path) -> None : ...
17
+ def __del__ (self) -> None : ...
18
+ # ========
19
+ def get_code_preprocessed (self, code : Code) -> bool : ...
20
+ def set_code_preprocessed (self, code : Code, preprocessed: bool) -> None : ...
21
+ # ========
22
+ async def async_get_module_name (self, module: Module) -> str : ...
23
+ def set_module_name (self, module: Module, name : str) -> None : ...
24
+ async def async_get_module_imports (self, module: Module) -> list[path]: ...
25
+ async def async_set_module_imports (self, module: Module, imports : list[path]) -> None : ...
26
+ def get_module_precompiled(self, module: Module) -> bool : ...
27
+ def set_module_precompiled(self, module: Module, precompiled : bool) -> None : ...
28
+ # ========
29
+ async def async_get_source_imports (self, source: Source) -> list[path]: ...
30
+ async def async_set_source_imports (self, source: Source, imports : list[path]) -> None : ...
31
+ def get_source_compiled (self, source: Source) -> bool : ...
32
+ def set_source_compiled (self, source: Source, compiled : bool) -> None : ...
33
+ # ========
34
+ def get_object_libs (self, object: Object) -> list[path]: ...
35
+ def set_object_libs (self, object: Object, libs : list[path]) -> None : ...
36
+ def get_object_shared (self, object: Object) -> bool : ...
37
+ def set_object_shared (self, object: Object, shared : bool) -> None : ...
38
+ def get_object_linked (self, object: Object) -> bool : ...
39
+ def set_object_linked (self, object: Object, linked : bool) -> None : ...
40
+ # ========
41
+
42
+ class _StatusNotFoundError(KeyError):
43
+ pass
44
+ def _get (self, entry: list[str], check: dict[str, typing.Any], result: str) -> typing.Any : ...
45
+ def _set (self, entry: list[str], check: dict[str, typing.Any], result: dict[str, typing.Any]) -> None : ...
46
+ def _reflect(self, object: object) -> dict[str, typing.Any]: ...
47
+ _content : typing.Any
48
+
49
+
50
+
51
+ @member(UnitStatusLogger)
52
+ def __init__(self: UnitStatusLogger, build_cache_dir: path) -> None:
53
+ try:
54
+ self._content = json.load(open(f'{build_cache_dir}/unit_status.json', 'r'))
55
+ except:
56
+ self._content = {}
57
+
58
+ @member(UnitStatusLogger)
59
+ def get_code_preprocessed(self: UnitStatusLogger, code: Code) -> bool:
60
+ try:
61
+ return self._get(entry=['code', 'preprocessed', code.file], check={'code': code, 'compiler': compiler}, result='preprocessed')
62
+ except UnitStatusLogger._StatusNotFoundError:
63
+ return False
64
+
65
+ @member(UnitStatusLogger)
66
+ def set_code_preprocessed(self: UnitStatusLogger, code: Code, preprocessed: bool) -> None:
67
+ self._set(entry=['code', 'preprocessed', code.file], check={'code': code, 'compiler': compiler}, result={'preprocessed': preprocessed})
68
+
69
+ @member(UnitStatusLogger)
70
+ async def async_get_module_name(self: UnitStatusLogger, module: Module) -> str:
71
+ try:
72
+ name = self._get(entry=['module', 'name', module.file], check={'module': module, 'compiler': compiler}, result='name')
73
+ except UnitStatusLogger._StatusNotFoundError:
74
+ await module.async_preprocess()
75
+ statements = re.findall(
76
+ pattern=r'^\s*(export\s+)?module\s+(\w+([\.:]\w+)*)\s*;\s*$',
77
+ string =open(module.preprocessed_file).read(),
78
+ flags =re.MULTILINE
79
+ )
80
+ if len(statements) == 0:
81
+ raise LogicError(f'module {module.file} does not have a export statement')
82
+ elif len(statements) == 1:
83
+ name = statements[0].group(2)
84
+ self.set_module_name(module=module, name=name)
85
+ else: # len(exports) >= 2:
86
+ raise LogicError(f'module {module.file} has multiple export statements (with statements = {statements})')
87
+ return name
88
+
89
+ @member(UnitStatusLogger)
90
+ def set_module_name(self: UnitStatusLogger, module: Module, name: str) -> None:
91
+ self._set(entry=['module', 'name', module.file], check={'module': module, 'compiler': compiler}, result={'name': name})
92
+
93
+ @member(UnitStatusLogger)
94
+ async def async_get_module_imports(self: UnitStatusLogger, module: Module) -> list[path]:
95
+ try:
96
+ imports = self._get(entry=['module', 'imports', module.file], check={'module': module, 'compiler': compiler}, result='imports')
97
+ except UnitStatusLogger._StatusNotFoundError:
98
+ await module.async_preprocess()
99
+ statements = re.findall(
100
+ pattern=r'^\s*import\s+module\s+(\w+([\.:]\w+)*)\s*;\s$',
101
+ string =open(module.preprocessed_file, 'r').read(),
102
+ flags =re.MULTILINE
103
+ )
104
+ imports = [f'{module.context_package.search_module_dir}/{statement.group(1).replace('.', '/').replace(':', '/')}' for statement in statements]
105
+ await self.async_set_module_imports(module=module, imports=imports)
106
+ return imports
107
+
108
+ @member(UnitStatusLogger)
109
+ async def async_set_module_imports(self: UnitStatusLogger, module: Module, imports: list[path]) -> None:
110
+ self._set(entry=['module', 'imports', module.file], check={'module': module, 'compiler': compiler}, result={'imports': imports})
111
+ self._set(entry=['object', 'libs', module.object_file], check={'object': Object(module.object_file), 'compiler': compiler}, result={'libs' : [module.object_file for module in await when_all([Module.__anew__(Module, import_) for import_ in imports])]})
112
+
113
+ @member(UnitStatusLogger)
114
+ def get_module_precompiled(self: UnitStatusLogger, module: Module) -> bool:
115
+ try:
116
+ return self._get(entry=['module', 'precompiled', module.file], check={'module': module, 'compiler': compiler}, result='precompiled')
117
+ except UnitStatusLogger._StatusNotFoundError:
118
+ return False
119
+
120
+ @member(UnitStatusLogger)
121
+ def set_module_precompiled(self: UnitStatusLogger, module: Module, precompiled: bool) -> None:
122
+ self._set(entry=['module', 'precompiled', module.file], check={'module': module, 'compiler': compiler}, result={'precompiled': precompiled})
123
+
124
+ @member(UnitStatusLogger)
125
+ async def async_get_source_imports(self: UnitStatusLogger, source: Source) -> list[path]:
126
+ try:
127
+ imports = self._get(entry=['source', 'imports', source.file], check={'source': source, 'compiler': compiler}, result='imports')
128
+ except UnitStatusLogger._StatusNotFoundError:
129
+ await source.async_preprocess()
130
+ statements = re.findall(
131
+ pattern=r'^\s*import\s+module\s+(\w+([\.:]\w+)*)\s*;\s$',
132
+ string =open(source.preprocessed_file, 'r').read(),
133
+ flags =re.MULTILINE
134
+ )
135
+ imports = [f'{source.context_package.search_module_dir}/{statement.group(1).replace('.', '/').replace(':', '/')}' for statement in statements]
136
+ await self.async_set_source_imports(source=source, imports=imports)
137
+ return imports
138
+
139
+ @member(UnitStatusLogger)
140
+ async def async_set_source_imports(self: UnitStatusLogger, source: Source, imports: list[path]) -> None:
141
+ self._set(entry=['source', 'imports', source.file], check={'source': source, 'compiler': compiler}, result={'imports': imports})
142
+ self._set(entry=['object', 'libs', source.object_file], check={'object': Object(source.object_file), 'compiler': compiler}, result={'libs' : [module.object_file for module in await when_all([Module.__anew__(Module, import_) for import_ in imports])]})
143
+
144
+ @member(UnitStatusLogger)
145
+ def get_source_compiled(self: UnitStatusLogger, source: Source) -> bool:
146
+ try:
147
+ return self._get(entry=['source', 'compiled', source.file], check={'source': source, 'compiler': compiler}, result='compiled')
148
+ except UnitStatusLogger._StatusNotFoundError:
149
+ return False
150
+
151
+ @member(UnitStatusLogger)
152
+ def set_source_compiled(self: UnitStatusLogger, source: Source, compiled: bool) -> None:
153
+ self._set(entry=['source', 'compiled', source.file], check={'source': source, 'compiler': compiler}, result={'compiled': compiled})
154
+
155
+ @member(UnitStatusLogger)
156
+ def get_object_libs(self: UnitStatusLogger, object: Object) -> list[path]:
157
+ try:
158
+ return self._get(entry=['object', 'libs', object.file], check={'object': object, 'compiler': compiler}, result='libs')
159
+ except UnitStatusLogger._StatusNotFoundError:
160
+ raise LogicError(f'object does not have a libs cache (from a module or source)')
161
+
162
+ @member(UnitStatusLogger)
163
+ def set_object_libs(self: UnitStatusLogger, object: Object, libs: list[path]) -> None:
164
+ self._set(entry=['object', 'libs', object.file], check={'object': object, 'compiler': compiler}, result={'libs': libs})
165
+
166
+ @member(UnitStatusLogger)
167
+ def get_object_shared(self: UnitStatusLogger, object: Object) -> bool:
168
+ try:
169
+ return self._get(entry=['object', 'shared', object.file], check={'object': object, 'compiler': compiler}, result='shared')
170
+ except UnitStatusLogger._StatusNotFoundError:
171
+ return False
172
+
173
+ @member(UnitStatusLogger)
174
+ def set_object_shared(self: UnitStatusLogger, object: Object, shared: bool) -> None:
175
+ self._set(entry=['object', 'shared', object.file], check={'object': object, 'compiler': compiler}, result={'shared': shared})
176
+
177
+ @member(UnitStatusLogger)
178
+ def get_object_linked(self: UnitStatusLogger, object: Object) -> bool:
179
+ try:
180
+ return self._get(entry=['object', 'linked', object.file], check={'object': object, 'compiler': compiler}, result='linked')
181
+ except UnitStatusLogger._StatusNotFoundError:
182
+ return False
183
+
184
+ @member(UnitStatusLogger)
185
+ def set_object_linked(self: UnitStatusLogger, object: Object, linked: bool) -> None:
186
+ self._set(entry=['object', 'linked', object.file], check={'object': object, 'compiler': compiler}, result={'linked': linked})
187
+
188
+ @member(UnitStatusLogger)
189
+ def _get(self: UnitStatusLogger, entry: list[str], check: dict[str, typing.Any], result: str) -> typing.Any | typing.Literal[False]:
190
+ ptr = self._content
191
+ for subentry in entry:
192
+ if subentry not in ptr.keys():
193
+ raise UnitStatusLogger._StatusNotFoundError()
194
+ ptr = ptr[subentry]
195
+ for subcheck in check.keys():
196
+ if ptr[subcheck] != self._reflect(ptr[subcheck]):
197
+ raise UnitStatusLogger._StatusNotFoundError()
198
+ return ptr[result]
199
+
200
+ @member(UnitStatusLogger)
201
+ def _set(self: UnitStatusLogger, entry: list[str], check: dict[str, typing.Any], result: dict[str, typing.Any]) -> None:
202
+ ptr = self._content
203
+ for subentry in entry:
204
+ if subentry not in ptr.keys():
205
+ ptr[subentry] = {}
206
+ ptr = ptr[subentry]
207
+ for subcheck in check.keys():
208
+ ptr[subcheck] = self._reflect(check[subcheck])
209
+ for subresult in result.keys():
210
+ ptr[subresult] = self._reflect(result[subresult])
211
+
212
+ @member(UnitStatusLogger)
213
+ def _reflect(self: UnitStatusLogger, object: object) -> dict[str, typing.Any]:
214
+ reflected = vars(object)
215
+ for key, value in reflected.items():
216
+ if hasattr(value, '__dict__'):
217
+ reflected[key] = '...'
218
+ elif isinstance(value, list):
219
+ for index, subvalue in enumerate(typing.cast(list[object], value)):
220
+ value[index] = self._reflect(subvalue)
221
+ else:
222
+ reflected.pop(key)
223
+ return reflected
224
+
@@ -0,0 +1,25 @@
1
+ from cppmakelib.error.config import ConfigError
2
+ from cppmakelib.system.linux import Linux
3
+ from cppmakelib.system.macos import Macos
4
+ from cppmakelib.system.windows import Windows
5
+
6
+ system: Linux | Macos | Windows
7
+
8
+
9
+
10
+ def _choose_system() -> Linux | Macos | Windows:
11
+ matches: list[Linux | Macos | Windows] = []
12
+ errors : list[Exception] = []
13
+ for System in (Linux, Macos, Windows):
14
+ try:
15
+ matches += [System()]
16
+ except ConfigError as error:
17
+ errors += [error]
18
+ if len(matches) == 0:
19
+ raise ConfigError(f'system is not supported (with matches = {matches})') from ExceptionGroup('no compiler is matched', errors)
20
+ elif len(matches) == 1:
21
+ return matches[0]
22
+ else:
23
+ raise ConfigError(f'system is ambiguous (with matches = {matches})')
24
+
25
+ system = _choose_system()
@@ -0,0 +1,26 @@
1
+ from cppmakelib.error.config import ConfigError
2
+ from cppmakelib.utility.decorator import member
3
+ from cppmakelib.utility.filesystem import path
4
+
5
+ import sys
6
+
7
+ class Linux:
8
+ def __init__(self) -> None: ...
9
+ executable_suffix: str = ''
10
+ object_suffix : str = '.o'
11
+ static_suffix : str = '.a'
12
+ dynamic_suffix : str = '.so'
13
+ compiler : path = 'g++'
14
+
15
+ def _check(self) -> None: ...
16
+
17
+
18
+
19
+ @member(Linux)
20
+ def __init__(self: Linux) -> None:
21
+ self._check()
22
+
23
+ @member(Linux)
24
+ def _check(self: Linux) -> None:
25
+ if sys.platform != 'linux':
26
+ raise ConfigError(f'linux check failed (with sys.platform = {sys.platform})')
@@ -0,0 +1,26 @@
1
+ from cppmakelib.error.config import ConfigError
2
+ from cppmakelib.utility.decorator import member
3
+ from cppmakelib.utility.filesystem import path
4
+
5
+ import sys
6
+
7
+ class Macos:
8
+ def __init__(self) -> None: ...
9
+ executable_suffix: str = ''
10
+ object_suffix : str = '.o'
11
+ static_suffix : str = '.a'
12
+ dynamic_suffix : str = '.dylib'
13
+ compiler : path = 'clang++'
14
+
15
+ def _check(self) -> None: ...
16
+
17
+
18
+
19
+ @member(Macos)
20
+ def __init__(self: Macos) -> None:
21
+ self._check()
22
+
23
+ @member(Macos)
24
+ def _check(self: Macos) -> None:
25
+ if sys.platform != 'darwin':
26
+ raise ConfigError(f'macos check failed (with sys.platform = {sys.platform})')
@@ -0,0 +1,26 @@
1
+ from cppmakelib.error.config import ConfigError
2
+ from cppmakelib.utility.decorator import member
3
+ from cppmakelib.utility.filesystem import path
4
+
5
+ import sys
6
+
7
+ class Windows:
8
+ def __init__(self) -> None: ...
9
+ executable_suffix: str = '.exe'
10
+ object_suffix : str = '.obj'
11
+ static_suffix : str = '.lib'
12
+ dynamic_suffix : str = '.dll'
13
+ compiler : path = 'cl.exe'
14
+
15
+ def _check(self) -> None: ...
16
+
17
+
18
+
19
+ @member(Windows)
20
+ def __init__(self: Windows) -> None:
21
+ self._check()
22
+
23
+ @member(Windows)
24
+ def _check(self: Windows) -> None:
25
+ if sys.platform != 'win32' and sys.platform != 'win64':
26
+ raise ConfigError(f'windows check failed (with sys.platform = {sys.platform})')
@@ -0,0 +1,26 @@
1
+ from cppmakelib.basic.context import context
2
+ from cppmakelib.unit.package import Package
3
+ from cppmakelib.utility.decorator import member, unique
4
+ from cppmakelib.utility.filesystem import path
5
+
6
+ class Binary:
7
+ def __new__ (cls, file : path) -> Binary: ...
8
+ def __init__ (self, file : path) -> None : ...
9
+ def install(self, install_dir: path) -> Binary: ...
10
+ async def async_install(self, install_dir: path) -> Binary: ...
11
+ def sign (self) -> Binary: ...
12
+ async def async_sign (self) -> Binary: ...
13
+ def strip (self) -> Binary: ...
14
+ async def async_strip (self) -> Binary: ...
15
+ file : path
16
+ context_package: Package
17
+ link_flags : list[str]
18
+
19
+
20
+
21
+ @member(Binary)
22
+ @unique
23
+ def __init__(self: Binary, file: path) -> None:
24
+ self.file = file
25
+ self.context_package = context.package
26
+ self.link_flags = self.context_package.link_flags
@@ -0,0 +1,62 @@
1
+ from cppmakelib.basic.context import context
2
+ from cppmakelib.compiler.all import compiler
3
+ from cppmakelib.executor.scheduler import scheduler
4
+ from cppmakelib.unit.package import Package
5
+ from cppmakelib.unit.preprocessed import Preprocessed
6
+ from cppmakelib.utility.algorithm import recursive_collect
7
+ from cppmakelib.utility.decorator import member, once, relocatable, syncable, unique
8
+ from cppmakelib.utility.filesystem import modified_time_file, path, relative_path
9
+ from cppmakelib.utility.time import time
10
+
11
+ class Code:
12
+ def __new__ (cls: ..., file: path) -> Code : ...
13
+ async def __anew__ (cls: ..., file: path) -> Code : ...
14
+ def __init__ (self, file: path) -> None : ...
15
+ async def __ainit__ (self, file: path) -> None : ...
16
+ def preprocess (self) -> Preprocessed: ...
17
+ async def async_preprocess (self) -> Preprocessed: ...
18
+ def is_preprocessed(self) -> bool : ...
19
+ async def async_is_preprocessed(self) -> bool : ...
20
+ file : path
21
+ modified_time : time
22
+ preprocessed_file: path
23
+ compile_flags : list[str]
24
+ define_macros : dict[str, str]
25
+ context_package : Package
26
+
27
+
28
+
29
+ @member(Code)
30
+ @relocatable
31
+ @syncable
32
+ @unique
33
+ async def __ainit__(self: Code, file: path) -> None:
34
+ self.file = file
35
+ self.modified_time = modified_time_file(self.file)
36
+ self.context_package = context.package
37
+ self.preprocessed_file = f'{self.context_package.build_code_dir}/{relative_path(from_path=self.context_package.dir, to_path=self.file)}'
38
+ self.compile_flags = self.context_package.compile_flags
39
+ self.define_macros = self.context_package.define_macros
40
+
41
+ @member(Code)
42
+ @syncable
43
+ @once
44
+ async def async_preprocess(self: Code) -> Preprocessed:
45
+ if not await self.async_is_preprocessed():
46
+ async with scheduler.schedule():
47
+ await compiler.async_preprocess(
48
+ code_file =self.file,
49
+ preprocessed_file=self.preprocessed_file,
50
+ compile_flags =self.compile_flags,
51
+ define_macros =self.define_macros,
52
+ include_dirs =[self.context_package.search_header_dir] + recursive_collect(self.context_package, next=lambda package: package.require_packages, collect=lambda package: package.install_include_dir)
53
+ )
54
+ self.context_package.unit_status_logger.set_code_preprocessed(code=self, preprocessed=True)
55
+ return Preprocessed(self.preprocessed_file)
56
+
57
+ @member(Code)
58
+ @syncable
59
+ @once
60
+ async def async_is_preprocessed(self: Code) -> bool:
61
+ return self.context_package.unit_status_logger.get_code_preprocessed(code=self)
62
+
@@ -0,0 +1,12 @@
1
+ from cppmakelib.unit.binary import Binary
2
+ from cppmakelib.utility.decorator import member, unique
3
+ from cppmakelib.utility.filesystem import path
4
+
5
+ class Dynamic(Binary):
6
+ def __new__ (cls, file: path) -> Dynamic: ...
7
+ def __init__ (self, file: path) -> None : ...
8
+
9
+ @member(Dynamic)
10
+ @unique
11
+ def __init__(self: Dynamic, file: path) -> None:
12
+ super(Dynamic, self).__init__(file)
@@ -0,0 +1,35 @@
1
+ from cppmakelib.error.subprocess import SubprocessError
2
+ from cppmakelib.executor.run import async_run
3
+ from cppmakelib.unit.binary import Binary
4
+ from cppmakelib.utility.decorator import member, once, syncable, unique
5
+ from cppmakelib.utility.filesystem import path
6
+
7
+ class Executable(Binary):
8
+ def __new__ (cls, file: path) -> Executable: ...
9
+ def __init__ (self, file: path) -> None : ...
10
+ def execute(self) -> None : ...
11
+ async def async_execute(self) -> None : ...
12
+ def test (self) -> None : ...
13
+ async def async_test (self) -> None : ...
14
+
15
+
16
+
17
+ @member(Executable)
18
+ @unique
19
+ def __init__(self: Executable, file: path) -> None:
20
+ super(Executable, self).__init__(file)
21
+
22
+ @member(Executable)
23
+ @syncable
24
+ @once
25
+ async def async_execute(self: Executable) -> None:
26
+ try:
27
+ await async_run(file=self.file)
28
+ except SubprocessError:
29
+ pass
30
+
31
+ @member(Executable)
32
+ @syncable
33
+ @once
34
+ async def async_test(self: Executable) -> None:
35
+ await async_run(file=self.file)
@@ -0,0 +1,63 @@
1
+ from cppmakelib.compiler.all import compiler
2
+ from cppmakelib.executor.operation import when_all
3
+ from cppmakelib.executor.scheduler import scheduler
4
+ from cppmakelib.unit.code import Code
5
+ from cppmakelib.unit.preparsed import Preparsed
6
+ from cppmakelib.utility.algorithm import recursive_collect
7
+ from cppmakelib.utility.decorator import member, once, relocatable, syncable, unique
8
+ from cppmakelib.utility.filesystem import path, relative_path
9
+
10
+ class Header(Code):
11
+ def __new__ (cls: ..., file: path) -> Header : ...
12
+ async def __anew__ (cls: ..., file: path) -> Header : ...
13
+ def __init__ (self, file: path) -> None : ...
14
+ async def __ainit__ (self, file: path) -> None : ...
15
+ def preparse (self) -> Preparsed: ...
16
+ async def async_preparse (self) -> Preparsed: ...
17
+ def is_preparsed(self) -> bool : ...
18
+ async def async_is_preparsed(self) -> bool : ...
19
+ name : str
20
+ preparsed_file : path
21
+ object_file : path
22
+ diagnostic_file : path
23
+ include_headers : list[Header]
24
+
25
+
26
+
27
+ @member(Header)
28
+ @relocatable
29
+ @syncable
30
+ @unique
31
+ async def __ainit__(self: Header, file: path) -> None:
32
+ await super(Header, self).__ainit__(file)
33
+ self.name = relative_path(from_path=self.context_package.search_header_dir, to_path=self.file)
34
+ self.preparsed_file = f'{self.context_package.build_header_dir}/{self.name}{compiler.preparsed_suffix}'
35
+ self.diagnostic_file = f'{self.context_package.build_header_dir}/{self.name}{compiler.diagnostic_suffix}'
36
+ self.include_headers = await when_all([Header.__anew__(Header, file) for file in self.context_package.unit_status_logger.get_header_includes(header=self)])
37
+
38
+ @member(Header)
39
+ @syncable
40
+ @once
41
+ async def async_preparse(self: Header) -> Preparsed:
42
+ if not await self.async_is_preparsed():
43
+ await when_all([header.async_preparse() for header in self.include_headers])
44
+ await self.async_preprocess()
45
+ async with scheduler.schedule():
46
+ await compiler.async_preparse(
47
+ header_file =self.file,
48
+ preparsed_file =self.preparsed_file,
49
+ compile_flags =self.compile_flags,
50
+ define_macros =self.define_macros,
51
+ include_dirs =[self.context_package.build_header_dir] + recursive_collect(self.context_package, next=lambda package: package.require_packages, collect=lambda package: package.install_include_dir),
52
+ diagnostic_file=self.diagnostic_file
53
+ )
54
+ self.context_package.unit_status_logger.set_header_preparsed(header=self, result=True)
55
+ return Preparsed(self.preparsed_file)
56
+
57
+ @member(Header)
58
+ @syncable
59
+ @once
60
+ async def async_is_preparsed(self: Header) -> bool:
61
+ return all(await when_all([header.async_is_preparsed() for header in self.include_headers])) and \
62
+ await self.async_is_preparsed() and \
63
+ self.context_package.unit_status_logger.get_header_preparsed(header=self)