Skip to content

Commit

Permalink
[fix] improve caching of cmake sysinfo with toolchains
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed Oct 30, 2022
1 parent a7f2ef8 commit 384a055
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 163 deletions.
8 changes: 4 additions & 4 deletions src/c4/cmany/architecture.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ class Architecture(BuildItem):
"""Specifies a processor architecture"""

@staticmethod
def default():
def default(toolchain_file: str=None):
"""return the architecture of the current machine"""
return Architecture(__class__.default_str())
return Architecture(__class__.default_str(toolchain_file))

@staticmethod
def default_str():
s = CMakeSysInfo.architecture()
def default_str(toolchain_file: str=None):
s = CMakeSysInfo.architecture(toolchain=toolchain_file)
if s == "amd64":
s = "x86_64"
return s
Expand Down
36 changes: 10 additions & 26 deletions src/c4/cmany/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,47 +254,31 @@ def add_select(parser):
given either as a comma-separated list or with repeated invokations
of their arguments. Commas can be escaped by using a backslash,
\\.""")
#
dft = [system.System.default_str()]
g.add_argument("-s", "--systems", metavar="os1,os2,...",
default=dft, action=BuildItemArgument,
action=BuildItemArgument,
help="""Specify a comma-separated list of operating systems
to combine. Defaults to the current system, """ +
_item_printer(dft) + """.""")
#
dft = [architecture.Architecture.default_str()]
to combine. Defaults to the current system.""")
g.add_argument("-a", "--architectures", metavar="arch1,arch2,...",
default=dft, action=BuildItemArgument,
action=BuildItemArgument,
help="""Specify a comma-separated list of processor
architectures to combine. Defaults to CMake's default
architecture on this system, """ +
_item_printer(dft) + """.""")
#
dft = [compiler.Compiler.default_str()]
architecture on this system.""")
g.add_argument("-c", "--compilers", metavar="compiler1,compiler2,...",
default=dft, action=BuildItemArgument,
action=BuildItemArgument,
help="""Specify a comma-separated list of compilers to
combine. Compilers can be given as an absolute path, or as
a name, in which case that name will be searched for in
the current shell's PATH. Defaults to CMake's default
compiler on this system, """ +
_item_printer(dft) + """.""")
#
# dft = [build_type.BuildType.default_str()] # avoid a circular dependency
dft = ["Release"]
compiler on this system.""")
g.add_argument("-t", "--build-types", metavar="type1,type2,...",
default=dft, action=BuildItemArgument,
action=BuildItemArgument,
help="""Specify a comma-separated list of build types
to combine. Defaults to """ + _item_printer(dft) + """.""")
#
# dft = [variant.Variant.default_str()] # avoid a circular dependency
dft = ["none"]
to combine.""")
g.add_argument("-v", "--variants", metavar="variant1,variant2,...",
default=["none"], action=BuildItemArgument,
action=BuildItemArgument,
help="""Specify a comma-separated list of variants
to combine. The variant name 'none' is special and will be
omitted from the name of the resulting build. Defaults to
""" + _item_printer(dft) + """.""")
omitted from the name of the resulting build. Defaults to none.""")
#add_combination_flags(parser)


Expand Down
17 changes: 5 additions & 12 deletions src/c4/cmany/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,7 @@ def __init__(self, proj_root, build_root, install_root,
super().__init__(tag)
#
self.toolchain_file = self._get_toolchain()
if self.toolchain_file:
comps = cmake.extract_toolchain_compilers(self.toolchain_file)
if comps.get('CMAKE_CXX_COMPILER'):
c = Compiler(comps['CMAKE_CXX_COMPILER'])
else:
c = Compiler(os.environ.get('CXX'))
dbg(f"CMAKE_CXX_COMPILER not found, trying environment var CXX:", c)
self.adjust(compiler=c)
#
# WATCHOUT: this may trigger a readjustment of this build's parameters
# WATCHOUT: this may trigger a readjustment of the build's parameters
self.generator = self.create_generator(num_jobs)
#
# This will load the vars from the builddir cache, if it exists.
Expand Down Expand Up @@ -117,7 +108,7 @@ def _set_name_and_paths(self):
self.installdir = os.path.join(self.installroot, self.installtag)
self.preload_file = os.path.join(self.builddir, Build.pfile)
self.cachefile = os.path.join(self.builddir, 'CMakeCache.txt')
for prop in "projdir buildroot installroot buildtag installtag builddir installdir preload_file cachefile".split(" "):
for prop in "system architecture compiler build_type variant projdir buildroot installroot buildtag installtag builddir installdir preload_file cachefile".split(" "):
dbg(" {}: {}={}".format(self.tag, prop, getattr(self, prop)))
return self.tag

Expand All @@ -138,7 +129,7 @@ def create_generator(self, num_jobs, fallback_generator="Unix Makefiles"):
if self.system.name == "windows":
return Generator(fallback_generator, self, num_jobs)
else:
return Generator(Generator.default_str(), self, num_jobs)
return Generator(Generator.default_str(self.toolchain_file), self, num_jobs)

def adjust(self, **kwargs):
for k, _ in kwargs.items():
Expand Down Expand Up @@ -466,9 +457,11 @@ def _get_toolchain(self):
tc = BuildFlags.merge_toolchains(tc, fs.toolchain)
if not tc:
return None
dbg("toolchain:", tc)
if not os.path.isabs(tc):
tc = os.path.join(os.getcwd(), tc)
tc = os.path.abspath(tc)
dbg("toolchain:", tc)
if not os.path.exists(tc):
raise err.ToolchainFileNotFound(tc, self)
return tc
Expand Down
5 changes: 4 additions & 1 deletion src/c4/cmany/build_flags.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .named_item import NamedItem as NamedItem

from . import util
from .util import logdbg as dbg
from . import err


Expand Down Expand Up @@ -59,9 +60,11 @@ def log(self, log_fn=print, msg=""):

@staticmethod
def merge_toolchains(tc1, tc2):
if ((tc1 != tc2) and (tc1 is not None and tc2 is not None)):
dbg("merge_toolchains:", tc1, tc2)
if ((tc1 != tc2) and ((tc1 is not None) and (tc2 is not None))):
raise err.Error("conflicting toolchains: {} vs {}", tc1, tc2)
if tc1 is None and tc2 is not None:
dbg("picking toolchain:", tc2)
tc1 = tc2
return tc1

Expand Down
33 changes: 24 additions & 9 deletions src/c4/cmany/build_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,40 @@
from .combination_rules import CombinationRules


# some of parsing functions below are difficult; this is a debugging scaffold
# some of the parsing functions below are difficult; this is a
# debugging scaffold
_dbg_parse = False
def _dbg(fmt, *args):
if not _dbg_parse: return
print(fmt.format(*args))


def dbg(fmt, *args, **kwargs):
util.logdbg(fmt.format(*args, **kwargs))


# -----------------------------------------------------------------------------
class BuildItem(NamedItem):
"""A base class for build items."""

@staticmethod
def create(map_of_class_name_to_tuple_of_class_and_specs):
def create_build_items(names_and_classes, **kwargs):
items = BuildItemCollection()
for cls_name, (cls, spec_list) in map_of_class_name_to_tuple_of_class_and_specs.items():
if isinstance(spec_list, str):
spec_list = util.splitesc_quoted(spec_list, ',')
for s in spec_list:
items.add_build_item(cls(s))
for name, cls in names_and_classes.items():
spec_list = kwargs.get(name)
if spec_list is None:
item = cls.default(kwargs.get('toolchain'))
dbg('{}: none given; picking default {}: {}', name, cls.__name__, item)
items.add_build_item(item)
else:
if isinstance(spec_list, str):
splitted = util.splitesc_quoted(spec_list, ',')
dbg('{}: str given; splitting: {} -> {}', name, spec_list, splitted)
spec_list = splitted
for s in spec_list:
dbg('{}: adding {}', name, s)
item = cls(s)
items.add_build_item(item)
items.resolve_references()
return items

Expand Down Expand Up @@ -177,7 +192,7 @@ def parse_args(v_):
if rest:
vli.append(rest)
_dbg("parse_args 3.2.3: rest={} vli={}", rest, vli)
if _dbg_parse: print("parse_args 4: vli=", vli)
_dbg("parse_args 4: vli=", vli)
# unquote split elements
vli = [util.unquote(v).strip(',') for v in vli]
_dbg("parse_args 5: input=____{}____ output=__{}__", v_, vli)
Expand Down Expand Up @@ -240,7 +255,7 @@ def __init__(self, *args, **kwargs):
def __eq__(self, other):
"""code quality checkers complain that this class adds attributes
without overriding __eq__. So just fool them!"""
return super().__init__(other)
return super().__eq__(other)

def add_build_item(self, item):
# convert the class name to snake case and append s for plural
Expand Down
Loading

0 comments on commit 384a055

Please sign in to comment.