Bug 18423 – rdmd incorrectly assumes that the D compiler outputs dependency info to stdout

Status
RESOLVED
Resolution
MOVED
Severity
major
Priority
P1
Component
tools
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-02-11T15:22:46Z
Last change time
2020-04-09T10:00:24Z
Assigned to
No Owner
Creator
Joseph Rushton Wakeling

Comments

Comment #0 by joseph.wakeling — 2018-02-11T15:22:46Z
When `rdmd` invokes the D compiler to generate dependencies information, it makes a hardcoded assumption that this information gets written by the compiler to `stdout`. However, this assumption is not valid for all D compilers. In particular, compiler frontend messages are written out to a configurable `stdmsg`: https://github.com/dlang/dmd/commit/dc8421f ... and this configurability is used by GDC to output such messages to `stderr` (reflecting GCC policy that `stdout` is reserved for `-pipe` output; see: https://github.com/dlang/tools/pull/297#issuecomment-363342259). This means not only that `rdmd` will not work with more recent GDC releases, but that `rdmd`'s assumptions about `stdout` are not valid in general (given the configurable `stdmsg` in the DMD frontend). The gory details ~~~~~~~~~~~~~~~~ The `getDependencies` function inside `rdmd.d` invokes the D compiler via the `run` command, passing in options (the `depsGetter` variable) and the name of a file to which to write the compiler output (`depsFilename`): ``` immutable depsExitCode = run(depsGetter, depsFilename); ``` Internally, `run` takes this and uses `spawnProcess` to invoke the D compiler: ``` private int run(string[] args, string output = null, bool replace = false) { ... File outputFile; if (output.ptr) outputFile = File(output, "wb"); else outputFile = stdout; auto process = spawnProcess(args, stdin, outputFile); return process.wait(); } ``` In other words, `run` opens a file whose name is given by `depsFilename`, and uses it to replace `stdout` for the spawned process. The contents of this file are then read using the nested `readDepsFile()` function defined internally inside `getDependencies`. In consequence, if the information parsed by `readDepsFile` is not written to `stdout` by the D compiler, it will not get written into `outputFile`, and therefore not be available to parse.
Comment #1 by joseph.wakeling — 2018-02-11T15:30:16Z
For context, this issue was observed while trying to update rdmd's integration tests to use gdmd: https://github.com/dlang/tools/pull/307#issuecomment-363564781
Comment #2 by pro.mathias.lang — 2020-04-09T10:00:24Z