Part 2: automake standard engineering organization

Source: Internet
Author: User
Tags doxygen automake

++ The second part is the standard engineering organization of automake: ++
I. Overall directory:
Generally, the following directories and files are created by yourself (see figure 2) or automatically generated using acmkdir:
1. directory:
(1) required:
M4: a third-party or self-written macro used in configure. In
DOC: various documents
SRC: top-level directory of the source code (how to break down it is your own business)
Config: place some files in the configure process, so that the top-level directory is not so many files
(2) Optional:
Include: an optional Directory. You can use configure to link all header files to this directory. Generally, this is not required.
Lib: an optional Directory. If you like, you can implement system calls (for calls that are not implemented on some platforms) and commonly used small code (you may think it is too small, every project is often used, and SRC should not be used as a library.) Put it in this directory.
2. file:
For example, README, authors, news, changelog, install, and copying are required by automake. They must exist unless you use the automake -- foreign option.

2. Create a project step by step:
(For my example, see each step. The example is not described separately)

1. Create a required directory:
Mkdir SRC config Doc M4

2. Create the configure. In file:
Ac_init ([Kid], # project name
[0.1], # version number
[Yi Feng yifengcn@gmail.com], # name and mailbox
[Kid]) # Make Dist/distcheck package name
Ac_config_aux_dir (config) # Put some files generated by configure here (to make the upper layer clean)
Am_config_header (config. h) # configure the header file name config. h
Am_init_automake ([dist-bzip2]) # Of course there are many parameters here, and [dist-bzip2] indicates make Dist/distcheck package by bz2 package, the default is GZ

Ac_prog_cc # Check the C compiler used
Ac_prog_cxx # Check the C ++ compiler used
Ac_prog_install # generate the installation script install-SH
Ac_prog_ranlib # Use ac_prog_ranlib to generate a static library (generate a library index)
Ac_prog_libtool # If you only generate a static library, use ranlib. Libtool is used for dynamic libraries
Ac_prog_make_set # I have not seen any difference in this option. Add it.

Ac_config_files ([# configure. in is also used for automake. automake will put your makefile in the following places. AM/xxx. PC. convert in to makefile. in template/xxx. PC. The following files. AM/. PC. In must be written by yourself.
Makefile # It comes from the top-level makefile. am, that is, subdirs, specifying M4, SRC, Doc
Src/makefile # The total makefile. Am from the src directory (source file). It also specifies the subdirs
Src/libhello/makefile # This is from makefile. AM in the libhello subdirectory under SRC, providing the libhello Library
Src/libhello/hello-1.0.pc # because this library is to be installed, this file is installed for PKG-config to use
Src/bin/makefile # This is from the bin subdirectory under SRC. It is a runable program that uses the libhello library.
DOC/makefile # The Installation Method of man files is shown here, in the same way.
M4/makefile # If you put your Configure. In macro in it, you need.
])

Ac_output

Note:
(1) generate a database
Ranlib was previously used to generate an index for a static library. But later, libtool emerged. This tool specifically generates "Libraries", including static and dynamic, so you don't have to use ranlib any more. However, if you only generate a static library, you can use ranlib. ac_prog_libtool makes configure take a long time: (In addition, I have never used libtool separately (it is independent of Autoconf and automake, GNU is a tool that provides unified interfaces for different platforms, such as whether to implement dynamic libraries and what parameters should be added. It is not related to these differences when users generate libraries ), however, it works very well with automake. As shown below, it will generate both static and dynamic libraries by default. If your program has a master program and a dynamic library, you must use the master program to connect to the database. By default, it connects to the dynamic library. After you make install them, you LDD the main program and you will find that the dynamic library it depends on is a full-path library! This avoids a dynamic library search mechanism of LD. So. You do not need to make any settings (such as ldconfig) to run your program.
Let's take a look at the command line output. In fact, GCC added parameters such as-wl when linking the Library (libhello. So) and intercepted the following:
Gcc-wall-g-O3-g-O2-o. libs/kid main. o-lM .. /.. /src/libhello /. libs/libhello. so-wl, -- rpath-wl,/home/ECHO/tmp/ECHO // lib
It is worth mentioning why the libtool interfaces are unified. For more information, see makefile. the am file is abstracted as: you only need to write a library with the suffix. la. Then, dynamic libraries (such as. So) and static libraries (such as. A) that meet the requirements of the platform are automatically generated)
(2). PC. In
Generally, if you want to install the library, it is best to provide the XXX. PC. In file for user friendliness. The content of this file is shown below. However, like any target to be installed, you must specify "primitive" in makefile. am at its level ". That is:
Pkgconfigdir = $ (libdir)/pkgconfig
Pkgconfig_data = hello-1.0.pc
To know the installation path and the method for generating the. PC file by. PC. In.
(The. PC file can also be used as a parameter directly for PKG-config. You can try PKG-config XXX. PC -- Libs -- cflags)
The installation path of the. PC file is usually pkgconfig under $ (libdir). Here $ (libdir) = $ (prefix)/lib.

3. Put your source file in the corresponding directory and create makefile. Am according to the makefile location specified in configure. In:
The general principle of writing makefile. Am is given first -- "Writing makefile is a write rule, while writing makefile. am is a value assignment"
(1) The upper makefile. Am only writes subdirs and extra_dist:
Where do you want to generate XX (such as a library generated by the source file) and install XX (such as the man file in the DOC), you must have makefile. am. For hierarchical organization, makefile. Am is required for each level of directory. The directory at the upper level has subdirectories, and makefile. AM in the upper level directory only needs to write subdirs = sub1 sub2 sub3. The key here is that the compilation sequence is specified by the sub1 sub2 sub3 order !! If sub1 sub2 is a database and sub3 is a program that uses them, it is correct to specify this!
The purpose of extra_dist = file1 file2 is only: If you have a special file (that is, it is not a makefile. am or not in the autotools system) to be retained to the hairstyle version generated by make Dist, use extra_dist to specify it; otherwise, it will not be included. For example, the./reconf file (including libtoolize aclocal autconf autoheader and automake) You Write must be reserved with extra_dist.

(2) lower-level vertex (that is, the source code directory, or other to be generated (such as XXX. PC), makefile in the directory where the file to be installed (such as man) is located. am should write clearly the assignment of each variable! For example, am_cppflags is a variable of automake. For detailed variation details, see the variable index appendix of automake.htm (document on the GNU homepage.

------------ A. Global :--------------
Am_cppflags =-I...-d... # parameters for the pre-processor (while Des is an old usage, the new am_cppflags is recommended)
Am_ldflags =-L # is used for-L and may be used for other purposes.
Ldadd =-lm-lhello # For-l
Am_cflags # What do you want to add to the above three items, such as-wall-O3-G
Note:
Global means: this file is valid. Currently, I don't need to use it. I haven't looked for methods to pass variables like export in makefile. Now, the method I used in makefile. am still does not focus on the makefile. AM in the upper directory to place shared variables, such as header file positions (many-I) in the upper layer. In fact, scattered, each unit can be independent, but also very good.
Adding am means: without the corresponding variables of AM, it is designed for the user of the package, that is, the user can do this:./configure cflags = '-wall '. If you use cflags in makefile. am, it will be overwritten by the user. Therefore, you must add an AM _ prefix to indicate that the variable is used for developers and will not be overwritten by the user. Ldadd is used to add-L, which has nothing to do with the user, so there is no use of the am _ prefix.
The four variables mentioned here will be used for all preprocessing, compilation, and linking related to this makefile. am.

----------- B. element :-------------
In many cases, it can be understood that the "location _ installation method = primitive1 primitive2" is used to define elements primitive1 and primitive2. Elements are the targets of compilation, generation (such as XXX. PC), or installation (such as man files. This tells us that primitive1 and primitive2 will be installed to the $ (prefix)/location, and the installation method will follow what you specified. Let's look at several examples of non-programs:
===For example, if you want to install cow.1 to Man1, write makefile. am as follows:
Manw.mans = cow.1
That's all. Man1 indicates that the file will be installed in $(prefix)/share/man/Man1 (do not say why share is not written into the element ), mans points out that cow.1 is a man file and does not need to be processed. When you make install, put it directly in $(prefix)/share/man/Man1. However, manw.mans = cow.1 is written in this way, and no more attributes will be written (See C. property), but one of the automake rules is that if you want to include program files in make Dist, you should write xx_sources again to specify which files need to be compiled and packaged, or use extra_dist = to specify the file to be included. Because of the corresponding man_mans, if cow_1_sources is written, the syntax is incorrect. Because there is no sources corresponding to mans, automake defaults to man1_mans = cow.1, it does not contain a pack from cow.1 to make Dist. What should we do? Automake provides the dist _ prefix, which corresponds to the nodist _ prefix, indicating this element. Instead of writing similar sources, you can directly put the file with the same name in make Dist.
Therefore, the final form is: dist_manw.mans = cow.1
To install the hello-1.0.pc, you just need to write in makefile. am:
Pkgconfigdir = $ (libdir)/pkgconfig
Pkgconfig_data = hello-1.0.pc
Note that pkgconfig in pkgconfig_data cannot be determined. The difference between pkgconfig and Man1 is that Man1 is defined by automake, of course, if you write this, it indicates where to install it -- in fact, a variable named Mandir is defined by default, and it is equal to $ (prefix)/share/man. However, the pkgconfig you write is not built-in by automake and does not have the corresponding dir variable. Therefore, you must specify pkgconfigdir = $ (libdir)/pkgconfig on your own to let automake know, you want to install it here! Here, libdir is the variable defined by automake. It can be written directly. It corresponds to the lib_xxx (such as lib_libraries) Element Definition. The purpose of _ data here is to explain how the hello-1.0.pc.in works: if you reference a prefix in it, the configure script will replace the variables in the hello-1.0.pc.in at runtime, to generate hello-1.0.pc. For example, if you specify./configure -- prefix = ....

The following lists the commonly used element definitions. These are all the variable values of automake.htm. See the variable index appendix of automake.htm (document on the GNU homepage.
Extra_programs = # It should be listed here./configure is used to determine whether to generate the target.
Bin_programs = kid # This is the way to define program elements. bindir = $ (prefix)/bin is defined by automake by default.
Sbin_programs = # If you want to install sbin.
Lib_libraries = libhello. A # method for defining static library elements, which is specified by libraries and must be compiled into a static library.
Pkglib_libraries = # When pkgxxx is added, it indicates that only the package name is added during installation, that is, pkglibdir = $ (prefix)/lib/@ package @ where package should be configure. replace the one you wrote in.
Include_headers = # This is to list the header files you want to install. This is generally used for creating a library and then the header files you want to install are provided here.
Pkginclude_headers = # is the same as pkglib.
Noinst_programs = # noinst _ indicates that the generated items are not installed. This indicates that the generated program, make install will not install
Noinst_libraries = # This is commonly used, because you may generate a static library for your program in the subdirectory.
Lib_ltlibraries = libhello. La # This is too common. To generate a dynamic library, use libtool (LT). Here ltlibraries indicates that libtool is used. Note: In this case, the dynamic library libhello and static library will be generated! If you write noinst_ltlibraries, only the static library is generated !! So, in fact, the above noinst_libraries is no longer significant (but it makes the configure time much faster)
Xmldir = $ (datadir)/XML # here is an example of custom Element Definition. You need to install it in the "XML directory", which is specified as $ (datadir)/XML, $ (datadir) is defined by the system. If there is no manual, make install once and you will know its default value.
Xml_data = file. xml # Next, we need to point out the method of making data. To put it another way: the concept of data is very broad. Many files that do not know how to classify can be installed with this. However, if you need the content in the file to be adjusted by configure, then Mr Cheng. in the file, use @ var @ to reference the variable (many variables you can see can be used. put configure in. in, see. PC. in.
Manw.mans = # automake defines the man installation method.
Data_data = # automake defines how to install data files (such as XXX. PC.
Pkgdata_data = # The same as pkglib with a PKG prefix.

The complete pre-defined installation path is listed below: (check the manual for some of the corresponding BBB in aaa_bbb)
1. Program-related files are installed in one of the following locations:
Bindir = $ (exec_prefix)/bin
Sbindir = $ (exec_prefix)/sbin
Libexecdir = $ (exec_prefix)/libexec
Libdir = $ (exec_prefix)/lib
Includedir = $ (prefix)/include
2. Data Files shocould be installed in one of the following directories:
Datadir = $ (prefix)/share
Sysconfdir = $ (prefix)/etc
Sharedstatedir = $ (prefix)/COM
Localstatedir = $ (prefix)/var
3. Documentation shoshould be installed in the following directories:
Infodir = $ (prefix)/info
Mandir = $ (prefix)/man
Man1dir = $(prefix)/Man1
4. Then there are some directories for developing various eccentric types of files:
Lispdir = $ (datadir)/Emacs/Site-lisp
M4dir = $ (datadir)/aclocal
5. Some subdirectories for convenience:
Pkglibdir = $ (libdir)/@ package @
Pkgincludedir = $ (includedir)/@ package @
Pkgdatadir = $ (datadir)/@ package @

--------------- C. attributes :------------------
Obviously, setting the above element is not enough. An element has its attributes. The attribute value is "element _ attribute ". If "element" contains ".", replace it.
= The attributes of the library element are as follows: (assuming the above element is defined as lib_ltlibraries = libhello. La)
Libhello_la_sources = hello1.c hello2.c hello. h
# Set the soname: libhello-2.1.3.so.3.0.0
Libhello_la_ldflags =-release 2.1.3-version-Info :3:3
# There are two versions, which are not required. But it is required for formal use. Release is defined by you. There are rules for version. Check it online. The first form is A: B: C. The colon cannot be a. Number, and each number is meaningful. It is a description of the changes to the library interface. I don't know why is specified here. The above is 3.0.0. It may be invalid.
Libhello_a_libadd = obj1.o sub/libsub. La # add some existing. O/. A/. La/. So to aggregate.
Libhello_a_dependencies = dep1 # This dependency indicates that it must be compiled after dep1. It is not the aggregate meaning of libadd. No, because the directory order is specified directly in makefile. Am subdirs in the upper-level directory, and the compilation order is based on that.

= The attributes of the program element are as follows: (assuming the Element Definition above is bin_programs = kid)
Kid_sources = A. c B. c a. h B. H # list all files !! Includes header files. Only those listed here can be included in the package generated by make Dist/distcheck.
Kid_ldflags = #-L and other options.
Kid_ldadd = #-L option
Kid_dependencies = # Same library element attribute example.

Note: Here _ ldflags and so on are local variables such as am_ldflags above, which are only valid for this one.

4. The folders and files in this example are as follows: (Add the following content after the preceding two steps)
(1) $ (top_srcdir)/reconf
This file is used to simplify the command set when the configure. In, makefile. am non-file list and other file changes need to be regenerated.
The content is as follows:
#! /Bin/bash
Echo '-libtoolize'
Libtoolize -- force # This is used with libtool. If you want to generate a dynamic library, use this.
Echo '-aclocal-I M4'
Aclocal-I M4 # generate an actual script for the macro in configure. In.
Echo '-autoconf'
Autoconf # convert Configure. In to configure
Echo '-autohead'
Autoheader # generate the config. H. In Template
Echo '-automake -- add-missing -- foreign'
Automake -- add-missing -- foreign # convert the makefile. Am you specified in Configure. In To The makefile. In template.
(2) $ (top_srcdir)/makefile. AM
This is the makefile. am at the top level. The content is as follows:
Extra_dist = reconf configure # in the package generated by make Dist, it contains the reconf and configure that may not have been included (configure will include, but it can also be written here)
Subdirs = M4 SRC doc # three directories (among them, M4 is used to store the User-Defined Configure. In macro, which is generally not used)
(3) $ (top_srcdir)/M4/makefile. AM
Because the M4 directory is useless here, you can create a makefile. Am file with empty content in it.
(4) $ (top_srcdir)/doc/makefile. AM
In the doc, I put a man file named cow.1 (the content is empty), and its makefile. am content is as follows:
Dist_man1_mans = cow.1
# (The reason for Dist addition is described above, because this only writes the element cow.1 and does not write its attributes, for example, what files are there, automake, by default, does not add it to the packaging file of make Dist. Therefore, the prefix "dist _" is added to indicate that cow.1 is used as the file name and the file is added to the Make Dist package file)
(5) $ (top_srcdir)/src/makefile. AM
This file is the total makefile of the src directory. the src directory contains the libhello and bin directories. The contents of makefile. Am are as follows:
Subdirs = libhello bin # Put libhello in front and let it compile first. Otherwise, the bin cannot be compiled.
(6) $ (top_srcdir)/src/libhello/makefile. AM
This file is the total makefile of the libhello directory. The content is as follows:
Am_cflags =-wall-g-O3

Lib_ltlibraries = libhello. La
Include_headers = Hello. h # This is the header file installed for the library
Libhello_la_sources = hello1.c hello2.c hello. h
Libhello_la_ldflags =-release 2.1.3-version-Info # Set the soname: libhello-2.1.3.so.3.0.0

Pkgconfigdir = $ (libdir)/pkgconfig
Pkgconfig_data = hello-1.0.pc

------ Other files :------
Hello-1.0.pc.in content (this is a general template, change the name, description, version, Libs can be, a more comprehensive template man PKG-config, at the end of a point ):
Prefix = @ prefix @
Exec_prefix = @ exec_prefix @
Libdir = @ libdir @
Includedir = @ includedir @

Name: Hello
Description: Say hello Library
Requires:
Version: @ 1.0 @
Libs:-L $ {libdir}-lhello
Cflags:-I $ {includedir}-I $ {libdir}

Source File hello1.c:
# Include "Hello. H"

Void hello1 (INT times)
{
Int I = 0;
For (I = 0; I <SQRT (times); I ++ ){
Printf ("Hello kid1! /N ");
}
}

Source File hello2.c:
# Include "Hello. H"

Void hello2 (INT times)
{
Int I = 0;
For (I = 0; I <SQRT (times); I ++ ){
Printf ("Hello kid2! /N ");
}
}

Source File hello. h:
# Ifndef hello_h
# Define hello_h

# Include <stdio. h>
# Include <math. h>
Void hello1 (INT times );
Void hello2 (INT times );

# Endif

(7) $ (top_srcdir)/src/bin/makefile. AM
This is the main makefile of the bin program directory. The content is as follows:
Am_cppflags =-I $ (top_srcdir)/src/libhello
Am_ldflags =-L $ (top_builddir)/src/libhello
Ldadd =-lhello-LM
Am_cflags =-wall-g-O3

Bin_programs = kid
Kid_sources = Main. c

Content of the source file main. C:
# Include "Hello. H"

Int main (INT argc, char * argv [])
{
Hello1 (4 );
Hello2 (16 );
Return 0;
}

5. Make distcheck check and packaging:
Make Dist can be used for packaging. You can use make distcheck to simulate User Detection and package it.
In my example, an error is reported in Main. O-lhello (although make is good) When make distcheck is used ). However, it is normal to use the generated package file after it is unlocked. Later, I realized that make distcheck will check the build in vpath mode. This error is because the build in vpath mode is not successful.
That is, there is a compilation method, for example, after you enter the $ (top_srcdir) directory, you are not. /configure, but create a build directory, and then in the directory .. /configure; Make; make install. In this way, everything in the original $ (top_srcdir) directory will not be affected. The generated files are all under build! Including the directory tree where all makefile. Am is located.
Vpath comes from GNU make. In essence, make is in a directory, but its files are allowed to come from other places.

Later, I checked autotools_tutorial.html and found that, as mentioned in 6.7 General automake principles, if you want to support vpath, note the following two variables:
$ (Top_srcdir) can only be used for your own files.
$ (Top_builddir) must be used to generate the file. If the system generates a library, the path-l... will be extracted using $ (top_builddir.
At that time, it was because am_ldflags =-L $ (top_builddir)/src/libhello in makefile. Am in Bin used $ (top_srcdir.
However, note that both variables are considered as the top-level directory of the project, that is, the directory level of SRC.

6. Use:
Some usage methods are listed below:
(1) add, delete, and change the file name in makefile. am. You only need to make. If you want to change something else, you should mostly re-automake and then make. However, it is generally not necessary to repeat the libtoolize; aclocal; Autoconf; autohead steps.
If the configure. In file is modified, if the makefile is still in progress, most of them will directly make the file, and it will automatically re-go./reconf and./configure.
(2) The prefix and Exec-Prefix mentioned previously are configured in configure as follows:
Configure -- prefix =/home/echo -- Exec-Prefix =/home/ECHO/Linux
Exec-prefix is set to equal to prefix by default, but if you set another path, all the binary files (that is, related to the platform) files will be installed in the path specified by Exec-prefix, and other files will be installed in the path specified by prefix as usual. This is because you may have the following requirement: You will compile binary files on many platforms, put them under different Exec-prefix, and then use them as network servers for users on different platforms.
In addition, the use of configure to configure user variables is as follows (User variables correspond to the above mentioned am _ variable): Configure cflags = '-wall-O3-G'
(3) wildcards?
Automake does not support $ (wildcards. Not only is it not supported, but it also makes you feel that it should not be supported. See 27.3 why doesn't automake support wildcards in the GNU automake documentation ?. If you want to implement this, write your own scripts.
(4) install and cancel the installation:
If you want to install it in your own directory, use./configure -- prefix =. When you make install, use your own user. Some subdirectories, such as bin and Lib, will be automatically generated.
For some dynamic libraries, if you want to install them to your own directory without configuring ldconfig as the root user, you can have GCC generate an execution file, use-wl to specify the absolute path, which is described above. It is not enough to store data in the same directory. However, this is generally done by automake.
Make uninstall can delete installed items.

7. More topics:
(1) Obviously, the definition of "element" cannot solve all problems, because apart from MANs and data, we may have our own views on Element Generation! In addition, we may have our own views on source file compilation. Therefore, automake allows you to write makefile rules in makefile. Am !!
In the example of autotools_tutorial.html 6.13 scripts with automake, here we will introduce if you want to install some scripts.
(2) doxygen support:
In this case, you need to add a macro in M4 and some other configurations. Then, the makefile will automatically have a target to generate the doxygen document.

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.