Skip to content

modules that can be linked successfully when compiled with optimizations, fail to link with: multiple definition of `__stginit_ZCMain'

When compiling a set of 3 modules (in a certain order), linking of the final executable fails because there are conflicting symbols in some of the .o.

When doing the compilation in the same order, but with optimizations, it succeeds.

The simple test case:

A.hs:

module A where
main :: IO ()
main = putStrLn "A"

B.hs:

module B where
import A()
main :: IO ()
main = putStrLn "B"

C.hs:

import B()
main :: IO ()
main = putStrLn "hi"

When I compile it with in the order specified by the attached ./bug-reproduce.sh and Makefile, the following happens:

./bug-reproduce.sh 
rm -fv a A.o A.hi
removed 'a'
removed 'A.o'
removed 'A.hi'
rm -fv b B.o B.hi
removed 'b'
removed 'B.o'
removed 'B.hi'
rm -fv c C.o C.hi
removed 'c'
removed 'C.o'
removed 'C.hi'
ghc -Wall  A.hs -main-is A.main -o a
[1 of 1] Compiling A                ( A.hs, A.o )
Linking a ...
ghc -Wall  B.hs -main-is B.main -o b
[1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
[2 of 2] Compiling B                ( B.hs, B.o )
Linking b ...
ghc -Wall  C.hs -o c
[2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
[3 of 3] Compiling Main             ( C.hs, C.o )
Linking c ...
removed 'A.o'
ghc -Wall  A.hs -main-is A.main -o a
[1 of 1] Compiling A                ( A.hs, A.o )
Linking a ...
ghc -Wall  B.hs -main-is B.main -o b
[2 of 2] Compiling B                ( B.hs, B.o ) [flags changed]
Linking b ...
./A.o: In function `siv_closure':
(.data+0x0): multiple definition of `__stginit_ZCMain'
B.o:(.data+0x0): first defined here
./A.o: In function `ZCMain_main_srt':
(.data+0x70): multiple definition of `ZCMain_main_closure'
B.o:(.data+0x70): first defined here
./A.o:(.text+0xb8): multiple definition of `ZCMain_main_info'
B.o:(.text+0xb8): first defined here
collect2: error: ld returned 1 exit status
make: *** [B.o] Error 1

But it succeeds if done as ./bug-reproduce.sh GHC_OPTS=-O1 (probably, the optimizations remove the conflicting symbols):

./bug-reproduce.sh GHC_OPTS=-O1
rm -fv a A.o A.hi
removed 'a'
removed 'A.o'
removed 'A.hi'
rm -fv b B.o B.hi
removed 'b'
removed 'B.o'
removed 'B.hi'
rm -fv c C.o C.hi
removed 'c'
removed 'C.o'
removed 'C.hi'
ghc -Wall -O1 A.hs -main-is A.main -o a
[1 of 1] Compiling A                ( A.hs, A.o )
Linking a ...
ghc -Wall -O1 B.hs -main-is B.main -o b
[1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
[2 of 2] Compiling B                ( B.hs, B.o )
Linking b ...
ghc -Wall -O1 C.hs -o c
[2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
[3 of 3] Compiling Main             ( C.hs, C.o )
Linking c ...
removed 'A.o'
ghc -Wall -O1 A.hs -main-is A.main -o a
[1 of 1] Compiling A                ( A.hs, A.o )
Linking a ...
ghc -Wall -O1 B.hs -main-is B.main -o b
[1 of 2] Compiling A                ( A.hs, A.o ) [flags changed]
[2 of 2] Compiling B                ( B.hs, B.o ) [flags changed]
Linking b ...
ghc -Wall -O1 C.hs -o c
[2 of 3] Compiling B                ( B.hs, B.o ) [flags changed]
Linking c ...

Couldn't the compiler detect and handle such cases?

Edited by imz
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information