Discussion:
[Chicken-users] Duplicate symbol errors with functors and -static flag
Antoine Luciani
2018-11-20 23:03:58 UTC
Permalink
Hello,

I came across weird duplicate symbol errors while using functors and the
-static flag in CHICKEN 5.

You can find the full repro here in case my explanation is not clear:
https://github.com/antoine1fr/chicken-functor-static-error.

Given:

* a unit 'a',
* a unit 'make-b' that defines a functor 'make-b' and uses 'a',
* a unit 'b-foo' that creates the module 'b-foo' from 'make-b'.

The following link command:

$ csc -v -static -o test ./a.o ./make-b.o ./b-foo.o ./test.o

generates the following call to the C compiler:

'clang' 'test.o' 'b-foo.o' 'make-b.o' 'a.o' 'a.o' -o 'test' -m64 -L/usr/local/Cellar/chicken/5.0.0/lib /usr/local/Cellar/chicken/5.0.0/lib/libchicken.a -lm

The problem is that 'a.o' is issued twice to clang. This results in
duplicate symbol errors.

Here are the full build logs:

$ make
csc -J -static -o a.o -c a.scm
csc -J -static -o make-b.o -c make-b.scm
csc -J -static -o b-foo.o -c b-foo.scm
csc -J -static -o test.o -c test.scm
csc -v -static -o test ./a.o ./make-b.o ./b-foo.o ./test.o
'clang' 'test.o' 'b-foo.o' 'make-b.o' 'a.o' 'a.o' -o 'test' -m64 -L/usr/local/Cellar/chicken/5.0.0/lib /usr/local/Cellar/chicken/5.0.0/lib/libchicken.a -lm
duplicate symbol _C_a_toplevel in:
a.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Error: shell command terminated with non-zero exit status 256: 'clang' 'test.o' 'b-foo.o' 'make-b.o' 'a.o' 'a.o' -o 'test' -m64 -L/usr/local/Cellar/chicken/5.0.0/lib /usr/local/Cellar/chicken/5.0.0/lib/libchicken.a -lm
make: *** [test] Error 1

Can someone tell me what I'm doing wrong?

Best,
Antoine
Evan Hanson
2018-11-20 23:59:38 UTC
Permalink
Hi Antoine,

The issue here is the "./" prefix on $(SCHEME_OBJECTS). Your project
works fine with just the following change:

3c3
< SOURCE_PREFIX = ./
---
SOURCE_PREFIX =
CHICKEN uses a naive string comparison to deduplicate object files, so "./a.o"
and "a.o" are considered to be distinct. The first of these files you provide
explicitly in the Make rule for "test" (which is fine), while the second of
them comes from CHICKEN's dependency resolution (as a prerequisite of the
functor instantiation, b-foo). Because the two differ as strings, they are not
deduplicated, both are passed to clang, and you get a linking error.

We may want to improve on this in the future by normalising filenames or
comparing them as paths, but for right now that is the cause and what you can
do to solve it.

All the best,

Evan

P.S. Thank you for the very high-quality reproduction.
Antoine Luciani
2018-11-21 02:04:22 UTC
Permalink
Post by Evan Hanson
Hi Antoine,
The issue here is the "./" prefix on $(SCHEME_OBJECTS). Your project
3c3
< SOURCE_PREFIX = ./
---
SOURCE_PREFIX =
CHICKEN uses a naive string comparison to deduplicate object files, so "./a.o"
and "a.o" are considered to be distinct. The first of these files you provide
explicitly in the Make rule for "test" (which is fine), while the second of
them comes from CHICKEN's dependency resolution (as a prerequisite of the
functor instantiation, b-foo). Because the two differ as strings, they are not
deduplicated, both are passed to clang, and you get a linking error.
We may want to improve on this in the future by normalising filenames or
comparing them as paths, but for right now that is the cause and what you can
do to solve it.
All the best,
Evan
P.S. Thank you for the very high-quality reproduction.
Thanks for the fast and exhaustive answer. Your fix works for me. I can
easily rearrange my workflow and stop relying on this SOURCE_PREFIX
variable.

Best,
Antoine

Loading...