Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / linker

Jerry and Maaza: Romancing Autotools

5.00/5 (1 vote)
10 Apr 2016CPOL9 min read 11.6K  
What is missing in articles on the Internet about Autotools is the cue of how they all fit together in a simple and concise manner. You will have less of a hard time following the story if, like Jerry, you have some knowledge about Makefiles and compiler, linker, and preprocessor options.

A Day At Work

So, Jerry had released his labor of love the C++ project in open-source. One can only imagine the smile on his face to learn that the astronauts that were sent to the Far Galaxy were interested in obtaining this application. His application, TimeTravel, requires little advertising; it is good. No other application does what TimeTravel does. One of the astronauts used up for two and a half hours the small bandwidth they had on the spaceship to download TimeTravel. But, he was not able to install it on his Linux PC. He got an error of a missing file during compilation. What a disappointment! Some other people who tried so hard to install the program but could not, have traced down Jerry's personal email and inundated him in enraged messages. He does not remember including his email address in any of the documentation in TimeTravel; nevertheless, indignant customers managed to find him. An angry mob started forming outside.

“Knock, knock!”

It was Maaza who was announcing her arrival in a soft, angelic voice. Jerry quickly came out of his daydreaming. Maaza's company has always been welcome. Her ever pristine looks lead Jerry to wonder how many hours she spends to get ready in the morning. Surprisingly, she is the first one to arrive at the office. Once or twice, he sighted her at the gym; she did not look like she would cut corners when it comes to taking care of her body. First impressions are the ones that last, as they say it. Jerry's first encounter of Maaza was through her resume when he was asked by the boss to evaluate candidates for a software engineering opening. Maaza's stellar achievements as a student did not land her the job at the time, for lack of experience, but she persisted in applying for other positions.

“You said you brought in the flash drive? Is that what you said over IM?”

“Yes, Maaza. I did bring it in,” responded Jerry. “I appreciate your help. The last thing I want is to put in the public domain an untested product.”

Like most other men his age, Jerry found himself goofing around to impress the opposite sex with his humor. “You know, I would not want angry villagers coming after me with torches and forks,” he said. Maaza gave away her smile, and Jerry could not ask for more.

“I will take a look at it this evening. But, I am sure you have already covered all the basics,” Maaza replied. She turned over and started walking back to her desk.

“Talk to you later, then.”

The Evening At Home

The summer's evening was still young when Jerry picked up his cell phone to call Maaza. “Hey Maaza, what's up? Do you have TimeTravel up and running already?”

“Been struggling with it for about one hour, can't install. I think it is because I am missing a couple of shared libraries.”

Maaza is a respectable Linuxian; Jerry knew better than to ask her if she overlooked some small things. If she was not able to install it effortlessly, he knew most people would find it even harder. “Here, let's continue this conversation over IM,” he said. “I am also going to send you a patch. I have made a couple of changes.”

“You have a patch?” questioned Maaza, but she did not even wait for an answer. “So, what is the version number of the one that you gave me this morning?”

“I didn't think I would need a version number, I do not intend to maintain it once it is out there, you know,” explained Jerry.

“Well, you're kind of maintaining it right now, though,” remarked Maaza. “I am going to send you instructions on how to do these things using Autotools.”

A Little Chitchat

A couple of minutes elapsed until Maaza's IM status turned on.

Jerry:
Hello again!
Maaza:
Okay, we will go over it step by step. First, create a file called configure.ac in the root directory of your project. I am seeing that you have named your root directory as timetravel_src, so put configure.ac in timetravel_src.
Jerry:
What is configure.ac? What is it used for?
Maaza:
Before I tell you how you can use configure.ac, I guess, I should first inform you about Autotools. This is just a collective name for the three programs: Autoconf, Automake, and Libtool. Autoconf is a collection of M4 macros that eventually produce a shell script called configure. This script is run on the target machine to test the resident operating system and settings. Automake is a program that takes in files called Makefile.am and produces files called Makefile.in. Compiler and linker options as well as header files and target source files are specified in Makefile.ac. Libtool helps make uniform the creation of shared libraries among different operating systems. All of these programs are coordinated by the configure script which is made, remember, using the template in configure.ac.
Jerry:
I believe I have seen Automake being used before, but my question to you is where regular, good-old Makefiles fit in this picture. Check out this article ...
http://www.codeproject.com/Articles/31488/Makefiles-in-Linux-An-Overview
Maaza:
I know you have quite a few Makefiles in your source package, but what you want is configurable Makefiles. I am certain your Makefiles work on your machine because you made sure that they work with the environment, settings, and libraries on your machine; no guarantees, though, that my machine will have those settings and libraries. So you need to make your Makefiles configurable to my setup. The least you can do is have your package check if the settings on my machine are what it needs for a successful build and install. Remember what I said earlier about Makefile.in's? When configure script runs, it replaces certain elements in Makefile.in files to produce the final, well-configured Makefiles.
Jerry:
This is getting interesting by the minute. I have created configure.ac. What do I do next?
Maaza:
You know what? I should just show you one of my configure.ac files. It will be easier for the discussion rather than have you type all that goes in configure.ac.
Jerry:
Always thoughtful, Maaza. Thank you.
 

Maaza picked up a configure.ac file that she uses for one of her C++ projects, made some quick changes, and sent it to Jerry.

## timetravel_src/configure.ac
	############# initializing project with version number
	##package_name = timetravel
	##version_number = 1.0.0
	##bug_report_email_address = username@domain.com
	##AC_INIT(package_name, version_number, bug_report_email_address)
	AC_INIT([timetravel], [1.0.0], [username@domain.com])
	############## initializing Automake
	AM_INIT_AUTOMAKE
	############## initializing libtool
	LT_INIT
	############## checking programs
	##checking C++ compiler
	AC_PROG_CXX
	##checking C Preprocessor
	AC_PROG_CPP
	##checking C compiler
	AC_PROG_CC
	############## checking libraries
	AC_CHECK_LIB([pthread], [main])
	############## checking header files
	AC_CHECK_HEADERS([stdlib.h stringstrings.h sys/socket.h sys/time.h])
	############## generating output makefiles from input
	AC_CONFIG_FILES(Makefile ttravel/Makefile)
	AC_OUTPUT
Maaza:
I have commented the steps, but, generally speaking, these are the macros that you might need for being able to adapt to a target system. As you can see, I started with AC_INIT to give a package name and version number to the project, I did some checking for some programs, libraries, and headers. I closed out by specifying the Makefiles I need created. Of course, a whole lot of other macros can go in between these. For a comprehensive list, just look in Automake: General Index in gnu.org.
Jerry:
Wait—is this it? What about the Makefiles?
Maaza:
Okay, will explain Makefile.am as well. I said earlier on that configure.ac takes in M4 macros. Well, you can put anything from M4 macros to Linux shell commands in configure.ac and Makefile.am files, but in Makefile.am we primarily use variables that Automake correctly interprets for the desired effect. Automake variables are assigned by values to create Libtool libraries, archive libraries, executables, and so on. They are also used to indicate the destination directory where these binaries will be installed. Each of these variables has two components separated by underscore: the primary variable and the directory variable. For example, in bin_PROGRAMS, PROGRAMS is the primary telling us it will be used to generate executables, and bin is the destination directory--more specifically, $(prefix)/bin. By default, $(prefix) resolves to /usr/local, but like many things in Autotools, that is also configurable and can be changed to somewhere else like /usr/ttravel. The other variables that you might be interested to look at are: lib_LIBRARIES and lib_LTLIBRARIES. As you can guess, LIBRARIES is used for static .a libraries and LTLIBRARIES for Libtool generated .la shared libraries.
## timetravel_src/ttravel/Makefile.am
	AM_CXXFLAGS = -g -std=c++11 -Wall -pedantic
	############# two static libraries
	noinst_LIBRARIES = libairports.a libtrainstations.a
	##the two share mi_distance.cpp in common
	libairports_a_SOURCES = mi_distance.cpp mi_flightduration.cpp
	libairports_a_CPPFLAGS = -I../ttravel_headers
	libtrainstations_a_SOURCES = mi_distance.cpp mi_trainstops.cpp
	libtrainstations_a_CPPFLAGS = -I../ttravel_headers
	############# an lt library
	lib_LTLIBRARIES = ttravel.la
	libttravel_la_SOURCES = ttravel.cpp
	libttravel_la_CPPFLAGS = -I../ttravel_headers
	libttravel_la_LIBADD = libairports.a libtrainstations.a
	############# an executable
	bin_PROGRAMS = ttravel
	ttravel_SOURCES = ttravel_main.cpp
	ttravel_CPPFLAGS = -I../ttravel_headers
	ttravel_LDADD = ttravel.la
	ttravel_LDFLADS = -lpthread
Jerry:
I know what is going on here. You are setting AM_CXXFLAGS for the whole Makefile whereas ttravel_CPPFLAGS, libttravel_la_CPPFLAGS, libairports_a_CPPFLAGS, and libtrainstations_a_CPPFLAGS are getting set for the individual targets, right?
Maaza:
Exactly right! Sorry to drop a bomb on you like that. Well, as you can see, target_SOURCES is the variable that takes in the source files for that particular target; the rest seems to me self-explanatory. But, pay attention to the use of _LIBADD, _LDADD, and _LDFLAGS. The difference between _LIBADD and _LDADD is that _LIBADD joins components of a library and _LDADD is passed to the linker to produce an executable program. Linker should be set in _LDFLAGS, and if you have noticed, we checked for pthread in configure.ac, and now link against it.
Jerry:
You are amazing. Thank you!
Maaza:
One last thing—you need to create another Makefile.am in timetravel_src. This is going to be the first Makefile.am that configure.ac finds. This Makefile.am should contain a macro for recursive building. All you need is a one liner that says SUBDIRS = ttravel. You know, you cannot really have two Makefiles in the same directory for the simple reason that you cannot name them uniquely. So, we can refer to a Makefile by the directory which it resides. Now, I can just say that when you run the timetravel_src Makefile, the one in timetravel_src/ttravel will be executed first.
Maaza:
Having sorted all this out what is left to to is to run Autoconf, Automake, and Libtool in the right order. We have a command for that, In a terminal, navigate to timetravel_src where you have configure.ac and Makefile.am. Enter following command
autoreconf
This command will give you all of your Makefile.ins and the configure script.
All that the customer has to do after that is run
./configure<br />
make<br />
make install
Jerry:
I do not know how to thank you except to take out for dinner. Would that make your Account Manager “boyfriend” jealous? lol
Maaza:
That joke is getting a little too old. We had dinner that evening because we both stayed late to finish work.
Jerry:
But, you also went to the movies after that.
Maaza:
Strictly platonic!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)