jolt 0.9.342__py3-none-any.whl → 0.9.429__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 (158) hide show
  1. jolt/__init__.py +47 -0
  2. jolt/cache.py +358 -159
  3. jolt/cli.py +71 -104
  4. jolt/config.py +14 -26
  5. jolt/filesystem.py +2 -2
  6. jolt/graph.py +56 -28
  7. jolt/influence.py +67 -2
  8. jolt/loader.py +150 -186
  9. jolt/log.py +12 -2
  10. jolt/manifest.py +0 -46
  11. jolt/options.py +35 -12
  12. jolt/pkgs/abseil.py +42 -0
  13. jolt/pkgs/asio.py +25 -0
  14. jolt/pkgs/autoconf.py +41 -0
  15. jolt/pkgs/automake.py +41 -0
  16. jolt/pkgs/b2.py +31 -0
  17. jolt/pkgs/boost.py +111 -0
  18. jolt/pkgs/boringssl.py +32 -0
  19. jolt/pkgs/busybox.py +39 -0
  20. jolt/pkgs/bzip2.py +43 -0
  21. jolt/pkgs/cares.py +29 -0
  22. jolt/pkgs/catch2.py +36 -0
  23. jolt/pkgs/cbindgen.py +17 -0
  24. jolt/pkgs/cista.py +19 -0
  25. jolt/pkgs/clang.py +44 -0
  26. jolt/pkgs/cli11.py +23 -0
  27. jolt/pkgs/cmake.py +48 -0
  28. jolt/pkgs/cpython.py +196 -0
  29. jolt/pkgs/crun.py +29 -0
  30. jolt/pkgs/curl.py +38 -0
  31. jolt/pkgs/dbus.py +18 -0
  32. jolt/pkgs/double_conversion.py +24 -0
  33. jolt/pkgs/fastfloat.py +21 -0
  34. jolt/pkgs/ffmpeg.py +28 -0
  35. jolt/pkgs/flatbuffers.py +29 -0
  36. jolt/pkgs/fmt.py +27 -0
  37. jolt/pkgs/fstree.py +20 -0
  38. jolt/pkgs/gflags.py +18 -0
  39. jolt/pkgs/glib.py +18 -0
  40. jolt/pkgs/glog.py +25 -0
  41. jolt/pkgs/glslang.py +21 -0
  42. jolt/pkgs/golang.py +16 -11
  43. jolt/pkgs/googlebenchmark.py +18 -0
  44. jolt/pkgs/googletest.py +46 -0
  45. jolt/pkgs/gperf.py +15 -0
  46. jolt/pkgs/grpc.py +73 -0
  47. jolt/pkgs/hdf5.py +19 -0
  48. jolt/pkgs/help2man.py +14 -0
  49. jolt/pkgs/inja.py +28 -0
  50. jolt/pkgs/jsoncpp.py +31 -0
  51. jolt/pkgs/libarchive.py +43 -0
  52. jolt/pkgs/libcap.py +44 -0
  53. jolt/pkgs/libdrm.py +44 -0
  54. jolt/pkgs/libedit.py +42 -0
  55. jolt/pkgs/libevent.py +31 -0
  56. jolt/pkgs/libexpat.py +27 -0
  57. jolt/pkgs/libfastjson.py +21 -0
  58. jolt/pkgs/libffi.py +16 -0
  59. jolt/pkgs/libglvnd.py +30 -0
  60. jolt/pkgs/libogg.py +28 -0
  61. jolt/pkgs/libpciaccess.py +18 -0
  62. jolt/pkgs/libseccomp.py +21 -0
  63. jolt/pkgs/libtirpc.py +24 -0
  64. jolt/pkgs/libtool.py +42 -0
  65. jolt/pkgs/libunwind.py +35 -0
  66. jolt/pkgs/libva.py +18 -0
  67. jolt/pkgs/libvorbis.py +33 -0
  68. jolt/pkgs/libxml2.py +35 -0
  69. jolt/pkgs/libxslt.py +17 -0
  70. jolt/pkgs/libyajl.py +16 -0
  71. jolt/pkgs/llvm.py +81 -0
  72. jolt/pkgs/lua.py +54 -0
  73. jolt/pkgs/lz4.py +26 -0
  74. jolt/pkgs/m4.py +14 -0
  75. jolt/pkgs/make.py +17 -0
  76. jolt/pkgs/mesa.py +81 -0
  77. jolt/pkgs/meson.py +17 -0
  78. jolt/pkgs/mstch.py +28 -0
  79. jolt/pkgs/mysql.py +60 -0
  80. jolt/pkgs/nasm.py +49 -0
  81. jolt/pkgs/ncurses.py +30 -0
  82. jolt/pkgs/ng_log.py +25 -0
  83. jolt/pkgs/ninja.py +45 -0
  84. jolt/pkgs/nlohmann_json.py +25 -0
  85. jolt/pkgs/nodejs.py +19 -11
  86. jolt/pkgs/opencv.py +24 -0
  87. jolt/pkgs/openjdk.py +26 -0
  88. jolt/pkgs/openssl.py +103 -0
  89. jolt/pkgs/paho.py +76 -0
  90. jolt/pkgs/patchelf.py +16 -0
  91. jolt/pkgs/perl.py +42 -0
  92. jolt/pkgs/pkgconfig.py +64 -0
  93. jolt/pkgs/poco.py +39 -0
  94. jolt/pkgs/protobuf.py +77 -0
  95. jolt/pkgs/pugixml.py +27 -0
  96. jolt/pkgs/python.py +19 -0
  97. jolt/pkgs/qt.py +35 -0
  98. jolt/pkgs/rapidjson.py +26 -0
  99. jolt/pkgs/rapidyaml.py +28 -0
  100. jolt/pkgs/re2.py +30 -0
  101. jolt/pkgs/re2c.py +17 -0
  102. jolt/pkgs/readline.py +15 -0
  103. jolt/pkgs/rust.py +41 -0
  104. jolt/pkgs/sdl.py +28 -0
  105. jolt/pkgs/simdjson.py +27 -0
  106. jolt/pkgs/soci.py +46 -0
  107. jolt/pkgs/spdlog.py +29 -0
  108. jolt/pkgs/spirv_llvm.py +21 -0
  109. jolt/pkgs/spirv_tools.py +24 -0
  110. jolt/pkgs/sqlite.py +83 -0
  111. jolt/pkgs/ssl.py +12 -0
  112. jolt/pkgs/texinfo.py +15 -0
  113. jolt/pkgs/tomlplusplus.py +22 -0
  114. jolt/pkgs/wayland.py +26 -0
  115. jolt/pkgs/x11.py +58 -0
  116. jolt/pkgs/xerces_c.py +20 -0
  117. jolt/pkgs/xorg.py +360 -0
  118. jolt/pkgs/xz.py +29 -0
  119. jolt/pkgs/yamlcpp.py +30 -0
  120. jolt/pkgs/zeromq.py +47 -0
  121. jolt/pkgs/zlib.py +69 -0
  122. jolt/pkgs/zstd.py +33 -0
  123. jolt/plugins/autotools.py +66 -0
  124. jolt/plugins/cmake.py +74 -6
  125. jolt/plugins/conan.py +238 -0
  126. jolt/plugins/cxxinfo.py +7 -0
  127. jolt/plugins/docker.py +3 -3
  128. jolt/plugins/environ.py +11 -0
  129. jolt/plugins/fetch.py +141 -0
  130. jolt/plugins/gdb.py +10 -6
  131. jolt/plugins/git.py +60 -11
  132. jolt/plugins/libtool.py +63 -0
  133. jolt/plugins/linux.py +990 -0
  134. jolt/plugins/meson.py +61 -0
  135. jolt/plugins/ninja-compdb.py +11 -7
  136. jolt/plugins/ninja.py +245 -26
  137. jolt/plugins/paths.py +11 -1
  138. jolt/plugins/pkgconfig.py +219 -0
  139. jolt/plugins/podman.py +15 -41
  140. jolt/plugins/python.py +137 -0
  141. jolt/plugins/rust.py +25 -0
  142. jolt/plugins/scheduler.py +18 -14
  143. jolt/plugins/selfdeploy/setup.py +2 -1
  144. jolt/plugins/selfdeploy.py +21 -30
  145. jolt/plugins/strings.py +19 -10
  146. jolt/scheduler.py +428 -138
  147. jolt/tasks.py +159 -7
  148. jolt/tools.py +105 -51
  149. jolt/utils.py +16 -1
  150. jolt/version.py +1 -1
  151. {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/METADATA +64 -9
  152. jolt-0.9.429.dist-info/RECORD +207 -0
  153. {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/WHEEL +1 -1
  154. jolt/plugins/debian.py +0 -338
  155. jolt/plugins/repo.py +0 -253
  156. jolt-0.9.342.dist-info/RECORD +0 -93
  157. {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/entry_points.txt +0 -0
  158. {jolt-0.9.342.dist-info → jolt-0.9.429.dist-info}/top_level.txt +0 -0
jolt/plugins/meson.py ADDED
@@ -0,0 +1,61 @@
1
+ from jolt import Task, attributes
2
+
3
+
4
+ @attributes.common_metadata()
5
+ class Meson(Task):
6
+ """ Base class for Meson-based build tasks. """
7
+
8
+ abstract = True
9
+ """ This is an abstract base class that should be inherited by concrete tasks. """
10
+
11
+ incremental = True
12
+ """
13
+ Whether to use incremental builds.
14
+ If True, the build directories are preserved between runs.
15
+ """
16
+
17
+ options = []
18
+ """
19
+ Additional options to pass to the `meson` command.
20
+ """
21
+
22
+ srcdir = None
23
+ """
24
+ Source directory for the Meson project.
25
+
26
+ If None, defaults to the task work directory (joltdir).
27
+ """
28
+
29
+ def clean(self, tools):
30
+ at = tools.meson(incremental=self.incremental)
31
+ at.clean()
32
+
33
+ def run(self, deps, tools):
34
+ self.deps = deps
35
+ options = tools.expand(self.options)
36
+ at = tools.meson(deps, incremental=self.incremental)
37
+ at.configure(self.srcdir or self.joltdir, *options)
38
+ at.build()
39
+ at.install()
40
+
41
+ def publish(self, artifact, tools):
42
+ at = tools.meson(incremental=self.incremental)
43
+ at.publish(artifact)
44
+
45
+
46
+ def requires(meson=True, ninja=True):
47
+ """ Decorator to add Meson and Ninja requirements to a task. """
48
+
49
+ import jolt.pkgs.meson
50
+ import jolt.pkgs.ninja
51
+
52
+ def decorate(cls):
53
+ if meson:
54
+ cls = attributes.requires("requires_meson")(cls)
55
+ cls.requires_meson = ["meson"]
56
+ if ninja:
57
+ cls = attributes.requires("requires_ninja")(cls)
58
+ cls.requires_ninja = ["ninja"]
59
+ return cls
60
+
61
+ return decorate
@@ -115,7 +115,7 @@ def get_task_artifacts(task):
115
115
 
116
116
  class CompDBHooks(TaskHook):
117
117
  def __init__(self):
118
- self._depfiles = config.getboolean("ninja-compdb", "depfiles", True)
118
+ self._depfiles = config.getboolean("ninja-compdb", "depfiles", False)
119
119
 
120
120
  def publish_compdb(self, artifact, tools):
121
121
  with tools.cwd(self.outdir):
@@ -226,34 +226,37 @@ def compdb(ctx, task, default):
226
226
 
227
227
  """
228
228
 
229
- manifest = ctx.obj["manifest"]
230
229
  options = JoltOptions(default=default)
231
230
  acache = cache.ArtifactCache.get(options)
232
231
  TaskHookRegistry.get(options)
233
232
  executors = scheduler.ExecutorRegistry.get(options)
234
233
  registry = TaskRegistry.get()
235
234
  strategy = scheduler.DownloadStrategy(executors, acache)
236
- queue = scheduler.TaskQueue(strategy, acache, {})
235
+ queue = scheduler.TaskQueue()
237
236
 
238
237
  for params in default:
239
238
  registry.set_default_parameters(params)
240
239
 
241
- gb = graph.GraphBuilder(registry, acache, manifest, options, progress=True)
240
+ gb = graph.GraphBuilder(registry, acache, options, progress=True)
242
241
  dag = gb.build(task)
243
242
 
244
243
  try:
245
244
  with log.progress("Progress", dag.number_of_tasks(), " tasks", estimates=False, debug=False) as progress:
245
+ in_progress = set()
246
+
246
247
  while dag.has_tasks() or not queue.empty():
247
- leafs = dag.select(lambda graph, task: task.is_ready())
248
+ leafs = dag.select(lambda graph, task: task.is_ready() and task not in in_progress)
248
249
 
249
250
  # Order the tasks by their weights to improve build times
250
251
  leafs.sort(key=lambda x: x.weight)
251
252
 
252
253
  while leafs:
253
254
  task = leafs.pop()
254
- queue.submit(task)
255
+ executor = strategy.create_executor({}, task)
256
+ queue.submit(executor)
257
+ in_progress.add(task)
255
258
 
256
- task, error = queue.wait()
259
+ task, _ = queue.wait()
257
260
 
258
261
  # Materialize workspace resources so that
259
262
  # source code is available to the debugger.
@@ -272,6 +275,7 @@ def compdb(ctx, task, default):
272
275
  log.warning("Interrupted by user")
273
276
  try:
274
277
  queue.abort()
278
+ executors.shutdown()
275
279
  sys.exit(1)
276
280
  except KeyboardInterrupt:
277
281
  print()
jolt/plugins/ninja.py CHANGED
@@ -4,6 +4,7 @@ import copy
4
4
  import functools
5
5
  from ninja import ninja_syntax as ninja
6
6
  import os
7
+ import platform
7
8
  import re
8
9
  import sys
9
10
 
@@ -21,6 +22,12 @@ from jolt.error import raise_task_error_if
21
22
  from jolt.error import JoltError, JoltCommandError
22
23
 
23
24
 
25
+ c_standard_default = 17
26
+ cxx_standard_default = 17
27
+ c_standards_list = [90, 99, 11, 17, 23]
28
+ cxx_standards_list = [98, 11, 14, 17, 20, 23, 26]
29
+
30
+
24
31
  class CompileError(JoltError):
25
32
  def __init__(self, error):
26
33
  if error:
@@ -100,8 +107,8 @@ class attributes:
100
107
  self.info("Collecting coverage data into {covdatadir}")
101
108
 
102
109
  for _, artifact in deps.items():
103
- if str(artifact.paths.coverage_data):
104
- tools.copy(artifact.paths.coverage_data, self.covdatadir)
110
+ if artifact.paths.coverage_data:
111
+ tools.copy(str(artifact.paths.coverage_data), self.covdatadir)
105
112
 
106
113
  with tools.environ(GCOV_PREFIX=self.covdatadir):
107
114
  yield
@@ -196,8 +203,8 @@ class attributes:
196
203
  if not hasattr(self, "covdatadir"):
197
204
  self.covdatadir = tools.builddir("coverage-data")
198
205
  for _, artifact in deps.items():
199
- if str(artifact.paths.coverage_data):
200
- tools.copy(artifact.paths.coverage_data, self.covdatadir)
206
+ if artifact.paths.coverage_data:
207
+ tools.copy(str(artifact.paths.coverage_data), self.covdatadir)
201
208
 
202
209
  with tools.cwd(self.covdatadir):
203
210
  datafiles = tools.glob("**/*.gcda")
@@ -359,8 +366,8 @@ class attributes:
359
366
  if not hasattr(self, "covdatadir"):
360
367
  self.covdatadir = tools.builddir("coverage-data")
361
368
  for _, artifact in deps.items():
362
- if str(artifact.paths.coverage_data):
363
- tools.copy(artifact.paths.coverage_data, self.covdatadir)
369
+ if artifact.paths.coverage_data:
370
+ tools.copy(str(artifact.paths.coverage_data), self.covdatadir)
364
371
 
365
372
  reportdir = tools.builddir("coverage-report-lcov")
366
373
  htmldir = tools.builddir("coverage-report-lcov-html")
@@ -412,7 +419,7 @@ class attributes:
412
419
 
413
420
  reports = []
414
421
  for _, artifact in deps.items():
415
- if str(artifact.paths.coverage_report_lcov):
422
+ if artifact.paths.coverage_report_lcov:
416
423
  reports.append(str(artifact.paths.coverage_report_lcov))
417
424
  if reports:
418
425
  filtered_reports = []
@@ -751,6 +758,54 @@ class ProjectVariable(Variable):
751
758
  return "PV: default={},attrib={}".format(self._default, self._attrib)
752
759
 
753
760
 
761
+ class StdVariable(Variable):
762
+ def __init__(self, lang, flagfmt, values, supported=None, default=None):
763
+ self._lang = lang
764
+ self._flagfmt = flagfmt
765
+ self._values = values
766
+ self._supported = supported or values
767
+ self._default = default
768
+
769
+ def create(self, project, writer, deps, tools):
770
+ value = getattr(project, self.name, self._default) or self._default
771
+ if not value:
772
+ return
773
+ raise_task_error_if(
774
+ type(value) is not int,
775
+ project,
776
+ f"Illegal {self._lang} language standard: '{value}'. Expected integer."
777
+ )
778
+ raise_task_error_if(
779
+ value not in self._values,
780
+ project,
781
+ f"Illegal {self._lang} language standard: '{value}'. Expected one of: {', '.join([str(v) for v in self._values])}"
782
+ )
783
+
784
+ if value not in self._supported:
785
+ new_value = min(self._supported, key=lambda n: abs(n - value))
786
+ project.warning(f"{self._lang}{value} is not supported. Using {self._lang}{new_value} instead.")
787
+ value = new_value
788
+
789
+ writer.variable(self.name, self._flagfmt.format(value))
790
+
791
+
792
+ class OptimizationVariable(Variable):
793
+ def __init__(self, default, values, name=None):
794
+ self.name = name
795
+ self._default = default
796
+ self._values = values
797
+ assert type(values) is dict, "Optimization values must be dict with compiler flag mapping"
798
+
799
+ def create(self, project, writer, deps, tools):
800
+ value = str(getattr(project, "optimize", self._default))
801
+ raise_task_error_if(
802
+ value not in self._values,
803
+ project,
804
+ f"Illegal value assigned to 'optimize' ({value}). Expected: 'none', 'debug', 'size', or 'release'."
805
+ )
806
+ writer.variable(self.name, self._values[value])
807
+
808
+
754
809
  class SharedLibraryVariable(Variable):
755
810
  def __init__(self, name=None, default=None):
756
811
  self.name = name
@@ -1153,7 +1208,8 @@ class Skip(Rule):
1153
1208
 
1154
1209
  @task_attributes.system
1155
1210
  class MakeDirectory(Rule):
1156
- command_linux = "mkdir -p $out"
1211
+ command_darwin = "mkdir -p $out"
1212
+ command_linux = command_darwin
1157
1213
  command_windows = "if not exist $out mkdir $out"
1158
1214
 
1159
1215
  def __init__(self, name):
@@ -1539,7 +1595,17 @@ class GNUToolchain(Toolchain):
1539
1595
  cxxwrap = EnvironmentVariable(default="")
1540
1596
  flatc = ToolEnvironmentVariable(default="flatc", envname="FLATC", abspath=True)
1541
1597
  protoc = ToolEnvironmentVariable(default="protoc", envname="PROTOC", abspath=True)
1542
-
1598
+ strip = ToolEnvironmentVariable(default="strip", envname="STRIP", abspath=True)
1599
+
1600
+ cstd = StdVariable("C", "-std=c{}", values=c_standards_list, default=c_standard_default)
1601
+ cxxstd = StdVariable("C++", "-std=c++{}", values=cxx_standards_list, default=cxx_standard_default)
1602
+ optflag = OptimizationVariable(default="release", values={
1603
+ "none": "-O0",
1604
+ "debug": "-Og",
1605
+ "size": "-Os",
1606
+ "release": "-O2",
1607
+ None: "-O0",
1608
+ })
1543
1609
  asflags = EnvironmentVariable(default="")
1544
1610
  cflags = EnvironmentVariable(default="")
1545
1611
  cxxflags = EnvironmentVariable(default="")
@@ -1570,7 +1636,7 @@ class GNUToolchain(Toolchain):
1570
1636
  mkdir_debug = MakeDirectory(name="$outdir_rel/.debug")
1571
1637
 
1572
1638
  compile_pch = GNUCompiler(
1573
- command="$cxxwrap $cxx -x c++-header $cxxflags $shared_flags $imported_cxxflags $extra_cxxflags $covflags $macros $incpaths -MMD -MF $out.d -c $in -o $out",
1639
+ command="$cxxwrap $cxx -x c++-header $cxxstd $optflag $cxxflags $shared_flags $imported_cxxflags $extra_cxxflags $covflags $macros $incpaths -MMD -MF $out.d -c $in -o $out",
1574
1640
  deps="gcc",
1575
1641
  depfile="$out.d",
1576
1642
  infiles=[GNUPCHVariables.pch_ext],
@@ -1579,7 +1645,7 @@ class GNUToolchain(Toolchain):
1579
1645
  variables={"desc": "[PCH] {in_base}{in_ext}"})
1580
1646
 
1581
1647
  compile_c = GNUCompiler(
1582
- command="$ccwrap $cc -x c $pch_flags $cflags $shared_flags $imported_cflags $extra_cflags $covflags $macros $incpaths -MMD -MF $out.d -c $in -o $out",
1648
+ command="$ccwrap $cc -x c $cstd $pch_flags $optflag $cflags $shared_flags $imported_cflags $extra_cflags $covflags $macros $incpaths -MMD -MF $out.d -c $in -o $out",
1583
1649
  deps="gcc",
1584
1650
  depfile="$out.d",
1585
1651
  infiles=[".c"],
@@ -1589,7 +1655,7 @@ class GNUToolchain(Toolchain):
1589
1655
  implicit=["$cc_path"])
1590
1656
 
1591
1657
  compile_cxx = GNUCompiler(
1592
- command="$cxxwrap $cxx -x c++ $pch_flags $cxxflags $shared_flags $imported_cxxflags $extra_cxxflags $covflags $macros $incpaths -MMD -MF $out.d -c $in -o $out",
1658
+ command="$cxxwrap $cxx -x c++ $cxxstd $pch_flags $optflag $cxxflags $shared_flags $imported_cxxflags $extra_cxxflags $covflags $macros $incpaths -MMD -MF $out.d -c $in -o $out",
1593
1659
  deps="gcc",
1594
1660
  depfile="$out.d",
1595
1661
  infiles=[".cc", ".cpp", ".cxx"],
@@ -1658,6 +1724,55 @@ class GNUToolchain(Toolchain):
1658
1724
  suffix=".a")
1659
1725
 
1660
1726
 
1727
+ class BSDArchiver(Rule):
1728
+ def __init__(self, *args, **kwargs):
1729
+ super(BSDArchiver, self).__init__(*args, aggregate=True, **kwargs)
1730
+
1731
+ def build(self, project, writer, infiles, implicit=None, order_only=None):
1732
+ writer._objects = infiles
1733
+ project._binaries, _ = self._out(project, project.binary)
1734
+ file_list = FileListWriter("objects", project._binaries)
1735
+ file_list.build(project, writer, infiles)
1736
+ super().build(project, writer, infiles, implicit=writer.depimports, order_only=order_only)
1737
+
1738
+ def get_influence(self, task):
1739
+ return "BSDArchiver" + super().get_influence(task)
1740
+
1741
+
1742
+ class DarwinGNUToolchain(GNUToolchain):
1743
+ libtool = ToolEnvironmentVariable(default="libtool", envname="LIBTOOL", abspath=True)
1744
+ dsymutil = ToolEnvironmentVariable(default="dsymutil", envname="DSYMUTIL", abspath=True)
1745
+
1746
+ linker = GNULinker(
1747
+ command=" && ".join([
1748
+ "$ld $ldflags $imported_ldflags $extra_ldflags $covflags $libpaths @$outdir_rel/objects.list -o $out $libraries",
1749
+ "$dsymutil $out -o $outdir_rel/.debug/$binary.dSYM",
1750
+ "$strip $out",
1751
+ ]),
1752
+ infiles=[".o", ".obj", ".a"],
1753
+ outfiles=["{outdir}/{binary}"],
1754
+ variables={"desc": "[LINK] {binary}"},
1755
+ implicit=["$ld_path", "$dsymutil_path", "$strip_path", "$outdir_rel/.debug"])
1756
+
1757
+ dynlinker = GNULinker(
1758
+ command=" && ".join([
1759
+ "$ld $ldflags -shared $imported_ldflags $extra_ldflags $covflags $libpaths @$outdir_rel/objects.list -o $out $libraries",
1760
+ "$dsymutil $out -o $outdir_rel/.debug/$binary.dSYM",
1761
+ "$strip $out",
1762
+ ]),
1763
+ infiles=[".o", ".obj", ".a"],
1764
+ outfiles=["{outdir}/lib{binary}.so"],
1765
+ variables={"desc": "[LINK] {binary}"},
1766
+ implicit=["$ld_path", "$dsymutil_path", "$strip_path", "$outdir_rel/.debug"])
1767
+
1768
+ archiver = BSDArchiver(
1769
+ command="$libtool -static -o $out @$outdir_rel/objects.list && $ranlib $out",
1770
+ infiles=[".o", ".obj", ".a"],
1771
+ outfiles=["{outdir}/lib{binary}.a"],
1772
+ variables={"desc": "[AR] lib{binary}.a"},
1773
+ implicit=["$libtool_path", "$ranlib_path"])
1774
+
1775
+
1661
1776
  class MinGWToolchain(GNUToolchain):
1662
1777
  linker = GNULinker(
1663
1778
  command=" && ".join([
@@ -1686,6 +1801,62 @@ class MSVCArchiver(Rule):
1686
1801
  return "MSVCArchiver" + super().get_influence(task)
1687
1802
 
1688
1803
 
1804
+ class MSVCCRT(Variable):
1805
+ def __init__(self, default="/MD", flagsfn=None):
1806
+ self.default = default
1807
+ self.flagsfn = flagsfn
1808
+
1809
+ def _combine(self, project, crt1, crt2):
1810
+ if crt1 is None:
1811
+ return crt2
1812
+ if crt2 is None:
1813
+ return crt1
1814
+ raise_task_error_if(crt1 != crt2, project, "Mismatching Windows CRT library types (/MT vs /MD)")
1815
+ return crt1
1816
+
1817
+ def _select_flag(self, flags):
1818
+ """ Look for /Mxx flag in the list of flags """
1819
+ if flags is None:
1820
+ return None
1821
+ if "Static" in flags:
1822
+ return "/MT"
1823
+ if "StaticDebug" in flags:
1824
+ return "/MTd"
1825
+ if "Dynamic" in flags:
1826
+ return "/MD"
1827
+ if "DynamicDebug" in flags:
1828
+ return "/MDd"
1829
+ if "/MT" in flags:
1830
+ return "/MT"
1831
+ if "/MTd" in flags:
1832
+ return "/MTd"
1833
+ if "/MD" in flags:
1834
+ return "/MD"
1835
+ if "/MDd" in flags:
1836
+ return "/MDd"
1837
+ return None
1838
+
1839
+ def _select_dep_flags(self, project, dep):
1840
+ crt = self._select_flag(dep.cxxinfo.asflags.items())
1841
+ if hasattr(dep.cxxinfo, "crt"):
1842
+ crt = self._combine(project, crt, self._select_flag([str(dep.cxxinfo.crt)]))
1843
+ crt = self._combine(project, crt, self._select_flag(dep.cxxinfo.cflags.items()))
1844
+ return self._combine(project, crt, self._select_flag(dep.cxxinfo.cxxflags.items()))
1845
+
1846
+ def create(self, project, writer, deps, tools):
1847
+ crt = self._select_flag(getattr(project, "crt", None))
1848
+ crt = self._combine(project, crt, self._select_flag(project._asflags()))
1849
+ crt = self._combine(project, crt, self._select_flag(project._cflags()))
1850
+ crt = self._combine(project, crt, self._select_flag(project._cxxflags()))
1851
+ for _, artifact in deps.items():
1852
+ crt = self._combine(project, crt, self._select_dep_flags(project, artifact))
1853
+ writer.variable(self.name, crt or self.default)
1854
+
1855
+ @utils.cached.instance
1856
+ def get_influence(self, task):
1857
+ return "CRT"
1858
+
1859
+
1689
1860
  MSVCCompiler = GNUCompiler
1690
1861
  MSVCLinker = GNULinker
1691
1862
  MSVCDepImporter = GNUDepImporter
@@ -1695,9 +1866,10 @@ class MSVCToolchain(Toolchain):
1695
1866
  hh = Skip(infiles=[".h", ".hh", ".hpp", ".hxx"])
1696
1867
  bin = Skip(infiles=[".dll", ".exe"])
1697
1868
 
1698
- builddir = ProjectVariable(attrib="outdir")
1699
1869
  joltdir = ProjectVariable()
1870
+ builddir = ProjectVariable(attrib="outdir")
1700
1871
  outdir = ProjectVariable()
1872
+ outdir_rel = ProjectVariable()
1701
1873
  binary = ProjectVariable()
1702
1874
 
1703
1875
  cl = ToolEnvironmentVariable(default="cl", envname="cl_exe", abspath=True)
@@ -1706,13 +1878,25 @@ class MSVCToolchain(Toolchain):
1706
1878
  flatc = ToolEnvironmentVariable(default="flatc", envname="FLATC", abspath=True)
1707
1879
  protoc = ToolEnvironmentVariable(default="protoc", envname="PROTOC", abspath=True)
1708
1880
 
1881
+ cstd = StdVariable("C", "/std:c{}", values=c_standards_list, supported=[11, 17], default=c_standard_default)
1882
+ cxxstd = StdVariable("C++", "/std:c++{}", values=cxx_standards_list, supported=[14, 17, 20], default=cxx_standard_default)
1883
+ optflag = OptimizationVariable(default="speed", values={
1884
+ "none": "/Od",
1885
+ "debug": "/Od /Zi",
1886
+ "size": "/O1",
1887
+ "release": "/O2 /DNDEBUG",
1888
+ None: "/0d",
1889
+ })
1890
+ win32flags = Variable("/DWIN32 /D_WINDOWS /D_WIN32_WINNT=0x0601 /EHsc")
1709
1891
  asflags = EnvironmentVariable(default="")
1710
- cflags = EnvironmentVariable(default="/EHsc")
1711
- cxxflags = EnvironmentVariable(default="/EHsc")
1892
+ cflags = EnvironmentVariable(default="")
1893
+ cxxflags = EnvironmentVariable(default="")
1712
1894
  fbflags = EnvironmentVariable(default="")
1713
1895
  ldflags = EnvironmentVariable(default="")
1714
1896
  protoflags = EnvironmentVariable(default="")
1715
1897
 
1898
+ crt = MSVCCRT()
1899
+
1716
1900
  extra_asflags = ProjectVariable(attrib="asflags")
1717
1901
  extra_cflags = ProjectVariable(attrib="cflags")
1718
1902
  extra_cxxflags = ProjectVariable(attrib="cxxflags")
@@ -1727,26 +1911,26 @@ class MSVCToolchain(Toolchain):
1727
1911
  libraries = Libraries(suffix=".lib")
1728
1912
 
1729
1913
  compile_asm = MSVCCompiler(
1730
- command="$cl /nologo /showIncludes $asflags $extra_asflags $macros $incpaths /c /Tc$in /Fo$out",
1914
+ command="$cl /nologo /showIncludes $crt $win32flags $asflags $extra_asflags $macros $incpaths /c /Tc$in /Fo$out",
1731
1915
  deps="msvc",
1732
1916
  infiles=[".asm", ".s", ".S"],
1733
- outfiles=["{outdir}/{binary}.dir/{in_path}/{in_base}.obj"],
1917
+ outfiles=["{outdir}/{binary}.dir/{in_path}/{in_base}{in_ext}.obj"],
1734
1918
  variables={"desc": "[ASM] {in_base}{in_ext}"},
1735
1919
  implicit=["$cl_path"])
1736
1920
 
1737
1921
  compile_c = MSVCCompiler(
1738
- command="$cl /nologo /showIncludes $cxxflags $extra_cxxflags $macros $incpaths /c /Tc$in /Fo$out",
1922
+ command="$cl /nologo /showIncludes $cstd $crt $win32flags $optflag $cflags $extra_cflags $macros $incpaths /c /Tc$in /Fo$out",
1739
1923
  deps="msvc",
1740
1924
  infiles=[".c"],
1741
- outfiles=["{outdir}/{binary}.dir/{in_path}/{in_base}.obj"],
1925
+ outfiles=["{outdir}/{binary}.dir/{in_path}/{in_base}{in_ext}.obj"],
1742
1926
  variables={"desc": "[C] {in_base}{in_ext}"},
1743
1927
  implicit=["$cl_path"])
1744
1928
 
1745
1929
  compile_cxx = MSVCCompiler(
1746
- command="$cl /nologo /showIncludes $cxxflags $extra_cxxflags $macros $incpaths /c /Tp$in /Fo$out",
1930
+ command="$cl /nologo /showIncludes $cxxstd $crt $win32flags $optflag $cxxflags $extra_cxxflags $macros $incpaths /c /Tp$in /Fo$out",
1747
1931
  deps="msvc",
1748
1932
  infiles=[".cc", ".cpp", ".cxx"],
1749
- outfiles=["{outdir}/{binary}.dir/{in_path}/{in_base}.obj"],
1933
+ outfiles=["{outdir}/{binary}.dir/{in_path}/{in_base}{in_ext}.obj"],
1750
1934
  variables={"desc": "[CXX] {in_base}{in_ext}"},
1751
1935
  implicit=["$cl_path"])
1752
1936
 
@@ -1774,11 +1958,15 @@ class MSVCToolchain(Toolchain):
1774
1958
 
1775
1959
  _toolchains = {
1776
1960
  GNUToolchain: GNUToolchain(),
1961
+ DarwinGNUToolchain: DarwinGNUToolchain(),
1777
1962
  MSVCToolchain: MSVCToolchain(),
1778
1963
  }
1779
1964
 
1780
- if os.name == "nt":
1965
+ _system = platform.system()
1966
+ if _system == "Windows":
1781
1967
  toolchain = _toolchains[MSVCToolchain]
1968
+ elif _system == "Darwin":
1969
+ toolchain = _toolchains[DarwinGNUToolchain]
1782
1970
  else:
1783
1971
  toolchain = _toolchains[GNUToolchain]
1784
1972
 
@@ -1818,9 +2006,23 @@ class CXXProject(Task):
1818
2006
  cflags = []
1819
2007
  """ A list of compiler flags used when compiling C files. """
1820
2008
 
2009
+ cstd = None
2010
+ """
2011
+ C language standard to use (int). Default: 17
2012
+
2013
+ If the chosen standard is not supported, the nearest supported standard is selected.
2014
+ """
2015
+
1821
2016
  cxxflags = []
1822
2017
  """ A list of compiler flags used when compiling C++ files. """
1823
2018
 
2019
+ cxxstd = None
2020
+ """
2021
+ C++ language standard to use (int). Default: 17
2022
+
2023
+ If the chosen standard is not supported, the nearest supported standard is selected.
2024
+ """
2025
+
1824
2026
  depimports = []
1825
2027
  """ List of implicit dependencies """
1826
2028
 
@@ -1839,6 +2041,18 @@ class CXXProject(Task):
1839
2041
  macros = []
1840
2042
  """ List of preprocessor macros to set """
1841
2043
 
2044
+ optimize = "release"
2045
+ """
2046
+ Compiler optimization level.
2047
+
2048
+ Supported values are:
2049
+
2050
+ - "none" / None
2051
+ - "debug"
2052
+ - "size"
2053
+ - "release"
2054
+ """
2055
+
1842
2056
  sources = []
1843
2057
  """ A list of sources to compile.
1844
2058
 
@@ -2266,7 +2480,10 @@ if __name__ == "__main__":
2266
2480
  except JoltCommandError as e:
2267
2481
  self.buildlog = "\n".join(e.stdout)
2268
2482
  report = self._report_errors(self.buildlog)
2269
- raise CompileError(self._first_reported_error(report))
2483
+ error = self._first_reported_error(report)
2484
+ if error:
2485
+ raise CompileError(error)
2486
+ raise e
2270
2487
 
2271
2488
  if bool(getattr(self, "coverage", False)):
2272
2489
  self.covdatadir = tools.builddir("coverage-data")
@@ -2280,8 +2497,8 @@ if __name__ == "__main__":
2280
2497
  pass
2281
2498
  if self.selfsustained:
2282
2499
  for _, artifact in deps.items():
2283
- if str(artifact.paths.coverage_data):
2284
- tools.copy(artifact.paths.coverage_data, self.covdatadir)
2500
+ if artifact.paths.coverage_data:
2501
+ tools.copy(str(artifact.paths.coverage_data), self.covdatadir)
2285
2502
 
2286
2503
  def publish(self, artifact, tools):
2287
2504
  if bool(getattr(self, "coverage", False)):
@@ -2351,13 +2568,15 @@ if __name__ == "__main__":
2351
2568
  # LLVM linker errors
2352
2569
  report.add_regex_errors(
2353
2570
  "Linker Error",
2354
- r"^(?P<location>ld(\.lld)?): (error|warning): (?P<message>.*)",
2571
+ r"^(?P<location>(.*?)ld(\.lld)?): (error|warning): (?P<message>.*)",
2355
2572
  logbuffer)
2356
2573
 
2357
2574
  return report
2358
2575
 
2359
2576
  def _first_reported_error(self, report):
2360
2577
  """ Returns the first reported error or None if no errors were reported. """
2578
+ if report is None:
2579
+ return None
2361
2580
  for error in report.errors:
2362
2581
  return error
2363
2582
 
jolt/plugins/paths.py CHANGED
@@ -16,6 +16,12 @@ class PathVariable(ArtifactStringAttribute):
16
16
  def unapply(self, task, artifact):
17
17
  pass
18
18
 
19
+ def __bool__(self):
20
+ return bool(str(self))
21
+
22
+ def __eq__(self, value: str) -> bool:
23
+ return str(self) == str(value)
24
+
19
25
  def __str__(self):
20
26
  if self._value is None:
21
27
  return ""
@@ -30,6 +36,10 @@ class PathVariableSet(ArtifactAttributeSet):
30
36
  def create(self, name):
31
37
  return PathVariable(self._artifact, name)
32
38
 
39
+ def __getattr__(self, name):
40
+ attributes = self._get_attributes()
41
+ return attributes.get(name, None)
42
+
33
43
 
34
44
  @ArtifactAttributeSetProvider.Register
35
45
  class PathVariableSetProvider(ArtifactAttributeSetProvider):
@@ -41,7 +51,7 @@ class PathVariableSetProvider(ArtifactAttributeSetProvider):
41
51
  return
42
52
 
43
53
  for key, value in content["paths"].items():
44
- getattr(artifact.paths, key).set_value(value, expand=False)
54
+ setattr(artifact.paths, key, value)
45
55
 
46
56
  def format(self, artifact, content):
47
57
  if "paths" not in content: