Skip to content

Commit 565a10d

Browse files
committed
examples: 一份源码,两台机器,中间什么都没改
原来这个目录叫 baremetal 并且 [build] target 钉死在 riscv64-none-elf —— 那让它 成了一个「裸机的例子」,而不是设计文档那条主张的**演示**。 主张是:openkal 之上的程序,构建时不关心底下是哪个实现。所以现在: mcpp run 这台机器,openkal-linux 之上 mcpp run --target riscv64-none-elf riscv64,OpenSBI 之上,没有操作系统 同一个 src/main.cpp,没有 #if,没有第二个目录,两边打印同样的四行。 唯一不同的是内存布局,而 build.mcpp 把它放在一个对 target_os 的条件后面 —— 因为那是一句关于**机器**的陈述,不是关于程序的。 CI 两步:第二步跑宿主那条,并且 两边的四行 —— 断言的是「输出相同」而不是 「两边都有输出」。 已验证两个方向都通过。目录改名为 same-source,因为它现在说的是这件事。
1 parent 3a32350 commit 565a10d

7 files changed

Lines changed: 70 additions & 18 deletions

File tree

.github/workflows/ci.yml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ jobs:
155155
echo "$(cd "$(dirname "$BUILT")" && pwd)" >> "$GITHUB_PATH"
156156
"$BUILT" --version
157157
158-
- name: The same program on bare metal, with exceptions
158+
- name: The same source on bare metal, with exceptions
159159
if: matrix.toolchain == 'llvm@22.1.8'
160160
run: |
161161
set -euo pipefail
162-
cd examples/baremetal
162+
cd examples/same-source
163163
Q=$(ls -d "$HOME"/.mcpp/registry/data/xpkgs/xim-x-qemu-riscv/*/bin/qemu-system-riscv64 | head -1)
164164
# ⚠️ Anchored on the BARE NAME, so a checkout that already carries a
165165
# path is left alone rather than getting a path inside a path. The
@@ -172,4 +172,21 @@ jobs:
172172
grep -q 'sorted: 2 4 7' out.log # containers + algorithms + the allocator
173173
grep -q 'caught: 42' out.log # the unwinder found the handler
174174
grep -q 'unwound: true' out.log # ⭐ and ran a destructor on the way
175-
grep -q 'baremetal import std: ok' out.log
175+
grep -q 'import std over openkal: ok' out.log
176+
177+
# ⭐⭐ AND THE SAME SOURCE ON THIS MACHINE, WHICH IS WHAT MAKES THE STEP
178+
# ABOVE A DEMONSTRATION RATHER THAN AN ILLUSTRATION.
179+
#
180+
# Nothing is edited between the two commands — no `#if`, no second
181+
# directory, no second source. The only thing that differs is the memory
182+
# layout, and `build.mcpp` states it behind a condition on the target OS
183+
# because that is a statement about the machine.
184+
- name: The same source, on this machine, over openkal-linux
185+
if: matrix.toolchain == 'llvm@22.1.8'
186+
run: |
187+
set -euo pipefail
188+
cd examples/same-source && mcpp run 2>&1 | tee host.log
189+
grep -q 'import std over openkal: ok' host.log
190+
# The four lines are the same four lines.
191+
diff <(grep -E '^(sorted|caught|unwound|import std over openkal):' out.log) \
192+
<(grep -E '^(sorted|caught|unwound|import std over openkal):' host.log)

examples/baremetal/build.mcpp

Lines changed: 0 additions & 8 deletions
This file was deleted.

examples/same-source/build.mcpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import mcpp;
2+
#include <cstring>
3+
4+
int main() {
5+
// ⭐⭐ THE LINKER SCRIPT IS FOR THE MACHINE WITH NO OPERATING SYSTEM, AND
6+
// ONLY FOR IT. THAT CONDITION IS WHAT MAKES THIS ONE PROJECT INSTEAD OF TWO.
7+
//
8+
// The claim the design document makes is that a program above openkal is
9+
// built without regard to which implementation is beneath — same source,
10+
// different machine, nothing edited. A directory that could only be built
11+
// one way would illustrate that claim rather than demonstrate it.
12+
//
13+
// So: `mcpp run` puts this on the host over openkal-linux, and
14+
// `mcpp run --target riscv64-none-elf` puts the SAME source on riscv64 over
15+
// OpenSBI. Both print the same four lines. The only thing that differs is
16+
// the memory layout, which is a statement about the machine — and it is
17+
// stated here, once, behind the condition that says which machine.
18+
if (std::strcmp(mcpp::target_os(), "none") == 0) {
19+
// A relative path in `ldflags` would resolve against the build
20+
// directory; `link-script` resolves against the package root.
21+
mcpp::link_script("link.ld");
22+
}
23+
mcpp::rerun_if_changed("link.ld");
24+
mcpp::rerun_if_env_changed("MCPP_TARGET_OS");
25+
return 0;
26+
}
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
[package]
2-
name = "openkal-baremetal-import-std"
2+
name = "openkal-same-source"
33
version = "0.1.0"
44

5-
[build]
6-
target = "riscv64-none-elf"
5+
# ⚠️ NO `[build] target`, AND THAT IS THE POINT OF THE DIRECTORY.
6+
#
7+
# The same `src/main.cpp` is built two ways from here:
8+
#
9+
# mcpp run — this machine, over openkal-linux
10+
# mcpp run --target riscv64-none-elf — riscv64, over OpenSBI, no OS
11+
#
12+
# and both print the same four lines. Pinning a target here would make the
13+
# second command the only one, and then the directory would be an example of
14+
# bare metal rather than a demonstration that the source does not know.
715

816
# No sysroot: there is no system to take headers or libraries from. The runner
917
# is the emulator with firmware, because `-bios default` is what supplies the
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
// `import std;` on a machine with no operating system.
22
//
3-
// ⭐ THIS IS THE ACCEPTANCE CRITERION, AND ITS VALUE IS THAT IT CANNOT GO GREEN
4-
// BY ACCIDENT.
3+
// ⭐⭐ ONE SOURCE, TWO MACHINES, NOTHING EDITED BETWEEN THEM.
4+
//
5+
// mcpp run — this machine, over openkal-linux
6+
// mcpp run --target riscv64-none-elf — riscv64, over OpenSBI, no OS
7+
//
8+
// Both print the same four lines. That is the claim the design document makes
9+
// about building above openkal, written as something a reader can run rather
10+
// than something they have to believe.
11+
//
12+
// ⭐ AND THE SECOND COMMAND IS THE ACCEPTANCE CRITERION, BECAUSE IT CANNOT GO
13+
// GREEN BY ACCIDENT.
514
//
615
// A hosted target has a C library, a C++ runtime and an unwinder already
716
// installed, and a program that reaches one of them by mistake still works ---
@@ -55,6 +64,6 @@ int main() {
5564
// is consumed by a consteval constructor, and a value computed at run time
5665
// cannot be one. The compiler says so, which is the whole reason it is
5766
// written this way.
58-
std::println("baremetal import std: {}", ok ? "ok" : "FAILED");
67+
std::println("import std over openkal: {}", ok ? "ok" : "FAILED");
5968
return ok ? 0 : 1;
6069
}

mcpp.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ include_dirs = ["llvm-generated/freestanding"]
158158
#
159159
# The symbols are `__eh_frame_start` / `__eh_frame_end` (and the `_hdr_`
160160
# pair), and AddressSpace.hpp carries the linker script fragment that defines
161-
# them. examples/baremetal/link.ld is that fragment.
161+
# them. examples/same-source/link.ld is that fragment.
162162
cxxflags = ["-D_LIBUNWIND_USE_DLADDR=0", "-D_GNU_SOURCE",
163163
"-D_LIBUNWIND_IS_BAREMETAL=1"]
164164
# ⚠️ THE FLAG BELONGS TO THIS PACKAGE AND LANDS ON THE CONSUMER'S LINK.

0 commit comments

Comments
 (0)