#! /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 buildtarget="distcheck" overwrite=0 rebuild=0 rebuildfiles=() while test $# -gt 0; do case "$1" in (--configure|-c) configure=1;; (--build|-b) configure=1; build=1;; (--target|-t) shift; configure=1; build=1; buildtarget="$1";; (--overwrite|-o) overwrite=1;; (--rebuild|-r) rebuild=1;; (--rebuild-file|-f) shift; rebuildfiles+=("$1");; (--version|-v) echo "$Id$"; exit;; (--help|-h) less < same as -b, but specify target instead of distcheck --overwrite, -o overwrite all basic files (bootstrap.sh, m4-macros) --rebuild, -r force rebuild of generated files, even if modified --rebuild-file, -f 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 * resolve-debbuilddeps.sh - script to install debian package dependencies * resolve-rpmbuilddeps.sh - script to install RPM package dependencies * build-resource-file.sh - build resource.qrc file from a resource directory * mac-create-app-bundle.sh - script to create apple mac os-x app-bundle * AUTHORS - replace your name in AUTHORS before first run * NEWS - empty file add your project's news * README - add project description (first line is header, followed by an empty line) * 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 * html/makefile.am - if you enabled AX_BUILD_HTML * 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 * ${DEFAULT_PROJECT_NAME}.spec.in - if you enable AX_USE_RPM_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 * NEWS * README * configure.ac * src/makefile.am * html/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 * html/makefile.am depends on AX_BUILD_HTML * doc/doxyfile.in depends on AX_BUILD_EXAMPLES * debian/control.in depends on AX_USE_DOXYGEN, AX_USE_CPPUNIT, AX_CXX_QT, AX_CHECK_QT, AX_REQUIRE_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 * ${DEFAULT_PROJECT_NAME}.spec.in depends on AX_USE_RPM_PACKAGING, AX_USE_LIBTOOL, AX_CHECK_QT, AX_REQUIRE_QT, AX_CXX_QT, AX_USE_CPPUNIT 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. * NEWS: File to add project news. * 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() { local IFS="|" egrep -q '^ *'"($*)" 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"; 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 -o "$1" = "configure.ac" \ && ! 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 resolve-debbuilddeps.sh copy resolve-rpmbuilddeps.sh copy build-resource-file.sh copy mac-create-app-bundle.sh AUTHOR=$(gpg -K | sed -n 's,uid *,,p' | sort | head -1) if test -z "${AUTHOR}"; then AUTHOR="FIRSTNAME LASTNAME (URL) " fi to AUTHORS < #include #include #include int main(int argc, char *argv[]) try { QApplication a(argc, argv); QCommandLineParser parser; parser.addHelpOption(); parser.process(a); QStringList scripts(parser.positionalArguments()); ${PackageName} w; w.show(); return a.exec(); } catch (std::exception &x) { std::cerr<<"**** error: "< #include /// Main Window /** Main window for ${PACKAGE_NAME} */ class ${PackageName}: public QMainWindow, protected Ui::${PackageName} { Q_OBJECT; public: explicit ${PackageName}(QWidget *parent = 0): QMainWindow(parent) { setupUi(this); } virtual ~${PackageName}() {} }; #endif EOF to --condition AX_USE_CXX src/${PACKAGE_NAME}.ui < ${PackageName} 0 0 800 600 ${PackageName} 0 0 800 22 EOF to --condition AX_USE_CXX src/languages.qrc < ${PACKAGE_NAME}_de.qm ${PACKAGE_NAME}_fr.qm ${PACKAGE_NAME}_it.qm ${PACKAGE_NAME}_en.qm EOF fi to --condition AX_USE_CXX src/version.hxx < 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 <