0

My host computer is a x86 PC running Ubuntu 18 and have arm-linux-gnueabi-g++ and arm-linux-gnueabi-gcc suit installed. I had intended to cross-compiling and running a C++ project on my ARM (armv7l, Cortex-A17) device.

For ease of description of my problem, a testing project has been set with following three source files:

//global.hpp
class Global { public: Global();};
extern Global global;

//global.cpp
#include "global.hpp"
#include <iostream>
Global global;
Global::Global(){std::cout << "Global" << std::endl;}

//main.cpp
#include <iostream>
int main(int nArgCnt, char *ppArgs[]) {
  std::cout << "main" << std::endl;
  return 0;
}

And the build script "build.sh" is:

#!/bin/bash
arm-linux-gnueabi-g++ -c global.cpp -o global.o
arm-linux-gnueabi-ar qc libglobal.a global.o
arm-linux-gnueabi-g++ -static main.cpp libglobal.a -o main

After built done I push the executable "main" to device, running it got following result:

main

It seems that the constructor of Global not be called.

I have tried to directly link global.o into main, modified the build.sh to:

#!/bin/bash
arm-linux-gnueabi-g++ -c global.cpp -o global.o
arm-linux-gnueabi-g++ -static main.cpp global.o -o main

Then I got expected result:

Global
main

But this is just a tesing project, actually I have a more bigger project that have many sources and must be built with static linkage. How to make the constructor Global::Global() be called properly from libglobal.a ? Thank you for your help!

If I did the build with g++ and ar, the result is not expected also:

#!/bin/bash
g++ -c global.cpp -o global.o
ar qc libglobal.a global.o
g++ -static main.cpp libglobal.a -o main
./main

got

main

Finally, the question Why doesn't attribute((constructor)) work in a static library and it's solution did works.

Devymex
  • 446
  • 3
  • 17
  • Probably another better duplicate on static linkage, but it's good enough. – Matthieu Brucher Feb 01 '19 at 10:29
  • @Botje Thanks, but I think it is different between my problem with that question. – Devymex Feb 01 '19 at 10:39
  • I repeated your exact commands with g++ 7.3.0 and only "main" was printed. – Botje Feb 01 '19 at 10:44
  • Adding a `void unused() { new Global(); } ` without actually calling it is enough to pull in the Global symbol for me and have it show up. Probably the `--whole-archive` flag suggested in the linked post also works. – Botje Feb 01 '19 at 10:49
  • @Botje Thank you, I found the problem is exactly what you mentioned. I got the incorrect result from g++ because the old libglobal.a not been removed and ar just append something to it instead of completly recreate the libglobal.ar. Many thanks. – Devymex Feb 01 '19 at 11:05

0 Answers0