D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 18066 - duplicate symbol error when symbol is in a ".o" and a ".a" ; linker should accept it to allow partial recompilation
Summary: duplicate symbol error when symbol is in a ".o" and a ".a" ; linker should ac...
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Mac OS X
: P1 blocker
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-12-12 02:29 UTC by Timothee Cour
Modified: 2022-03-25 10:37 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Timothee Cour 2017-12-12 02:29:20 UTC
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 Timothee Cour 2017-12-12 02:39:43 UTC
EDIT: fun2.d is not essential and can be removed from this reduced case.
Comment 2 Timothee Cour 2017-12-12 02:52:29 UTC
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 Timothee Cour 2017-12-12 03:19:06 UTC
NOTE: there's also the mystery that "import std.file;" is somehow special and other imports don't have this error.
Comment 4 anonymous4 2017-12-12 10:36:53 UTC
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 RazvanN 2022-03-25 10:37:14 UTC
I can't reproduce this.