cmake-generators/cmake.sh

221 lines
4.5 KiB
Bash
Executable File

#!/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
[ -x "$(command -v make)" ] && GENERATOR="Unix Makefiles"
[ -x "$(command -v ninja)" ] && GENERATOR=Ninja
# 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 two levels upper
SOURCE_DIR="$(dirname -- "$(dirname -- "$(pwd)")")"
# Default build directory is _build
BUILD_DIR="${SOURCE_DIR}/_build"
# Default output directory is _output
OUTPUT_DIR="${SOURCE_DIR}/_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
if [ "x${GENERATOR}" = "x" ]; then
echo "Build command is not found"
exit 1
fi
CMAKE_ARGS=""
[ ${#@} -gt 0 ] && CMAKE_ARGS=("${@}")
[ ! -f "${SOURCE_DIR}/CMakeLists.txt" ] && { echo "Source directory does not contain CMakeLists.txt"; exit 4; }
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
export SINGLE_TYPE
export FORCE
CMAKE_BUILD_TYPES=(None Debug Release Profile RelWithDebInfo MinSizeRel)
QTCREATOR_BUILD_TYPES=(qtNone qtDebug qtRelease qtProfile)
generate_configuration() {
local BUILD_TYPE="${!#}"
local BUILD="$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}"
if [ "x${SINGLE_TYPE}" == "xn" ]; then
GEN_DIR="${BUILD_DIR}/${BUILD}"
else
GEN_DIR="${BUILD_DIR}/${SINGLE_TYPE}"
fi
if [ -d "${GEN_DIR}" ]; then
if [ "x${FORCE}" == "xy" ]; then
rm -rf "${GEN_DIR}"
else
echo "Build directory '${GEN_DIR}' already exists. Use --force to remove this directory or do it manually"
return
fi
fi
mkdir -p "${GEN_DIR}"
pushd "${GEN_DIR}" 2>/dev/null
cmake -G "${GENERATOR}" -DCMAKE_INSTALL_PREFIX="${OUTPUT_DIR}" -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 <<EOF
.PHONY: build
%:
@ninja \$@
build:
@ninja
EOF
fi
popd 2>/dev/null
}
export -f generate_configuration
if [ "x$SINGLE_TYPE" != "xn" ]; then
BUILD_TYPES=("${SINGLE_TYPE}")
else
if [ "x$QTCREATOR" == "xy" ]; then
BUILD_TYPES=("${QTCREATOR_BUILD_TYPES[@]}")
elif [ "x$CMAKE" == "xy" ]; then
BUILD_TYPES=("${CMAKE_BUILD_TYPES[@]}")
else
BUILD_TYPES=("Release")
fi
fi
if [ ${#BUILD_TYPES[@]} -eq 0 ]; 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 --delay 2 -r generate_configuration ::: "${BUILD_TYPES[@]}"
elif [ "$PV" -lt "20141023" ]; then
parallel --delay 2 -r --no-notice generate_configuration ::: "${BUILD_TYPES[@]}"
else
parallel --delay 2 -r --will-cite generate_configuration ::: "${BUILD_TYPES[@]}"
fi
else
for T in "${BUILD_TYPES[@]}"; do generate_configuration "${T}"; done
fi