15
15
import subprocess
16
16
import sys
17
17
import typing
18
+ from shlex import quote as shellquote
18
19
from typing import Optional
19
20
21
+ from .copytree import simple_copytree
20
22
from .dyndeps import create_dyn_dep_munger
21
23
from .envfuncs import add_path_entry , Env , path_search
22
24
from .fetcher import copy_if_different
@@ -157,6 +159,29 @@ def debug(self, reconfigure: bool) -> None:
157
159
shell = ["powershell.exe" ] if sys .platform == "win32" else ["/bin/sh" , "-i" ]
158
160
self ._run_cmd (shell , cwd = self .build_dir , env = env )
159
161
162
+ def printenv (self , reconfigure : bool ) -> None :
163
+ """print the environment in a shell sourcable format"""
164
+ reconfigure = self ._reconfigure (reconfigure )
165
+ self ._apply_patchfile ()
166
+ self ._prepare (reconfigure = reconfigure )
167
+ env = self ._compute_env (env = Env (src = {}))
168
+ prefix = "export "
169
+ sep = ":"
170
+ expand = "$"
171
+ expandpost = ""
172
+ if self .build_opts .is_windows ():
173
+ prefix = "SET "
174
+ sep = ";"
175
+ expand = "%"
176
+ expandpost = "%"
177
+ for k , v in sorted (env .items ()):
178
+ existing = os .environ .get (k , None )
179
+ if k .endswith ("PATH" ) and existing :
180
+ v = shellquote (v ) + sep + f"{ expand } { k } { expandpost } "
181
+ else :
182
+ v = shellquote (v )
183
+ print ("%s%s=%s" % (prefix , k , v ))
184
+
160
185
def build (self , reconfigure : bool ) -> None :
161
186
print ("Building %s..." % self .manifest .name )
162
187
reconfigure = self ._reconfigure (reconfigure )
@@ -225,14 +250,16 @@ def _build(self, reconfigure) -> None:
225
250
system needs to regenerate its rules."""
226
251
pass
227
252
228
- def _compute_env (self ):
253
+ def _compute_env (self , env = None ) -> Env :
254
+ if env is None :
255
+ env = self .env
229
256
# CMAKE_PREFIX_PATH is only respected when passed through the
230
257
# environment, so we construct an appropriate path to pass down
231
258
return self .build_opts .compute_env_for_install_dirs (
232
259
self .loader ,
233
260
self .dep_manifests ,
234
261
self .ctx ,
235
- env = self . env ,
262
+ env = env ,
236
263
manifest = self .manifest ,
237
264
)
238
265
@@ -461,6 +488,61 @@ def _build(self, reconfigure) -> None:
461
488
self ._run_cmd (install_cmd , env = env )
462
489
463
490
491
+ class SystemdBuilder (BuilderBase ):
492
+ # SystemdBuilder assumes that meson build tool has already been installed on
493
+ # the machine.
494
+ def __init__ (
495
+ self ,
496
+ loader ,
497
+ dep_manifests ,
498
+ build_opts ,
499
+ ctx ,
500
+ manifest ,
501
+ src_dir ,
502
+ build_dir ,
503
+ inst_dir ,
504
+ ) -> None :
505
+ super (SystemdBuilder , self ).__init__ (
506
+ loader ,
507
+ dep_manifests ,
508
+ build_opts ,
509
+ ctx ,
510
+ manifest ,
511
+ src_dir ,
512
+ build_dir ,
513
+ inst_dir ,
514
+ )
515
+
516
+ def _build (self , reconfigure ) -> None :
517
+ env = self ._compute_env ()
518
+ meson = path_search (env , "meson" )
519
+ if meson is None :
520
+ raise Exception ("Failed to find Meson" )
521
+
522
+ # Meson builds typically require setup, compile, and install steps.
523
+ # During this setup step we ensure that the static library is built and
524
+ # the prefix is empty.
525
+ self ._run_cmd (
526
+ [
527
+ meson ,
528
+ "setup" ,
529
+ "-Dstatic-libsystemd=true" ,
530
+ "-Dprefix=/" ,
531
+ self .build_dir ,
532
+ self .src_dir ,
533
+ ]
534
+ )
535
+
536
+ # Compile step needs to satisfy the build directory that was previously
537
+ # prepared during setup.
538
+ self ._run_cmd ([meson , "compile" , "-C" , self .build_dir ])
539
+
540
+ # Install step
541
+ self ._run_cmd (
542
+ [meson , "install" , "-C" , self .build_dir , "--destdir" , self .inst_dir ]
543
+ )
544
+
545
+
464
546
class CMakeBuilder (BuilderBase ):
465
547
MANUAL_BUILD_SCRIPT = """\
466
548
#!{sys.executable}
@@ -1084,9 +1166,14 @@ def _build(self, reconfigure) -> None:
1084
1166
perl = typing .cast (str , path_search (env , "perl" , "perl" ))
1085
1167
1086
1168
make_j_args = []
1169
+ extra_args = []
1087
1170
if self .build_opts .is_windows ():
1088
- make = "nmake.exe"
1171
+ # jom is compatible with nmake, adds the /j argument for parallel build
1172
+ make = "jom.exe"
1173
+ make_j_args = ["/j%s" % self .num_jobs ]
1089
1174
args = ["VC-WIN64A-masm" , "-utf-8" ]
1175
+ # fixes "if multiple CL.EXE write to the same .PDB file, please use /FS"
1176
+ extra_args = ["/FS" ]
1090
1177
elif self .build_opts .is_darwin ():
1091
1178
make = "make"
1092
1179
make_j_args = ["-j%s" % self .num_jobs ]
@@ -1119,11 +1206,14 @@ def _build(self, reconfigure) -> None:
1119
1206
"no-unit-test" ,
1120
1207
"no-tests" ,
1121
1208
]
1209
+ + extra_args
1122
1210
)
1211
+ # show the config produced
1212
+ self ._run_cmd ([perl , "configdata.pm" , "--dump" ], env = env )
1123
1213
make_build = [make ] + make_j_args
1124
- self ._run_cmd (make_build )
1214
+ self ._run_cmd (make_build , env = env )
1125
1215
make_install = [make , "install_sw" , "install_ssldirs" ]
1126
- self ._run_cmd (make_install )
1216
+ self ._run_cmd (make_install , env = env )
1127
1217
1128
1218
1129
1219
class Boost (BuilderBase ):
@@ -1240,7 +1330,7 @@ def build(self, reconfigure: bool) -> None:
1240
1330
os .makedirs (dest_parent )
1241
1331
if os .path .isdir (full_src ):
1242
1332
if not os .path .exists (full_dest ):
1243
- shutil . copytree (full_src , full_dest )
1333
+ simple_copytree (full_src , full_dest )
1244
1334
else :
1245
1335
shutil .copyfile (full_src , full_dest )
1246
1336
shutil .copymode (full_src , full_dest )
@@ -1252,7 +1342,7 @@ def build(self, reconfigure: bool) -> None:
1252
1342
os .chmod (full_dest , st .st_mode | stat .S_IXUSR )
1253
1343
else :
1254
1344
if not os .path .exists (self .inst_dir ):
1255
- shutil . copytree (self .src_dir , self .inst_dir )
1345
+ simple_copytree (self .src_dir , self .inst_dir )
1256
1346
1257
1347
1258
1348
class SqliteBuilder (BuilderBase ):
0 commit comments