Skip to content

Commit f1be1c7

Browse files
committed
fix(std-module): 一个字符串承载了两个事实,于是第二条命令收到十九个用不上的 flag
clang++: warning: argument unused during compilation: '-nostdinc++' clang++: warning: argument unused during compilation: '-isystem …' (共十九条,每个 include 目录一条) stdModuleFlags 同时携带「给哪台机器」和「头文件在哪」。构建这个模块有两步,只有 第一步两样都要:第二步编译的是 BMI,而 BMI 已经包含头文件贡献的一切。 把前半单独记为 stdModuleTargetFlags,第二步只用它。 ⭐ 核验方式是产物而不是「编过了」:同一个 codegen 步骤,用拆分后的 flag 和用完整 flag 各跑一次,std.o **逐字节相同**(sha256 a6d837241e7f02b2,736 字节),而后者 产生十九条警告。⇒ 被丢掉的 flag 确实无用。 ⚠️ 这些警告在每个平台上都存在,而在每个平台上都看不见:非 Windows 的命令以 2>&1 结尾,mcpp 又丢弃成功命令的输出 —— Windows 那条没有重定向,所以它是第一次被看见的 地方。⇒ 噪声本身不是缺陷,「十九条正确而无意义的警告排在任何有意义的警告之前」 才是。
1 parent ae9d18b commit f1be1c7

3 files changed

Lines changed: 36 additions & 3 deletions

File tree

src/build/prepare.cppm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5659,6 +5659,10 @@ prepare_build(bool print_fingerprint,
56595659
for (auto& f : mcpp::toolchain::graph_runtime_compile_flags(*tc))
56605660
flags += " " + f;
56615661
}
5662+
// Everything up to here says which machine the module is for; what
5663+
// follows says where its headers are. The codegen step needs only the
5664+
// first — see Toolchain::stdModuleTargetFlags.
5665+
tc->stdModuleTargetFlags = flags;
56625666
for (auto& f : pkg.manifest.stdModuleFlags) {
56635667
// A flag naming a path is relative to the package that named it,
56645668
// for the same reason the module source is.

src/toolchain/clang.cppm

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ std::vector<std::string> std_module_build_commands(const Toolchain& tc,
204204
// built without it is built for whatever machine is doing the building.
205205
if (!tc.stdModuleFlags.empty()) sysrootFlag = {};
206206
const std::string& extraFlags = tc.stdModuleFlags;
207+
// ⚠️ The codegen step compiles a BMI, which already carries what the
208+
// headers contributed; only the machine has to be restated. See
209+
// Toolchain::stdModuleTargetFlags.
210+
const std::string& codegenFlags = tc.stdModuleTargetFlags;
207211
#if defined(_WIN32)
208212
// Windows: use absolute paths, raw binary path as first token
209213
// (cmd.exe strips leading quotes), shq for args with spaces.
@@ -252,7 +256,7 @@ std::vector<std::string> std_module_build_commands(const Toolchain& tc,
252256
tc.binaryPath.string(),
253257
cppStandardFlag,
254258
sysrootFlag,
255-
extraFlags,
259+
codegenFlags,
256260
mcpp::xlings::shq(absBmi),
257261
mcpp::xlings::shq((cacheDir / "std.o").string()))
258262
};
@@ -277,7 +281,7 @@ std::vector<std::string> std_module_build_commands(const Toolchain& tc,
277281
mcpp::xlings::shq(tc.binaryPath.string()),
278282
cppStandardFlag,
279283
sysrootFlag,
280-
extraFlags,
284+
codegenFlags,
281285
mcpp::xlings::shq(relBmi))
282286
};
283287
#endif
@@ -338,6 +342,9 @@ std::vector<std::string> std_compat_build_commands(const Toolchain& tc,
338342
// this target. Reading that message, the mixture is invisible.
339343
if (!tc.stdModuleFlags.empty()) sysrootFlag = {};
340344
const std::string& extraFlags = tc.stdModuleFlags;
345+
// Same split as the `std` builder above: the second command compiles a BMI
346+
// and needs the machine restated, not the include paths.
347+
const std::string& codegenFlags = tc.stdModuleTargetFlags;
341348
// std.compat depends on std, so we need -fmodule-file=std=<std.pcm>
342349
// Note: the path after = must NOT be shell-quoted separately; the
343350
// entire -fmodule-file flag is a single token to the compiler.
@@ -384,7 +391,7 @@ std::vector<std::string> std_compat_build_commands(const Toolchain& tc,
384391
mcpp::xlings::shq(tc.binaryPath.string()),
385392
cppStandardFlag,
386393
sysrootFlag,
387-
extraFlags,
394+
codegenFlags,
388395
absStdBmi,
389396
mcpp::xlings::shq(absBmi),
390397
mcpp::xlings::shq(absObj))

src/toolchain/model.cppm

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,28 @@ struct Toolchain {
9393
// They reach the cache key without anything further being done: the key is
9494
// derived from the build COMMANDS, and these are part of them.
9595
std::string stdModuleFlags;
96+
// ⭐⭐ THE PART OF THE ABOVE THAT SAYS WHICH MACHINE, SEPARATED FROM THE
97+
// PART THAT SAYS WHERE THE HEADERS ARE.
98+
//
99+
// `stdModuleFlags` is one string carrying two different facts: the target
100+
// and its ABI-affecting options, and the include paths the module's SOURCE
101+
// needs. Building the module has two steps, and only the first needs both —
102+
// the second compiles a BMI, which already contains everything the headers
103+
// contributed.
104+
//
105+
// ⚠️ Passing the whole string to the second step is not wrong, it is noisy,
106+
// and the noise is the kind that hides things:
107+
//
108+
// clang++: warning: argument unused during compilation: '-nostdinc++'
109+
// clang++: warning: argument unused during compilation: '-isystem …'
110+
// (× 17, once per include directory)
111+
//
112+
// Seventeen warnings that are correct and mean nothing, in front of any
113+
// warning that would mean something. ⚠️ They were present on every platform
114+
// and visible on none: the non-Windows command ends in `2>&1` and mcpp
115+
// discards a successful command's output, so the Windows leg — which has no
116+
// redirection — is where they first appeared.
117+
std::string stdModuleTargetFlags;
96118
// A package in the graph supplies a C++ runtime built FOR THIS TARGET.
97119
// Read by the freestanding flag table, which otherwise forces exceptions
98120
// and run-time type information off for every unit — right when nothing can

0 commit comments

Comments
 (0)