Surprise using DMD as replacement C compiler
Carl Sturtivant
sturtivant at gmail.com
Thu Feb 29 15:34:43 UTC 2024
Hello, I ran into this issue when compiling an old large project
on Linux with DMD as its C compiler implicitly using
[ImportC](https://dlang.org/spec/importc.html). I was successful:
ImportC really came through!
I used `CC = dmd` in the configuration of the top level Makefile
and all was well after some technical rearrangements (e.g.
replacing `-o` by `-of=` when the compiler is invoked and fixing
up old C constructs that DMD didn't like) excepting one part of
the build.
That part made a dynamic library, and had to get exactly the
right command line arguments to the C compiler for linking so
that symbols would be exported and so forth. To do that, it ran a
shell script to do the linking containing a branch based upon the
output of `uname -s`. To do that it set shell variables in the
environment the script runs in by e.g. in the Makefile the shell
command `CC="$(CC)"` prefixing the command to run the script.
Imagine my surprise when I got what follows in the terminal on
typing `make`.
```
dmd -shared -fPIC -of=libcfunc.so external.o
Error: -o no longer supported, use -of or -od
Error: unrecognized switch '-Xlinker'
Error: unrecognized switch '--export-dynamic'
Error: unrecognized switch '-Xlinker'
Error: unrecognized switch '-Bstatic'
Error: unrecognized switch '-lphobos2'
Error: unrecognized switch '-Xlinker'
Error: unrecognized switch '-Bdynamic'
Error: unrecognized switch '-lpthread'
Error: unrecognized switch '-lm'
Error: unrecognized switch '-lrt'
Error: unrecognized switch '-ldl'
run `dmd` to print the compiler manual
run `dmd -man` to open browser on manual
Error: linker exited with status 1
```
The reason for this is that the *shell variable* `CC` is set to
`CC=dmd` when DMD is invoked in the script. It seems that DMD
uses its paired C compiler to do the linking and if the shell
variable CC is defined, will get the compiler from its value,
meaning itself in this case!
The result is what you see: a command line intended for `gcc` is
instead executed with `dmd` in its place. Naturally `dmd` knows
nothing of the various options used by `gcc` to invoke the linker
at `dmd`'s request and complains accordingly, so at least
recursion of this forwarding is prevented.
A test if `CC` is `dmd` in the script with `unset CC` preceding
explicit use of `dmd` in place of `$CC` works around the problem.
More information about the Digitalmars-d
mailing list