0

I have developed a set of libraries/common classes that I use in all my apps (this is on unix), and compiled them into a shared object (.so). Then, when I compile my individual apps, I link the library with the executable with -L /libs/ -l mylib . When running any app, I then make sure that the /libs directory is in my LD_LIBRARY_PATH

This works perfectly fine in most cases. The problem I'm facing is that I change these libraries often, and therefore for my existing applications stop working if they are not recompiled/re-linked against the new .so file.

Here's my question: (finally)
Is there a way that I can link in my library code (via compiler flags, etc.) such that the executable is 'stand-alone' meaning that all of the required code is there? This way, the apps can use the code that it was compiled with, without regard to if and when I change the library. I don't care if the executable size grows or anything like that - I've got the disk space.

3
Contributors
15
Replies
16
Views
11 Years
Discussion Span
Last Post by winbatch
0

Yes. - it's called a static link. It means that all of the runtime you need is part of the image file - obviously a much bigger image file.

I can't tell which version of unix you have, but your man ld page will tell you how to do that. In most flavors of Unix you provide the cc command with a list of static libraries ".a" files including libc.a. You will also have to put your own runtime into one of these archives as well - or link against the objects in it. Again, the ld manpage is your friend.

0

I'm using Solaris and I'm using the forte compiler (ie CC ). I'm now trying to use the 'ar' command...

Also note that my library contains a lot of template code. Is this going to work if statically linked?

0

You're on the right track. I don't use Solaris, but I do know it has some (what I think are) funny conventions.

Now that I know it's Solaris, you can use versioning of your .so files, as long as you keep all the old ones out there. You can park all you stuff in a special area that won't get clobbered in an update, then define LD_LIBRARY_PATH (or SHRLIB_PATH) so that dld can open the libraries -if you plan to move them around later. Link specifically against a version like "-l mylib.3.2"

0

The versioning idea is a possibility, I was just hoping I could keep an executable stand-alone (this way I could move it to another solaris machine without having to copy over the library, etc.)

0

The "moving over" part is the reason for which static linking exists.

Your problem could be looked at another way: as an implementation/deployment issue.
Matching up correct code with correct run-times. If you are working for a company ask them to look at TeamTrack and ChangeMan from Serena. You can also package everything as one tarball and use cvs or whatever to manage your tarballs.

0

Yes, this is why I want to link statically. My problem now however seems to be that my template code cannot be linked statically. Is that a known issue? Does template code need to be linked dynamically? (Given that it determines the classes/types at runtime, it seems somewhat logical).. If that's the case, I may be stuck.

0

No, no, not flags...

I'm assuming you're using C++ code - look for something like "libc++.a" and link against that. I don't know the name for the library file in Solaris.

0

No, no, not flags...

I'm assuming you're using C++ code - look for something like "libc++.a" and link against that. I don't know the name for the library file in Solaris.

Not sure what you're talking about... To refocus ourselves, what I'm trying to do is take a shared object that I wrote and have it be included as part of an executable itself so I can provide the executable without the library. Note sure where libc++ came into play...

0

My bad.

Just to clarify:
1. You can link an entire module statically.
2. You can link just one or two libraries statically, and link the rest of the image dynamically:

cc myfile.c /path/to/mylib.a /path/to/anotherlib.a -o myfile
0

My bad.

Just to clarify:
1. You can link an entire module statically.
2. You can link just one or two libraries statically, and link the rest of the image dynamically:

cc myfile.c /path/to/mylib.a /path/to/anotherlib.a -o myfile

Jim,

That's what I tried, but it doesn't like any of my classes that use templates. I don't have this trouble with the .so

0

Compile library:
CC -c -I./ -I./unix -g -D_DEBUG -D__SUNOS__ -D__UNIX__ -c *.cpp
BaseClass.cpp:
CommandLine.cpp:
DHException.cpp:
DHLogException.cpp:
DataBase.cpp:
Date.cpp:
FileUtilities.cpp:
General.cpp:
Globals.cpp:
Identifiable.cpp:
Log.cpp:
MainProgram.cpp:
MultiLog.cpp:
Printable.cpp:
StringUtils.cpp:

Link library:
CC -G -lsocket -lnsl -ldl *.o -o libhoff.so


Compile app:
CC -w -c -I./ -I../libs -D__SUNOS__ -c *.cpp

Link app:
CC -Bdynamic -lhoff *.o -o MyApp

---------------------------------------
Failed attempt with static:
CC -c -I./ -I./unix -g -D_DEBUG -D__SUNOS__ -D__UNIX__ -c *.cpp
BaseClass.cpp:
CommandLine.cpp:
DHException.cpp:
DHLogException.cpp:
DataBase.cpp:
Date.cpp:
FileUtilities.cpp:
General.cpp:
Globals.cpp:
Identifiable.cpp:
Log.cpp:
MainProgram.cpp:
MultiLog.cpp:
Printable.cpp:
StringUtils.cpp:

Link library:
/usr/ccs/bin/ar rc libhoffstatic.a *.o

Compile and Link app (and link errors)
CC -w -c -I./ -I../libs -I../libs/unix -D__SUNOS__ -c *.cpp
CC *.o ../libs/libhoffstatic.a -o Hoff
Undefined first referenced
symbol in file
long Properties<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >::getPropertyL(const std::basic_string<char,std::char_traits<char>,std::allocator<char> >&,const long) ../libs/libhoffstatic.a(CommandLine.o)
bool Properties<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >::getPropertyBool(const std::basic_string<char,std::char_traits<char>,std::allocator<char> >&) ../libs/libhoffstatic.a(CommandLine.o)
int Properties<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >::getPropertyI(const std::basic_string<char,std::char_traits<char>,std::allocator<char> >&) ../libs/libhoffstatic.a(CommandLine.o)
__rwstd::__rb_tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,__rwstd::__select1st<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg> > >::iterator __rwstd::__rb_tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,__rwstd::__select1st<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg> > >::erase(__rwstd::__rb_tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,__rwstd::__select1st<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg> > >::iterator,__rwstd::__rb_tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,__rwstd::__select1st<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg> > >::iterator) ../libs/libhoffstatic.a(CommandLine.o)
void Properties<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CommandLineArg>::add(const std::basic_string<char,std::char_traits<char>,std::allocator<char> >&,const CommandLineArg&,bool) ../libs/libhoffstatic.a(CommandLine.o)
std::list<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::iterator std::list<std::basic_string<char,std::char_traits<char>,std::allocator<char> ...


..etc...

0

I got it! I needed to compile the library like this.
CC -xar *.o -o libhoffstatic.a
where ( -xar is: )
-xar Create archive library with instantiated templates

and then compile the app:
CC -w -c -I./ -I../libs -I../libs/unix -D__SUNOS__ -c *.cpp
CC *.o ../libs/libhoffstatic.a -o Hoff

That worked - I was able to move the app 'Hoff' to another machine without the library.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.