How do I create a configure script?
This may sound like a very generic question but here it goes. I have a requirement to create a configure script for my application, the result of this configure would be a generated makefile (basic configure , make , make install ). My question is, where do I start in building this? Is there an example I can follow?
4 Answers 4
To create the standard «configure» script you need GNU autoconf. You may need GNU automake and libtool too.
There are tons of documentation and howtos. Google for something like «autoconf automake howto». The good documentation is in the official manual pages:
- Autoconf: http://www.gnu.org/software/autoconf/
- Automake: http://www.gnu.org/software/automake/automake.html
- Libtool: http://www.gnu.org/software/libtool/libtool.html
Autoconf will create your configure script starting from the «configure.ac» file. The «Makefile.am» file will instruct automake on how to create your makefile by the configure string. Libtool is needed to simplify libraries handling around your code.
You can start creating a configure.ac file by hand or you may use the «autoscan» helper that may help you to create something semi-automatic for you.
Then, when you are ready, this one will do the magic:
GNU docs imply there could be other configure script tools : gnu.org/prep/standards/html_node/Makefile-Conventions.html , Are there any such other tools (apart from manual of course)?
Sometimes a software product will ship with no configure script. Look for an autogen.sh script. it will probably run:
aclocal || die "aclocal failed" automake --add-missing --force-missing --copy --foreign || die "automake failed" autoreconf || die "autoreconf failed"
All of these answers are about autoconf which is a GNU tool. However, configure shell scripts have been in UNIX long before GNU and can be created by hand or in other ways.
What does configure do?
configure is a just shell script. It’s job is to generate a list of configuration variables that the makefile needs to build the software on that particular system. For example, it might determine the linker flags and header search paths needed to include a specific library.
configure can also accept options from the user, for example to control whether to build in debug or release mode.
Typically configure writes these variables to a file called config.mk which is included by the makefile . It may also generate a header config.h with some preprocessor defines. Note that configure is just a helpful automation for producing this. The user can always just hand edit config.mk themselves (especially on obscure systems).
How does configure detect features?
configure uses a variety of techniques to locate dependencies and detect system or hardware features. The least stable (but sometimes necessary way) is to check the uname to detect and operating system. One useful tool is pkg-config which can tell you where to find various installed libraries.
Lastly, configure scripts can always generate small snippets of code, and then trying to compile them to see if a feature is available.
Joe Nelson has a great article with examples for each of these ideas.
Should I write my own configure or use autoconf?
Most programs only have 1 or 2 small things they need to detect to get working. I think it makes sense to write a configure script in these cases, rather than try to figure out corner cases of the massive piece of software that is autotools. If you product a simple config.mk it can always be fixed by hand, and users of various systems will be helpful in getting your configure to work correctly.
For more complex dependencies, autoconf is probably useful.
To be fair to all parties, let’s relate the argument made in autoconf ‘s documentation:
The primary goal of Autoconf is making the user’s life easier; making the maintainer’s life easier is only a secondary goal.
Autoconf is highly successful at its goal—most complaints to the Autoconf list are about difficulties in writing Autoconf input, and not in the behavior of the resulting configure. Even packages that don’t use Autoconf will generally provide a configure script, and the most common complaint about these alternative home-grown scripts is that they fail to meet one or more of the GNU Coding Standards (see Configuration in The GNU Coding Standards) that users have come to expect from Autoconf-generated configure scripts.
- your configure might not have all the commands some users expect.
- You might detect features incorrectly or using incorrect assumptions for example if macOS < use mac commands >else < use linux commands >, instead of if gnuTools < use gnu commands >else < use bsd/posix commands >.
You will have to determine whether that’s important to you.
Kconfig make config¶
This file contains some assistance for using make *config .
Use «make help» to list all of the possible configuration targets.
The xconfig (‘qconf’), menuconfig (‘mconf’), and nconfig (‘nconf’) programs also have embedded help text. Be sure to check that for navigation, search, and other general help text.
General¶
New kernel releases often introduce new config symbols. Often more important, new kernel releases may rename config symbols. When this happens, using a previously working .config file and running «make oldconfig» won’t necessarily produce a working new kernel for you, so you may find that you need to see what NEW kernel symbols have been introduced.
To see a list of new config symbols, use:
cp user/some/old.config .config make listnewconfig
and the config program will list any new symbols, one per line.
Alternatively, you can use the brute force method:
make oldconfig scripts/diffconfig .config.old .config | less
Environment variables for *config
KCONFIG_CONFIG¶
This environment variable can be used to specify a default kernel config file name to override the default name of «.config».
KCONFIG_DEFCONFIG_LIST¶
This environment variable specifies a list of config files which can be used as a base configuration in case the .config does not exist yet. Entries in the list are separated with whitespaces to each other, and the first one that exists is used.
KCONFIG_OVERWRITECONFIG¶
If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not break symlinks when .config is a symlink to somewhere else.
CONFIG_ ¶
If you set CONFIG_ in the environment, Kconfig will prefix all symbols with its value when saving the configuration, instead of using the default, CONFIG_ .
Environment variables for ‘config’
KCONFIG_ALLCONFIG¶
(partially based on lkml email from/by Rob Landley, re: miniconfig)
The allyesconfig/allmodconfig/allnoconfig/randconfig variants can also use the environment variable KCONFIG_ALLCONFIG as a flag or a filename that contains config symbols that the user requires to be set to a specific value. If KCONFIG_ALLCONFIG is used without a filename where KCONFIG_ALLCONFIG == «» or KCONFIG_ALLCONFIG == «1», make *config checks for a file named «all.config» (corresponding to the *config command that was used) for symbol values that are to be forced. If this file is not found, it checks for a file named «all.config» to contain forced values.
This enables you to create «miniature» config (miniconfig) or custom config files containing just the config symbols that you are interested in. Then the kernel config system generates the full .config file, including symbols of your miniconfig file.
This ‘KCONFIG_ALLCONFIG’ file is a config file which contains (usually a subset of all) preset config symbols. These variable settings are still subject to normal dependency checks.
KCONFIG_ALLCONFIG=custom-notebook.config make allnoconfig
Is there a configuration file for gnu make?
I want to tell make that it shall always use -j4 option even if I didn’t specify it vie command line. Normally i would do this in some configuration file (i.e. ~/.makerc ). Does such file exist for gnu make?
5 Answers 5
However this will likely interfere with recursive-make-based builds (not that sensible people are using recursive make anyway!), by interfering with GNU make’s ability to communicate with its sub-makes.
So the more sensible approach is probably a wrapper script or an alias or shell function.
Well, yes and no — normally you would use an include file. Put your common configuration items together in a file, say common.mk and add
at the top of your makefile. If the flag doesn’t have a matching way to configure it from inside the make file, you can use a function
as far as that goes, alias make=»make -j4″. But aliases are so relatively inflexible and shell functions so straightforward that I almost always use functions.
How straightforward are they, really? You even have an error in this one: if any of your parameters to mk contain spaces, $* breaks; use «$@» instead.
And unquoted $* breaks in another way: it does pathname expansion; e.g. mk ‘*’ . These breakages do matter, because while targets will almost never contain spaces, asterisks, brackets, or question marks, variables you pass to make («make CFLAGS=’-g -O2′ target») might.
It doesn’t exist, but you can do this by having a recursive call into make.
-include $(HOME)/.makerc .DEFAULT_GOAL: all # This will handle a default goal if make is just called without any target all: $(MAKE) $(MAKE_OPTIONS) -f Makefile.real $(MAKECMDGOALS) # This handles all targets and passes it through %: $(MAKE) $(MAKE_OPTIONS) -f Makefile.real $(MAKECMDGOALS)
I would like to expand a bit on the solution hinted in John Marshall’s answer.
You can simply put a one-line wrapper script somewhere earlier in the $PATH with the following contents:
#!/bin/bash $(type -ap make | sed -n 2p) -j4 "$@"
(The script doesn’t have to be named make , and that would make it simpler, but I find it convenient if it is.)
I would argue that this is better than the other approaches for the following reasons:
- Unlike MAKEFLAGS approach, it does not break recursive builds (which are actually quite common in my experience).
- Unlike include .makerc approach, it can be applied locally without changing any existing makefiles or your workflow in any way.
- Unlike shell alias or function approach, it is shell-agnostic (doesn’t tie you to any particular shell) and works in any additional build scripts that you might have to use, too, as long as you launch them in the same environment.