Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force inclusion of an object file in a static library when linking into executable?

Tags:

I have a C++ project that due to its directory structure is set up as a static library A, which is linked into shared library B, which is linked into executable C. (This is a cross-platform project using CMake, so on Windows we get A.lib, B.dll, and C.exe, and on Linux we get libA.a, libB.so, and C.) Library A has an init function (A_init, defined in A/initA.cpp), that is called from library B's init function (B_init, defined in B/initB.cpp), which is called from C's main. Thus, when linking B, A_init (and all symbols defined in initA.cpp) is linked into B (which is our desired behavior).

The problem comes in that the A library also defines a function (Af, defined in A/Afort.f) that is intended to by dynamically loaded (i.e. LoadLibrary/GetProcAddress on Windows and dlopen/dlsym on Linux). Since there are no references to Af from library B, symbols from A/Afort.o are not included into B. On Windows, we can artifically create a reference by using the pragma:

#pragma comment (linker, "/export:_Af") 

Since this is a pragma, it only works on Windows (using Visual Studio 2008). To get it working on Linux, we've tried adding the following to A/initA.cpp:

extern void Af(void); static void (*Af_fp)(void) = &Af; 

This does not cause the symbol Af to be included in the final link of B. How can we force the symbol Af to be linked into B?

like image 302
Brian Bassett Avatar asked Jun 07 '10 18:06

Brian Bassett


People also ask

How static library is linked?

Static libraries are either merged with other static libraries and object files during building/linking to form a single executable or loaded at run-time into the address space of their corresponding executable at a static memory offset determined at compile-time/link-time.

What command is used to create a static library from object files in C?

Generate the static library using the following command line: “ ar -rc libstatic_library. a *.o ”, where “ar” is short for “archiver”. At this time, copies of the object files are placed in the library.

Can a static library depend on another static library?

Static libraries are just archives of object ( .o ) files, so you can't have embedded dependency information.


2 Answers

It turns out my original attempt was mostly there. The following works:

extern "C" void Af(void); void (*Af_fp)(void) = &Af; 

For those that want a self-contained preprocessor macro to encapsulate this:

#if defined(_WIN32) # if defined(_WIN64) #  define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:" #x)) # else #  define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:_" #x)) # endif #else # define FORCE_UNDEFINED_SYMBOL(x) extern "C" void x(void); void (*__ ## x ## _fp)(void)=&x; #endif 

Which is used thusly:

FORCE_UNDEFINED_SYMBOL(Af) 
like image 134
Brian Bassett Avatar answered Oct 04 '22 21:10

Brian Bassett


MSVC #pragma comment(linker, "/include:__mySymbol")

gcc -u symbol

like image 29
dex black Avatar answered Oct 04 '22 20:10

dex black