Skip to content

Instantly share code, notes, and snippets.

@takumakei
Last active August 29, 2015 14:24
Show Gist options
  • Save takumakei/20c0c5f32eb3e560c9bb to your computer and use it in GitHub Desktop.
Save takumakei/20c0c5f32eb3e560c9bb to your computer and use it in GitHub Desktop.
cbt - CMake Build Tool
#!/bin/bash
#
# CMake Build Tool
#
# Copyright (c) 2015 takumakei
#
# This software is released under the MIT License.
# http://opensource.org/licenses/mit-license.php
#
# $Id: a58f8ef02f7aa5084af21a933965ec23fd75e60a $
#
SCRIPT_NAME="$(basename "$0")"
main() {
local opts cmd
opts="update run compile clean make"
cmd=( $(compgen -W "$opts" "$1") )
if [ ${#cmd[@]} == 1 ]; then
"main_$cmd" "$@"
msg finish
elif [ "$1" == "c" ]; then
main_compile "$@"
else
main_help
fi
}
main_update() {
if [ -f CMakeLists.txt ]; then
cp -f CMakeLists.txt CMakeLists.bak
cmakelists no-source > CMakeLists.start
cmakelists > CMakeLists.update
diff3 -e -m CMakeLists.bak CMakeLists.start CMakeLists.update > CMakeLists.txt
rm -f CMakeLists.start CMakeLists.update
[ -d target ] || mkdir target
mv CMakeLists.bak target/
msg "CMakeLists.txt updated"
else
cmakelists > CMakeLists.txt
msg "CMakeLists.txt created"
fi
}
cmakelists() {
cat <<'EOF'
cmake_minimum_required(VERSION 2.8)
project(cbt)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -pedantic-errors")
set(CMAKE_CXX_FLAGS_DEBUG "-g3 -D_DEBUG -O0 -pg")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -march=native")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g3 -pg -march=native")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -march=native")
set(SOURCE_FILES
EOF
if [ "$1" != "no-source" ]; then
find . -name target -prune -or \
\( -name '*.c' -or \
-name '*.h' -or \
-name '*.m' -or \
-name '*.mm' -or \
-name '*.cc' -or \
-name '*.cpp' -or \
-name '*.hpp' \) -print | sed 's/../ /' | sort
fi
cat <<'EOF'
)
add_executable(a.out
${SOURCE_FILES})
# find_library(COCOA_LIBRARY Cocoa)
# find_library(CORE_FOUNDATION_LIBRARY CoreFoundation)
#
# target_link_libraries(a.out
# ${COCOA_LIBRARY}
# ${CORE_FOUNDATION_LIBRARY}
# my-lib)
install(TARGETS a.out DESTINATION bin)
EOF
}
main_run() {
[ -f CMakelists.txt ] || main_update
shift
if [[ "$1" =~ ^\+.* ]]; then
local watch_dir="${1#\+}"
if [ "$watch_dir" ]; then
[ -d "$watch_dir" ] || {
echo "ERROR: no such dir '$watch_dir'"
exit 1
}
else
watch_dir=.
fi
shift
trap "exit" SIGINT
while true; do
main_compile "" && {
msg run
"${aout:=$(find_bin)}" "$@"
}
echo_waiting
fswatch_code -r -1 "$watch_dir" > /dev/null
done
fi
main_compile "" && {
msg run
$(find_bin) "$@"
}
}
find_bin() {
local files
files=()
while read f; do
[ -x "$f" ] && files+=("$f")
done < <(find target/build -depth 1 -type f)
if [ ${#files[@]} == 0 ]; then
echo "ERROR: target binary not found"
exit 1
elif [ ${#files[@]} == 1 ]; then
echo "${files[0]}"
else
for i in "${files[@]}"; do
echo "$i"
done | peco
fi
}
main_compile() {
[ -f CMakelists.txt ] || main_update
[ -d target/build ] || mkdir -p target/build
shift
if [[ "$1" =~ ^\+.* ]]; then
local watch_dir="${1#\+}"
if [ "$watch_dir" ]; then
[ -d "$watch_dir" ] || {
echo "ERROR: no such dir '$watch_dir'"
exit 1
}
else
watch_dir=.
fi
shift
trap "exit" SIGINT
while true; do
msg compile
cd target/build
run_cmake && make
echo_waiting
cd ../..
fswatch_code -r -1 "$watch_dir" > /dev/null
done
fi
msg compile
( cd target/build; run_cmake && make )
}
run_cmake() {
# cmake -DCMAKE_VERBOSE_MAKEFILE=1 -DCMAKE_INSTALL_PREFIX="$PWD"/../stage ../..
# cmake -DCMAKE_INSTALL_PREFIX="$PWD"/../stage ../..
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="$PWD"/../stage ../..
}
echo_waiting() {
msg "waiting. use ^C to exit."
}
msg() {
local c=$?
[ $c == 0 ] && echo -n ⭕️ || echo -n ❌
echo " ==> [$( date +"%D %T" )] $*"
[ $c == 0 ] || false
}
fswatch_code() {
fswatch \
-i '\.c$' \
-i '\.h$' \
-i '\.m$' \
-i '\.mm$' \
-i '\.cc$' \
-i '\.cpp$' \
-i '\.hpp$' \
-e '.*' \
"$@"
}
main_clean() {
msg clean
if [ -d target/build ]; then
rm -fr target/build
exit 0
fi
exit 1
}
main_make() {
[ -f CMakelists.txt ] || main_update
[ -f target/build/Makefile ] || main_compile
cd target/build
shift
make "$@"
}
main_help() {
echo "usage: $SCRIPT_NAME command [options]"
echo
echo "commands are:"
echo " update update CMakeLists.txt"
echo " compile compile"
echo " compile +[dir] compile continuously"
echo " run [...] compile and run"
echo " run +[dir] [...] compile and run continuously"
echo " clean remove target/build"
echo " make [...] make on target/build"
exit 0
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment