Automatically Generating Makefile Files

For larger projects, manually writing Makefile files can be very challenging. Firstly, the structure of Makefile files is complex, and secondly, they are often constrained by the development environment. If the environment parameters differ or paths change, modifications to the Makefile may be necessary to adapt to these changes. Autotools is a suite of tools that can automatically generate Makefile files, providing strong support for the development of larger projects.Autotools mainly includes the following tools:autoscan: This tool is used during the automatic generation of Makefile to create a configure.scan file, which requires necessary modifications, such as adding required information or modifying some information to prepare for the automatic generation of the Makefile. It is then renamed to configure.ac or configure.in.aclocal: This is a Perl script that generates an aclocal.m4 file by scanning the configure.ac (or configure.in) file. The content of aclocal.m4 mainly consists of locally defined macros.autoconf: A shell script tool used to automatically configure software source code to adapt to various POSIX-like systems. configure.in is the script configuration file for autoconf, and its prototype file is configure.scan, generated by autoscan.autoheader: Generates a config.h.in file. This tool typically copies user-defined symbol definitions from the acconfig.h file.automake: A tool that automatically generates Makefile.in from the script configuration file Makefile.am, which the configure program uses to generate the Makefile.libtool: A tool that facilitates the generation of various program libraries.Figure 1 is a flowchart of the Makefile generation process. Below, we will illustrate the automatic generation process of the Makefile according to the steps shown in Figure 1.Automatically Generating Makefile Files1. Project Description

First, create a directory named ts to store the project files. Under ts, create a src directory, where the source code is generally placed (this is an unwritten rule). In the src directory, write three source programs, with the overall structure as follows:

  <ts>   |-<src>     |-teacher.c     |-student.c     |-ts.h

The code for these three source programs is as follows:

// ts.h#ifndef __STU__#define __STU__void student(void);#endif
#include &lt;stdio.h&gt;#include &lt;ts.h&gt;
#ifdef HAVE_CONFIG_H#include &lt;config.h&gt;#endif
int main(void){   printf("Teacher: I'm Mr. Bobo.\n");   printf("Teacher: Please tell me your names!\n");   student();   #ifdef HELLO   printf("Teacher: Hey Taotao, long time no see.\n");   #endif}
// student.c#include &lt;stdio.h&gt;
#ifdef HAVE_CONFIG_H#include &lt;config.h&gt;#endif
void student(void){    #ifdef HELLO    printf("Student: Hello, Mr. Bobo.\n");    #endif    printf("Student: My name is Taotao.\n");}

Functionality:

1) Teacher Bobo takes attendance.

2) If HELLO is defined, the student will greet the teacher and then state their name. Teacher Bobo will also greet the student.

3) If HELLO is not defined, the student will only state their name, and Teacher Bobo will conclude the attendance.

Clearly, the result of the program’s compilation and execution depends on whether the macro HELLO is defined. We can achieve different effects simply by deciding whether to define it before compilation.

Note: If config.h exists, the Makefile will pass the macro HAVE_CONFIG_H to the compiler during compilation. If HAVE_CONFIG_H is not defined, config.h should not be included during compilation.

2. Automatic Generation of Makefile Process

First, create a directory named ts to store the project files. Under ts, create a src directory, where the source code is generally placed (this is an unwritten rule). In the src directory, write three source programs, with the overall structure as follows:

Step 1: Confirm whether the Autotools tools are installed on the system.

If not installed, please install them first. This article is completed in a CentOS 7 environment. You can check whether the autotools tools are installed using the which command.

Automatically Generating Makefile Files

The local machine does not have the autotools tools installed. Now use the command yum -y install autoconf automake to install, as shown in the figure below.

Automatically Generating Makefile Files

Step 2: Generate the configure.in file.

There are two methods to generate the configure.in file: one is to write it from scratch, and the other is to use autoscan to generate it. Execute autoscan in the ts directory, which will generate a configure.scan file containing some template content. When using it, simply rename it to configure.in.

Automatically Generating Makefile Files

autoscan will also produce an autoscan.log file to record the scanning process of autoscan. This file can be safely deleted.

Modify the configure.in file, with the content as follows.

Automatically Generating Makefile Files

The underlined lines in the figure are the modified or added lines.

AC_PREREQ(2.69) ensures that a sufficiently new version of Autoconf is used. If the version of Autoconf used to create configure is earlier than the specified version, an error message will be printed to standard error output, and configure will not be created.

AC_INIT defines the basic information of the software, including setting the full name of the package, version number, and the email address used for reporting bugs.

AC_CONFIG_SRCDIR is used to detect whether the specified source file exists to determine the validity of the source directory.

AC_CONFIG_HEADER is used to generate the config.h file for use by autoheader.

AC_ARG_ENABLE defines a command-line option, formatted as:

AC_ARG_ENABLE (feature,

help-string

[, action-if-given

[, action-if-not-given]])

For example, if the option –enable-hello is defined, the parameters in AC_ARG_ENABLE are: feature is hello; the help-string can be [ –enable-hello Hello is present]; action-if-given is empty, meaning that when this option is present, enable_hello takes the default value of yes; action-if-not-given is enable_hello=no, meaning that when this option is absent, the value of enable_hello is no.

AC_DEFINE: Defines a macro.

AM_INIT_AUTOMAKE initializes automake. The parameters passed to this macro are the name and version number of the application to be compiled.

AC_OUTPUT: Sets the files to be generated by configure. If it is Makefile, configure will incorporate the results it checks into the Makefile.in file to produce the appropriate Makefile.

Note: The macros used in configure.in are of two types: those starting with AC, provided by autoconf, and those starting with AM, provided by automake.

Step 3: Run aclocal.

Run aclocal in the ts directory, which will generate the aclocal.m4 file and the autom4te.cache directory.

Automatically Generating Makefile Files

Step 4: Write acconfig.hAll macros used in configure.in should be declared in this file, generally using #undef to declare. The source code for acconfig.h is as follows:

#undef HELLO

That is, HELLO is undefined.Step 5: Run autoheaderautoheader will generate the config.h.in file based on configure.in and acconfig.h.Automatically Generating Makefile FilesStep 6: Write Makefile.amGenerally, there should be a Makefile.am in both the top-level directory and each subdirectory. The content for this example is:

Automatically Generating Makefile Files

The first line tells automake not to check for the existence of files like AUTHORS, README, etc. in the directory.The second line tells automake to process the src subdirectory. automake provides three software levels: foreign, gnu, and gnits, allowing users to choose. The default level is gnu. In this example, the foreign level is used, which only checks for necessary files. Define the name of the executable file to be generated. If multiple executable files are to be generated, separate each file name with a space.The content of the Makefile.am file in the src directory is as follows:

Automatically Generating Makefile Files

The first line serves the same purpose as before.The second line is the name of the target executable program.The third line lists the source programs and header files required to generate the ts executable file.Step 7: Run automakeNext, execute automake by entering automake -a in the command line.Step 8: Run autoconfExecuting autoconf will generate the final configure.

Automatically Generating Makefile Files

3. Testing

(1) Without the –enable-hello option

Automatically Generating Makefile Files

Note: Some screenshots

Automatically Generating Makefile Files

Automatically Generating Makefile Files

Automatically Generating Makefile Files

(2) With the –enable-hello option

Automatically Generating Makefile Files

Automatically Generating Makefile Files

4. Tar PackageNow, our small software has been tested and is ready for release. In the ts directory, there are many files, some of which we wrote ourselves, and some are temporary files generated during compilation. Which ones need to be packaged into the release package? Of course, you can select each file one by one, but the Autotools tools provide us with several extremely convenient functions for packaging. We can use make dist or make distcheck to generate the corresponding tar package, with the latter also helping us test whether the release package can work properly, so it is recommended to use make distcheck.Automatically Generating Makefile FilesAutomatically Generating Makefile FilesAs you can see, the release package ts-1.0.tar.gz has been placed in the ts directory. Did you notice that the software name and version number here are exactly the two parameters passed to AM_INIT_AUTOMAKE in configure.in! Now you can try to unpack and install it.

Leave a Comment