Creating library in linux

12.15 – Creating a library file in Linux

How to create a library file in Linux

Library file is a group of compiled object files saved with .a file extension in case of Linux. Generally functions, enumerations, user defined types and constants shared by more than one application are broken out of the application source code, compiled and bundled as a library file. All the predefined functions are managed in standard libraries of gcc. We can also create our own library and can be used in any application. The main advantages with libraries are

  • Same library can be shared by multiple applications
  • Vendors can release libraries as APIs (Application Program Interface)
  • It reduces the applications source size and saves the compilation time
  • We no need to specify different object files while linking to make a build

Now in this session, we will see how a static library can be created and used in Linux step by step

Step 1: Implement the library source files and save them with .c file extension.
Here “first.c” has a function adding() that takes two integers and returns sum of them, “second.c” has a function subtraction() that takes two integers and returns subtraction of them.

Select Save (Alt+s), Quit (Alt+Q)

Select Save (Alt+s), Quit (Alt+Q)

Step 2: Compile and generate object files of both .c files using gcc compiler
-c is an option to generate only object files with .o file extension

Step 3: Create the library file using archive tool ar. It groups all the object files and generates a library file with .a file extension.
-c is an option to create a new archive
-r is an option to replace an existed archive if existed with the same name
-v to verbose (display) the contents of library

-t is an option to display the contents of a library file

Step 4: Create a header file with the prototypes of library functions and save with .h file extension

Select Save (Alt+s), Quit (Alt+q)

Step 5: We can use both the library functions and header file in any C program within the same folder

Select save (Alt+S), Quit (Alt+Q)

Step 6: Compile and execute the program
While linking the library, specify the name of library file and the location of header file along with the program name
-I to specify the path of header file ( ./ means same folder in Linux)
-o to specify the name of output file

Static Vs. Dynamic Library:

By default the executable file created by the gcc is dynamically linked with the library. The executable file created by the compiler can be only executed in the same system in which library file is created or loaded but, can’t be executed on another system.

In the above example main.out (executable file) uses the library file mylib.a during execution. The program may not be executed on deleting mylib.a

By using an option –static we can statically link the executable file with the library, that means libraries are added to the executable code so that, executable file can be loaded on to any machine and executed.

By using the command file we come to know that, by default gcc follows dynamic linking and can be statically linked using the –static flag with gcc

Читайте также:  Proceeding using windows 1252

By using the the option –l with the ls command we come to know that, the size of executable file created with static link is nearly 60 times greater than the file created with dynamic linkage (default)

One more thing to discuss is, in the above output there is something like “not stripped”. Which means there is some extra information like metadata in the executable. That extra unnecessary information can be removed using the tool strip. After stripping the file, the sizes may be reduced by few kilo bytes.

Источник

How to create Shared Library in Linux ?

If you want to create static library visit our another article “How to Create Static Library in Linux ?”

Below program demos how to create a shared library and link it with the main program to create a executable. Shared libraries requires less RAM than static libraries, has only one copy in RAM at any point of time. You can read more information at “Difference between static and dynamic library linking”

For simple demo, we will write two files / c program each of which has one function defined inside it.

From “nm” command, we can see that now our created library has the symbols from both the object files first.o and second.o. so, now our shared library is ready. Now lets write a main program or application which will use this library and write its own application using library functions as,

Now, lets try to execute our newly created executable “main” as,

Despite having our library created and linked, Why this happened ? Lets try to diagnose,

As per ldd, its showing that main is unable to find the “testlib.so” since this is dynamically linked library, we have to mention the path where this library is stored to the executable during the start. Ideally, the path searched are what has been seen in “LD_LIBRARY_PATH” so, we have to add our present path to this environment variable as,

Now, check with “ldd”, it shows library found.

OR You can use the Makefile as below to compile everything and just type “make” in same directory by copying this Makefile.

If you want to create static library visit our another article “How to Create Static Library in Linux ?”

Источник

Shared libraries with GCC on Linux

Libraries are an indispensable tool for any programmer. They are pre-existing code that is compiled and ready for you to use. They often provide generic functionality, like linked lists or binary trees that can hold any data, or specific functionality like an interface to a database server such as MySQL.

Most larger software projects will contain several components, some of which you may find use for later on in some other project, or that you just want to separate out for organizational purposes. When you have a reusable or logically distinct set of functions, it is helpful to build a library from it so that you do not have to copy the source code into your current project and recompile it all the time — and so you can keep different modules of your program disjoint and change one without affecting others. Once it is been written and tested, you can safely reuse it over and over again, saving the time and hassle of building it into your project every time.

Building static libraries is fairly simple, and since we rarely get questions on them, I will not cover them. I will stick with shared libraries, which seem to be more confusing for most people.

Before we get started, it might help to get a quick rundown of everything that happens from source code to running program:

  1. C Preprocessor: This stage processes all the preprocessor directives. Basically, any line that starts with a #, such as #define and #include.
  2. Compilation Proper: Once the source file has been preprocessed, the result is then compiled. Since many people refer to the entire build process as compilation, this stage is often referred to as compilation proper. This stage turns a .c file into an .o (object) file.
  3. Linking: Here is where all of the object files and any libraries are linked together to make your final program. Note that for static libraries, the actual library is placed in your final program, while for shared libraries, only a reference to the library is placed inside. Now you have a complete program that is ready to run. You launch it from the shell, and the program is handed off to the loader.
  4. Loading: This stage happens when your program starts up. Your program is scanned for references to shared libraries. Any references found are resolved and the libraries are mapped into your program.
Читайте также:  Обновления для windows phone denim

Steps 3 and 4 are where the magic (and confusion) happens with shared libraries.

Now, on to our (very simple) example.

foo.h defines the interface to our library, a single function, foo(). foo.c contains the implementation of that function, and main.c is a driver program that uses our library.

For the purposes of this example, everything will happen in /home/username/foo

Step 1: Compiling with Position Independent Code

We need to compile our library source code into position-independent code (PIC): 1

Step 2: Creating a shared library from an object file

Now we need to actually turn this object file into a shared library. We will call it libfoo.so:

Step 3: Linking with a shared library

As you can see, that was actually pretty easy. We have a shared library. Let us compile our main.c and link it with libfoo. We will call our final program test. Note that the -lfoo option is not looking for foo.o, but libfoo.so. GCC assumes that all libraries start with lib and end with .so or .a (.so is for shared object or shared libraries, and .a is for archive, or statically linked libraries).

Telling GCC where to find the shared library

Uh-oh! The linker does not know where to find libfoo. GCC has a list of places it looks by default, but our directory is not in that list. 2 We need to tell GCC where to find libfoo.so. We will do that with the -L option. In this example, we will use the current directory, /home/username/foo:

Step 4: Making the library available at runtime

Good, no errors. Now let us run our program:

Oh no! The loader cannot find the shared library. 3 We did not install it in a standard location, so we need to give the loader a little help. We have a couple of options: we can use the environment variable LD_LIBRARY_PATH for this, or rpath. Let us take a look first at LD_LIBRARY_PATH:

Using LD_LIBRARY_PATH

There is nothing in there. Let us fix that by prepending our working directory to the existing LD_LIBRARY_PATH:

What happened? Our directory is in LD_LIBRARY_PATH, but we did not export it. In Linux, if you do not export the changes to an environment variable, they will not be inherited by the child processes. The loader and our test program did not inherit the changes we made. Thankfully, the fix is easy:

Good, it worked! LD_LIBRARY_PATH is great for quick tests and for systems on which you do not have admin privileges. As a downside, however, exporting the LD_LIBRARY_PATH variable means it may cause problems with other programs you run that also rely on LD_LIBRARY_PATH if you do not reset it to its previous state when you are done.

Читайте также:  Git add windows path

Using rpath

Now let s try rpath (first we will clear LD_LIBRARY_PATH to ensure it is rpath that is finding our library). Rpath, or the run path, is a way of embedding the location of shared libraries in the executable itself, instead of relying on default locations or environment variables. We do this during the linking stage. Notice the lengthy “-Wl,-rpath=/home/username/foo” option. The -Wl portion sends comma-separated options to the linker, so we tell it to send the -rpath option to the linker with our working directory.

Excellent, it worked. The rpath method is great because each program gets to list its shared library locations independently, so there are no issues with different programs looking in the wrong paths like there were for LD_LIBRARY_PATH.

rpath vs. LD_LIBRARY_PATH

There are a few downsides to rpath, however. First, it requires that shared libraries be installed in a fixed location so that all users of your program will have access to those libraries in those locations. That means less flexibility in system configuration. Second, if that library refers to a NFS mount or other network drive, you may experience undesirable delays — or worse — on program startup.

Using ldconfig to modify ld.so

What if we want to install our library so everybody on the system can use it? For that, you will need admin privileges. You will need this for two reasons: first, to put the library in a standard location, probably /usr/lib or /usr/local/lib, which normal users do not have write access to. Second, you will need to modify the ld.so config file and cache. As root, do the following:

Now the file is in a standard location, with correct permissions, readable by everybody. We need to tell the loader it is available for use, so let us update the cache:

That should create a link to our shared library and update the cache so it is available for immediate use. Let us double check:

Now our library is installed. Before we test it, we have to clean up a few things:

Clear our LD_LIBRARY_PATH once more, just in case:

Re-link our executable. Notice we do not need the -L option since our library is stored in a default location and we are not using the rpath option:

Let us make sure we are using the /usr/lib instance of our library using ldd:

Good, now let us run it:

That about wraps it up. We have covered how to build a shared library, how to link with it, and how to resolve the most common loader issues with shared libraries — as well as the positives and negatives of different approaches.

  1. It looks in the DT_RPATH section of the executable, unless there is a DT_RUNPATH section.
  2. It looks in LD_LIBRARY_PATH. This is skipped if the executable is setuid/setgid for security reasons.
  3. It looks in the DT_RUNPATH section of the executable unless the setuid/setgid bits are set (for security reasons).
  4. It looks in the cache file /etc/ld/so/cache (disabled with the -z nodeflib linker option).
  5. It looks in the default directories /lib then /usr/lib (disabled with the -z nodeflib linker option).

What is position independent code? PIC is code that works no matter where in memory it is placed. Because several different programs can all use one instance of your shared library, the library cannot store things at fixed addresses, since the location of that library in memory will vary from program to program. ↩

GCC first searches for libraries in /usr/local/lib, then in /usr/lib. Following that, it searches for libraries in the directories specified by the -L parameter, in the order specified on the command line. ↩

Источник

Оцените статью