In what order are autotools invoked to create a build system? - c

I'm trying to use autotools to create a build system for a C program. However, after reading info automake, I'm still very confused about the order of which tools are invoked by the developer.
Let's think about a very simple hello world application. In the root dir of the application there is simple src/hello.c and nothing else. What tools need to be called in what order to create configure and a Makefile?
I figured out by myself (partially reading doc, partially just trying) that autoscan comes first and generates a "sketch" of the configure.ac. Then autoheader appearently creates a header file (why?). Next autoconf finally creates the configure script, which will ultimately create a config.h.
However, I am still missing a Makefile which I believe is created by automake, but this requires a Makefile.am which I don't know how to generate. Is this file generated at all or hand-written by the developer?

The functionality of the autotools tends to blur at the edges. There's a decent flow chart describing the ordering here. The Makefile.am is typically hand-written. Many projects keep a simple shell script at the top-level of the source tree, i.e., autogen.sh or initgen.sh. The autogen.sh I use:
#! /bin/sh
case `uname` in Darwin*) glibtoolize --copy ;;
*) libtoolize --copy ;; esac
aclocal -I m4 --install
autoheader
autoconf
automake --foreign --add-missing --force-missing --copy
This is still one of the best practical guides I've seen. I believe it's available in book form too.

Your Makefile.am should look something like
bin_PROGRAMS = hello
AUTOMAKE_OPTIONS = foreign
hello_SOURCES = src/hello.c
Run automake and it will create a Makefile.in

Related

How to build axis2c Unofficial source code

I have to create SOAP services in C using axis2C. But since axis2C is kind of not maintained properly as per this question, I have to use axis2C unofficial source code. But I could not see configure file to build the sources. How should I build this. I checked all the documentation both in here and in the github repo but no luck. All points to the axis2C official documentation. Should I copy the sources from unofficial to official code and try with the configure script in official folder ?
This project probably uses the GNU build system. In this system, ./configure is a portable shell script that is automatically generated from hand-written input files, the main file is configure.ac.
So, distribution packages of the source will contain ./configure, therefore enabling anyone on any platform with a sh-compatible shell and a make utility to build the software. But as it is a generated file, you will not find it in source-code repositories, e.g. on github.
To build a package using the GNU build system directly from source controls, you have to use the GNU autotools yourself to generate ./configure. In order to do this, install the following packages:
autoconf -- generates ./configure from ./configure.ac.
automake -- generates portable makefile templates Makefile.in from Makefile.am (those templates are then filled with values by the ./configure script to write the final Makefiles)
libtool -- tools for building dynamic shared objects on different platforms
Then, the command autoreconf -i given in the root of your source package should generate the ./configure script for you.
Note that there are packages providing a script ./autogen.sh (or similarly named). If this is there, you should call it instead of running autoreconf -i yourself, it might contain additional necessary preparation steps. ./autogen.sh will typically directly run the generated ./configure for you.

Automake error './ltmain.sh' not found

I've installed mingw and msys by using mingw-get-setup.exe. I've also installed Autotools(autoconf, automake,m4,libtool) into C:\/opt/autotools.
When I run automake, the following error always occurs:
configure.ac:11: error: required file './ltmain.sh' not found
If I copy ltmain.sh from libtool’s installed tree, execution will finish normally.
How can I configuure automake to find ltmain.sh without copying?
In an autoconf/automake/libtool project you need to run:
libtoolize: this copies/links a few support scripts, including ltmain.sh (which is the main component of libtool).
aclocal: this looks up all m4 macros that your configure script will need, and make a local copy for easier access.
autoheader: optional, if you want to use config.h/AC_CONFIG_HEADERS, otherwise all the test result macros will be inlined when you call the compiler.
autoconf: to expand all the macros used by configure.ac into the configure script.
automake: to convert all the Makefile.am into Makefile.in templates. You probably want to invoke this with --add-missing so additional support scripts can be linked/copied to your project (such as compile, missing, depcomp, test-driver, etc).
Don't worry about running each tool. Just invoke autoreconf -i and it'll run the tools that are needed. Add -v if you want to see what tools is being executed. To avoid mistakes, just put a script like this at the root of your project:
#!/bin/bash -x
mkdir -p m4
exec autoreconf --install "$#"
Users that checkout/clone the project directly from the source repository will need to run this ./bootstrap script at least once. This is not needed if the user got a tarball distribution.
Automake can take fairly good care of itself; it'll re-invoke the above tools when needed, when you run make. But if you generate a broken Makefile, you'll need to invoke ./bootstrap and ./configure again to generate new Makefiles.
As DanielKO stated, ltmain.sh is created by libtoolize.
However, what if it doesn't?
The following requirements need to be met:
configure.ac must exist and contain at least one of:
AM_PROG_LIBTOOL,AC_PROG_LIBTOOL,LT_INIT
(see function func_require_seen_libtool in /usr/bin/libtoolize)
If configure.ac does not contain a AC_CONFIG_AUX_DIR, libtoolize will look for a file called 'install-sh' or 'install.sh' in ., .. and ../.. and if found use that as "auxdir" and install ltmain.sh there (see function func_require_aux_dir inside libtoolize).
In my case, I was working on an "example project" in a subdirectory of another project, and the example project did not have a AC_CONFIG_AUX_DIR in its configure.ac; therefore libtoolize found the root of the parent project and installed ltmain.sh there instead of in the example project's root.

Makefile.in without Makefile.am in projects

In several projects I have seen the Makefile.in without Makefile.am . E.g. bash http://git.savannah.gnu.org/cgit/bash.git/tree/ and dtach http://dtach.cvs.sourceforge.net/viewvc/dtach/dtach/
I always thought that Makefile.in was generated by automake. Also with Makefile.am being a user written file I would not have thought it would be omitted from the code repository. In the bash source tree, the Makefile.in is far too big to be hand written and the Makefile.in in dtach also looks generated. How was the Makefile.in generated in projects like these two?
The libtool and automake autotools can be used independently of one another (or not at all), depending on what you need autoconf to do. Therefore, it's not required to use automake to generate Makefile.in.
The automake tool also conspicuously outputs that it has been used:
# Makefile.in generated by automake 1.11.1 from Makefile.am.
So it's likely that the Makefile.ins you have seen are edited "by hand".
A Makefile.in looks like a regular Makefile but usually it expects to be completed by the configure script (for example with the location of a library that the user has in a different directory).
Makefile.am is used by Automake to build such a Makefile.in. If the developers that made the package you're using already had a Makefile and writing a Makefile.am for it was too much effort they just converted it to a Makefile.in.

Autocreate directories when building

I have a project written in C and I am using mercurial (I can use git too) for version control and GNU make for building. The project includes several empty directories used for build-time generated files, such as dependency makefiles and object files.
When I check out the project, however, empty directories are not created (they are ignored by the version control system) and the build fails.
The only remedy I have in mind is to add a mkdir -p directive in every single recipe in the 58 makefiles of the project (it is quite big). Apart from a lot of editing, mkdir -p is discouraged in the GNU make manual for being incompatible with other versions of make.
Is there any smarter way to overcome the problem?
Both git and Mercurial track files, not directories, so empty directories will not be stored.
The common trick is to just add an empty file to the directories you need, like:
touch output/.empty
And then add that to the repository.
You can have:
output/%: output/.empty
output/.empty:
$(MKDIR_P) output
touch output/.empty
in the makefile. Than all files in output will depend on creating the directory without modifying each rule separately.
The $(MKDIR_P) definition (mkdir -p for most systems or a special script where that does not work) can be provided by configuration script (e.g. autoconf using AC_PROG_MKDIR_P) or conditional setting in the makefile.
As you mention that you could use git as well, maybe that you would be interested by the fact that bazaar can track directories the same way it does for files. I don't know if it is an option for you, just saying.

I need my Debian rules file to simply copy files to it's target

I have a large project where we have the following files:
A few 3rd party pre-compiled binaries
Our own in-house binaries
collection of Ruby scripts
A sizable Ruby on Rails project
This product will be installed on appliance hardware that my employer has already selected, using Ubuntu Linux (Lucid) as the target OS, with our goal of distributing the archive as a Debian package to ease installation and upgrades. Additionally, we have a number of ERB templates that we need to "fill-in" with appropriate values on a per-customer basis, so the use of the postinst script will be particularly handy for our purposes.
As a side note, the Debian packages will be stored on a server repository that we manage in-house.
At this stage, I have used dh_make to create the Debian directory and related files (e.g., rules, control, etc.), but the rules file that is generated seems like overkill for my purposes.
Based on this description, all I really need the "rules" file to do is simply copy files from a source directory (or within an archive) to the target directories shown below:
/opt/company_product/3rd_party_binaries/bin
/opt/company_product/3rd_party_binaries/etc
/opt/company_product/in_hourse_binaries/bin
/opt/company_product/in_hourse_binaries/etc
/opt/company_product/ruby
/opt/company_product/rails_project
/opt/company_product/etc
/opt/company_product/shared/logs
/opt/company_product/shared/tmp
/opt/company_product/shared/license
...and so on.
I've read the Debian Policy Manual and several How-To's which indicate that you should not alter the rules file to use mkdir to create directories and there is generally a dh_ app (e.g., dh_installdirs, et al) that can suit your needs for nearly any installation purposes. The man pages for these dh_ related apps are cursory at best, and I am an "example" kind of guy.
That said, I'm a little lost on what the best approach is to getting my rules file to install my various pre-compiled binaries and Ruby/Rails text files to the desired locations.
Here's my initial rules file. It's pretty much a standard boilerplate rules file that dh_make creates. My thinking is that I should comment out all sections except for the install and then find the appropriate command(s) to make directories, copy files, etc. within that section.
Any advice or suggestions are greatly appreciated.
#!/usr/bin/make -f
package = testapp
CC = gcc
CFLAGS = -g -Wall
ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O2
endif
#export DH_VERBOSE=1
clean:
dh_testdir
dh_clean
rm -f build
install: build
dh_clean
dh_installdirs
echo "Place the Install Script here"
cp $(CURDIR)/testapp-2.0.tar.gz $(CURDIR)/debian/$(package)/opt/testapp-2.0
echo "Finished copying folders"
build:
touch build
binary-indep: install
# There are no architecture-independent files to be uploaded
# generated by this package. If there were any they would be
# made here.
binary-arch: install
dh_testdir -a
dh_testroot -a
dh_installdocs -a
dh_installchangelogs -a
dh_strip -a
dh_compress -a
dh_fixperms -a
dh_installdeb -a
dh_shlibdeps -a
dh_gencontrol -a
dh_md5sums -a
dh_builddeb -a
binary: binary-indep binary-arch
.PHONY: binary binary-arch binary-indep clean checkroot
Although you've already got your own answer, I'll point out a couple of things.
You seem to be doing this in a very complicated manner. If you simply need to copy files into certain directories, write a debian/mypackagename.install with the following format:
path/to/file/relative/to/source/root path/to/install/relative/to/system/root
(do not prepend / before /usr, or /opt, or whatever your target directory is. Read man dh_install for more information)
Then your debian/rules can be:
#!/usr/bin/make -f
%:
dh $#
If you have some sort of makefile, etc in your source root, then append this to the above rules file:
override_dh_auto_build:
override_dh_auto_install:
Don't forget put 7 in debian/compat.
Also, you shouldn't install files into /opt/ or /usr/local/, etc. Those are meant for files not installed by Debian packages. Debian recommends installing in /usr/share/yourcompany/. As juzzlin points out below, the Ubuntu Software Center may have different requirements.
More specifically, your mypackage.install file should look like this:
src/bin/* usr/bin
src/etc/* etc/
You can install cdbs and change the rules file like this
#!/usr/bin/make -f
include /usr/share/cdbs/1/rules/debhelper.mk
binary-install/package_name::
mkdir debian/$(cdbs_curpkg)/destination_path
cp path_of_your_files debian/$(cdbs_curpkg)/destination_path

Resources