Library in Linux ****

Source: Internet
Author: User
Tags gtk
When programming on Linux, some non-standard libraries (that is, libraries installed on your own) are often used. These non-standard libraries may have different installation locations, this brings us trouble in programming.
This article aims to solve this problem for cainiao like me. The level is limited, and the writing will inevitably be incorrect. I hope the prawns will not be enlightened.

When programming on Linux, some non-standard libraries (that is, libraries installed on your own) are often used. These non-standard libraries may have different installation locations, this brings us trouble in programming.
This article aims to solve this problem for cainiao like me. The level is limited, and the writing will inevitably be incorrect. I hope the prawns will not be enlightened.

1. Header file location
By default, GCC searches for the header file under the/usr/include directory, which is the path of the header file of the standard library. However, non-standard libraries generally do not directly store the header file under this directory, the general practice is to create a directory of your own under this directory, and then directly or in different categories under this directory (that is, to create a deeper directory, GTK + is an example) put your own header file. In this case, these header files are not found during GCC compilation. We will see the error message "×××: no such file or directory. The solution is to use the-I option of GCC to list these non-standard paths (in actual programming, PKG-config -- cflags is generally used to complete this job ).
2. Database location
By default, GCC will link to the Standard C language library. However, if the library used is a "product", GCC will not automatically link it. If there is no explicit link, during the link stage, ": Undefined reference to 'gtk _ container_set_border_width 'appears'
/Tmp/ccvhaxux. O (. Text + 0x1af): In function 'main': "error. The solution is to use the-l parameter of GCC to display the library to be linked. In this way, GCC searches for the default directories (/usr/lib and/lib Directories) based on a specific naming rule and automatically links them. However, if the library is placed in a defined directory, GCC still cannot find it. In this case, you can use gcc-L to list the paths of non-standard libraries. In actual programming, this task is completed by PKG-config -- libs.
The above two times mentioned the PKG-config command, you may have a question: do you know eight hundred years before PKG-config and eight hundred years later? In fact, PKG-config also has its own set of rules to provide information about the database to be queried.
When you want to query the information of a specified library (such as the GTK +-2.0 library, run the PKG-config command with the GTK +-2.0 parameter (for example, PKG-config -- Libs -- cflags GTK +-2.0 ). In this case, PKG-config will go to the default directory (such as the/usr/lib/pkgconfig directory) and the directory specified by pkg_config_path to find a configuration file, this file records the information of the queried database on the system. The naming rule for this configuration file is: the name of the database to be queried plus the suffix. PC. To query GTK +-2.0 information, PKG-config searches for GTK +-2.0.pc according to the above description. If it is found, everything is fine. The information of the explicit library is directly based on the content of the found file. If the configuration file with the. PC suffix is not found, an error message is displayed, prompting you to continue searching. For example:
[Leo @ Leo ~] $ PKG-config -- Libs -- cflags gtkmm-2.0
Package gtkmm-2.0 was not found in the PKG-config search path.
Perhaps you shoshould Add the directory containing 'gtkmm-2.0.pc'
To the pkg_config_path environment variable
No package 'gtkmm-2.0 'Found
There are two possibilities: one is that the gtkmm-2.0.pc is not placed under/usr/lib/PKG-config. Second, gtkmm-2.0 is not installed.
Corresponding solution: In the first case, directly use the find, locate and other commands to find the gtkmm-2.0.pc, add the path to the environment variable pkg_config_path, and then run the command PKG-config -- Libs -- cflags gtkmm-2.0. In the second case, you can only install the gtkmm-2.0 library. PKG-config searches for the. PC file in/usr/lib/pkgconfig by default. If no, an error is returned. If. in other PC directories, use: Export pkg_config_path =/XXX/pkgconfig/: $ pkg_config_path (for example, some. PC files are usually stored in/usr/local/lib/pkgconfig ). In fact, the usage of PKG-config is similar to that of my familiar SDL-config paragui-config. SDL-config paragui-Config Only obtains some information about SDL and paragui. PKG-config can get some information about other packages. PKG-config -- cflags -- libs paragui is consistent with paragui-config -- cflags -- libs. PKG-config -- cflags -- libs FreeType2 and freetype2-config -- cflags -- libs works the same way, but FreeType2 developers do not necessarily provide freetype2-config commands, usually give. put the PC file under/usr/lib/pkgconfig, so that PKG-config can be found.
For more detailed usage of PKG-config, refer to the manpage of PKG-config :)

As mentioned above, when the library is explicitly linked, GCC will search for the library name according to its own rules. Now let's talk about the library naming rules.
The databases in the system are divided into two types: static databases and dynamic databases (about the differences between dynamic databases and static databases and how to add your own libraries, see another article on my blog ). The difference between static and dynamic libraries is that the suffix name is different. The dynamic library ends with. So (shared object), while the static library ends with. A (archive. For various reasons, the dynamic library is preferentially linked. If the connection fails, the static library is connected.
In addition to the different suffixes, both the dynamic and static libraries have the same prefix Lib, so that the dynamic library is as tangible as libxx. so form. Correspondingly, the static library name looks like this libxx. a.
For example, when the-LM parameter is used to link the Math Library, GCC will look for libm. So or libm.. 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, a series of header files are generally provided, and the header file contains 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 ");
} Compile the dynamic library command: GCC (-FPIC)-shared-O libmyfunction. So myfunction. c
-FPIC allows the output object module to be generated in the form of relocated addresses.
-Shared specifies to generate the corresponding dynamic link library file for the corresponding source file. 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 (after my test, it can indeed be successful)
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. Previously, I thought that as long as the connection is successful, the execution will be successful, and it was not necessarily. Recently, programs in windows have similar symptoms. Now the symptoms in Windows also know the cause. The basic principles of the operating system are absolutely consistent, and the basic principles of both Linux and Windows must be consistent.
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.