3

How can I tell the linker of g++ to allow multiple definitions of symbols (choose the first appearance)?

-z multidefs Allows multiple symbol definitions. By default, multiple symbol definitions occurring between relocatable objects (.o files) will result in a fatal error condition. This option suppresses the error condition and allows the first symbol definition to be taken. This option is valid only when the -b svr4 option is specified.

The -zmuldefs option is not recognized by g++, nor -z OPTION. What's the correct parameter? Is it possible?

quimnuss
  • 1,503
  • 2
  • 17
  • 37
  • you should nail the issue in the code first, why do you have multiple definitions? – billz Jul 03 '13 at 09:11
  • @billz Both ITK and opencv define encode and decode functions of jasper. This does not cause any trouble on Linux nor Windows, only Mac (gcc47 from MacPorts). The code is not the problem. I've solved it by compiling opencv without Jasper, but I still want to be able to overcome this issue by allowing multiple definitions which are the same. – quimnuss Jul 03 '13 at 09:13
  • I believe I was using the -Xlinker option wrong, I have to use it for every parameter, I'll get back to it in an hour. – quimnuss Jul 03 '13 at 09:15
  • Do you have multiple definitions in one compilation unit, or in few? I was unable to compile with "-z muldefs" when I put multiple definitions in one file, but when I put them in two, compiled with g++ -c, and then linked with g++ -z muldefs, I only got warning "/usr/bin/ld: Warning: size of symbol `add(int, int)' changed from 18 in test.o to 20 in test2.o" – Alex1985 Jul 03 '13 at 09:18
  • @Alex1985 In few. However, the option is not recognized at all, so I believe I'm inputing it wrong. – quimnuss Jul 03 '13 at 10:15
  • Mmh, I've realized that `ld -z` does also spit out ùnrecognized option`, which made me discover that Mac does not use gnu ld. – quimnuss Jul 03 '13 at 10:35

2 Answers2

6

There is no such thing as the "linker of g++", it uses your system's own linker.

To pass options through from GCC to the linker you need to use GCC's -Wl, or -Xlinker options:

-Xlinker option
Pass option as an option to the linker. You can use this to supply system-specific linker options which GCC does not know how to recognize.
If you want to pass an option that takes a separate argument, you must use -Xlinker twice, once for the option and once for the argument. For example, to pass -assert definitions, you must write -Xlinker -assert -Xlinker definitions. It does not work to write -Xlinker "-assert definitions", because this passes the entire string as a single argument, which is not what the linker expects.
When using the GNU linker, it is usually more convenient to pass arguments to linker options using the option=value syntax than as separate arguments. For example, you can specify -Xlinker -Map=output.map rather than -Xlinker -Map -Xlinker output.map. Other linkers may not support this syntax for command-line options.

-Wl,option
Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. You can use this syntax to pass an argument to the option. For example, -Wl,-Map,output.map passes -Map output.map to the linker. When using the GNU linker, you can also get the same effect with -Wl,-Map=output.map.

So you would want to use

-Xlinker -z -Xlinker multidefs

or

-Wl,-z,multidefs

but the docs you quoted say you must also use -b svr4 to use that option, e.g.

-Wl,-b,svr4,-z,multidefs

Edit: From your comments I see you're on Mac OS X, which uses the darwin linker, and its man page shows the corresponding option is obsolete:

-m Don't treat multiple definitions as an error. This is no longer supported. This option is obsolete.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • THank you @Jonathan It looks like the XCode system's `ld` is not the GNU linker, since it does not recognize those options. In fact `-b` is deprecated. So, how can I tell the linker to ignore multiple definitions? – quimnuss Jul 03 '13 at 10:48
  • Oh, and somebody knows what linker is Mac's XCode using? – quimnuss Jul 03 '13 at 10:49
  • It uses the darwin linker, see http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/ld.1.html, which says "-m Don't treat multiple definitions as an error. This is no longer supported. This option is obsolete." – Jonathan Wakely Jul 03 '13 at 10:50
  • Thanks, so it's not possible to do what I intended, since apparently gnu ld is not supported either. – quimnuss Jul 03 '13 at 12:37
  • If you post the previous comment as an answer and rephrase it a little bit I'll mark it as an answer, although the question has become ambiguous indeed. – quimnuss Jul 03 '13 at 12:39
4

GCC uses ld as linker in linux, which is part of binutils created by GNU.

It seems the newer version of ld do not support -z muldefs option. You can try to use --allow-multiple-definition as an alternative.

hidefromkgb
  • 5,834
  • 1
  • 13
  • 44
CatDog
  • 415
  • 6
  • 12
  • 1
    As Jonathan Wakely said, there is no "GCC Linker", it uses `ld` of `GNU binutils` as the linker. The newest `GNU binutil` is version 2.28, which seems do not support `-z muldef` option. You can use `--allow-multiple-definitions` as a replacement. – CatDog Aug 30 '17 at 12:46
  • 1
    it is actually --allow-multiple-definition, without an 's' – philipp Dec 01 '17 at 18:10
  • @philipp Corrected. – hidefromkgb Sep 19 '18 at 11:44