How to Use GCC to compile dynamic libraries in Linux

Source: Internet
Author: User

1. Why use the library?

2. Database category

3. Create your own database

You may still remember the situation when you are new to Linux. If there is no package manager that can better resolve dependencies, installing software in Linux would be a tough task. When you install Package A, you may be prompted to install package B first. When you try your best to find Package B, you may be prompted to install package C first. I have been overwhelmed by such a problem. So far, I still feel confused and confused when I mention rpm. It is said that the system was bitten by a snake, and it would be hard to fear the ropes for ten years.

 

In Linux, one of the many dependencies is really helpful. This principle is: do not repeat what others have done. In other words, we try to make full use of others' labor results.

This involves how to effectively reuse code.

1. Why use the library?

There are two ways to reuse code.

Copy and paste

This is the least technical solution. If the code is small, the workload is tolerable. If the code is large, this method is not feasible. Even if someone tries to do this, who can ensure that all the code can be obtained?

The emergence of libraries solves this problem very well.

Library is an encapsulation mechanism. In short, all source code is compiled into a package after the target code is compiled.

So how can users know what interfaces this library provides? Is it necessary to use tools such as nm to scan one by one?

Don't worry. The database developers have already done everything well. In addition to the library containing the target code, www.linuxidc.com generally provides a series of header files, which contain the library interface. In order to make it easier for users, it is almost perfect to add a usage instruction.

2. Database category

2.1 database category

According to the link period, the database can be divided into static and dynamic databases.

The static library is linked in the Link phase (it seems like nonsense, but this is the case), so the generated executable file is not affected by the Library, even if the library is deleted, the program can still run successfully.

Unlike static databases, the link of dynamic databases is linked during program execution. Therefore, even if the program is compiled, the library must be kept on the system for calling when the program is running. (Todo: What does the link phase do when a dynamic library is linked)

2.2 comparison between static and dynamic Databases

In a sense, the link to a static library is also a copy and paste operation, but the object it operates on is the target code rather than the source code. Because the static library is directly embedded into the executable file after it is linked, there are two problems.

First, the system space is wasted. This is obvious. Imagine that if multiple programs link to the same database, each generated executable file will have a copy of the database, which will inevitably waste system space.

Furthermore, even a well-tuned library is prone to errors. Once any bugs in the database are found, it is troublesome to save the problem. You must find the program linking the database one by one and then recompile it.

The emergence of dynamic libraries makes up for the above disadvantages of static libraries. Because the dynamic library is linked when the program runs, only one copy must be retained on the disk, thus saving disk space. If you find a bug or want to upgrade it, you just need to replace it with a new library.

So is the static library useless?

Answer: neither is nor. Isn't there a saying: existence is reasonable. Since the static library has not been lost in the history of growth, it must be useful. Imagine the situation: If you have compiled a program using the libpcap library and want to run the program, but the pcap library is not installed on the system, how can this problem be solved? The simplest way is to link all the libraries to be linked to their static libraries when compiling the program, so that the program can be directly run on other systems.

A dynamic library is linked during the running of the program, so the running speed of the program is necessarily lower than that of the version linked to the static library. However, the lack of dynamic libraries is insignificant in today's hardware, so the linked programs generally give priority to the dynamic libraries when linking, unless you use the-static parameter to specify a link to the static library.

2.3 How can I determine whether a program is connected to a dynamic library?

The answer is to use the file utility.

The file program is used to determine the file type. Under the file command, all files are exposed.

By the way, this is a trick. Sometimes when you download the tar.gzor tar.bz2 file from a browser in windows, the suffix will become a strange tar.tar, and some new users will not know how to decompress it in Linux. However, the file type in Linux is not affected by the file suffix. Therefore, you can first run the file xxx.tar.tar command to check the file type and decompress it with tar and appropriate parameters.

 

In addition, you can use the program LDD utility to determine.

LDD is used to print information of all the dynamic libraries linked to the Target Program (specified by the command line parameter). If the target program does not link to the dynamic library, it prints "not a dynamic executable ", for the usage of LDD, See manpage.

3. Create your own database

3.1 create a dynamic library

Create the file hello. C with the following content:

# Include

Void Hello (void)

{

Printf ("Hello World/N ");

}

Use the command gcc-shared hello. C-o libhello. So to compile it into a dynamic library. We can see that the current directory has an additional file libhello. So.

[Leo @ Leo test] $ file libhello. So

Libhello. So: Elf 32-bit LSB shared object, Intel 80386, Version 1 (sysv), not stripped

As you can see, the file type is shared object.

Edit the test. c file as follows:

Int

Main ()

{

Hello ();

Return 0;

}

This can be compiled :)

[Leo @ Leo test] $ GCC test. c

/Tmp/ccm7w6mn. O: In function 'main ':

Test. c :(. Text + 0x1d): Undefined reference to 'Hello'

Collect2: LD returned 1 exit status

GCC cannot find the hello function at the link, and compilation fails :(. The reason is that hello is in the database we created. If GCC can find it, it will teach you to hell! OK.

[Leo @ Leo test] $ GCC test. C-lhello

/Usr/lib/GCC/i686-pc-Linux-gnu/4.0.0/.../i686-pc-Linux-gnu/bin/ld: cannot find-lhello

Collect2: LD returned 1 exit status

[Leo @ Leo test] $ GCC test. C-lhello-L.

[Leo @ Leo test] $

For the first compilation, the GCC will be linked to the Standard C library by default, but the symbolic name Hello cannot be parsed, so the connection phase will fail.

Now GCC test. C-lhello-L. has been compiled successfully. The default output is a. Out. Run the following command:

[Leo @ Leo test] $./A. Out

./A. Out: Error while loading shared libraries: libhello. So: cannot open shared object file: no such file or directory

Why? It turns out that although the dynamic library libhello. So was found in the link when the linker (dynamic linker), but the dynamic loader (Dynamic loader, usually/lib/ld-Linux.so.2) was not found. Let's take a look at LDD output:

[Leo @ Leo test] $ ldd a. Out

Linux-gate.so.1 => (0xffffe000)

Libhello. So => not found

Libc. so.6 =>/lib/libc. so.6 (0x40034000)

/Lib/ld-Linux.so.2 (0x40000000)

Indeed, no, libhello. So => not found.

Linux provides us with two solutions:

1. You can add the current path to/etc/lD. So. conf and run ldconfig, or run ldconfig with the current path as the parameter (root permission is required ).

2. Add the current path to the environment variable LD_LIBRARY_PATH.

 

Of course, if you do not think it will cause any confusion, you can directly import the library libraries to/lib,/usr/lib/, and other locations (it is inevitable that you have the permission to do so ), in this way, the linker and the loader can find the library accurately.

We adopt the second method:

[Leo @ Leo test] $ export LD_LIBRARY_PATH =.: $ LD_LIBRARY_PATH

 

[Leo @ Leo test] $ ldd a. Out

Linux-gate.so.1 => (0xffffe000)

Libhello. So =>./libhello. So (0x4001f000)

Libc. so.6 =>/lib/libc. so.6 (0x40036000)

/Lib/ld-Linux.so.2 (0x40000000)

Haha, now the ld-Linux.so.2 can find the library libhello. So.

Now you can run it directly:

[Leo @ Leo test] $./A. Out

Hello World

 

3.2 Create a static library

Still use the hello. C and test. C just now.

Step 1: generate the target file.

[Leo @ Leo test] $ gcc-C hello. c

[Leo @ Leo test] $ ls hello. O-l

-RW-r -- 1 Leo users 840 May 6 12:48 hello. o

Step 2: archive the target file.

[Leo @ Leo test] $ ar R libhello. A hello. o

AR: Creating libhello.

OK, libhello. A is the static library we have created, simple :)

[Leo @ Leo test] $ file libhello.

Libhello. A: Current ar Archive

The following command is to teach you how to link a static library in a program:

[Leo @ Leo test] $ GCC test. C-lhello-L.-static-O hello. Static

Let's use the file command to compare the differences between programs connected with dynamic and static libraries:

[Leo @ Leo test] $ GCC test. C-lhello-L.-O hello. Dynamic

As mentioned above, the linker links to the dynamic library (here it is libhello. So) by default, so you only need to remove the-static parameter in the previous command.

Use the file utility to verify whether an executable file is generated as required:

[Leo @ Leo test] $ file hello. Static hello. Dynamic

Hello. Static: Elf 32-bit LSB executable, Intel 80386, Version 1 (sysv), for GNU/Linux 2.6.6, statically linked, not stripped

Hello. Dynamic: Elf 32-bit LSB executable, Intel 80386, Version 1 (sysv), for GNU/Linux 2.6.6, dynamically linked (uses SHARED libs), not stripped

By the way, you can use LDD:

[Leo @ Leo test] $ LDD hello. Static hello. Dynamic

Hello. Static:

Not a dynamic executable

Hello. Dynamic:

Linux-gate.so.1 => (0xffffe000)

Libhello. So =>./libhello. So (0x4001f000)

Libc. so.6 =>/lib/libc. so.6 (0x40034000)

/Lib/ld-Linux.so.2 (0x40000000)

OK, it seems there is no problem, then compare the size first:

[Leo @ Leo test] $ LS-l Hello. [DS] *

-Rwxr-XR-x 1 Leo users 5911 12:54 hello. Dynamic

-Rwxr-XR-x 1 Leo users 628182 12:54 hello. Static

Let's see the difference. Comparing the target program that links the static library with the program that links the dynamic library is simply a giant!

It is difficult to see the difference in execution time in such a small program. But for the sake of completeness, let's take a look at the output of time:

[Leo @ Leo test] $ time./Hello. Static

Hello World

Real 0m0. 001 S

User 0m0. 000 s

Sys 0m0. 001 S

[Leo @ Leo test] $ time./Hello. Dynamic

Hello World

Real 0m0. 001 S

User 0m0. 000 s

Sys 0m0. 001 S

If the program is large, the effect will be obvious.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.