Comment #0 by timothee.cour2 — 2015-07-26T10:26:15Z
Reduced test case:
see
https://github.com/timotheecour/dsnippet/tree/master/bug_duplicate_symbol_error
The makefile in that directory should explain the bug:
Makefile:
----
dmd=~/git_clone/D/Digger/result/bin/dmd
#works with dmd
all0:
${dmd} -oflibproj6.a -lib -g project2.d foo2.d foo1.d
${dmd} -ofout -g libproj6.a foo1.d main.d
#works with dmd
all1:
${dmd} -oflibproj6.a -lib -g project2.d foo1.d foo2.d
${dmd} -ofout -g libproj6.a foo2.d main.d
#worked with dmd_067_1_X
#works with dmd from: ./digger build v2.068.0-b1
#FAILS with dmd from: ./digger build
#FAILS with dmd from: ./digger build master (v2.068-devel-494a91d)
#has failed for a few months on git master AFAIR
all1_order_flipped:
${dmd} -oflibproj6.a -lib -g project2.d foo2.d foo1.d
${dmd} -ofout -g libproj6.a foo2.d main.d
----
This bug is very annoying as it prevents partial recompilation
Comment #1 by timothee.cour2 — 2015-07-26T20:28:35Z
digger bisect returns:
2015-07-26T13:16:37.992:common.d:log:25 digger: bisect.d:113 ba17fa7669885dca1c8f7b246483149d37b3f10d is the first bad commit
commit ba17fa7669885dca1c8f7b246483149d37b3f10d
Author: Martin Nowak <[email protected]>
Date: Tue Mar 31 04:43:51 2015 +0200
phobos: Merge pull request #2956 from jmdavis/tempFile
https://github.com/D-Programming-Language/phobos/pull/2956
Implement issue# 13996. Add File.tempFile.
Although this may just be a side effect of another root cause?
Comment #2 by timothee.cour2 — 2015-07-27T02:45:48Z
using different parameters for digger bisect:
bad = master @ 1 month ago
good = master @ 2 months ago
returns:
digger: bisect.d:113 f1bf3d208546728d433de7b3d53631497846b117 is the first bad commit
commit f1bf3d208546728d433de7b3d53631497846b117
Author: Dmitry Olshansky <[email protected]>
Date: Fri Jun 26 20:08:27 2015 +0300
phobos: Merge pull request #3443 from CyberShadow/pull-20150626-091553-uni-stray-stdio-import
https://github.com/D-Programming-Language/phobos/pull/3443
std.uni: Remove stray std.stdio import
Comment #3 by timothee.cour2 — 2015-07-27T02:46:58Z
Is the root cause a symbol that should've been a weak symbol?
Comment #4 by k.hara.pg — 2015-07-29T16:41:25Z
Equivalent link failure happens in win32/64.
But the regression version is not same:
With 2.064, 2.065, 2.066.0, 2.066.1
--> no problem happens
With 2.067.0, 2.067.1, 2.068.0-beta1, 2.068.0-beta2, git-head
--> duplicated symbol error happens with 'make all1_order_flipped'
Comment #5 by code — 2015-07-30T08:23:16Z
(In reply to Timothee Cour from comment #0)
> This bug is very annoying as it prevents partial recompilation
There are many catches with that.
Comment #6 by code — 2015-07-30T08:24:04Z
This might have the same cause as issue 14748.
Comment #7 by k.hara.pg — 2015-07-30T09:16:53Z
Created attachment 1534
Win32 reduced case without Phobos dependency
(In reply to Kenji Hara from comment #4)
> Equivalent link failure happens in win32/64.
> But the regression version is not same:
>
> With 2.064, 2.065, 2.066.0, 2.066.1
> --> no problem happens
>
> With 2.067.0, 2.067.1, 2.068.0-beta1, 2.068.0-beta2, git-head
> --> duplicated symbol error happens with 'make all1_order_flipped'
In win32, the attached reduced case fails from 2.067. It was introduced in:
> commit 679929fa2da120db76d91303efd2316370970d1e
> Merge: 430bdba 706aa61
> Author: Andrei Alexandrescu <[email protected]>
> Date: Wed Jan 28 08:44:07 2015 -0800
>
> Merge pull request #4354 from 9rnsr/fix14044
>
> [REG2.066] Issue 14044 - dmd generates spurious functions in object file created from empty module
However, I don't understand why the change introduced the bug...
Furthermore, I'm not sure that's really same with the original issue, because it happens from 2.068-beta2 in OSX.
Comment #8 by code — 2015-07-30T09:30:32Z
(In reply to Timothee Cour from comment #3)
> Is the root cause a symbol that should've been a weak symbol?
ModuleInfos aren't weak symbols.
You didn't past the error message. Which ModuleInfo is duplicated?
I guess it's either foo2 or main.
Comment #9 by timothee.cour2 — 2015-07-30T17:22:18Z
(In reply to Martin Nowak from comment #8)
> (In reply to Timothee Cour from comment #3)
> > Is the root cause a symbol that should've been a weak symbol?
>
> ModuleInfos aren't weak symbols.
> You didn't past the error message. Which ModuleInfo is duplicated?
> I guess it's either foo2 or main.
duplicate symbol _D4foo212__ModuleInfoZ in:
out.o
libproj6.a(foo2.o)
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Comment #10 by timothee.cour2 — 2015-07-30T17:25:09Z
(In reply to Martin Nowak from comment #5)
> (In reply to Timothee Cour from comment #0)
> > This bug is very annoying as it prevents partial recompilation
>
> There are many catches with that.
I'm well aware. However this technique, when properly used, allows very fast recompilation. We should not prevent this.
Comment #11 by k.hara.pg — 2015-07-31T01:33:03Z
(In reply to Timothee Cour from comment #9)
> duplicate symbol _D4foo212__ModuleInfoZ in:
> out.o
> libproj6.a(foo2.o)
> ld: 1 duplicate symbol for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see
> invocation)
The duplicated symbol name is same with in win32.
Comment #12 by k.hara.pg — 2015-07-31T02:03:31Z
Created attachment 1538
A little updated test case
OK, I understand the issue mechanism. It's obvious from the list files of libproj.lib and out.obj. (`make genlist`)
With the `make a1f` command, the last link for out.exe will pull foo2.obj in the lib file, because:
The instantiated function _D5stdio12__T7writelnZ7writelnFNaNbNiNfAyaZv uses _D5stdio7__arrayZ for array bounds check, but it's stored in foo2.obj in the lib.
By that, the symbol _D4foo212__ModuleInfoZ in lib will also linked because it's in foo2.obj.
On the other hand, out.obj also contains _D4foo212__ModuleInfoZ, then they conflicts each other.
----
The essential fix I think is: when the lib file is compiled, the helper functions
(__array, etc) of non-root modules (e.g. stdio) should be separated their own obj file.
Comment #13 by bugzilla — 2015-07-31T08:41:16Z
The module info symbol should only be generated by compiling foo2 from the command line. Why is it generated into out.obj?
Comment #14 by k.hara.pg — 2015-07-31T08:58:39Z
(In reply to Walter Bright from comment #13)
> The module info symbol should only be generated by compiling foo2 from the
> command line. Why is it generated into out.obj?
foo2.d is compiled twice. One generated obj is stored into the lib file, one another is stored into out.obj.
This is the issue case from the original case.
all1_order_flipped:
${dmd} -oflibproj6.a -lib -g project2.d foo2.d foo1.d
${dmd} -ofout -g libproj6.a foo2.d main.d
Comment #15 by k.hara.pg — 2015-07-31T11:43:08Z
(In reply to Kenji Hara from comment #12)
> The essential fix I think is: when the lib file is compiled, the helper
> functions
> (__array, etc) of non-root modules (e.g. stdio) should be separated their
> own obj file.
Implemented.
https://github.com/D-Programming-Language/dmd/pull/4851