#!/bin/bash set -o errexit -o pipefail -o noclobber -o nounset # Test if getopt exists command -v getopt >/dev/null 2>&1 || { echo "can't execute getopt"; exit 1; } # Test if getopt works ! getopt --test 2> /dev/null [[ ${PIPESTATUS[0]} -ne 4 ]] && { exit 2; } # List of available options OPTIONS=g:t:qcfs:b:o: LONGOPTS=generator:,type:,qtcreator,cmake,force,source-dir:,build-dir:,output-dir: # Parse options ! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") [[ ${PIPESTATUS[0]} -ne 0 ]] && exit 3 # Read getopt's output to handle the quoting right eval set -- "$PARSED" # Default generator GENERATOR="Unix Makefiles" # Generate single build type SINGLE_TYPE="n" # Generate QtCreator build types QTCREATOR="n" # Generate CMake build types CMAKE="n" # Force destructive actions FORCE="n" # Default source directory is current SOURCE_DIR="$(dirname $(pwd))" # Default build directory is ../build BUILD_DIR="$(dirname -- "${SOURCE_DIR}/." | sed 's/\(.*\)\/.*/\1\/build/')" # Default output directory is ../output OUTPUT_DIR="$(dirname -- "${SOURCE_DIR}/." | sed 's/\(.*\)\/.*/\1\/output/')" while true; do case "$1" in -g|--generator) GENERATOR="$2" shift 2 ;; -t|--type) SINGLE_TYPE="$2" shift 2 ;; -q|--qtcreator) QTCREATOR="y" shift ;; -c|--cmake) CMAKE="y" shift ;; -f|--force) FORCE="y" shift ;; -s|--source-dir) SOURCE_DIR="$2" shift 2 ;; -b|--build-dir) BUILD_DIR="$2" shift 2 ;; -o|--output-dir) OUTPUT_DIR="$2" shift 2 ;; --) shift break ;; *) echo "Programming error" exit 3 ;; esac done CMAKE_ARGS=" " [ ! -z "${@}" ] && CMAKE_ARGS="${@}" [ ! -f "${SOURCE_DIR}/CMakeLists.txt" ] && { echo "Source directory does not contain CMakeLists.txt"; exit 4; } if [ -d "${BUILD_DIR}" ]; then if [ "x${FORCE}" == "xy" ]; then rm -rf "${BUILD_DIR}" else echo "Build directory already exists. Use --force to remove this directory or do it manually" exit 5 fi fi if [ "x${SINGLE_TYPE}" != "xn" ]; then case "${SINGLE_TYPE}" in None|Debug|Release|Profile|RelWithDebInfo|MinSizeRel) true ;; *) echo "Wrong CMake build type" exit 6 ;; esac fi export CMAKE export QTCREATOR export GENERATOR export SOURCE_DIR export BUILD_DIR export OUTPUT_DIR export CMAKE_ARGS CMAKE_BUILD_TYPES=(None Debug Release RelWithDebInfo MinSizeRel) QTCREATOR_BUILD_TYPES=(qtNone qtDebug qtRelease qtProfile) generate_configuration() { local BUILD_TYPE="${!#}" local BUILD="$BUILD_TYPE" echo $BUILD_TYPE if [ "x$QTCREATOR" == "xy" ]; then case "$BUILD_TYPE" in qtNone) BUILD="unknown" BUILD_TYPE="None" ;; qtDebug) BUILD="debug" BUILD_TYPE="Debug" ;; qtRelease) BUILD="release" BUILD_TYPE="Release" ;; qtProfile) BUILD="profile" BUILD_TYPE="Profile" ;; esac fi GEN_DIR="${BUILD_DIR}" [ "x${SINGLE_TYPE}" == "xn" ] && GEN_DIR="${BUILD_DIR}/${BUILD}" [ -d "${GEN_DIR}" ] && return 0 mkdir -p "${GEN_DIR}" pushd "${GEN_DIR}" 2>/dev/null cmake -G "${GENERATOR}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" ${CMAKE_ARGS} "${SOURCE_DIR}" if [ "x$GENERATOR" == "xNinja" ]; then # Generate fake Makefile, so make can run ninja build cat > Makefile </dev/null } export -f generate_configuration BUILD_TYPES="" if [ "x$SINGLE_TYPE" != "xn" ]; then BUILD_TYPES="${SINGLE_TYPE}" else [ "x$QTCREATOR" == "xy" ] && BUILD_TYPES+=" ${QTCREATOR_BUILD_TYPES[@]}" [ "x$CMAKE" == "xy" ] && BUILD_TYPES+=" ${CMAKE_BUILD_TYPES[@]}" fi if [ "x${BUILD_TYPES}" == "x" ]; then echo "No build type selected." echo "Use -c for default CMake build types" echo "Use -q for build types for QtCreator" echo "Use -t name for build with type 'name'" exit 0 fi # Try to work in parallel if [ -x "$(command -v parallel)" ]; then PV=$(parallel --version | head -n 1 | awk '{ print $3; }') if [ "$PV" -lt "20131121" ]; then parallel generate_configuration ::: ${BUILD_TYPES} elif [ "$PV" -lt "20141023" ]; then parallel --no-notice generate_configuration ::: ${BUILD_TYPES} else parallel --will-cite generate_configuration ::: ${BUILD_TYPES} fi else for T in ${BUILD_TYPES}; do generate_configuration "${T}"; done fi