Bug 18066 – duplicate symbol error when symbol is in a ".o" and a ".a" ; linker should accept it to allow partial recompilation
Status
RESOLVED
Resolution
WORKSFORME
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2017-12-12T02:29:20Z
Last change time
2022-03-25T10:37:14Z
Assigned to
No Owner
Creator
Timothee Cour
Comments
Comment #0 by timothee.cour2 — 2017-12-12T02:29:20Z
it worked in dmd2_071_2, it fails in dmd2_072_0.
reduced case:
```
fun1.d:
module fun1;
import std.file; // NOTE: other modules (eg std.stdio) don't have this error
fun2.d:
module fun2;
main_aux.d:
module main_aux; void main(){}
```
```
dmd -of=./build//app.o -c -g fun1.d fun2.d main_aux.d
libtool -static ./build//app.o -o ./build//libapp.a
dmd -of=./build//app -g -L./build//libapp.a main_aux.d
duplicate symbol __Dmain in:
./build//app.o
./build//libapp.a(app.o)
duplicate symbol _D8main_aux12__ModuleInfoZ in:
./build//app.o
./build//libapp.a(app.o)
duplicate symbol _D8main_aux7__arrayZ in:
./build//app.o
./build//libapp.a(app.o)
duplicate symbol _D8main_aux8__assertFiZv in:
./build//app.o
./build//libapp.a(app.o)
duplicate symbol _D8main_aux15__unittest_failFiZv in:
./build//app.o
./build//libapp.a(app.o)
duplicate symbol _main in:
./build//app.o
./build//libapp.a(app.o)
```
NOTE: works if building library directly in this particular case, eg:
`dmd -of=./build//libapp.a -lib -g fun1.d fun2.d main_aux.d`
but this isn't always desirable to do so.
NOTE: I am passing main_aux.d twice but this shouldn't be a problem because it's first passed as ".o" and then as part of a ".a" which should avoid duplicate symbol errors: https://stackoverflow.com/questions/34454355/why-doesnt-the-linker-complain-of-duplicate-symbols
NOTE: this pattern (recompiling a file already part of a library) is *essential* to support speedy partial recompilation and avoid recompiling the whole app (eg if we want to speed up edit/recompile cycle) and must be supported.
Comment #1 by timothee.cour2 — 2017-12-12T02:39:43Z
EDIT: fun2.d is not essential and can be removed from this reduced case.
Comment #2 by timothee.cour2 — 2017-12-12T02:52:29Z
EDIT: the reason i thought dmd2_071_2 accepted it was because the syntax -of= was introduced in 072, and shell magic made the example work somehow by accident, so reclassified as blocker instead of regression.
Nevertheless, IMO partial recompilation should be accepted. If not what are workarounds?
Comment #3 by timothee.cour2 — 2017-12-12T03:19:06Z
NOTE: there's also the mystery that "import std.file;" is somehow special and other imports don't have this error.
Comment #4 by dfj1esp02 — 2017-12-12T10:36:53Z
Try to compile main_aux separately?
---
dmd -of=./build//app.o -c -g fun1.d fun2.d
dmd -of=./build//main.o -c -g main_aux.d
libtool -static ./build//app.o ./build//main.o -o ./build//libapp.a
dmd -of=./build//app -g -L./build//libapp.a main_aux.d
---
Usually linker can't omit symbols selectively from one object file, so you should compile to separate object files, what dmd -lib does - that's why it works.
btw what is // ?
Comment #5 by razvan.nitu1305 — 2022-03-25T10:37:14Z