5

I'm trying to link some parts of a static library into a program written in C++ using g++ under Linux.

my_lib.h

#ifdef USE_EXTERN_LIB
# include <extern_lib.h>
void do_something (struct extern_lib);
#endif

void do_other (int);

my_lib.c

#include "my_lib.h"

#ifdef USE_EXTERN_LIB
void do_something (struct extern_lib l)
{
  // do something
}
#endif

void do_other (int a)
{
  // do something
}

I'm statically creating libmy_lib.a with -DUSE_EXTERN_LIB preprocessor flag to include all into it.

but what I want to do is to create two programs: one that uses this library with *extern_lib* and one that use it without *extern_lib*, i.e.:

g++ -L/path/to/lib -lmy_lib -o prog_wihtout_lib prog_without_lib.cc 
g++ -DUSE_EXTERN_LIB -L/path/to/lib -lmy_lib -o prog_with_lib prog_with_lib.cc

The second program compiles but not the first, it says that extern_lib is undeclared.

With a dynamic library, there is no problem because symbols are loaded at runtime but I want a static library. Is there a way to link only desired modules of a static lib?

EDIT

prog_without_lib.cc

#include "my_lib.h"

int main ()
{
  do_other (42);

  return 0;
}

prog_with_lib.cc

#include "my_lib.h"

int main ()
{
  do_other (42);

  struct extern_lib l;
  do_something (l);

  return 0;
}

Thanks.

marmottus
  • 351
  • 1
  • 3
  • 18

2 Answers2

5

Just link in the library, and let the linker worry about removing unused code. That's its job.

What you're trying to do makes no sense (and no, it would make no sense in a dynamic library either.) Defines only have an effect when you compile the library, and you do that on the first line. On the second line, you merely link the already-compiled library into your executable. But really, the entire point in static libraries is that they're visible to the linker, so it can (among other things) strip out any unused code. So why do you need the USE_EXTERN_LIB define at all?

jalf
  • 243,077
  • 51
  • 345
  • 550
0

You have to add the external library to the command line when you build in the second command line:

g++ -DUSE_EXTERN_LIB -I/path/to/external_lib/headers -o prog_wih_lib prog_with_lib.cc -L/path/to/external_lib/libfile -lexternal_lib -lmy_lib

Also note that I put the libraries at the end of the command line. It might not be necessary anymore, but it used to be the linker scanned the input files in the order they were given on the command line, so if a library was on the command line before the object-file using it, the linker exited with an error saying symbols couldn't be found.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621