views:

79

answers:

3

Hi, I have the problem mentioned. I create an object inside a static lib, it is there when I run nm on the static lib, but when i link the lib to a binary and run nm it has disappeared. I know this problem has been asked before, but I could not find any answers. It is important for me to be able to retain that variable in the binary because we are trying to implement version checks for static libs in a binary. Please help. Thank you. Example code follows:

test.h

#ifndef TEST_H
#define TEST_H

class Test
{   
    public:
        Test();
};

extern Test* gpTest;

#endif

test.cpp

#include "test.h"

Test::Test()
{
    gpTest = this;
}   

Test test;

main.cpp

#include "test.h"
#include <iostream>

using namespace std;

Test* gpTest = NULL;

int main()
{
    return 0;
}

BUILD

g++ -c test.cpp -o test.o
ar cr test.a test.o
g++ main.cpp -o app -L/home/duminda/intest/test.a

nm -C test.a

0000000000000054 t global constructors keyed to _ZN4TestC2Ev
000000000000002b t __static_initialization_and_destruction_0(int, int)
0000000000000016 T Test::Test()
0000000000000000 T Test::Test()
                 U __gxx_personality_v0
                 U gpTest
0000000000000000 B test

nm -C app

0000000000600e10 d _DYNAMIC
0000000000600fe8 d _GLOBAL_OFFSET_TABLE_
0000000000400754 t global constructors keyed to gpTest
0000000000400858 R _IO_stdin_used
                 w _Jv_RegisterClasses
0000000000400717 t __static_initialization_and_destruction_0(int, int)
                 U std::ios_base::Init::Init()@@GLIBCXX_3.4
                 U std::ios_base::Init::~Init()@@GLIBCXX_3.4
0000000000601050 b std::__ioinit
0000000000600df0 d __CTOR_END__
0000000000600de0 d __CTOR_LIST__
0000000000600e00 D __DTOR_END__
0000000000600df8 d __DTOR_LIST__
0000000000400968 r __FRAME_END__
0000000000600e08 d __JCR_END__
0000000000600e08 d __JCR_LIST__
0000000000601038 A __bss_start
                 U __cxa_atexit@@GLIBC_2.2.5
0000000000601028 D __data_start
0000000000400810 t __do_global_ctors_aux
0000000000400670 t __do_global_dtors_aux
0000000000601030 D __dso_handle
                 w __gmon_start__
                 U __gxx_personality_v0@@CXXABI_1.3
0000000000600ddc d __init_array_end
0000000000600ddc d __init_array_start
0000000000400770 T __libc_csu_fini
0000000000400780 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000601038 A _edata
0000000000601058 A _end
0000000000400848 T _fini
00000000004005a0 T _init
0000000000400620 T _start
000000000040064c t call_gmon_start
0000000000601038 b completed.6096
0000000000601028 W data_start
0000000000601040 b dtor_idx.6098
00000000004006e0 t frame_dummy
0000000000601048 B gpTest
000000000040070c T main
+1  A: 

optimizing compiler/linker - you are not using gpTest in main() so it is not added to the code. If you place a reference/use inside the main() function it will reappear.

slashmais
Actually, it is the linker that throws it away. I want to stop that without referring to the variable in app because it is ugly to do that for the ~10 libs we have in every binary. I can actually use a dedicated file to do that, but would really like to get another solution.
nakiya
slashmais
+2  A: 

If nothing in the program references an object-file from a library, then there is no reason for the linker to include that object-file in the executable. A linker is designed to pick only those parts from a library that are needed to resolve open dependencies.

When using static linking, the only options are:

  1. Don't use libraries, but pass all the relevant object files explicitly to the linker
  2. Make sure at least one of the object files from the application depends on the relevant object-file from the library.

Perhaps dynamic linking can be of assistance here, but I don't know for sure.

Bart van Ingen Schenau
We need this for versioning in static libs. :(
nakiya
No you don't. I mean, Other people version their static libs and clearly they don't rely on this functionality - possibly - just possibly - because its hard to manage.
Chris Becke
A: 

I found what I was looking for :D. It seems that linker flag --whole-archive is there to make sure all symbols in static lib regardless of whether they are accessed by app or not get into app. Though I still have trouble getting this to work, I guess I am on the right path.

nakiya