Skip to content

Commit c7c89e5

Browse files
Install Uapi/shield crate to staging (#10)
- [x] create local registry at startup - [x] remove nigthly cargo - [x] install uapi - [x] install shield - [x] install deps (kconfig, metadata) - [x] install task - [x] relink task
2 parents bc142c7 + 235fddd commit c7c89e5

File tree

14 files changed

+402
-98
lines changed

14 files changed

+402
-98
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
`cargo_config`
2+
==============
3+
4+
.. argparse::
5+
:module: outpost.barbican._internals.cargo_config
6+
:func: argument_parser
7+
:prog: barbican --internal cargo_config
8+
9+
.. seealso::
10+
11+
:py:mod:`outpost.barbican._internals.cargo_config` module documentation
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
`cargo_install`
2+
===============
3+
4+
.. argparse::
5+
:module: outpost.barbican._internals.cargo_install
6+
:func: argument_parser
7+
:prog: barbican --internal cargo_install
8+
9+
.. seealso::
10+
11+
:py:mod:`outpost.barbican._internals.cargo_install` module documentation
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SPDX-FileCopyrightText: 2024 Ledger SAS
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""Generate a .cargo/config.toml per cargo app.
6+
7+
Add target specific and per apps compile flags in a config.
8+
"""
9+
10+
from argparse import ArgumentParser
11+
from pathlib import Path
12+
import typing as T
13+
14+
15+
def run_cargo_config(rustargs: Path, target: Path, extra_args: str, outdir: Path) -> None:
16+
rust_target = target.read_text().splitlines()[0]
17+
rust_flags = rustargs.read_text().splitlines()
18+
rust_flags.extend(extra_args.split(" "))
19+
linker_args = list(filter(lambda x: x.startswith("-Clinker"), rust_flags))
20+
linker = linker_args[0].split("=")[1] if len(linker_args) else "is not set"
21+
rust_flags = list(filter(lambda x: not x.startswith("-Clinker"), rust_flags))
22+
23+
config = f"""
24+
[build]
25+
target = "{rust_target}"
26+
target-dir = "{str(outdir.resolve())}"
27+
rustflags = {rust_flags}
28+
29+
[target.{rust_target}]
30+
{"#" if not len(linker_args) else ""}linker = "{linker}"
31+
32+
[env]
33+
OUT_DIR = "{str(outdir.resolve())}"
34+
"""
35+
36+
(outdir / ".cargo" / "config.toml").write_text(config)
37+
38+
39+
def argument_parser() -> ArgumentParser:
40+
parser = ArgumentParser()
41+
parser.add_argument("--rustargs-file", type=Path, help="rustargs file path")
42+
parser.add_argument("--target-file", type=Path, help="rust target file path")
43+
parser.add_argument("--extra-args", type=str)
44+
parser.add_argument("outdir", type=Path, help="output directory")
45+
46+
return parser
47+
48+
49+
def run(argv: T.List[str]) -> None:
50+
"""Execute gen crate cargo config command."""
51+
args = argument_parser().parse_args(argv)
52+
run_cargo_config(args.rustargs_file, args.target_file, args.extra_args, args.outdir)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SPDX-FileCopyrightText: 2024 Ledger SAS
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""Generate a .cargo/config.toml per cargo app.
6+
7+
Add target specific and per apps compile flags in a config.
8+
"""
9+
10+
from argparse import ArgumentParser
11+
from pathlib import Path
12+
import typing as T
13+
14+
from .install import run_install, argument_parser as install_argument_parser
15+
16+
17+
def argument_parser() -> ArgumentParser:
18+
parser = install_argument_parser()
19+
parser.add_argument(
20+
"--target-file",
21+
type=Path,
22+
help="rust target file",
23+
)
24+
parser.add_argument(
25+
"--profile",
26+
action="store",
27+
type=str,
28+
default="release",
29+
help="cargo build profile",
30+
)
31+
32+
return parser
33+
34+
35+
def run(argv: T.List[str]) -> None:
36+
args = argument_parser().parse_args(argv)
37+
target: str = args.target_file.read_text().splitlines()[0]
38+
from_dir: Path = (args.from_dir / target / args.profile).resolve(strict=True)
39+
run_install(from_dir, args.files, args.suffix)

src/outpost/barbican/_internals/gen_task_metadata_bin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,6 @@ def argument_parser() -> ArgumentParser:
105105
def run(argv: T.List[str]) -> None:
106106
args = argument_parser().parse_args(argv)
107107
# XXX: use builddir as option
108-
run_gen_task_metadata_bin(args.input, args.output, ProjectPath.load(args.projectdir / "build"))
108+
run_gen_task_metadata_bin(
109+
args.input, args.output, ProjectPath.load(args.projectdir / "output" / "build")
110+
)

src/outpost/barbican/barbican.py

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@
2121
from .logger import logger, log_config
2222
from . import config
2323
from .package import Package, create_package, Backend
24+
from .package.kernel import Kernel
25+
from .package.runtime import Runtime
2426
from .package.meson import Meson
2527
from .package.cargo import Cargo
28+
from .package import cargo
2629

2730
from .buildsys import ninja_backend
28-
from .utils import pathhelper
31+
from .utils import pathhelper, working_directory
2932

3033

3134
class Project:
3235
def __init__(self, project_dir: pathlib.Path) -> None:
3336
self.path = pathhelper.ProjectPath(
3437
project_dir=project_dir,
35-
output_dir=project_dir,
38+
output_dir=project_dir / "output",
3639
)
3740

3841
# XXX:
@@ -58,18 +61,12 @@ def __init__(self, project_dir: pathlib.Path) -> None:
5861
# This will be, likely, false for next devel step.
5962

6063
# Instantiate Sentry kernel
61-
self._packages.append(
62-
Meson("kernel", self, self._toml["kernel"], Package.Type.Kernel) # type: ignore
63-
)
64+
self._kernel = Kernel(self, self._toml)
65+
self._packages.append(self._kernel._package)
66+
6467
# Instantiate libshield
65-
self._packages.append(
66-
Meson(
67-
"runtime",
68-
self,
69-
self._toml["runtime"],
70-
Package.Type.Runtime, # type: ignore[arg-type]
71-
)
72-
)
68+
self._runtime = Runtime(self, self._toml)
69+
self._packages.append(self._runtime._package)
7370

7471
if "application" in self._toml:
7572
self._noapp = False
@@ -95,6 +92,15 @@ def update(self) -> None:
9592
p.update()
9693

9794
def setup(self) -> None:
95+
96+
logger.info("Create Cargo local repository")
97+
registry = cargo.LocalRegistry(
98+
self.path.sysroot_data_dir / "cargo" / "registry" / "outpost_sdk"
99+
)
100+
cargo_config = cargo.Config(self.path.output_dir, registry)
101+
registry.init()
102+
self._kernel.install_crates(registry, cargo_config)
103+
self._runtime.install_crates(registry, cargo_config)
98104
logger.info(f"Generating {self.name} Ninja build File")
99105
ninja = ninja_backend.NinjaGenFile(os.path.join(self.path.build_dir, "build.ninja"))
100106

@@ -112,7 +118,7 @@ def setup(self) -> None:
112118
)
113119

114120
ninja.add_meson_rules()
115-
ninja.add_cargo_rules()
121+
ninja.add_cargo_rules(self._kernel.rustargs, self._kernel.rust_target)
116122

117123
# Add setup/compile/install targets for meson packages
118124
for p in self._packages:
@@ -143,20 +149,22 @@ def setup(self) -> None:
143149

144150
# Dummy link, for non pic application
145151
for package in self._packages:
146-
if package.is_application and package.backend == Backend.Meson:
147-
ninja.add_relink_meson_target(
152+
# if package.is_application and package.backend == Backend.Meson:
153+
if package.is_application:
154+
ninja.add_relink_target(
148155
package.name,
149156
package.installed_targets[0],
150157
package.dummy_linked_targets[0],
151158
dummy_linker_script,
159+
package_name=package.name if package.backend == Backend.Meson else "kernel",
152160
)
153161

154162
layout_sys_exelist = []
155163
layout_app_exelist = []
156164
for package in self._packages:
157165
if package.is_sys_package:
158166
layout_sys_exelist.extend(package.installed_targets)
159-
elif package.backend == Backend.Meson:
167+
else:
160168
layout_app_exelist.extend(package.dummy_linked_targets)
161169

162170
firmware_layout = ninja.add_internal_gen_memory_layout_target(
@@ -174,7 +182,7 @@ def setup(self) -> None:
174182

175183
# gen_ld/relink/gen_meta/objcopy app(s)
176184
for package in self._packages:
177-
if package.is_application and package.backend == Backend.Meson:
185+
if package.is_application:
178186
# XXX: Handle multiple exe package
179187
elf_in = package.installed_targets[0]
180188
elf_out = package.relocated_targets[0]
@@ -189,15 +197,21 @@ def setup(self) -> None:
189197
pathlib.Path(firmware_layout[0]),
190198
package.name,
191199
)
192-
ninja.add_relink_meson_target(
200+
ninja.add_relink_target(
193201
package.name,
194202
elf_in,
195203
elf_out,
196204
linker_script,
197-
package.name,
205+
package_name=package.name if package.backend == Backend.Meson else "kernel",
198206
)
199207

200-
ninja.add_objcopy_rule(elf_out, hex_out, "ihex", [], package.name)
208+
ninja.add_objcopy_rule(
209+
elf_out,
210+
hex_out,
211+
"ihex",
212+
[],
213+
package_name=package.name if package.backend == Backend.Meson else "kernel",
214+
)
201215
app_hex_files.append(hex_out)
202216

203217
ninja.add_gen_metadata_rule(
@@ -238,7 +252,8 @@ def update(project: Project) -> None:
238252

239253

240254
def setup(project: Project) -> None:
241-
project.setup()
255+
with working_directory(project.path.output_dir):
256+
project.setup()
242257

243258

244259
def common_argument_parser() -> ArgumentParser:

src/outpost/barbican/buildsys/ninja_backend.py

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def add_gen_ldscript_target(
156156
},
157157
)
158158

159-
def add_relink_meson_target(
159+
def add_relink_target(
160160
self,
161161
name: str,
162162
orig_elf: Path,
@@ -271,16 +271,19 @@ def add_meson_rules(self) -> None:
271271
"touch $out",
272272
)
273273

274-
def add_cargo_rules(self) -> None:
274+
def add_cargo_rules(self, rustargs: Path, rust_target: Path) -> None:
275275
self._ninja.newline()
276276
self._ninja.variable("cargo", find_program("cargo"))
277+
self._ninja.variable("rustargs", str(rustargs.resolve()))
278+
self._ninja.variable("rust_target", str(rust_target.resolve()))
277279
self._ninja.newline()
278280
self._ninja.rule(
279281
"cargo_compile",
280282
description="cargo compile $name",
281283
pool="console",
282-
command="$cargo build -Z unstable-options --manifest-path=$sourcedir/Cargo.toml "
283-
"--target-dir=$builddir --out-dir=$builddir && touch $out",
284+
command="cd $builddir "
285+
+ " && config=$config $cargo build --manifest-path=$sourcedir/Cargo.toml --release"
286+
+ " && touch $out && cd -",
284287
)
285288
self._ninja.newline()
286289
self._ninja.rule(
@@ -291,6 +294,26 @@ def add_cargo_rules(self) -> None:
291294
)
292295

293296
def add_cargo_package(self, package: "Package") -> None:
297+
self._ninja.newline()
298+
self._ninja.build(
299+
f"{package.build_dir}/.cargo/config.toml",
300+
"internal",
301+
variables={
302+
"cmd": "cargo_config",
303+
"args": f"--rustargs-file={str(package._parent._kernel.rustargs)} "
304+
+ f"--target-file={str(package._parent._kernel.rust_target)} "
305+
+ '--extra-args="'
306+
+ " ".join(package.build_options)
307+
+ '" '
308+
+ f"{str(package.build_dir)}",
309+
"description": f"cargo config {package.name}",
310+
},
311+
order_only=[f"{dep}_install.stamp" for dep in package.deps],
312+
)
313+
self._ninja.newline()
314+
self._ninja.build(
315+
f"{package.name}_setup", "phony", f"{package.build_dir}/.cargo/config.toml"
316+
)
294317
self._ninja.newline()
295318
self._ninja.build(
296319
f"{package.name}_compile.stamp",
@@ -299,19 +322,28 @@ def add_cargo_package(self, package: "Package") -> None:
299322
"sourcedir": package.src_dir,
300323
"builddir": package.build_dir,
301324
"name": package.name,
325+
"config": package._dotconfig,
302326
},
327+
implicit=f"{package.name}_setup",
303328
)
304329
self._ninja.newline()
305330
self._ninja.build(f"{package.name}_compile", "phony", f"{package.name}_compile.stamp")
306331
self._ninja.newline()
332+
333+
# XXX:
334+
# Cargo binary are built w/o .elf extension that is required here
335+
# so split provides name and pass extension as suffix for install rule
336+
307337
self._ninja.build(
308338
f"{package.name}_install.stamp",
309339
"internal",
310340
implicit=f"{package.name}_compile",
311341
variables={
312-
"cmd": "install",
313-
"args": f"--suffix=.elf {str(package.build_dir)} "
314-
+ " ".join((str(t) for t in package.installed_targets)), # noqa: W503
342+
"cmd": "cargo_install",
343+
"args": "--suffix=.elf "
344+
+ f"--target-file={str(package._parent._kernel.rust_target)} "
345+
+ f"{str(package.build_dir)} "
346+
+ " ".join((str(t.with_suffix("")) for t in package.installed_targets)),
315347
"description": f"cargo install {package.name}",
316348
},
317349
)

0 commit comments

Comments
 (0)