Compare commits

...
10 Commits
15 changed files with 342 additions and 132 deletions
+4 -4
View File
@@ -42,8 +42,8 @@ class GnucDriver(CompilerDriver):
args.extend(options.flags) args.extend(options.flags)
if len(options.archives) > 0: if len(options.archives) > 0:
for directory in options.libdirs: args.append(f"-L{str(directory)}") args.extend([f"-L{str(directory)}" for directory in options.libdirs])
for archive in options.archives: args.append(f"-l{archive}") args.extend([f"-l{str(archive)}" for archive in options.archives])
cmdstr = ' '.join(args) cmdstr = ' '.join(args)
# self.logger.info(cmdstr) # self.logger.info(cmdstr)
@@ -126,8 +126,8 @@ class GnucDriver(CompilerDriver):
args.extend(options.flags) args.extend(options.flags)
if len(options.archives) > 0: if len(options.archives) > 0:
for directory in options.libdirs: args.append(f"-L{str(directory)}") args.extend([f"-L{str(directory)}" for directory in options.libdirs])
for archive in options.archives: args.append(f"-l{archive}") args.extend([f"-l{str(archive)}" for archive in options.archives])
cmdstr = ' '.join(args) cmdstr = ' '.join(args)
# self.logger.info(cmdstr) # self.logger.info(cmdstr)
+12 -12
View File
@@ -16,12 +16,12 @@ class CompilerOptions:
stdcpp: StdCpp = StdCpp.C14 stdcpp: StdCpp = StdCpp.C14
optlevel: Optimization = Optimization.NONE optlevel: Optimization = Optimization.NONE
incdirs: set[Path] = field(default_factory=set) incdirs: list[Path] = field(default_factory=list)
libdirs: set[Path] = field(default_factory=set) libdirs: list[Path] = field(default_factory=list)
objfiles: set[Path] = field(default_factory=set) objfiles: list[Path] = field(default_factory=list)
archives: set[str] = field(default_factory=set) archives: list[str] = field(default_factory=list)
defines: set[str] = field(default_factory=set) defines: list[str] = field(default_factory=list)
flags: set[str] = field(default_factory=set) flags: list[str] = field(default_factory=list)
def __deepcopy__(self, memo) -> Self: def __deepcopy__(self, memo) -> Self:
return CompilerOptions( return CompilerOptions(
@@ -30,10 +30,10 @@ class CompilerOptions:
self.stdc, self.stdc,
self.stdcpp, self.stdcpp,
self.optlevel, self.optlevel,
set(self.incdirs), list(self.incdirs),
set(self.libdirs), list(self.libdirs),
set(self.objfiles), list(self.objfiles),
set(self.archives), list(self.archives),
set(self.defines), list(self.defines),
set(self.flags) list(self.flags)
) )
+205
View File
@@ -0,0 +1,205 @@
from dataclasses import dataclass
from dataclasses import field
from ..models import Access
from ..models import Accessor
from ..models import Output
from ..models import Project
from ..models import Target
from ._shared import targets_by_name_mapping
from ._shared import tests_by_name_mapping
from ._shared import project_by_targets_mapping
@dataclass
class _FlattenContext:
_incs_list: list[Accessor] = field(init=False, default_factory=list)
_dirs_list: list[Accessor] = field(init=False, default_factory=list)
_opts_list: list[Accessor] = field(init=False, default_factory=list)
_defs_list: list[Accessor] = field(init=False, default_factory=list)
_deps_list: list[Accessor] = field(init=False, default_factory=list)
_libs_list: list[Accessor] = field(init=False, default_factory=list)
_srcs_list: list[Accessor] = field(init=False, default_factory=list)
_incs_set: set[Accessor] = field(init=False, default_factory=set)
_dirs_set: set[Accessor] = field(init=False, default_factory=set)
_opts_set: set[Accessor] = field(init=False, default_factory=set)
_defs_set: set[Accessor] = field(init=False, default_factory=set)
_deps_set: set[Accessor] = field(init=False, default_factory=set)
_libs_set: set[Accessor] = field(init=False, default_factory=set)
_srcs_set: set[Accessor] = field(init=False, default_factory=set)
@property
def incs(self) -> list[Accessor]:
return self._incs_list
@property
def dirs(self) -> list[Accessor]:
return self._dirs_list
@property
def opts(self) -> list[Accessor]:
return self._opts_list
@property
def defs(self) -> list[Accessor]:
return self._defs_list
@property
def deps(self) -> list[Accessor]:
return self._deps_list
@property
def libs(self) -> list[Accessor]:
return self._libs_list
@property
def srcs(self) -> list[Accessor]:
return self._srcs_list
def inherit_target(self, target: Target) -> None:
for inc in target.incs.includes: self.append_inc(inc)
for drn in target.incs.libraries: self.append_dir(drn)
for opt in target.opts: self.append_opt(opt)
for dfn in target.defs: self.append_def(dfn)
for dep in target.deps: self.append_dep(dep)
for lib in target.libs: self.append_lib(lib)
if target.type == Output.INT:
for src in target.srcs: self.append_src(src)
def append_inc(self, inc: Accessor) -> None:
if inc.level == Access.PRIVATE or inc in self._incs_set:
return
self._incs_set.add(inc)
self._incs_list.insert(0, inc)
def append_dir(self, lib: Accessor) -> None:
if lib.level == Access.PRIVATE or lib in self._dirs_set:
return
self._dirs_set.add(lib)
self._dirs_list.insert(0, lib)
def append_opt(self, opt: Accessor) -> None:
if opt.level == Access.PRIVATE or opt in self._opts_set:
return
self._opts_set.add(opt)
self._opts_list.insert(0, opt)
def append_def(self, dfn: Accessor) -> None:
if dfn.level == Access.PRIVATE or dfn in self._defs_set:
return
self._defs_set.add(dfn)
self._defs_list.insert(0, dfn)
def append_dep(self, dep: Accessor) -> None:
if dep.level == Access.PRIVATE or dep in self._deps_set:
return
self._deps_set.add(dep)
self._deps_list.insert(0, dep)
def append_lib(self, lib: Accessor) -> None:
if lib.level == Access.PRIVATE or lib in self._libs_set:
return
self._libs_set.add(lib)
self._libs_list.insert(0, lib)
def append_src(self, src: Accessor) -> None:
if src.level == Access.PRIVATE or src in self._srcs_set:
return
self._srcs_set.add(src)
self._srcs_list.insert(0, src)
def flatten_targets(project: Project) -> None:
for target in project.targets:
if target._flattend:
continue
context = _FlattenContext()
context.append_inc(Accessor(
level = Access.PUBLIC \
if target.name in project.exports \
else Access.PROTECTED,
value = project.origination.src("include")
))
context.append_dir(Accessor(
level = Access.PUBLIC,
value = project.destination.libpath
))
_flatten_target(context, target)
def flatten_tests(project: Project) -> None:
for target in project.tests:
if target._flattend:
continue
context = _FlattenContext()
context.append_inc(Accessor(
level = Access.PRIVATE,
value = project.origination.src("include")
))
context.append_dir(Accessor(
level = Access.PRIVATE,
value = project.destination.libpath
))
_flatten_test(context, target)
def _flatten_target(context: _FlattenContext, target: Target) -> None:
if target._flattend:
return
for dependency in target.deps:
if (parent:=targets_by_name_mapping.get(dependency.value)) == None:
raise ValueError(f"No such dependable target: {dependency.value}")
_target_inherit_target(context, parent)
target.incs.includes.extend(context.incs)
target.incs.libraries.extend(context.dirs)
target.opts.extend(context.opts)
target.defs.extend(context.defs)
target.deps.extend(context.deps)
target.libs.extend(context.libs)
target.srcs.extend(context.srcs)
target._flattend = True
def _flatten_test(context: _FlattenContext, target: Target) -> None:
if target._flattend:
return
for dependency in target.deps:
if (parent:=targets_by_name_mapping.get(dependency.value)) == None:
raise ValueError(f"No such dependable target: {dependency.value}")
_test_inherit_target(context, parent)
target.incs.includes.extend(context.incs)
target.incs.libraries.extend(context.dirs)
target.opts.extend(context.opts)
target.defs.extend(context.defs)
target.deps.extend(context.deps)
target.libs.extend(context.libs)
target.srcs.extend(context.srcs)
target._flattend = True
def _target_inherit_target(context: _FlattenContext, parent: Target) -> None:
if parent.name in tests_by_name_mapping:
raise ValueError("Cannot inherit tests")
_inherit_raw(context, parent)
def _test_inherit_target(context: _FlattenContext, parent: Target) -> None:
_inherit_raw(context, parent)
def _inherit_raw(context: _FlattenContext, parent: Target) -> None:
parent_project = project_by_targets_mapping.get(parent.name)
assert parent_project is not None, "Parent project not mapped!"
_flatten_target(context, parent)
context.inherit_target(parent)
context.append_inc(Accessor(
level = Access.PROTECTED,
value = parent_project.origination.src("include")
))
context.append_dir(Accessor(
level = Access.PROTECTED,
value = parent_project.destination.libpath
))
context.append_lib(Accessor(
level = Access.PROTECTED,
value = parent.name
))
+15 -69
View File
@@ -1,18 +1,17 @@
import yaml import yaml
from copy import deepcopy
from pathlib import Path from pathlib import Path
from ..models import Access
from ..models import Accessor
from ..models import Dependency from ..models import Dependency
from ..models import Destination from ..models import Destination
from ..models import Origination from ..models import Origination
from ..models import Output
from ..models import Project from ..models import Project
from ..models import Target
from ..shell import execute from ..shell import execute
from .._config import Config from .._config import Config
from ._except import NoProjectFoundError from ._except import NoProjectFoundError
from ._flatten import flatten_targets
from ._flatten import flatten_tests
from ._shared import projects_by_name_mapping from ._shared import projects_by_name_mapping
from ._shared import targets_by_name_mapping from ._shared import targets_by_name_mapping
from ._shared import tests_by_name_mapping from ._shared import tests_by_name_mapping
@@ -37,8 +36,8 @@ def load(path: Path) -> Project:
_collect_required(project) _collect_required(project)
_collect_targets(project) _collect_targets(project)
_collect_tests(project) _collect_tests(project)
_flatten_targets(project) flatten_targets(project)
_flatten_tests(project) flatten_tests(project)
return project return project
except Exception as rethrowme: except Exception as rethrowme:
raise rethrowme raise rethrowme
@@ -51,7 +50,7 @@ def _collect_profiles(project: Project) -> None:
def _collect_required(project: Project) -> None: def _collect_required(project: Project) -> None:
for required in project.requires: for required in project.requires:
_clone_then_load_required(required) _load_required(required)
def _collect_targets(project: Project) -> None: def _collect_targets(project: Project) -> None:
for target in project.targets: for target in project.targets:
@@ -64,68 +63,12 @@ def _collect_tests(project: Project) -> None:
if test.name not in tests_by_name_mapping: if test.name not in tests_by_name_mapping:
tests_by_name_mapping[test.name] = test tests_by_name_mapping[test.name] = test
def _flatten_targets(project: Project) -> None: def _load_required(required: Dependency) -> None:
for target in project.targets: # Determine if local then load or clone then load.
_flatten_target(target) if required.local:
target.incs.includes.add(Accessor( load(Path(required.remote))
level = Access.PUBLIC \ return
if target.name in project.exports \ _clone_then_load_required(required)
else Access.PRIVATE,
value = project.origination.src("include")
))
target.incs.libraries.add(Accessor(
level = Access.PUBLIC,
value = project.destination.libpath
))
def _flatten_tests(project: Project) -> None:
for test in project.tests:
_flatten_target(test)
test.incs.includes.add(Accessor(
level = Access.PRIVATE,
value = project.origination.src("include")
))
test.incs.libraries.add(Accessor(
level = Access.PRIVATE,
value = project.destination.libpath
))
def _flatten_target(target: Target) -> None:
for dependency in target.deps:
if (parent:=targets_by_name_mapping.get(dependency.value)) == None:
raise ValueError(f"No such dependable target: {dependency.value}")
_inherit_target(target, parent)
def _inherit_target(target: Target, parent: Target) -> None:
if parent.name in tests_by_name_mapping:
raise ValueError("Cannot inherit tests")
_flatten_target(parent)
target.incs.includes.update([v for v in parent.incs.includes if v.level != Access.PRIVATE])
target.incs.libraries.update([v for v in parent.incs.libraries if v.level != Access.PRIVATE])
parent_project = project_by_targets_mapping.get(parent.name)
assert parent_project is not None, "Parent project not mapped!"
target.incs.includes.add(Accessor(
level = Access.PUBLIC,
value = parent_project.origination.src("include")
))
target.incs.libraries.add(Accessor(
level = Access.PUBLIC,
value = parent_project.destination.libpath
))
target.opts.update([v for v in parent.opts if v.level != Access.PRIVATE])
target.defs.update([v for v in parent.defs if v.level != Access.PRIVATE])
target.deps.update([v for v in parent.deps if v.level != Access.PRIVATE])
target.libs.update([v for v in parent.libs if v.level != Access.PRIVATE])
target.libs.add(Accessor(
level = Access.PUBLIC,
value = parent.name
))
if parent.type == Output.INT:
target.srcs.update([v for v in parent.srcs if v.level != Access.PRIVATE])
def _clone_then_load_required(required: Dependency) -> None: def _clone_then_load_required(required: Dependency) -> None:
reqpath = Config.config_directory / required.cid reqpath = Config.config_directory / required.cid
@@ -146,6 +89,9 @@ def _clone_required(
global errstr global errstr
errstr = stderr errstr = stderr
from .._logger import logger
logger.info(f"Cloning {required.remote}...")
execute( execute(
f"git clone -b {required.branch} --depth 1 {required.remote} {reqpath}", f"git clone -b {required.branch} --depth 1 {required.remote} {reqpath}",
handle_success, handle_success,
+9 -2
View File
@@ -1,6 +1,7 @@
import yaml import yaml
from dataclasses import dataclass from dataclasses import dataclass
from dataclasses import field
from typing import ClassVar from typing import ClassVar
from typing import Self from typing import Self
@@ -15,7 +16,13 @@ class Dependency(yaml.YAMLError):
yaml_tag: ClassVar[str] = u"!dependency" yaml_tag: ClassVar[str] = u"!dependency"
remote: str remote: str
branch: Branch branch: Branch = field(default="main")
local: bool = field(default=False)
def __post_init__(self) -> None:
from urllib.parse import urlparse
url = urlparse(self.remote)
self.local = not self.remote.startswith("git@") and not url.scheme
@property @property
def cid(self) -> str: def cid(self) -> str:
@@ -27,7 +34,7 @@ class Dependency(yaml.YAMLError):
path = parsed.path.strip("/") path = parsed.path.strip("/")
if path.endswith(".git"): if path.endswith(".git"):
path = path[:-4] path = path[:-4]
return path + str(self.branch) return path + "@" + str(self.branch)
@classmethod @classmethod
def to_dict(cls, data: Self) -> dict: def to_dict(cls, data: Self) -> dict:
+2 -8
View File
@@ -24,21 +24,15 @@ class Destination:
def objpath(self) -> Path: def objpath(self) -> Path:
return self._objpath return self._objpath
def __init__(self, outpath: Path, mkdirs=True) -> None: def __init__(self, outpath: Path) -> None:
self._root = outpath / ".chinook" self._root = outpath / ".chinook"
self._binpath = self._root / "bin" self._binpath = self._root / "bin"
self._libpath = self._root / "lib" self._libpath = self._root / "lib"
self._objpath = self._root / "obj" self._objpath = self._root / "obj"
if mkdirs:
self._root.mkdir(parents=True, exist_ok=True)
self._binpath.mkdir(parents=True, exist_ok=True)
self._libpath.mkdir(parents=True, exist_ok=True)
self._objpath.mkdir(parents=True, exist_ok=True)
@staticmethod @staticmethod
def cwd() -> 'Destination': def cwd() -> 'Destination':
return Destination(Path.cwd(), mkdirs=False) return Destination(Path.cwd())
def bin(self, file: str) -> Path: def bin(self, file: str) -> Path:
return self.binpath / file return self.binpath / file
+4 -4
View File
@@ -16,8 +16,8 @@ class Includes(yaml.YAMLObject):
yaml_loader: ClassVar[Any] = yaml.SafeLoader yaml_loader: ClassVar[Any] = yaml.SafeLoader
yaml_tag: ClassVar[str] = u"!includes" yaml_tag: ClassVar[str] = u"!includes"
includes: set[Accessor] = field(default_factory=set) includes: list[Accessor] = field(default_factory=list)
libraries: set[Accessor] = field(default_factory=set) libraries: list[Accessor] = field(default_factory=list)
@classmethod @classmethod
def to_dict(cls, data: Self) -> dict: def to_dict(cls, data: Self) -> dict:
@@ -38,8 +38,8 @@ class Includes(yaml.YAMLObject):
@classmethod @classmethod
def from_dict(cls, data: dict) -> Self: def from_dict(cls, data: dict) -> Self:
return cls(**{ return cls(**{
"includes": set(Accessor.from_list(data.get("includes", []))), "includes": Accessor.from_list(data.get("includes", [])),
"libraries": set(Accessor.from_list(data.get("libraries", []))) "libraries": Accessor.from_list(data.get("libraries", []))
}) })
@classmethod @classmethod
+26 -10
View File
@@ -21,15 +21,31 @@ class Target(yaml.YAMLObject):
name: str name: str
type: Output type: Output
incs: Includes incs: Includes
opts: set[Accessor] = field(default_factory=set) opts: list[Accessor] = field(default_factory=list)
defs: set[Accessor] = field(default_factory=set) defs: list[Accessor] = field(default_factory=list)
deps: set[Accessor] = field(default_factory=set) deps: list[Accessor] = field(default_factory=list)
libs: set[Accessor] = field(default_factory=set) libs: list[Accessor] = field(default_factory=list)
srcs: set[Accessor] = field(default_factory=set) srcs: list[Accessor] = field(default_factory=list)
# Internal to the tool. # Internal to the tool.
_flattend: bool = field(init=False,default=False)
_prepared: bool = field(init=False,default=False) _prepared: bool = field(init=False,default=False)
def __deepcopy__(self, memo) -> Self:
return Target(
self.name,
self.type,
Includes(
list(self.incs.includes),
list(self.incs.libraries)
),
list(self.opts),
list(self.defs),
list(self.deps),
list(self.libs),
list(self.srcs)
)
@classmethod @classmethod
def to_dict(cls, data: Self) -> dict: def to_dict(cls, data: Self) -> dict:
return { return {
@@ -69,11 +85,11 @@ class Target(yaml.YAMLObject):
"name": data.get("name") or bad_attr("name", data), "name": data.get("name") or bad_attr("name", data),
"type": data.get("type") or bad_attr("type", data), "type": data.get("type") or bad_attr("type", data),
"incs": Includes.from_dict(data.get("incs", {})), "incs": Includes.from_dict(data.get("incs", {})),
"opts": set(Accessor.from_list(data.get("opts", []))), "opts": Accessor.from_list(data.get("opts", [])),
"defs": set(Accessor.from_list(data.get("defs", []))), "defs": Accessor.from_list(data.get("defs", [])),
"deps": set(Accessor.from_list(data.get("deps", []))), "deps": Accessor.from_list(data.get("deps", [])),
"libs": set(Accessor.from_list(data.get("libs", []))), "libs": Accessor.from_list(data.get("libs", [])),
"srcs": set(Accessor.from_list(data.get("srcs", []))) "srcs": Accessor.from_list(data.get("srcs", []))
}) })
@classmethod @classmethod
+12 -4
View File
@@ -1,6 +1,7 @@
from logging import getLogger from logging import getLogger
from logging import Logger from logging import Logger
from ..models import Output
from ..models import Project from ..models import Project
from ..models import Result from ..models import Result
from ..models import Target from ..models import Target
@@ -23,12 +24,13 @@ def build(
commands: list[Command] = [] commands: list[Command] = []
for target in project.targets: for target in project.targets:
commands.extend(_prepare_dependencies(appcfg, target, logger)) commands.extend(_prepare_dependencies(appcfg, project, target, logger))
commands.extend(prepare(appcfg, project, target, logger)) commands.extend(prepare(appcfg, project, target, logger))
return execute(commands, "Building") return execute(commands, "Building")
def _prepare_dependencies( def _prepare_dependencies(
appcfg: Config, appcfg: Config,
project: Project,
target: Target, target: Target,
logger: Logger = _logger logger: Logger = _logger
) -> list[Command]: ) -> list[Command]:
@@ -39,8 +41,14 @@ def _prepare_dependencies(
for required in target.deps: for required in target.deps:
dependency = find_target_by_name(required.value) dependency = find_target_by_name(required.value)
if dependency._prepared: if dependency.type == Output.IMP or \
dependency.type == Output.INT or \
dependency._prepared:
continue continue
project = find_project_by_target(required.value)
commands.extend(prepare(appcfg, project, target, logger)) parent = find_project_by_target(required.value)
if project.cid != parent.cid:
if required.value not in parent.exports:
raise Exception(f"Cannot depend on non-exported target: {required.value}")
commands.extend(prepare(appcfg, parent, dependency, logger))
return commands return commands
+8 -7
View File
@@ -43,9 +43,9 @@ def prepare(
defopts = CompilerOptions() defopts = CompilerOptions()
defopts.pic = target.type == Output.DLL defopts.pic = target.type == Output.DLL
defopts.incdirs.update([v.value for v in target.incs.includes]) defopts.incdirs.extend([v.value for v in target.incs.includes])
defopts.defines.update([v.value for v in target.defs]) defopts.defines.extend([v.value for v in target.defs])
defopts.flags.update([v.value for v in target.opts]) defopts.flags.extend([v.value for v in target.opts])
for file in target.srcs: for file in target.srcs:
srcfile = project.origination.src(file.value) srcfile = project.origination.src(file.value)
dstfile = project.destination.obj(file.value) dstfile = project.destination.obj(file.value)
@@ -53,9 +53,10 @@ def prepare(
dstfile.parent.mkdir(parents=True, exist_ok=True) dstfile.parent.mkdir(parents=True, exist_ok=True)
commands.append(CompileObject(compiler, defopts, logger, srcfile, dstfile)) commands.append(CompileObject(compiler, defopts, logger, srcfile, dstfile))
if not latest(srcfile, outfile): if not latest(srcfile, outfile):
outfile.parent.mkdir(parents=True, exist_ok=True)
objects.append(dstfile) objects.append(dstfile)
defopts.objfiles.update(objects) defopts.objfiles.extend(objects)
del objects del objects
defopts.pic = False defopts.pic = False
@@ -65,10 +66,10 @@ def prepare(
libtgt = find_target_by_name(library.value) libtgt = find_target_by_name(library.value)
libprj = find_project_by_target(libtgt.name) libprj = find_project_by_target(libtgt.name)
if libtgt.type == Output.LIB: if libtgt.type == Output.LIB:
defopts.libdirs.add(libprj.destination.libpath) defopts.libdirs.append(libprj.destination.libpath)
defopts.archives.add(library.value) defopts.archives.append(library.value)
elif libtgt.type == Output.DLL: elif libtgt.type == Output.DLL:
defopts.objfiles.add(libprj.destination.dll(library.value)) defopts.objfiles.append(libprj.destination.dll(library.value))
if len(defopts.objfiles) == 0: if len(defopts.objfiles) == 0:
return commands return commands
+16 -4
View File
@@ -1,6 +1,7 @@
from logging import getLogger from logging import getLogger
from logging import Logger from logging import Logger
from ..models import Output
from ..models import Project from ..models import Project
from ..models import Result from ..models import Result
from ..models import Target from ..models import Target
@@ -24,10 +25,14 @@ def test(
commands: list[Command] = [] commands: list[Command] = []
for target in project.tests: for target in project.tests:
commands.extend(_prepare_dependencies(appcfg, target, logger)) commands.extend(_prepare_dependencies(appcfg, project, target, logger))
commands.extend(prepare(appcfg, project, target, logger)) commands.extend(prepare(appcfg, project, target, logger))
results = execute(commands, "Building") results = execute(commands, "Building")
for result in results:
if not result.success:
return results
commands.clear() commands.clear()
for target in project.tests: for target in project.tests:
testfile = project.destination.bin(target.name) testfile = project.destination.bin(target.name)
@@ -37,6 +42,7 @@ def test(
def _prepare_dependencies( def _prepare_dependencies(
appcfg: Config, appcfg: Config,
project: Project,
target: Target, target: Target,
logger: Logger = _logger logger: Logger = _logger
) -> list[Command]: ) -> list[Command]:
@@ -47,8 +53,14 @@ def _prepare_dependencies(
for required in target.deps: for required in target.deps:
dependency = find_target_by_name(required.value) dependency = find_target_by_name(required.value)
if dependency._prepared: if dependency.type == Output.IMP or \
dependency.type == Output.INT or \
dependency._prepared:
continue continue
project = find_project_by_target(required.value)
commands.extend(prepare(appcfg, project, dependency, logger)) parent = find_project_by_target(required.value)
if project.cid != parent.cid:
if required.value not in parent.exports:
raise Exception(f"Cannot depend on non-exported target: {required.value}")
commands.extend(prepare(appcfg, parent, dependency, logger))
return commands return commands
+3
View File
@@ -11,3 +11,6 @@ targets:
type: program type: program
deps: [example] deps: [example]
srcs: [./entry.cpp] srcs: [./entry.cpp]
exports:
- example
+13
View File
@@ -0,0 +1,13 @@
name: local
gpid: examples
semv: 1.0.0
requires:
- remote: examples/archive
targets:
- name: hello
type: program
deps: [example] # Comes from local required
srcs:
- ./entry.cpp
+5
View File
@@ -0,0 +1,5 @@
extern "C" void print(const char* str);
int main() {
print("Hello, World!");
}
+1 -1
View File
@@ -9,7 +9,7 @@ targets:
- ./fibonacci.cpp - ./fibonacci.cpp
tests: tests:
- name: factorial_test - name: testing
type: program type: program
deps: [fibonacci] deps: [fibonacci]
srcs: srcs: