#! /bin/bash
## @file
##
## $Id$
##
## $Date$
## $Author$
##
## @copy © Marc Wäckerlin
## @license LGPL, see file COPYING
##
## $Log: bootstrap.sh,v $
## Revision 1.3 2004/08/31 15:57:19 marc
## added file header
##
MY_NAME=${0##*/}
PROJECT_PATH=$(pwd)
DEFAULT_PROJECT_NAME=${PROJECT_PATH##*/}
configure=0
build=0
overwrite=0
rebuild=0
rebuildfiles=()
while test $# -gt 0; do
case "$1" in
(--configure|-c) configure=1;;
(--build|-b) configure=1; build=1;;
(--overwrite|-o) overwrite=1;;
(--rebuild|-r) rebuild=1;;
(--rebuild-file|-f) shift; rebuildfiles+=("$1");;
(--version|-v)
echo "$Id$";
exit;;
(--help|-h) less < rebild specific file (can be added multiple times)
--help, -h show this help
--version, -v show version and date of this file
DESCRIPTION
Initializes your build environment, as far as neccessary. Reads your
used features from configure.ac, if that file exists, or creates a
configure.ac. Automatically copies or creates all required template
files.
From your new and empty project's subversion path, call $0 to
initialize your build environment.
Before you call ${MY_NAME} the very first time, edit ${0#/*}/AUTHORS
and replace it with your name (or the authors of your project, one
name each line, main developper and copyright holder on the first
line).
The first call to ${MY_NAME} should be something like
../bootstrap-build-environment/${MY_NAME} and not
./${MY_NAME}. Actually, you called $0.
In the way you called ${MY_NAME}, it has detected
${DEFAULT_PROJECT_NAME} as the project name for your project in
${PROJECT_PATH}. In the first run, you should call ${MY_NAME} from a
checked out the bootstrap-build-environment from
https://dev.marc.waeckerlin.org/, and the path from where you call
${MY_NAME} (which is actually ${PROJECT_PATH}) should be the path to
your newly created project. Please note that your project must be a
checked out subversion repository, since this build environment
relies on subversion.
Example for an initial run, where your new projet is stored in
subversion on svn:/path/to/your/new-project:
cd ~/svn
svn co https://dev.marc.waeckerlin.org/svn/bootstrap-build-environment/trunk \\
bootstrap-build-environment
svn co svn:/path/to/your/new-project/trunk new-project
cd new-project
../bootstrap-build-environment/bootstrap.sh
RUNNING
If you run ${MY_NAME}, it first generates the necessary files (see
below), then first runs make distclean if a makefile exists. After
this it calles aclocal, libtoolize, automake, autoconf and
optionally ./configure.
GENERATED FILES
This script copies the following files into your project environment:
* ${MY_NAME}
* ax_init_standard_project.m4 - auxiliary macro definition file
* ax_cxx_compile_stdcxx_11.m4 - auxiliary macro definition file
* ax_check_qt.m4 - auxiliary macro definition file
* AUTHORS - replace your name in AUTHORS before first run
* configure.ac - global configuration file template
* makefile.am - global makefile template
* src/makefile.am - if you enabled AX_USE_CXX
* src/version.hxx - if you enabled AX_USE_CXX
* src/version.cxx - if you enabled AX_USE_CXX
* scripts/makefile.in - if you enabled AX_USE_SCRIPTS
* doc/makefile.am - if you enabled AX_USE_DOXYGEN
* doc/doxyfile.in - if you enabled AX_USE_DOXYGEN
* test/makefile.am - if you enabled AX_USE_CPPUNIT
* examples/makefile.am - if you enabled AX_BUILD_EXAMPLES
* debian/changelog.in - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/control.in - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/docs - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/${DEFAULT_PROJECT_NAME}.install - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/${DEFAULT_PROJECT_NAME}.dirs - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/${DEFAULT_PROJECT_NAME}-dev.install - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/${DEFAULT_PROJECT_NAME}-dev.dirs - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/rules - if you enabled AX_USE_DEBIAN_PACKAGING
* debian/compat - if you enabled AX_USE_DEBIAN_PACKAGING
* src/${DEFAULT_PROJECT_NAME}.pc.in - if you enabled AX_USE_LIBTOOL
REBUILDING FILES
To rebuild all these files, just run "${MY_NAME} -r".
To copy only the files provided by this package, that means those
files you must never change, that means to update the build system
to the latest release, run "${MY_NAME} -o"
You can also rebuild a list of singleany list of specific file files
by adding option "${MY_NAME} -f " to rebuild file
"". You can add option "-f" more than once.
FILES TO EDIT
After creation of the files, you can edit them according to your
needs. Please don't forget to redo your edits after rebuilding a
file. Most files don't even need to be edited, they work out of the
box.
The following files normally require editing:
* AUTHORS
* README
* configure.ac
* src/makefile.am
* test/makefile.am
* examples/makefile.am
FILE DEPENDENCIES
You should rebuild (see above) the files, whenever you change the
configuration a dependent, i.e.:
* test/makefile.am depends on AX_USE_LIBTOOL
* doc/doxyfile.in depends on AX_BUILD_EXAMPLES
* debian/control.in depends on AX_USE_DOXYGEN, AX_USE_CPPUNIT,
AX_CXX_QT, AX_CXX_CHECK_QT, AX_USE_LIBTOOL
* debian/${DEFAULT_PROJECT_NAME}.install depends on AX_USE_LIBTOOL
* debian/${DEFAULT_PROJECT_NAME}.dirs depends on AX_USE_LIBTOOL
* debian/${DEFAULT_PROJECT_NAME}-dev.install depends on AX_USE_LIBTOOL
* debian/${DEFAULT_PROJECT_NAME}-dev.dirs depends on AX_USE_LIBTOOL
FILES
* AUTHORS: First line is the main author and used in Debian and RPM
packaging, so there must be a GPG key that matches
to this line.
* README: First line is a short description of your project, then an
empty line must follow. All remaining lines are a
long description of your project. this information
is copied, e.g. in Debian or RPM packages. In C++
running:\e[0m $* ..."
result=$($* 2>&1)
res=$?
if test $res -ne 0; then
if test $check -eq 1; then
echo -e " \e[31merror\e[0m"
echo -e "\e[1m*** Failed with return code: $res\e[0m"
if test -n "$result"; then
echo "$result"
fi
exit 1
else
echo -e " \e[33mignored\e[0m"
fi
else
echo -e " \e[32msuccess\e[0m"
fi
}
testtag() {
egrep -q '^ *'"$1" configure.ac
}
contains() {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
checkdir() {
if ! test -d "$1"; then # create path
run mkdir -p "$1"
run svn add "$1"
fi
}
checkfile() {
exists=0
if test -f "$1"; then
exists=1
fi
test $exists -eq 1
}
to() {
while test $# -gt 0; do
mode="u=rw,g=rw,o=r"
case "$1" in
(--condition) shift # test for a tag, abort if not set
if ! testtag "$1" configure.ac; then
return
fi;;
(--mode) shift # test for a tag, abort if not set
mode="$1";;
(*) break;;
esac
shift;
done
if checkfile "$1" && test $rebuild -eq 0 \
&& ! contains "$1" "${rebuildfiles[@]}"; then
# file already exists and must not be rebuilt
return 1
fi
checkdir "$(dirname ${1})"
echo -en "\e[1m-> generating:\e[0m $1 ..."
result=$(cat > "$1" 2>&1)
res=$?
if test $res -ne 0; then
echo -e " \e[31merror\e[0m"
echo -e "\e[1m*** Failed with return code: $res\e[0m"
if test -n "$result"; then
echo "$result"
fi
exit 1
else
echo -e " \e[32msuccess\e[0m"
fi
chmod $mode $1
if test $exists -eq 0; then
run svn add "$1"
run svn propset svn:keywords "Id" "$1"
fi
return 0
}
copy() {
if checkfile "$1" && test $overwrite -eq 0 \
&& ! contains "$1" "${rebuildfiles[@]}"; then
# file already exists and must not be rebuilt
return
fi
run cp "${0%/*}/$1" "$1"
if test $exists -eq 0; then
run svn add "$1"
run svn propset svn:keywords "Id" "$1"
fi
}
doxyreplace() {
echo -en "\e[1m-> doxyfile:\e[0m configure $1 ..."
if sed -i 's|\(^'"$1"' *=\) *.*|\1'" $2"'|g' doc/doxyfile.in; then
echo -e " \e[32msuccess\e[0m"
else
echo -e " \e[31merror\e[0m"
echo -e "\e[1m**** command: $0 $*\e[0m"
exit 1
fi
}
doxyadd() {
echo -en "\e[1m-> doxyfile:\e[0m configure $1 ..."
if sed -i '/^'"$1"' *=/a'"$1"' += '"$2" doc/doxyfile.in; then
echo -e " \e[32msuccess\e[0m"
else
echo -e " \e[31merror\e[0m"
echo -e "\e[1m**** command: $0 $*\e[0m"
exit 1
fi
}
# Initialize the environment:
copy ${MY_NAME}
copy ax_init_standard_project.m4
copy ax_cxx_compile_stdcxx_11.m4
copy ax_check_qt.m4
copy AUTHORS
to configure.ac <
namespace NAMESPACE {
/// get package string which consists of package name and package version
std::string package_string();
/// get package name
std::string package_name();
/// get package version
std::string version();
/// get code build date
std::string build_date();
/// get author, i.e. copyright holder
std::string author();
/// get short package description (1st line of README)
std::string description();
/// get long package description (starting at 3rd line in README)
std::string readme();
/// get package logo file name
std::string logo();
/// get package icon file name
std::string icon();
/// used for what filename
extern const std::string WHAT;
/// used for ident filename
extern const std::string IDENT;
}
EOF
to --condition AX_USE_CXX src/version.cxx <
namespace NAMESPACE {
std::string package_string() {
return PACKAGE_STRING;
}
std::string package_name() {
return PACKAGE_NAME;
}
std::string version() {
return PACKAGE_VERSION;
}
std::string build_date() {
return BUILD_DATE;
}
std::string author() {
return AUTHOR;
}
std::string description() {
return DESCRIPTION;
}
std::string readme() {
return README;
}
std::string logo() {
return PROJECT_LOGO;
}
std::string icon() {
return PROJECT_ICON;
}
const std::string WHAT("#(@) " PACKAGE_STRING);
const std::string IDENT("\$Id: " PACKAGE_STRING);
}
EOF
echo "${HEADER}MAINTAINERCLEANFILES = makefile.in" | to --condition AX_USE_SCRIPTS scripts/makefile.am
echo "${HEADER}MAINTAINERCLEANFILES = makefile.in" | to --condition AX_USE_DOXYGEN doc/makefile.am
to --condition AX_USE_CPPUNIT test/makefile.am <