Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined linker symbol at runtime when the symbol equals zero

I am trying to use linker symbols to automatically set a version number in my executables, and it seems to work as long as the symbols aren't set to zero...

In my C code:

extern char __VERSION_MAJ;
extern char __VERSION_MIN;

...

printf("Version %u.%u\n", (unsigned) &__VERSION_MAJ, (unsigned) &__VERSION_MIN);

And in my makefile:

LDFLAGS += -Xlinker --defsym=__VERSION_MAJ=1
LDFLAGS += -Xlinker --defsym=__VERSION_MIN=0

Results in the following output when I try to run the executable test:

./test: symbol lookup error: ./test: undefined symbol: __VERSION_MIN

If I change the symbol definition as follows:

LDFLAGS += -Xlinker --defsym=__VERSION_MAJ=1
LDFLAGS += -Xlinker --defsym=__VERSION_MIN=1

Then it works just fine:

Version 1.1

I've read about linker symbols here http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/Linker.pdf and trawled google but haven't spotted anything that says 0 is a disallowed value for custom linker symbols.

Also, if I look at the linker map output it does have __VERSION_MIN:

0x0000000000000001                __VERSION_MAJ = 0x1
0x0000000000000000                __VERSION_MIN = 0x0

So, I'm quite stumped!

I would just use gcc -D__VERSION_MIN=0 instead, but that leads to trickiness and makefile ugliness with using prerequisites to rebuild the application when the version changes (it will be stored in a text file, not hard-coded in the makefile as above.)

I'm compiling and linking with gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) for target i686-linux-gnu, if any of that makes a difference.

Executive summary:

  • Should a --defsym expression that results in 0 be allowed?
  • What am I doing wrong?
  • Is there a better/simpler way to achieve this?
like image 398
Kisama Avatar asked Nov 12 '22 17:11

Kisama


1 Answers

If you want to use

gcc -D__VERSION_MIN=0

then you have to remove the definition from your header file

extern char __VERSION_MIN;

The

gcc -D__VERSION_MIN=0

is equivalent to define __VERSION_MIN as a macro in your c code

#define __VERSION_MIN 0

And then you can not define __VERSION_MIN twice in your C code

extern char __VERSION_MIN;
#define __VERSION_MIN 0

This is not allowed

So If you want to use

gcc -D__VERSION_MIN=0

then you have to remove extern char __VERSION_MIN; from your code

like image 145
MOHAMED Avatar answered Nov 15 '22 06:11

MOHAMED