Introduction
This article describes the method of generating Makefile from the Gnu autoconf and Automake in Linux systems. This paper mainly discusses the ins and outs of generating Makefile and its mechanism, and then introduces the methods and rules of configuration configure.ac in detail. At the end of this paper, the method of generating dynamic link library by using Libtool is presented, and several comprehensive examples are given, and the usage of Autotools tool set is expounded in detail.
Make is a very important compilation command, both in Linux and in the UNIX environment. Whether you are developing your own projects or installing applications, we often use make or makes install. With make tools, we can break down large-scale development projects into more manageable modules, and for an application that includes hundreds of source files, using make and makefile tools makes it easy to straighten out the intricacies of each source file. But it is a challenge for any programmer to write Makefile manually by looking at make's help documentation. Fortunately, the GNU-provided Autoconf and Automake are two sets of tools that make writing makefile no longer a challenge.
This article will show you how to use the GNU Autoconf and Automake tools to help us automate the generation of Makefile files, and let the software be developed like most source packages, just "./configure", "make", "made Install the program to the system. autoconf
Autoconf is a shell scripting tool for generating automated software source packages that can be used to adapt to a variety of UNIX class systems, where autoconf needs to M4 to generate scripts. Automake
Automake is a tool that automatically generates makefile.in from a makefile.am file. Perl is also needed in order to generate Makefile.in,automake, since the publication created by Automake fully adheres to the GNU standard, so Perl is not required for creation.
Currently Automake supports three directory levels: flat, shallow, and deep. Flat means that all files are in the same directory. Is that all source files, header files, and other library files are in the current directory and have no subdirectories. Termutils is this category. Shallow refers to the main source code is stored in the top-level directory, the other parts are stored in subdirectories. is the main source file in the current directory, while some other implementation of the various parts of the source files are located in their different directories. Automake itself is this category. Deep means that all source code is stored in subdirectories; The top-level directory contains configuration information primarily. Is that all source files and their own header files are located in a subdirectory of the current directory, and the current directory does not have any source files. The GNU Cpio and GNU Tar are in this category.
The flat type is the simplest, and the deep type is the most complex. It is not difficult to see that our simulation needs are based on the third kind of deep type, that is, we have to do challenging things:). Libtool
There is a big difference in the way that dynamic-link libraries are built in different systems, mainly because each system does not have the same view and implementation of dynamic-link libraries, and the compiler supports options for dynamic-link libraries. For developers, if you attempt to migrate software using dynamic libraries between these systems, it is tedious and difficult to refer to Kuse's difficult system manuals and to modify the corresponding Makefile.
The GNU Libtool makes it easy to create dynamic link libraries in different systems. It hides the differences between different systems through an abstraction called the Libtool Library, giving developers a consistent interface. For the most part, the developer doesn't even have to look at the system manual, just the GNU Libtool usage. Also, Makefile that use Libtool can be written once to be used on multiple systems.
The Libtool library can be a static-link library, which can be a dynamic-link library, or it can contain both. In the remainder of this article, we will describe the establishment and use of the Libtool library, and properly describe the mapping between the Libtool library and the system dynamic or static link libraries. Libtool Basic Usage
This section shows an example of how to use Libtool to create a final link library from source code and complete steps for executing a program, which is often used during software development, including: Creating Libtool object files; Create Libtool library; install Libtool Library; Use the Libtool library; Unload the Libtool library;
First, you need to prepare a source file compress.c, the code is as follows:
#include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include < stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> # Include <limits.h> #include <assert.h> #include <zlib.h> int compress _file (const char *filename) { int src_fd, dest_fd; struct stat sb;
BYTEF&NBSP;*SRC, *dest; ulong dest_len; char dest_file[path_max]; src_fd = open (filename, O_
rdonly); assert (dest_fd !=-1);
assert (fstat (SRC_FD, &SB) !=-1); src = mmap (null, sb.st_size, prot_read, map_private, src_fd, 0)
; assert (src != map_failed);
dest_len = compressBound (sb.st_size);
dest = malloc (Dest_len); assert (dest); assert (compress (dest, &dest_len, src, sb.st_size) ==&NBSP;Z_OK); munmap (src, sb.st_size); close (SRC_FD); snprintf (dest_file, sizeof
(dest_file), "%s.z", filename); dest_fd = creat (DEST_FILE,&NBSP;S_IRUSR&NBSP;|&NBSP;S_IWUSR); assert (dest_fd
!=-1);
write (Dest_fd, dest, dest_len);
close (DEST_FD); free (dest); return 0; }
This file implements a function, Compress_file (), which takes a file name as a parameter, then compresses the file to generate a. z-end compressed file. The Compress () function is used in this file, and this function is provided by LIBZ.
It takes two steps to build the Libtool library from the source file, first establish the Libtool object file, and then build the Libtool library. Create a Libtool object file
If you use traditional methods, creating an object file typically uses the following command:
$ gcc-c COMPRESS.C
Use Libtool to use the following command:
$ libtool--mode=compile gcc-c foo.c
As you can see, using Libtool only needs to pass "traditional" commands (gcc-c foo.c) as parameters to Libtool. In the above command, Libtool uses the compile mode (--mode=compile option), which is the pattern for creating object files, and Libtool has other modes, which are described later. The above command output is as follows:
mkdir. Libs gcc-c compress.c-fpic-dpic-o. LIBS/COMPRESS.O gcc-c compress.c-o compress.o >/dev/null 2>&1
It builds two files, one is. LIBS/COMPRESS.O, when this file is created, Libtool automatically inserts the-fpic and-dpic options, tells the compiler to generate the location-independent code, and then uses the file to build the dynamic-link library. Generating the second file COMPRESS.O does not add additional options, it is ready to be used to establish a static link library. In addition to the above two files, Libtool also established a file Compress.lo, this file is Libtool object file, which is actually a text file, which records the creation of dynamic link library and static link library respectively required real file name, the back Libtool This file will be used instead of directly using the. LIBS/COMPRESS.O and COMPRESS.O. Build Libtool Library
Create the Libtool library with the following command:
$ libtool--mode=link gcc-o libcompress.la Compress.lo-rpath/tmp-lz
Note that this uses Compress.lo as the input file, and tells Libtool that the target file generated for libcompress.la,.la is Libtool's library file suffix. The-rpath option tells Libtool where the library will be installed, and if the-rpath option is omitted, the dynamic-link library is not generated. Because the Compress function provided by LIBZ is used in our library, the-LZ option is also provided, and Libtool remembers the dependency and automatically links the dependent libraries when using our library. The above command output is as follows:
gcc-shared. Libs/compress.o-lz-wl,-soname-wl,libcompress.so.0-o. libs/libcompress.so.0.0.0 (CD. Libs && rm-f libcompress.so.0 && ln-s libcompress.so.0.0.0 libcompress.so.0) (CD. Libs && rm-f libcompress.so && Amp Ln-s libcompress.so.0.0.0 libcompress.so) ar cru. LIBS/LIBCOMPRESS.A compress.o ranlib. LIBS/LIBCOMPRESS.A creating libc Ompress.la (CD. Libs && rm-f libcompress.la && ln-s.. /libcompress.la libcompress.la)
As you can see, Libtool automatically inserts the compilation options-shared required to establish a dynamic link library. Also, it establishes a static link library. LIBS/LIBCOMPRESS.A, we'll show you how to control Libtool to build only the libraries you need. You might wonder why the dynamic link library that was created has the. 0 and. 0.0.0 suffixes, which are not to be heeded here, and will be explained later in the introduction of the Libtool library version information. It is worth noting that Libtool would like to follow up using libcompress.la files instead of using LIBCOMPRESS.A and libcompress.so files directly, if you do this, though it can, but will destroy the portability of the Libtool library. [edit] Install Libtool library
If you plan to publish an established Libtool library, you can install it using the following command:
$ libtool--mode=install install-c libcompress.la/tmp
We need to tell Libtool to use the Install command, Libtool supports install and CP, which is used with install. While we were in the front of the library, we specified the path (/tmp) for the library to be installed through the-rpath option, but here we have to provide the installation path. Please make sure they are consistent. The output of this command is as follows:
Install. libs/libcompress.so.0.0.0/tmp/libcompress.so.0.0.0 (cd/tmp && {ln-s-F libcompress.so.0.0.0 libcompr ess.so.0 | | {rm-f libcompress.so.0 && ln-s libcompress.so.0.0.0 libcompress.so.0;}; }) (Cd/tmp && {ln-s-f libcompress.so.0.0.0 libcompress.so | | {rm-f libcompress.so && ln-s libcompress.so.0.0.0 libcompress.so;}; }) install. libs/libcompress.lai/tmp/libcompress.la install. LIBS/LIBCOMPRESS.A/TMP/LIBCOMPRESS.A chmod 644/tmp/ LIBCOMPRESS.A RANLIB/TMP/LIBCOMPRESS.A ...
You can see that it installs the real dynamic link library and the static link library, but also installs the Libtool library file libcompress.la, which can be used by subsequent libtool commands. After the installation is complete, you may need to do some configuration to use correctly, Libtool's finish mode can give us some hints in this regard:
$ libtool-n--mode=finish/tmp
The output of this command is a bit long, so it is not listed here, if you do not properly use the installed library, please run this command. using the Libtool library
To use the Libtool library created earlier in your application is simple, prepare a source file main.c, which will use the functions defined in the Libcompress.la library, with the following code:
#include <stdio.h> extern int compress_file (const char *filename); int main (int argc, char*argv[]) {if (ARGC < 2) {printf ("Usage:%s file\n", argv[0]); return 1;} return Compress_f Ile (Argv[1]); }
We still have to build the Libtool object file for Main.c, as in the previous method:
$ libtool--mode=compile gcc-c main.c
using the installed library
Then use the following command link to execute the file:
$ libtool--mode=link Gcc-o main main.lo/tmp/libcompress.la
We can also use LIBCOMPRESS.A or libcompress.so directly, but using Libtool is easier because it will help you resolve dependencies, such as our libcompress dependency libz. The output of the above command is as follows:
Gcc-o Main. libs/main.o/tmp/libcompress.so-lz-wl,--rpath-wl,/tmp-wl,--rpath-wl,/tmp
Here, Libtool automatically selects the link dynamic link library and adds the--rpath options required by the runtime, as well as the dependent library-lz. If you want to use a static link library, just add the-static-libtool-libs option, as follows:
$ libtool--mode=link Gcc-o main main.lo/tmp/libcompress.la-static-libtool-libs
The output of this command is as follows:
Gcc-o Main. Libs/main.o/tmp/libcompress.a-lz
using a library that is not installed
You can also use a library that is not yet installed, which is almost the same as using the installed library, except that the specified input file location is different, and if we are developing COMPRESS.C and MAIN.C in the same directory, use the following command:
$ libtool--mode=link gcc-o main Main.lo./libcompress.la
Unlike using the installed library, the main program created at this time is just a wrapper script, and if you do it directly it won't be a problem, but if you want to debug it, for example:
$ GDB Main
GdB complains that main is not an executable format and cannot be accepted. At this point we need to use the Libtool execution mode and use the following command to debug the program:
$ libtool--mode=execute GDB Main
uninstalling the Libtool library
Use the following command to uninstall the installed library:
$ libtool--mode=uninstall rm/tmp/libcompress.la
The output of this command is as follows:
Rm/tmp/libcompress.la/tmp/libcompress.so.0.0.0/tmp/libcompress.so.0/tmp/libcompress.so/tmp/libcompress.a
This will remove all installed library files. Libtool Advanced Usage
This section will be a more comprehensive description of the Libtool, including the following: creating dynamically loaded modules; Disable the creation of dynamic or static link libraries; Libtool command mode; library version information; to create a dynamically loaded module
Some advanced software systems do not need to be linked to a particular library when they are built, but can dynamically load a conforming library at runtime to provide additional functionality, which is often referred to as a plug-in system. There are some differences between dynamically loaded libraries and the usual libraries, which can be opened by Dlopen () and can be queried for the symbols it outputs through DLSYM ().
Using Libtool can easily build such a library, or in the case of the previous COMPRESS.C, we can create a dynamically loaded module by this command:
$ libtool--mode=link gcc-o compress.la compress.lo-rpath/tmp-lz-module-avoid-version
Adding an additional two parameters here,-module tells Libtool to create a dynamically loaded module,-avoid-version tells Libtool not to add a version number. In Unix/linux systems, libraries are usually prefixed with lib, and the output file we specify above is compress.la instead of libcompress.la, which is a feature of the dynamically loaded module, which does not need to follow the usual library naming conventions. In practical applications, dynamically loaded modules usually use some of the functions provided by the main program, in order to meet the needs of dynamic modules, when compiling the main program, you need to add the-export-dynamic option. Disable the creation of dynamic or static link libraries
In most cases, Libtool is configured to create both a dynamic-link library and a static-link library. You can view the current configuration of Libtool by using the following command:
$ Libtool--features
Its output is as follows:
HOST:I686-PC-LINUX-GNU enable shared libraries enable static libraries
But sometimes, just want to create a dynamic link library or just want to create a static link library, this needs to modify the Libtool itself. The following describes the Libtool combined with autoconf and automake when used, there will be a simpler approach.