Programs on Linux install data for programs into $PREFIX/share/programname
, how does the program know where that is, does it n开发者_开发百科eed to be compiled in?
Would it be suitable to assume that the binary is in $PREFIX/bin
, and use that to determine $PREFIX
?
This only needs to work on Linux, and specifically, I am using C.
It depends entirely on the program. A common pattern is to define PREFIX as a preprocessor directive. GNU autoconf has standard names and allows them to be overridden at configure time.
As p00ya has pointed out, it depends on the program. I'd say most programs have a compile-time default, and some also use an environment variable to locate their data files; the environment variable technique can be handy if you're not distributing the sources of your software and you don't expect administrators or package maintainers to recompile it for their system. If you're planning on using an environment variable, you should probably generate wrapper scripts with the proper paths at install-time, or provide your users with appropriate instructions (i.e. what to add to their shell init script).
Lets take a hypothetical:
You are compiling the program
foo
that needs a version oflibfoo
that is newer than the one provided by the system. You lack adequate privileges to upgrade the systemlibfoo
, additionally the program wants to deposit files into /etc, where you don't have permission to write. How could you compile and install the program?
Most build configuration software offers a lot more than just --prefix
, many give you the ability to specify the system configuration location (--sysconfdir
), the location to look for shared libraries by default (--libdir
), the location to deposit compiled executables (--bindir
) and other 'all in one' shortcuts like --datarootdir
.
In fact:
tpost@tpost-desktop:~/Desktop/oss-projects/srce/srce.hg$ ./configure --help
`configure' configures SRCE 1.0.9 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print `checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for `--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or `..']
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc. You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.
For better control, use the options below.
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/srce]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
Optional Features and Packages:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--enable-unsafe enable unsafe operation [default=no]
--with-user specify the system user [default=root]
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
CPP C preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to <foo@foo.com>.
If a program is actually utilizing the build system configuration tool correctly, it allows you to fine tune each knob that dictates the build process. For instance, you might want --prefix to be /home, but use a location somewhere in /usr/share for a custom version of libfoo that root has deposited for people who can't use the system version for whatever reason.
Some of these paths are set when a program is linked
, not merely compiled, but yes they are a part of the resulting ELF object. Other files that are installed as plain text (i.e. config files, interpreted languages, etc) are either:
- Modified or generated en situ so that they contain the paths you specified
- Smart enough to search for the files that they need, given your PATH setting
- Smart enough to search for the files that they need, even outside of PATH (env variables usually come into play here)
Its usually a combination of the three.
Lets look at a dummy foo.ini.in
file that would be used to generate the real foo.ini:
[global]
output_path=@prefix@/var/spool
Which, if configured with --prefix=/home/sam would produce a foo.ini that looks like this:
[global]
output_path=/home/sam/var/spool
Note, the above is autoconf centric, but does illustrate the concept.
The other important thing to realize is that not all programs that use a build configuration tool actually use the preferences it allows you to set. I've seen a lot of programs that just obey the --prefix and --with-somelib / --without-somelib options that they add.
In short, not one behavior fits all, but that's a brief overview of how it usually works.
One of the files that autotools
creates is config.h
, and it's in here that the various paths are stored. You can customize config.h.in
to add additional paths for your application's use.
精彩评论