@ -14,23 +14,209 @@
## added file header
##
MY_NAME = ${ 0 ##*/ }
PROJECT_PATH = $( pwd )
DEFAULT_PROJECT_NAME = ${ PROJECT_PATH ##*/ }
configure = 0
build = 0
overwrite = 0
rebuild = 0
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; ;
( --version| -v)
echo " $Id $" ;
exit; ;
( --help| -h) less <<EOF
SYNOPSIS
${ MY_NAME } [ --help| -h] [ --configure| -c]
OPTIONS
--configure, -c call ./configure after initialization
--build, -c build, call ./configure && make after initialization
--overwrite, -o overwrite all basic files ( bootstrap.sh, m4-macros)
--rebuild -r force rebuild of generated files, even if modified
--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 } -o " . You can also
remove and rebuild a single file by removing it from subversion,
just call "svn rm <file>" and " ${ MY_NAME } " to rebuild file "<file>" .
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++
<ou can access the readme by calling
${ DEFAULT_PROJECT_NAME } ::description( ) .
* ChangeLog: Your changelog is automatically maintained from
subversion history, using svn2cl. You don' t need to
care about.
* configure.ac: This file becomes very short and simple. You provide
the project name, the major and minor version. The
least version number is automatically taken from
subversion' s revision, so every checkin
automatically increments the least version
number. The following macros are supported:
* Enable C++: AX_USE_CXX
* Enable LibTool library creation: AX_USE_LIBTOOL
* Enable Scripts: AX_USE_SCRIPTS
* Enable Doxygen documentation generation: AX_USE_DOXYGEN
* Enable Debian packaging by calling "make deb" : AX_USE_DEBIAN_PACKAGING
* Not yet implemented: AX_USE_RPM_PACKAGING
* Enable C++ testing using CppUnit: AX_USE_CPPUNIT
* Enable C++ examples, i.e. for libraries: AX_BUILD_EXAMPLES
* Check for C++11 support: AX_CXX_COMPILE_STDCXX_11 ( see ax_cxx_compile_stdcxx_11.m4)
* Require a QT module: AX_REQUIRE_QT ( see ax_check_qt.m4)
* Optionally use a QT module: AX_CHECK_QT ( see ax_check_qt.m4)
* Require a module: AX_PKG_REQUIRE ( see ax_init_standard_project.m4)
* Check for an optional module: AX_PKG_CHECK ( see ax_init_standard_project.m4)
EXAMPLES: src/makefile.am in a QT project
In this example, you wrote the following files:
* ${ DEFAULT_PROJECT_NAME } .hxx - Qt Header file, passed to moc
* ${ DEFAULT_PROJECT_NAME } .cxx - C++ file containing main( )
* ${ DEFAULT_PROJECT_NAME } .ui - UI file
All rules are implicitely added, all you need to do is to add the
following definitions, most lines are generic:
bin_PROGRAMS = ${ DEFAULT_PROJECT_NAME }
${ DEFAULT_PROJECT_NAME } _MOCFILES = moc_${ DEFAULT_PROJECT_NAME } .cxx
${ DEFAULT_PROJECT_NAME } _UIFILES = ui_${ DEFAULT_PROJECT_NAME } .hxx
${ DEFAULT_PROJECT_NAME } _SOURCES = version.cxx version.hxx ${ DEFAULT_PROJECT_NAME } .cxx ${ DEFAULT_PROJECT_NAME } _MOCFILES ${ DEFAULT_PROJECT_NAME } _UIFILES
BUILT_SOURCES = \$ { ${ DEFAULT_PROJECT_NAME } _MOCFILES} \$ { ${ DEFAULT_PROJECT_NAME } _UIFILES}
EXTRA_DIST = \$ { ${ DEFAULT_PROJECT_NAME } _MOCFILES:moc_%.cxx= %.hxx} \$ { ${ DEFAULT_PROJECT_NAME } _UIFILES:ui_%.hxx= %.ui}
MAINTAINERCLEANFILES = makefile.in
EOF
exit; ;
( *) break; ;
esac
shift;
done
MY_NAME = ${ 0 ##*/ }
PROJECT_PATH = $( pwd )
DEFAULT_PROJECT_NAME = ${ PROJECT_PATH ##*/ }
HEADER = ' ## @id $Id$
HEADER = '## @id ' "\$Id\$" '
#
# This file has been added by '${MY_NAME}' on '$(date -R)'
# This file has been added by '${MY_NAME}' on '$(date +"%Y-%m-%d %H:%M %Z")'
# Feel free to change it or even remove and rebuild it, up to your needs
#
## 1 2 3 4 5 6 7 8
@ -77,18 +263,29 @@ checkdir() {
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 test -f " $1 " ; then # file already exists
if checkfile " $1 " && test $rebuild -eq 0 ; then # file already exists
return
fi
checkdir " $( dirname ${ 1 } ) "
@ -105,13 +302,19 @@ to() {
else
echo -e " \e[32msuccess\e[0m"
fi
run svn add " $1 "
run svn propset svn:keywords "Id" " $1 "
chmod $mode $1
if test $exists -eq 0; then
run svn add " $1 "
run svn propset svn:keywords "Id" " $1 "
fi
}
copy( ) {
if ! test -f " $1 " ; then
run cp " ${ 0 %/* } / $1 " " $1 "
if checkfile " $1 " && test $overwrite -eq 0; then
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
@ -119,11 +322,22 @@ copy() {
doxyreplace( ) {
echo -en " \e[1m-> doxyfile:\e[0m configure $1 ... "
if sed -i 's|\(^' " $1 " ' *=\) *|\1' " $2 " '|g' doc/doxyfile.in; then
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: sed -i 's|\(^'" $1 "' *=\) *|\1'" $2 "'|g' doc/doxyfile.in;\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
}
@ -147,12 +361,17 @@ AX_INIT_STANDARD_PROJECT
# requirements, uncomment, what you need:
#AX_USE_CXX
#AX_USE_LIBTOOL
#AX_USE_SCRIPTS
#AX_USE_DOXYGEN
#AX_USE_DEBIAN_PACKAGING
#AX_USE_RPM_PACKAGING
#AX_USE_CPPUNIT
#AX_BUILD_EXAMPLES
# qt features, uncomment, what you need:
#AX_CHECK_QT([QT], [QtCore QtGui QtNetwork], [QtWidgets])
#AM_CPPFLAGS="${AM_CPPFLAGS} -DQT_NO_KEYWORDS"
# create output
AC_OUTPUT
EOF
@ -160,17 +379,99 @@ EOF
exit 0
fi
PACKAGE_NAME = $( sed -n 's/.*m4_define *( *x_package_name *, *\([^ ]*\) *).*/\1/p' configure.ac)
echo " ${ HEADER } " | to --condition AX_USE_CXX src/makefile.am
echo " ${ HEADER } " | to --condition AX_USE_DOXYGEN doc/makefile.am
echo " ${ HEADER } MAINTAINERCLEANFILES = makefile.in " | to --condition AX_USE_CXX src/makefile.am
to --condition AX_USE_CXX src/version.hxx <<EOF
/*! @file
@id \$ Id\$
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
#include <string>
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 <code>what filename</code>
extern const std::string WHAT;
/// used for <code>ident filename</code>
extern const std::string IDENT;
}
EOF
to --condition AX_USE_CXX src/version.cxx <<EOF
/*! @file
@id $Id \$
*/
// 1 2 3 4 5 6 7 8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
#include <string>
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 <<EOF
${ HEADER } AM_CPPFLAGS = -I${ top_srcdir } /src -I${ top_builddir } /src
AM_LDFLAGS = -L${ top_builddir } /src/.libs
LDADD = -l${ PACKAGE_NAME }
MAINTAINERCLEANFILES = makefile.in
EOF
to --condition AX_BUILD_EXAMPLES examples/makefile.am <<EOF
${ HEADER } AM_CPPFLAGS = -I${ top_srcdir } /src -I${ top_builddir } /src
AM_LDFLAGS = -L${ top_builddir } /src/.libs
LDADD = -l${ PACKAGE_NAME }
MAINTAINERCLEANFILES = makefile.in
EOF
if testtag AX_USE_DOXYGEN && ! test -f doc/doxyfile.in; then
run doxygen -g doc/doxyfile.in
@ -183,27 +484,47 @@ if testtag AX_USE_DOXYGEN && ! test -f doc/doxyfile.in; then
doxyreplace INLINE_INHERITED_MEMB YES
doxyreplace MULTILINE_CPP_IS_BRIEF YES
doxyreplace TAB_SIZE 2
doxyreplace ALIASES '"id=\par File-ID\n" "copy=\par Copyright\n" "license=\par License\n" "classmutex=\par Reentrant:\nAccess is locked with class static mutex @c " "instancemutex=\par Reentrant:\nAccess is locked with per instance mutex @c " "mutex=\par Reentrant:\nAccess is locked with mutex @c "'
doxyreplace ALIASES '"id=\\par File-ID\\n"'
doxyadd ALIASES '"copy=\\par Copyright\\n"'
doxyadd ALIASES '"license=\\par License\\n"'
doxyadd ALIASES '"classmutex=\\par Reentrant:\\nAccess is locked with class static mutex @c "'
doxyadd ALIASES '"instancemutex=\\par Reentrant:\\nAccess is locked with per instance mutex @c "'
doxyadd ALIASES '"mutex=\\par Reentrant:\\nAccess is locked with mutex @c "'
doxyreplace ENABLE_PREPROCESSING YES
doxyreplace MACRO_EXPANSION YES
doxyadd PREDEFINED '"NAMESPACE=@PACKAGE_NAME@"'
doxyreplace BUILTIN_STL_SUPPORT YES
doxyreplace DISTRIBUTE_GROUP_DOC YES
doxyreplace EXTRACT_ALL YES
doxyreplace EXTRACT_PACKAGE YES
doxyreplace EXTRACT_PRIVATE YES
doxyreplace EXTRACT_STATIC YES
doxyreplace EXTRACT_LOCAL_CLASSES YES
doxyreplace EXTRACT_LOCAL_METHODS YES
doxyreplace EXTRACT_ANON_NSPACES YES
doxyreplace SHOW_GROUPED_MEMB_INC YES
doxyreplace SORT_MEMBERS_CTORS_1ST YES
doxyreplace WARN_IF_UNDOCUMENTED NO
doxyreplace WARN_LOGFILE doxygen.errors
doxyreplace INPUT "@top_srcdir@/src"
if testtag AX_USE_SCRIPTS; then
doxyadd INPUT "@top_srcdir@/scripts"
fi
if testtag AX_USE_CPPUNIT; then
doxyadd INPUT "@top_srcdir@/test"
fi
doxyreplace FILE_PATTERNS '*.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.idl *.ddl *.odl *.h *.hh *.hxx *.hpp *.h++ *.cs *.d *.php *.php4 *.php5 *.phtml *.inc *.m *.markdown *.md *.mm *.dox *.py *.f90 *.f *.for *.tcl *.vhd *.vhdl *.ucf *.qsf *.as *.js'
doxyadd FILE_PATTERNS *.wt
doxyreplace RECURSIVE YES
doxyreplace EXCLUDE_PATTERNS "moc_* uic_* qrc_*"
if testtag AX_BUILD_EXAMPLES; then
doxyreplace EXAMPLE_PATH @top_srcdir@/examples
fi
doxyreplace EXAMPLE_RECURSIVE YES
doxyreplace FILTER_PATTERNS '*.wt=doxygen-webtester.sed'
doxyreplace SOURCE_BROWSER YES
doxyreplace INLINE_SOURCES YES
doxyreplace GENERATE_TESTLIST YES
doxyreplace GENERATE_TREEVIEW NO
doxyreplace SEARCHENGINE YES
doxyreplace GENERATE_HTML YES
@ -237,8 +558,7 @@ Maintainer: @AUTHOR@
Build-Depends: debhelper, pkg-config, autotools-dev, lsb-release $( if testtag AX_USE_DOXYGEN; then echo -n ", doxygen, graphviz" ; fi ; if testtag AX_USE_CPPUNIT; then echo -n ", libcppunit-dev" ; fi ; if testtag AX_CXX_QT || testtag AX_CXX_CHECK_QT; then echo -n ", qtbase5-dev | libqt4-dev, qtbase5-dev-tools | qt4-dev-tools" ; fi )
Package: @PACKAGE_NAME@
$( if testtag AX_USE_LIBTOOL; then echo "Section: libs" ; fi )
Architecture: any
$( if testtag AX_USE_LIBTOOL; then echo "Section: libs" ; fi ) Architecture: any
Depends: \$ { shlibs:Depends} , \$ { misc:Depends}
Description: @DESCRIPTION@
@README_DEB@
@ -258,29 +578,18 @@ EOF
NEWS
README
EOF
to debian/${ PACKAGE_NAME } .install <<EOF
usr/bin/*
to --condition AX_USE_LIBTOOL debian/${ PACKAGE_NAME } .install <<EOF
usr/lib/lib*.so.*
$( if ! testtag AX_USE_LIBTOOL; then echo " usr/share/doc/ ${ PACKAGE_NAME } /html " ; fi )
EOF
to debian/${ PACKAGE_NAME } .dirs <<EOF
usr/lib
EOF
if testtag AX_USE_LIBTOOL; then
to debian/${ PACKAGE_NAME } -dev.install <<EOF
to --condition AX_USE_LIBTOOL debian/${ PACKAGE_NAME } -dev.install <<EOF
usr/include/*
usr/lib/lib*.a
usr/lib/lib*.so
usr/lib/pkgconfig/*
usr/lib/*.la
$( if testtag AX_USE_LIBTOOL; then echo " usr/share/doc/${ PACKAGE_NAME } /html" ; fi )
usr/share/doc/${ PACKAGE_NAME } /html
EOF
to debian/${ PACKAGE_NAME } -dev.dirs <<EOF
usr/lib
usr/include
EOF
fi
to debian/rules <<EOF
to --mode "u=rwx,g=rwx,o=rx" debian/rules <<EOF
${ HEADER } %:
dh \$ @
EOF
@ -288,10 +597,10 @@ EOF
fi
if ! test -f makefile.am; then
SUBDIRS = ""
for d in src test doc examples; do
for d in src test scripts doc examples; do
test -d $d && SUBDIRS = " ${ SUBDIRS } $d "
done
echo " ${ HEADER } SUBDIRS = ${ SUBDIRS } " | to makefile.am
echo " ${ HEADER } SUBDIRS = ${ SUBDIRS } \n\nMAINTAINERCLEANFILES = makefile.in " | to makefile.am
fi
to --condition AX_USE_LIBTOOL src/${ PACKAGE_NAME } .pc.in <<EOF
${ HEADER } prefix = @prefix@
@ -321,3 +630,8 @@ run autoconf
if test " $configure " -eq 1; then
./configure $*
fi
#### Run Make If User Requires ####
if test " $build " -eq 1; then
make
fi