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.
- cppmake-127.0.16.dist-info/METADATA +191 -0
- cppmake-127.0.16.dist-info/RECORD +55 -0
- {cppmake-127.0.13.dist-info → cppmake-127.0.16.dist-info}/WHEEL +1 -1
- cppmake-127.0.16.dist-info/entry_points.txt +3 -0
- cppmake-127.0.16.dist-info/top_level.txt +3 -0
- cppmaked.py +2 -0
- cppmakelib/__init__.py +32 -0
- cppmakelib/basic/config.py +50 -0
- cppmakelib/basic/context.py +39 -0
- cppmakelib/builder/cmake.py +71 -0
- cppmakelib/builder/include.py +15 -0
- cppmakelib/builder/makefile.py +68 -0
- cppmakelib/compiler/all.py +26 -0
- cppmakelib/compiler/clang.py +196 -0
- cppmakelib/compiler/emcc.py +79 -0
- cppmakelib/compiler/gcc.py +237 -0
- cppmakelib/compiler/msvc.py +24 -0
- cppmakelib/error/config.py +5 -0
- cppmakelib/error/logic.py +6 -0
- cppmakelib/error/subprocess.py +9 -0
- cppmakelib/executor/operation.py +15 -0
- cppmakelib/executor/run.py +84 -0
- cppmakelib/executor/scheduler.py +91 -0
- cppmakelib/logger/compile_commands.py +30 -0
- cppmakelib/logger/make_progress.py +0 -0
- cppmakelib/logger/module_mapper.py +6 -0
- cppmakelib/logger/unit_status.py +224 -0
- cppmakelib/system/all.py +25 -0
- cppmakelib/system/linux.py +26 -0
- cppmakelib/system/macos.py +26 -0
- cppmakelib/system/windows.py +26 -0
- cppmakelib/unit/binary.py +26 -0
- cppmakelib/unit/code.py +62 -0
- cppmakelib/unit/dynamic.py +12 -0
- cppmakelib/unit/executable.py +35 -0
- cppmakelib/unit/header.py +63 -0
- cppmakelib/unit/module.py +69 -0
- cppmakelib/unit/object.py +71 -0
- cppmakelib/unit/package.py +87 -0
- cppmakelib/unit/precompiled.py +6 -0
- cppmakelib/unit/preparsed.py +6 -0
- cppmakelib/unit/preprocessed.py +3 -0
- cppmakelib/unit/source.py +64 -0
- cppmakelib/utility/algorithm.py +44 -0
- cppmakelib/utility/color.py +14 -0
- cppmakelib/utility/decorator.py +120 -0
- cppmakelib/utility/filesystem.py +71 -0
- cppmakelib/utility/import_.py +21 -0
- cppmakelib/utility/remote/client.py +2 -0
- cppmakelib/utility/remote/protocol.py +32 -0
- cppmakelib/utility/remote/remote.py +43 -0
- cppmakelib/utility/remote/server.py +0 -0
- cppmakelib/utility/time.py +1 -0
- cppmakelib/utility/version.py +65 -0
- cppmake-127.0.13.dist-info/METADATA +0 -9
- cppmake-127.0.13.dist-info/RECORD +0 -6
- cppmake-127.0.13.dist-info/entry_points.txt +0 -2
- cppmake-127.0.13.dist-info/top_level.txt +0 -1
- /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
|
+

|
|
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,,
|
cppmaked.py
ADDED
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()
|