LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How To Statically Link to a Library Using g++? (https://www.linuxquestions.org/questions/programming-9/how-to-statically-link-to-a-library-using-g-646060/)

jonwatson 05-31-2008 09:51 AM

How To Statically Link to a Library Using g++?
 
Hi All,

In a nutshell, I am having troubles understanding and implementing static linking using g++. I haven't done anything with C++ since 1999 and my knowledge ranges from rusty to never-even-knew-that and am hoping someone with more experience can fill in some blanks for me.

I am writing an application that makes use of NetSeiben C++ SSH library (1). It requires the botan library to handle the cryptographic stuff (2) and I am having troubles linking to it. I'm also having conceptual problems understanding why I have to compile using the command that I do.

Problem number one is the command I seem to have to use in order to compile my application at all with the ne7ssh libraries. It only produces a working executable of I compile using this command:

Code:

g++ foo.cpp -ofoo src/crypt.cpp src/ne7ssh_channel.cpp src/ne7ssh_connection.cpp src/ne7ssh_error.cpp src/ne7ssh_kex.cpp src/ne7ssh_keys.cpp src/ne7ssh_mutex.cpp src/ne7ssh.cpp src/ne7ssh_session.cpp src/ne7ssh_string.cpp src/ne7ssh_transport.cpp src/ne7ssh_sftp.cpp src/ne7ssh_sftp_packet.cpp -lbotan
While this isn't a huge problem, really, it looks and feels so clunky that I am afraid I am doing something wrong that will later bite me in the butt. Is there a better practice to achieve the same result?

Problem number two is that all of the standard libs and botan, are being dynamically linked to my app and for reasons which are outside of the scope of this email, we require static linking:

Code:

ldd foo
        linux-vdso.so.1 =>  (0x00007ffff37fe000)
        libbotan-1.6.3.so => /usr/lib/libbotan-1.6.3.so (0x00007f58eafdc000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f58eacd1000)
        libm.so.6 => /lib/libm.so.6 (0x00007f58eaa50000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f58ea842000)
        libc.so.6 => /lib/libc.so.6 (0x00007f58ea4e0000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007f58ea2c4000)
        libbz2.so.1.0 => /lib/libbz2.so.1.0 (0x00007f58ea0b4000)
        libcrypto.so.0.9.8 => /usr/lib/libcrypto.so.0.9.8 (0x00007f58e9d34000)
        libgmp.so.3 => /usr/lib/libgmp.so.3 (0x00007f58e9af5000)
        librt.so.1 => /lib/librt.so.1 (0x00007f58e98ec000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007f58e96d5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f58eb442000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f58e94d1000)

The problem is that I cannot figure out how to statically link the botan library. I have done considerable Googling and it seems that the solution is to generate an archive .a file using the ar application and include all of the botan object files in the archive. I found a botan.a file in my /usr/lib directory an attempted to recompile using the -static switch and appending /usr/lib/libbotan.a to the end of the compile command, but g++ throws a bunch of undefined references to the botan library which seems to indicate it is not being included properly. An 'ar -t libbotan.a' shows a long list of .o files contained in the archive which is what I expect.

So I guess my question is that assuming this .a file is what I need in order to statically link the botan library to my application, what do I do with it? I can't seem to find the proper way to include it in the compile command so I'm left not sure if I need to include it in one of the other cpp files or something else. This is the part of my knowledge that is deep into never-even-knew-that territory.

Can someone point me in the right direction? Links, advice, tips all appreciated.

Thanks,

Jon

1. http://netsieben.com/products/ssh/
2. http://botan.randombit.net/

pinniped 05-31-2008 07:21 PM

It is not at all unusual for a compiler line to get incredibly long (especially when building anything complex). Usually various build tools are used instead and they hide some of the complexity.

To statically link to libraries, add the '-static' argument before the list of c/o/libs.
To statically link to libc, add '-static-libgcc'

jonwatson 06-01-2008 03:08 PM

Hi,

I've tried the -static and -Bstatic switches and they just cause the compiler to puke on the Botan stuff so it's evidently not getting linked in. I have something to try from someone else and when I do I'll add it to this post, whether successful or not.

Many people have told me that a long compiler invocation is normal. I never really linked to any libraries before or used anyone else's code so I didn't have the experience to know that.

Thanks!

Jon

bjdodo 07-22-2008 03:50 AM

Hello

I have a similar problem, I hope you do not mind if I join this thread.

I have three libraries that I would like to link statically, all the rest I would like to link dynamically.
When I build the three libraries, all of them have the following files:

They have a libxxx.la file, and in a subdirectory called .libs they have the .so and the .a files.

If I am not mistaken, the .so file is there for dynamic linking, and the .a file for static linking.

>> Q1: Could someone please tell me the purpose of the .la file?

If I specify this for the linker:

/path/to/la/file/libxxx.la, it will link dynamically with the .so file.

Now I have been able to achieve static linking for 2 of the libraries by using this line:

/path/to/la/file/.libs/libxxx.a

>> Q2: Is this the usual way to link statically?

>> Q3: I have read that there is a -static switch. Could that be used for each of the 3 libraries so that
the rest is still dynamically linked? If yes, could someone please give an example about it? Where shall
I put the -static switch? If I use the -static switch, shall I specify the .la file, or still the .a file
for the linker?

>> Q4: I have read that if I link all the dependent libraries statically then the resulting executable
would run on any other linux machine. Is that so? Would not even the kernel version matter?

>> Q5: My guess is that if I link against a library statically then I have to link all of its dependencies
statically. Is that so?

Thank you very much for all answers!!!

Jozsi

bjdodo 07-23-2008 07:37 AM

Hi

OK, so this it so far what I've figured out:

>> Q1:

The la file is generated by automake, it is a simple text file. It contains info about how to link the files in the .libs directory. E.g. it might contain additional libraries that have to be found and linked, otherwise not all symbols will be defined.

>> Q5:

Now I believe that this is not true. E.g. skype links QT4 statically, but the rest dynamically. I bet QT4 depends on lots of libraries that it does not link statically. I do not understand how that could be possible.

If you can give any hints about the listed questions, I'd be happy to hear about them :-)

Thanks,
Jozsi


All times are GMT -5. The time now is 01:36 AM.