Incredibly, somehow everyone else missed the canonical way to do this, which has been around since 2 years before this thread began. :-)
I wondered the same thing as the OP and was disappointed by the lack of proper (non-ugly) ways to do this when I read this thread.
A few days later, while idly browsing release notes for Autoconf, I reached the release notes for Autoconf 2.65. And would you believe it?
Major changes in Autoconf 2.65 (2009-11-21) [stable]
[...]
config.status now provides a --config option to produce the configuration.
So, just running ./config.status --config does precisely what the OP asked for.
Here is the corresponding reference in the documentation: 17 config.status invocation, and a quote:
Answer from underscore_d on Stack Overflow
--configPrint the configuration settings in reusable way, quoted for the shell, and exit. For example, for a debugging build that otherwise reuses the configuration from a different build directory build-dir of a package in src-dir, you could use the following:
args=`build-dir/config.status --config` eval src-dir/configure "$args" CFLAGS=-g --srcdir=src-dir
Incredibly, somehow everyone else missed the canonical way to do this, which has been around since 2 years before this thread began. :-)
I wondered the same thing as the OP and was disappointed by the lack of proper (non-ugly) ways to do this when I read this thread.
A few days later, while idly browsing release notes for Autoconf, I reached the release notes for Autoconf 2.65. And would you believe it?
Major changes in Autoconf 2.65 (2009-11-21) [stable]
[...]
config.status now provides a --config option to produce the configuration.
So, just running ./config.status --config does precisely what the OP asked for.
Here is the corresponding reference in the documentation: 17 config.status invocation, and a quote:
--configPrint the configuration settings in reusable way, quoted for the shell, and exit. For example, for a debugging build that otherwise reuses the configuration from a different build directory build-dir of a package in src-dir, you could use the following:
args=`build-dir/config.status --config` eval src-dir/configure "$args" CFLAGS=-g --srcdir=src-dir
config.status has the options in it; ./config.status --recheck re-runs configure with the original options. You could interrupt that and reissue the command (which it will show you before running it), or you could edit config.status and add your new parameters to $ac_configure_extra_args.
I do kinda wish they'd made it easier to do this. Once upon a time head config.status would get you the original configure command. ./config.status --rerun extra args here would have been nice.
gcc - Compiling from source: What are the options for config script "build"? - Unix & Linux Stack Exchange
When compiling, can I use a file for ./configure options? - Unix & Linux Stack Exchange
unix - Why always ./configure; make; make install; as 3 separate steps? - Stack Overflow
Newbie wondering about settings.
Incredibly, somehow everyone else missed the canonical way to do this, which has been around since 2 years before this thread began. :-)
I wondered the same thing as the OP and was disappointed by the lack of proper (non-ugly) ways to do this when I read this thread.
A few days later, while idly browsing release notes for Autoconf, I reached the release notes for Autoconf 2.65. And would you believe it?
Major changes in Autoconf 2.65 (2009-11-21) [stable]
[...]
config.status now provides a --config option to produce the configuration.
So, just running ./config.status --config does precisely what the OP asked for.
Here is the corresponding reference in the documentation: 17 config.status invocation, and a quote:
Answer from underscore_d on Stack Overflow
--configPrint the configuration settings in reusable way, quoted for the shell, and exit. For example, for a debugging build that otherwise reuses the configuration from a different build directory build-dir of a package in src-dir, you could use the following:
args=`build-dir/config.status --config` eval src-dir/configure "$args" CFLAGS=-g --srcdir=src-dir
./configure --help
That will show you all options for that particular configure script.
Some are the same across all configure scripts produced by Autoconf (which is most of them, but not all); for instance --prefix is basically universal. Others are peculiar to the particular configure script.
To expand $HOME in your file you could use envsubst first (be aware this will expand any env variable). Then you could read the result into an array e.g. with zsh
args=(${(f)"$(< <(envsubst <infile))"})
or with bash
readarray -t args < <(envsubst <infile)
and then run
./configure "${args[@]}"
Alternatively, you could use tr to format the result as a single line of options preceded by ./configure, and pipe that to sh:
{ printf %s './configure '; tr '\n' ' ' <infile; } | sh
One way to do this is to use xargs, which turns whitespace-separated strings on stdin into command-line arguments. If your file is called switches, this would look like:
xargs ./configure < switches
This will not expand things like * or $VAR. If (as in your edit) you want these to be expanded, then there are a few approaches. We can simply create a command and pass it to sh:
xargs printf '%s ' ./configure < switches | sh
Or, if you have envsubst, this will expand variables (like ${HOME}) but not file globs (*):
envsubst < switches | xargs ./configure
Because each step does different things
Prepare(setup) environment for building
./configure
This script has lots of options that you should change. Like --prefix or --with-dir=/foo. That means every system has a different configuration. Also ./configure checks for missing libraries that should be installed. Anything wrong here causes not to build your application. That's why distros have packages that are installed on different places, because every distro thinks it's better to install certain libraries and files to certain directories. It is said to run ./configure, but in fact you should change it always.
For example have a look at the Arch Linux packages site. Here you'll see that any package uses a different configure parameter (assume they are using autotools for the build system).
Building the system
make
This is actually make all by default. And every make has different actions to do. Some do building, some do tests after building, some do checkout from external SCM repositories. Usually you don't have to give any parameters, but again some packages execute them differently.
Install to the system
make install
This installs the package in the place specified with configure. If you want you can specify ./configure to point to your home directory. However, lots of configure options are pointing to /usr or /usr/local. That means then you have to use actually sudo make install because only root can copy files to /usr and /usr/local.
Now you see that each step is a pre-requirement for next step. Each step is a preparation to make things work in a problemless flow. Distros use this metaphor to build packages (like RPM, deb, etc.).
Here you'll see that each step is actually a different state. That's why package managers have different wrappers. Below is an example of a wrapper that lets you build the whole package in one step. But remember that each application has a different wrapper (actually these wrappers have a name like spec, PKGBUILD, etc.):
def setup:
... #use ./configure if autotools is used
def build:
... #use make if autotools is used
def install:
... #use make all if autotools is used
Here one can use autotools, that means ./configure, make and make install. But another one can use SCons, Python related setup or something different.
As you see splitting each state makes things much easier for maintaining and deployment, especially for package maintainers and distros.
First, it should be ./configure && make && make install since each depends on the success of the former. Part of the reason is evolution and part of the reason is convenience for the development workflow.
Originally, most Makefiles would only contain the commands to compile a program and installation was left to the user. An extra rule allows make install to place the compiled output in a place that might be correct; there are still plenty of good reasons that you might not want to do this, including not being the system administrator, not want to install it at all. Moreover, if I am developing the software, I probably don't want to install it. I want to make some changes and test the version sitting in my directory. This becomes even more salient if I'm going to have multiple versions lying around.
./configure goes and detects what is available in the environment and/or is desired by the user to determine how to build the software. This is not something that needs to change very often and can often take some time. Again, if I am a developer, it's not worth the time to reconfigure constantly. More importantly, since make uses timestamps to rebuild modules, if I rerun configure there is a possibility that flags will change and now some of the components in my build will be compile with one set of flags and others with a different set of flags that might lead to different, incompatible behaviour. So long as I don't rerun configure, I know that my compilation environment remains the same even if I change my sources. If I rerun configure, I should make clean first, to remove any built sources to ensure things are built uniformly.
The only case where the three command are run in a row are when users install the program or a package is built (e.g., Debian's debuild or RedHat's rpmbuild). And that assumes that the package can be given a plain configure, which is not usually the case for packaging, where, at least, --prefix=/usr is desired. And pacakgers are like to have to deal with fake-roots when doing the make install part. Since there are lots of exceptions, making ./configure && make && make install the rule would be inconvenient for a lot of people who do it on a far more frequent basis!