cppmake 127.0.14__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.14.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.14.dist-info/METADATA +0 -9
  56. cppmake-127.0.14.dist-info/RECORD +0 -6
  57. cppmake-127.0.14.dist-info/entry_points.txt +0 -2
  58. cppmake-127.0.14.dist-info/top_level.txt +0 -1
  59. /cppmake/__main__.py → /cppmake.py +0 -0
@@ -0,0 +1,191 @@
1
+ Metadata-Version: 2.4
2
+ Name: cppmake
3
+ Version: 127.0.16
4
+ Summary: A modern C++ builder based on C++20 Modules.
5
+ Author-email: shyeyian <shyeyian@icloud.com>
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.13
8
+ Description-Content-Type: text/markdown
9
+
10
+ # Cppmake: A C++20 Modules Build System
11
+
12
+ Cppmake is a modern, fast, and accurate C++ build system focusing on C++20 Modules.
13
+
14
+ Cppmake aims to
15
+ - Make everything modular.
16
+ - Easily modularize third-party libraries.
17
+ - Be fast, parallel, and fully cached.
18
+
19
+ Cppmake is written in pure Python with no additional pip dependencies.
20
+
21
+ # Show
22
+
23
+ ![vedio](share/make.gif)
24
+
25
+ # Install
26
+
27
+ Use pip to install cppmake:
28
+ ```sh
29
+ pip install cppmake
30
+ ```
31
+ Or install from source:
32
+ ```sh
33
+ git clone https://github.com/anonymouspc/cppmake
34
+ cd cppmake
35
+ python install.py
36
+ ```
37
+
38
+ # Getting Started
39
+
40
+ In a cppmake project:
41
+ - module `aaa.bbb` should be placed at `module/aaa/bbb.cpp`
42
+ - module `aaa:ccc` should be placed at `module/aaa/ccc.cpp`
43
+ - source `main` should be placed at `source/main.cpp`
44
+ - `std` module will be auto-installed.
45
+
46
+ For example:
47
+ ```
48
+ ├── module
49
+ │ ├── aaa.cpp
50
+ │ ├── aaa
51
+ │ │ ├── bbb.cpp // aaa.bbb
52
+ │ │ └── ccc.cpp // aaa:ccc
53
+ │ └── ddd.cpp
54
+ ├── source
55
+ │ └── main.cpp
56
+ └── cppmake.py
57
+ ```
58
+ Then, run
59
+ ```sh
60
+ cppmake
61
+ ```
62
+ The output will be generated in the `binary/` directory.
63
+
64
+ # Advanced
65
+
66
+ Cppmake provides various configurable options, such as:
67
+ ```sh
68
+ cppmake --compiler=clang++ --std=c++23
69
+ ```
70
+ ```sh
71
+ cppmake --compiler=/opt/gcc/bin/g++ --linker=lld --std=c++26 --type=release --target=make --parallel=$(nproc)
72
+ ```
73
+
74
+ System/compiler support:
75
+ | | clang | emcc | gcc | msvc |
76
+ |:-------:|:-----:|:----:|:---:|:----:|
77
+ | Linux | ✓ | ✓ | ✓ | N/A |
78
+ | Macos | ✓ | ✓ | ✓ | N/A |
79
+ | Windows | ✗ | ✗ | ✗ | ✗ |
80
+ - ✓: Supported and tested.
81
+ - ✗: Not implemented yet; planned for future releases.
82
+ - *(The author does not own a Windows PC. Contributions for Windows support are welcome!)*
83
+
84
+ # Configure
85
+
86
+ Cppmake uses a `cppmake.py` file (pure Python) to describe the C++ project. The configuration is entirely standard Python syntax.
87
+
88
+ For example:
89
+ ```py
90
+ from cppmakelib import *
91
+ def make():
92
+ Source("main").compile()
93
+ ```
94
+ This `cppmake.py` defines a single source `source/main.cpp`, which will be
95
+ built into a binary.
96
+ - *(Imported modules and packages will be built automatically before compiling the source. For example, if `source/main.cpp` imports module my_module and module `boost.asio`, then Cppmake will precompile module `my_module`, cmake build `boost`, and precompile module `boost.asio` before finally compiling `source/main.cpp`.)*
97
+ - *(By default, the imported modules and packages form a [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) and will be executed with maximum possible parallelism, depending on your cpu thread count. You can control the level of parallelism using `cppmake --parallel=N`, or force serial compilation through `cppmake --parallel=1`.)*
98
+
99
+ Another example:
100
+ ```py
101
+ from cppmakelib import *
102
+
103
+ if type(compiler) == Gcc:
104
+ compiler.compile_flags += ["-fno-inline"] # global
105
+ compiler.define_macros |= {"NDEBUG": '1'} # global
106
+
107
+ package.define_macros = {"MY_MACRO": "42"} # package-local
108
+
109
+ def build(): # select a source file to compile
110
+ if type(system) == Linux:
111
+ Source("linux").compile()
112
+
113
+ def test(): # compile and test all units
114
+ for file in iterate_dir("source/test", recursive=True):
115
+ Source(file=file).compile()
116
+ Executable(file=file).run()
117
+ ```
118
+ This `cppmake.py` defines 2 targets (switchable via
119
+ `cppmake --target=build|test`) and several configuration rules. You can
120
+ easily extend it with any other Python code.
121
+
122
+ # Integrating third-party packages
123
+
124
+ Third-party packages should be located in `package/`, for example
125
+ ```
126
+ ├── module
127
+ │ ├── aaa.cpp
128
+ │ ├── aaa
129
+ │ │ ├── bbb.cpp // aaa.bbb
130
+ │ │ └── ccc.cpp // aaa:ccc
131
+ │ └── ddd.cpp
132
+ ├── source
133
+ │ └── main.cpp
134
+ ├── package
135
+ │ ├── boost
136
+ │ │ ├── git
137
+ │ │ │ └── [git clone]
138
+ │ │ ├── module
139
+ │ │ │ ├── boost.cpp // boost
140
+ │ │ │ └── boost
141
+ │ │ │ ├── asio.cpp // boost.asio
142
+ │ │ │ ├── beast.cpp // boost.beast
143
+ │ │ │ └── numeric.cpp // boost.numeric
144
+ │ │ │ ├── interval.cpp // boost.numeric.interval
145
+ │ │ │ └── ublas.cpp // boost.numeric.ublas
146
+ │ │ └── cppmake.py
147
+ │ └── eigen
148
+ │ ├── git
149
+ │ │ └── [git clone]
150
+ │ ├── module
151
+ │ │ └── eigen.cpp // eigen
152
+ │ └── cppmake.py
153
+ └── cppmake.py
154
+ ```
155
+
156
+ In `package/boost/cppmake.py` we can define a `build()` function to describe how this package should be built. For example:
157
+ ```py
158
+ # package/boost/cppmake.py
159
+ from cppmakelib import *
160
+
161
+ def build():
162
+ cmake.build(
163
+ package=package,
164
+ args=[
165
+ "-DBUILD_SHARED_LIBS=OFF"
166
+ ]
167
+ )
168
+ ```
169
+ Then:
170
+ ```cpp
171
+ // package/boost/module/boost/asio.cpp
172
+ module;
173
+ #include <boost/asio.hpp>
174
+ export module boost.asio;
175
+ export namespace boost::asio
176
+ {
177
+ using boost::asio::io_context;
178
+ //...
179
+ }
180
+ ```
181
+ will modularize boost.asio into a module.
182
+
183
+ Builder support:
184
+ | cmake | include* | makefile | meson | msbuild |
185
+ |:-----:|:--------:|:--------:|:-----:|:-------:|
186
+ | ✓ | ✓ | ✓ |(soon) | ✗ |
187
+ - ✓: Supported and tested.
188
+ - ✗: Not implemented yet; planned for future releases.
189
+ - *(include: means header-only libraries.)*
190
+
191
+ # Thank you!
@@ -0,0 +1,55 @@
1
+ cppmake.py,sha256=xbfuYDNg1BJ2MQKqP-nBZ0FGSoEB651FAxeWoR-Dyrk,1316
2
+ cppmaked.py,sha256=53d6Byv2xUv31UAoMHH5Lym6Q5SSIdYm5Oj8-2b-T0E,19
3
+ cppmakelib/__init__.py,sha256=meHRNq2JVOGvxkShKnmCuNeMsJ4t0Bp1yHQ8j7xisHQ,1123
4
+ cppmakelib/basic/config.py,sha256=f-Pb7xGzy7z7Y6symG3wgLzqgxsOps6Rd3cnZL8qog8,2594
5
+ cppmakelib/basic/context.py,sha256=BUL5i1Ii8TB_iyTDYS1PWQz1AjfiSGnk5ha7EJFTwxE,1297
6
+ cppmakelib/builder/cmake.py,sha256=DDI1bQxgubc4d8_-6710Ztz_Q0kCO1jHusVaR_fvKa4,2398
7
+ cppmakelib/builder/include.py,sha256=G4WVZLOxxLPwpJDKCW1OBMc-d8n1vGEHQJpOr1DMhHI,586
8
+ cppmakelib/builder/makefile.py,sha256=k1uSDpFSXBqEyFMnarrNM1luQD8Ah_jN2sSvGQYT7WM,2258
9
+ cppmakelib/compiler/all.py,sha256=0zYy3qF0WwF2JGztUs_JK7WgbXOZmXMxgM2EHErVYmc,948
10
+ cppmakelib/compiler/clang.py,sha256=GhOmnYlNcpQ0kKB3rWjmZnMR0R5uUcBkN1k6Zo5m4ns,8863
11
+ cppmakelib/compiler/emcc.py,sha256=N33g7nYFphltbvW8VA3crt178fdX2ZZjnYofBcnUCEA,3151
12
+ cppmakelib/compiler/gcc.py,sha256=vqE9iJMGEY82cWzGScDjLHuWijPCgf7faqEA3hoof6g,12035
13
+ cppmakelib/compiler/msvc.py,sha256=8AeKDFWGh4efg0xs8N52lVMA1qdVS_ggzeWgFaPyq08,707
14
+ cppmakelib/error/config.py,sha256=lUUIJJJHM20UDVzFq9Ar4eOqlJHPfCTSjtkHoOARFkw,167
15
+ cppmakelib/error/logic.py,sha256=ovqfqfM41Ar_LDB5NqisEPYK8ppAo4cFIimZFRGNmnQ,167
16
+ cppmakelib/error/subprocess.py,sha256=NyrH4g0CTM2OP0esJtwwbmNczqdfBepHLGC3M8IRdps,312
17
+ cppmakelib/executor/operation.py,sha256=A7P7v2JxvA-FjtOwep20Hl2OzbE1-j8lrZg8IfkpD8Q,652
18
+ cppmakelib/executor/run.py,sha256=Gq5O5CPjPEzoTkJPpNOWwj0WV8rwOfsTEj6qoI8x0Ok,5599
19
+ cppmakelib/executor/scheduler.py,sha256=UKEWy3U9mwQIiwxOloQDNKsuI6Iw0JJ7yklvtqxXeIE,3081
20
+ cppmakelib/logger/compile_commands.py,sha256=vw4cgBofHK5tLqIJJn1AxPIDiVoK271m9zO4-0krs9I,922
21
+ cppmakelib/logger/make_progress.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ cppmakelib/logger/module_mapper.py,sha256=htD2bT2pz564zxokttSqLuSOv2UU4X1rdpEhuGWfh4w,176
23
+ cppmakelib/logger/unit_status.py,sha256=w1gng94cSxPsCyeb2NJ4izcN_cSFJCRj3Ezcru4jSKc,12405
24
+ cppmakelib/system/all.py,sha256=SCGq5GSNrWlTWuE2hx8DEJsS-utrAZQiOrHyv5zbStQ,850
25
+ cppmakelib/system/linux.py,sha256=3Qt8M_b7R_mnPRGZ_CPgEY9YHwRauWZDcRJHBEmWfP4,659
26
+ cppmakelib/system/macos.py,sha256=u52SQfJ38cYdzBJlxWW-n1mHyjPS4qOC9CEsrWZ6FeE,667
27
+ cppmakelib/system/windows.py,sha256=wcn70tEKRAiQs3abGhTqMmU0qxuQVMjuGnStuBeFAbY,711
28
+ cppmakelib/unit/binary.py,sha256=gvv0ZHFQRlyMVrDJ8SmTioORpxWevoxzCP4GoHIh_u8,1058
29
+ cppmakelib/unit/code.py,sha256=HrGyHaqsJ56LN9mRp-Odlxj81GqRMbBk9p2HaxTW5tE,2865
30
+ cppmakelib/unit/dynamic.py,sha256=qxa--uJzU-SnNiBn0UJ1lh7iWGhBX9aJbr3nVJjFNq4,395
31
+ cppmakelib/unit/executable.py,sha256=Rn_BfxEiUv6x-nNzNaNiba620hy-0iTsoEesczKh5F8,1129
32
+ cppmakelib/unit/header.py,sha256=__9hwYSW6pp0LMVqvDjiN2P3THb2t6tUh8DbHIjgxQs,3179
33
+ cppmakelib/unit/module.py,sha256=tH3VBvr93nmmlbCqxoW_EMxqSOd5oTLK-oMCkHxojiM,3744
34
+ cppmakelib/unit/object.py,sha256=leH5FrxSR5tqGFCTtcK1pyjMgmaWoitGfoSHe2Ugcz0,3565
35
+ cppmakelib/unit/package.py,sha256=PQbgVo1VOW5jsvABF-nqQhkaI0oOan5x12WwIHmmvOA,3748
36
+ cppmakelib/unit/precompiled.py,sha256=5VRzdb8-GOByzZH9UmHZSW2-11-wNIWuLW6n2dJ8f9k,233
37
+ cppmakelib/unit/preparsed.py,sha256=N3PuBlSkWcrR9sUay23-gP8SU3eV9oH8rRKBDQKTBpU,227
38
+ cppmakelib/unit/preprocessed.py,sha256=DiCouO_9jqPjMp5fOa_ofkoIPqT6PGmlnfJD2htX7ow,68
39
+ cppmakelib/unit/source.py,sha256=bijgUDu9q07WjY65y_tqOA1JVOIB1D-0DR24gLnRVTc,3316
40
+ cppmakelib/utility/algorithm.py,sha256=lssr2pwtZg4ozWiN994YNM_8hpkuO5ypwAgePHj2-3E,1883
41
+ cppmakelib/utility/color.py,sha256=KOEt_116tXpl-houoRRaAgDtICUt1JxwsBC3RznbvO8,259
42
+ cppmakelib/utility/decorator.py,sha256=7JQ7weTQvuUeUgS-LodIi4YdgCe-7k2rV3mjw-Zu7Vw,6936
43
+ cppmakelib/utility/filesystem.py,sha256=stvMjUY7rHwgPu5F4u4tHwcIVQF_DQ-MmD5AB6qE7OQ,2580
44
+ cppmakelib/utility/import_.py,sha256=3S01IgezSNxWwKpGK2si1w1TGkk_CxR4aDSJ88U0t6w,788
45
+ cppmakelib/utility/time.py,sha256=n6YjgHOpXg7-1LFMzOw2UOr5XDXaWi4ub3CuotfwhPU,10
46
+ cppmakelib/utility/version.py,sha256=_IvzOQNnrOAxUWLGMyZ4OeGZoTKFJ_LKqNelkTgusP8,3088
47
+ cppmakelib/utility/remote/client.py,sha256=5FEQ86-f-j0Vm_uLJ3SSIKYStBwM2VqbogkTPEMKt0s,22
48
+ cppmakelib/utility/remote/protocol.py,sha256=W5l08clEfMDdMK1pwSh8viKeI0bEanyDuse5gTC7ecc,1094
49
+ cppmakelib/utility/remote/remote.py,sha256=_Js4McneDRc4QsV0aiYmkIFfxPyMP1N7TqLu2i702nk,1398
50
+ cppmakelib/utility/remote/server.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ cppmake-127.0.16.dist-info/METADATA,sha256=ASQW5jswoXJHsKiyoDzXfzyc3oSbZpTH3mzAkbjyEZA,5727
52
+ cppmake-127.0.16.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
53
+ cppmake-127.0.16.dist-info/entry_points.txt,sha256=j0a6PH2Oo88b4nX0-m6CWSUQ0Lb3SYH5GDBtdECK_8k,66
54
+ cppmake-127.0.16.dist-info/top_level.txt,sha256=DQF_BjuSUuvQMC6xFPikLsxY9Fp72ygEJiEgh5xTjC0,28
55
+ cppmake-127.0.16.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ cppmake = cppmake:main
3
+ cppmaked = cppmaked:main
@@ -0,0 +1,3 @@
1
+ cppmake
2
+ cppmaked
3
+ cppmakelib
cppmaked.py ADDED
@@ -0,0 +1,2 @@
1
+ def main():
2
+ ...
cppmakelib/__init__.py ADDED
@@ -0,0 +1,32 @@
1
+ from .basic.config import config
2
+
3
+ from .builder.cmake import cmake
4
+ from .builder.include import include
5
+ from .builder.makefile import makefile
6
+
7
+ from .compiler.all import compiler
8
+ from .compiler.clang import Clang
9
+ from .compiler.emcc import Emcc
10
+ from .compiler.gcc import Gcc
11
+ from .compiler.msvc import Msvc
12
+
13
+ from .error.config import ConfigError
14
+ from .error.logic import LogicError
15
+ from .error.subprocess import SubprocessError
16
+
17
+ from .utility.filesystem import path, exist_file, exist_dir, create_file, create_dir, copy_file, copy_dir, remove_file, remove_dir, modified_time_file, iterate_dir
18
+
19
+ from .execution.operation import sync_wait, start_detached, when_all, when_any
20
+ from .execution.run import run
21
+
22
+ from .system.all import system
23
+ from .system.linux import Linux
24
+ from .system.macos import Macos
25
+ from .system.windows import Windows
26
+
27
+ from .unit.executable import Executable
28
+ from .unit.module import Module
29
+ from .unit.package import Package
30
+ from .unit.source import Source
31
+
32
+ self: Package
@@ -0,0 +1,50 @@
1
+ from cppmakelib.utility.filesystem import path
2
+ from cppmakelib.system.all import system
3
+ from cppmakelib.utility.decorator import member
4
+ import argparse
5
+ import functools
6
+ import os
7
+ import sys
8
+ import typing
9
+
10
+ class Config(argparse.Namespace):
11
+ def __init__ (self) -> None: ...
12
+ @functools.wraps(argparse.ArgumentParser.add_argument)
13
+ def add_argument(self, *args: ..., **kwargs: ...) -> None: ...
14
+ project : path
15
+ target : str
16
+ compiler: path
17
+ std : typing.Literal['c++20'] | typing.Literal['c++23'] | typing.Literal['c++26']
18
+ type : typing.Literal['debug'] | typing.Literal['release'] | typing.Literal['size']
19
+ jobs : int
20
+ verbose : bool
21
+
22
+ _parser: argparse.ArgumentParser
23
+
24
+ config: Config
25
+
26
+
27
+
28
+ @member(Config)
29
+ def __init__(self: Config) -> None:
30
+ self._parser = argparse.ArgumentParser()
31
+ self._parser.usage = 'cppmake [project] [options...]'
32
+ self._parser.add_argument('project', nargs='?', default='.', help=f'path to C++ project dir (example: ., .., /home/my/project; requires: containing cppmake.py; default: .)')
33
+ self._parser.add_argument('--target', default='make', help=f'select cppmake target (example: make, build, test; requires: defined in cppmake.py; default: make)')
34
+ self._parser.add_argument('--compiler', default=system.compiler, help=f'use specific C++ compiler (example: g++, /usr/bin/g++, /opt/homebrew/clang++; requires: executable; default: {system.compiler})')
35
+ self._parser.add_argument('--std', choices=['c++20', 'c++23', 'c++26'], default='c++26', help=f'use specific C++ standard (default: c++26)')
36
+ self._parser.add_argument('--type', choices=['debug', 'release', 'size'], default='debug', help=f'choose config type (default: debug)')
37
+ self._parser.add_argument('--jobs', type =lambda n: int(n), default=os.cpu_count(), help=f'allow maximun concurrency (default: {os.cpu_count()})')
38
+ self._parser.add_argument('--verbose', action ='store_true', default=False, help=f'print verbose outputs')
39
+ self._parser.parse_args(namespace=self)
40
+
41
+ @member(Config)
42
+ def add_argument(self: Config, *args: ..., **kwargs: ...) -> None:
43
+ self._parser.add_argument(*args, **kwargs)
44
+ self._parser.parse_args(namespace=self)
45
+
46
+ config = Config()
47
+
48
+ sys.dont_write_bytecode = True
49
+ os.chdir(config.project)
50
+ os.environ['LANG'] = 'C'
@@ -0,0 +1,39 @@
1
+ from cppmakelib.unit.package import Package
2
+ from cppmakelib.utility.decorator import member
3
+ import typing
4
+
5
+ class Context:
6
+ def switch(self, package: Package) -> typing.ContextManager[None]: ...
7
+ package: Package
8
+
9
+ class _ContextManager:
10
+ def __init__ (self, context: Context, package: Package) -> None: ...
11
+ def __enter__(self) -> None: ...
12
+ def __exit__ (self, *args: typing.Any, **kwargs: typing.Any) -> None: ...
13
+ context : Context
14
+ old_package: Package
15
+ new_package: Package
16
+
17
+ context: Context
18
+
19
+
20
+
21
+ @member(Context)
22
+ def switch(self: Context, package: Package) -> typing.ContextManager[None]:
23
+ return Context._ContextManager(self, package)
24
+
25
+ @member(Context._ContextManager)
26
+ def __init__(self: Context._ContextManager, context: Context, package: Package) -> None:
27
+ self.context = context
28
+ self.old_package = context.package
29
+ self.new_package = package
30
+
31
+ @member(Context._ContextManager)
32
+ def __enter__(self: Context._ContextManager) -> None:
33
+ self.context.package = self.new_package
34
+
35
+ @member(Context._ContextManager)
36
+ def __exit__(self: Context._ContextManager, *args: typing.Any, **kwargs: typing.Any) -> None:
37
+ self.context.package = self.old_package
38
+
39
+ context = Context()
@@ -0,0 +1,71 @@
1
+ from cppmakelib.basic.config import config
2
+ from cppmakelib.compiler.all import compiler
3
+ from cppmakelib.executor.run import async_run
4
+ from cppmakelib.utility.filesystemimport path, create_dir, remove_dir
5
+ from cppmakelib.utility.algorithm import recursive_collect
6
+ from cppmakelib.utility.decorator import syncable, unique
7
+ from cppmakelib.utility.version import Version
8
+
9
+ class Cmake:
10
+ name: str = 'cmake'
11
+ def __init__ (self, path: path = path('cmake')) -> None: ...
12
+ async def __ainit__(self, path: path = path('cmake')) -> None: ...
13
+ def async_build(self, package: Package, args: list[str]) -> None: ...
14
+
15
+
16
+
17
+ async def __ainit__(self, path: path = path('cmake')):
18
+ self.path = path
19
+ self.version = await self._async_get_version()
20
+
21
+ @syncable
22
+ async def async_build(self, package, args):
23
+ try:
24
+ create_dir(package.build_dir)
25
+ await async_run(
26
+ command=[
27
+ self.path,
28
+ '-S', package.git_dir,
29
+ '-B', package.build_dir,
30
+ f'-DCMAKE_BUILD_TYPE={config.type}',
31
+ f'-DCMAKE_CXX_COMPILER={compiler.path}',
32
+ f'-DCMAKE_CXX_FLAGS={' '.join(compiler.compile_flags + package.compile_flags)}',
33
+ f'-DCMAKE_PREFIX_PATH={';'.join(recursive_collect(package, next=lambda package: package.require_packages, collect=lambda package: package.install_dir))}',
34
+ f'-DCMAKE_INSTALL_PREFIX={package.install_dir}',
35
+ '-DCMAKE_INSTALL_LIBDIR=lib',
36
+ *args
37
+ ]
38
+ )
39
+ except:
40
+ remove_dir(package.build_dir)
41
+ raise
42
+ try:
43
+ await async_run(
44
+ command=[
45
+ self.path,
46
+ '--build', package.build_dir,
47
+ '-j', str(config.parallel)
48
+ ]
49
+ )
50
+ except:
51
+ raise
52
+ try:
53
+ create_dir(package.install_dir)
54
+ await async_run(
55
+ command=[
56
+ self.path,
57
+ '--install', package.build_dir,
58
+ '-j', str(config.parallel)
59
+ ]
60
+ )
61
+ except:
62
+ remove_dir(package.install_dir)
63
+ raise
64
+
65
+ async def _async_get_version(self):
66
+ return await Version.async_parse(
67
+ name =self.name,
68
+ command=[self.path, '--version'],
69
+ check =lambda stdout: stdout.startswith('cmake'),
70
+ lowest =4
71
+ )
@@ -0,0 +1,15 @@
1
+ from cppmakelib.utility.filesystemimport create_dir, remove_dir, copy_file, copy_dir
2
+
3
+ def include(package, file=None, dir=None, relpath='.'):
4
+ try:
5
+ create_dir(f'{package.include_dir}/{relpath}')
6
+ if file is not None and dir is None:
7
+ copy_file(f'{package.git_dir}/{file}', f'{package.include_dir}/{relpath}/{file}')
8
+ elif file is None and dir is not None:
9
+ copy_dir (f'{package.git_dir}/{dir}', f'{package.include_dir}/{relpath}/')
10
+ else:
11
+ assert False
12
+ except:
13
+ remove_dir(package.install_dir)
14
+ raise
15
+
@@ -0,0 +1,68 @@
1
+ from cppmakelib.basic.config import config
2
+ from cppmakelib.compiler.all import compiler
3
+ from cppmakelib.executor.run import async_run
4
+ from cppmakelib.utility.filesystemimport absolute_path, create_dir, remove_dir
5
+ from cppmakelib.utility.decorator import syncable, unique
6
+ from cppmakelib.utility.version import Version
7
+
8
+ class Makefile:
9
+ name = 'makefile'
10
+
11
+ @syncable
12
+ @unique
13
+ async def __ainit__(self, path='make'):
14
+ self.path = path
15
+ self.version = await self._async_get_version()
16
+
17
+ @syncable
18
+ async def async_build(self, package, file='configure', args=[]):
19
+ try:
20
+ create_dir(package.build_dir)
21
+ await async_run(
22
+ command=[
23
+ f'{package.git_dir}/{file}',
24
+ f'CXX={compiler.path}',
25
+ f'CXXFLAGS={' '.join(compiler.compile_flags + package.compile_flags)}'
26
+ f'--prefix={absolute_path(package.install_dir)}',
27
+ f'--libdir={absolute_path(package.install_dir)/'lib'}',
28
+ *args
29
+ ],
30
+ cwd=package.build_dir
31
+ )
32
+ except:
33
+ remove_dir(package.build_dir)
34
+ raise
35
+ try:
36
+ await async_run(
37
+ command=[
38
+ self.path,
39
+ f'CXX={compiler.path}',
40
+ f'CXXFLAGS={' '.join(compiler.compile_flags + package.compile_flags)}'
41
+ '-C', package.build_dir,
42
+ '-j', str(config.parallel)
43
+ ]
44
+ )
45
+ except:
46
+ raise
47
+ try:
48
+ create_dir(package.install_dir)
49
+ await async_run(
50
+ command=[
51
+ self.path, 'install'
52
+ '-C', package.build_dir,
53
+ '-j', str(config.parallel)
54
+ ]
55
+ )
56
+ except:
57
+ remove_dir(package.install_dir)
58
+ raise
59
+
60
+ async def _async_get_version(self):
61
+ return await Version.async_parse(
62
+ name ='makefile',
63
+ command=[self.path, '--version'],
64
+ check =lambda stdout: stdout.startswith('GNU Make'),
65
+ lowest =4
66
+ )
67
+
68
+ makefile = Makefile()
@@ -0,0 +1,26 @@
1
+ from cppmakelib.basic.config import config
2
+ from cppmakelib.compiler.clang import Clang
3
+ from cppmakelib.compiler.emcc import Emcc
4
+ from cppmakelib.compiler.gcc import Gcc
5
+ from cppmakelib.error.config import ConfigError
6
+
7
+ compiler: Clang | Emcc | Gcc
8
+
9
+
10
+
11
+ def _choose_compiler() -> Clang | Emcc | Gcc:
12
+ matches: list[Clang | Emcc | Gcc] = []
13
+ errors : list[Exception] = []
14
+ for Compiler in (Clang, Emcc, Gcc):
15
+ try:
16
+ matches += [Compiler(config.compiler)]
17
+ except ConfigError as error:
18
+ errors += [error]
19
+ if len(matches) == 0:
20
+ raise ConfigError(f'compiler is not supported (with path = {config.compiler}, matches = {matches})') from ExceptionGroup('no compiler is matched', errors)
21
+ elif len(matches) == 1:
22
+ return matches[0]
23
+ else:
24
+ raise ConfigError(f'compiler is ambiguous (with path = {config.compiler}, matches = {matches})')
25
+
26
+ compiler = _choose_compiler()