Skip to content

Commit dd3ab3a

Browse files
authored
A plugin hands a dependency on with reexport = true on its [dependencies] edge (#800)
* A plugin hands a dependency on with reexport = true on its [dependencies] edge (#797) The build programs' graph compiles a plugin's [dependencies] with it, and the import check offered `reexport = true` as the way to make such a dependency importable by the plugin's consumers' build programs -- but read reexport only on [build-dependencies] edges, so the advice did not work. A [dependencies] edge with reexport = true hands the library on; without it the import stays refused (e2e 910 G). docs/31 states it. * CHANGELOG: a plugin hands on a dependency with reexport = true
1 parent ed79c7c commit dd3ab3a

5 files changed

Lines changed: 32 additions & 8 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
directory as `engineModules`.
3030
- Read a unit that imports `mcpp.core` as a build-plugin unit (SPEC-007 §10). A
3131
plugin's `[dependencies]` are compiled with it for the build program, so a
32-
plugin may build on plugins and libraries; `mcpp build` and `mcpp test` in a
32+
plugin may build on plugins and libraries, and one it marks `reexport = true`
33+
is importable by its consumers' build programs; `mcpp build` and `mcpp test` in a
3334
plugin plan it in the build-program configuration. A plugin reached through
3435
a target's `[dependencies]`, a program target that imports `mcpp`, `--target`
3536
for another machine on a plugin, and `mcpp pack` of a plugin are refused,

‎docs/31-authoring-a-rule-package.md‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,11 @@ the build-program configuration only. Three consequences follow for its author.
178178
- **What the rule's library imports is in its `[dependencies]`.** A rule built
179179
on another rule (`mcpp:plugins`' `plugins-core`, say) or on an ordinary
180180
library (a TOML parser) names it there. When a consumer's build program uses
181-
the rule, those dependencies are compiled for the build program with it. The
182-
rule's `[build-dependencies]` serve the rule package's own `build.mcpp`, as
183-
any package's do.
181+
the rule, those dependencies are compiled for the build program with it. A
182+
dependency the consumers' build programs import themselves is handed on with
183+
`reexport = true` on its entry; without it the import is refused, naming the
184+
key. The rule's `[build-dependencies]` serve the rule package's own
185+
`build.mcpp`, as any package's do.
184186
- **The package builds and tests as the root of a build.** `mcpp build` in the
185187
package compiles its library for this machine, with the engine interface, and
186188
`mcpp test` runs its tests under `tests/` the same way: a test may import the

‎docs/zh/31-authoring-a-rule-package.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,9 @@ bool compile(options opt = {});
163163
164164
- **规则的库所导入的东西写在它的 `[dependencies]` 中。** 基于另一条规则(例如
165165
`mcpp:plugins` 的 `plugins-core`)或普通库(例如 TOML 解析器)的规则在那里写出它。消费方的
166-
构建程序使用这条规则时,这些依赖与它一起为构建程序编译。规则的 `[build-dependencies]`
167-
服务规则包自己的 `build.mcpp`,与任何包相同。
166+
构建程序使用这条规则时,这些依赖与它一起为构建程序编译。消费方的构建程序自己也导入的依赖,
167+
在其条目上写 `reexport = true` 交出;不写时该导入被拒绝,诊断写出这个键。规则的
168+
`[build-dependencies]` 服务规则包自己的 `build.mcpp`,与任何包相同。
168169
- **规则包可以作为构建的根构建与测试。** 在包中执行 `mcpp build` 会为本机编译它的库并带上
169170
引擎接口,`mcpp test` 以同样的方式运行 `tests/` 下的测试:测试可以导入规则的模块与 `mcpp`,
170171
在没有消费方工程的情况下检查规则的逻辑。

‎src/build/prepare/host_graph.cpp‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,16 @@ std::expected<void, std::string> check_program_imports(PrepareState& state, std:
307307
}
308308
const auto wants = mcpp::pm::imported_module_names(text);
309309
if (wants.empty()) return {};
310-
const auto libs = program_libraries(state, i);
310+
auto libs = program_libraries(state, i);
311+
// What a library hands on: a dependency on a `reexport = true` edge of its
312+
// own `[dependencies]` is importable by the programs that use the library,
313+
// as a `[build-dependencies]` entry it re-exports is (provisions).
314+
for (std::size_t k = 0; k < libs.size(); ++k)
315+
for (auto const& e : state.dependencyEdges)
316+
if (e.consumerPackageIndex == libs[k] && !e.buildTable && e.reexport
317+
&& e.dependencyPackageIndex < state.packages.size()
318+
&& std::ranges::find(libs, e.dependencyPackageIndex) == libs.end())
319+
libs.push_back(e.dependencyPackageIndex);
311320
std::set<std::string> available{"std", "std.compat", "mcpp", "mcpp.core"};
312321
std::map<std::string, std::size_t> providerOf;
313322
for (auto d : libs)

‎tests/e2e/910_a_build_plugin_is_a_package_of_the_build_program.sh‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
# D P1: a plugin reached through [dependencies] of a target is refused,
1212
# naming the chain and [build-dependencies];
1313
# E P4: a program target importing mcpp is refused;
14-
# F P5: `mcpp pack` refuses a plugin.
14+
# F P5: `mcpp pack` refuses a plugin;
15+
# G a library a plugin depends on is importable by the plugin's consumers'
16+
# build programs when the plugin hands it on (`reexport = true` on its
17+
# [dependencies] edge), and refused, naming `reexport`, when it does not.
1518
set -e
1619
TMP=$(mktemp -d)
1720
trap 'rm -rf "$TMP"' EXIT
@@ -95,4 +98,12 @@ grep -q "exists only in a build" e.log || fail "E: the refusal does not say why"
9598
cd "$TMP/rule"
9699
"$MCPP" pack > f.log 2>&1 && fail "F: mcpp pack accepted a plugin" f.log
97100
grep -q "is a build plugin" f.log || fail "F: the refusal does not say why" f.log
101+
# G
102+
cd "$TMP/app"
103+
printf 'import acme.rule;\nimport acme.util;\nint main() { if (util_base() == 40) acme::rule::go(); }\n' > build.mcpp
104+
"$MCPP" build > g1.log 2>&1 && fail "G: a library the plugin does not hand on was importable" g1.log
105+
grep -q "reexport = true" g1.log || fail "G: the refusal does not name reexport" g1.log
106+
sed -i 's|util = { path = "../util" }|util = { path = "../util", reexport = true }|' "$TMP/rule/mcpp.toml"
107+
"$MCPP" build > g2.log 2>&1 || fail "G: a library the plugin hands on was refused" g2.log
108+
[ "$("$MCPP" run 2>/dev/null | grep '^V=' | tail -1)" = "V=42" ] || fail "G: value" g2.log
98109
echo "PASS: 910_a_build_plugin_is_a_package_of_the_build_program"

0 commit comments

Comments
 (0)