Skip to content

Instantly share code, notes, and snippets.

@ifgeny87
Created April 20, 2020 07:22
Show Gist options
  • Select an option

  • Save ifgeny87/3f7423f079b29bc3ab87fb61e25ec3bb to your computer and use it in GitHub Desktop.

Select an option

Save ifgeny87/3f7423f079b29bc3ab87fb61e25ec3bb to your computer and use it in GitHub Desktop.
Script for automate creating C++ project with CMake building config
#!/bin/bash
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Скрипт для автоматического создания проекта C++ с подключением CMake конфига
# Author: https://github.com/ifgeny87
# Changelog:
# - 1.0.1 (2020-04-19)
# -- Умеет выполнять команду создания проекта
# -- Создает main.cpp, CMakeLists.txt, README.md
# -- Создает скрипты для очистки, сборки и тестирования приложения
# -- Позволяет добавить описание в README.md
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PROJER_VERSION=1.0.1
# Выводит хелп и завершает работу приложения
help()
{
echo "C++ Projer v${PROJECT_VERSION}
Using:
./projer.sh <command>
Possible commands:
-h - type this help and exit
-c - create a new C++ project"
exit 0
}
# Выводит меню, ожидает ввода пользователя и возвращает номер выбранного меню
function prog_menu
{
local KEY
echo "Select a command:
1) Create a new C++ project
0) Help"
while [ 1 = 1 ]; do
read -p "Your choise: " KEY
[ -n "$KEY" ] && ([ $KEY = 0 ] || [ $KEY = 1 ]) && return $KEY
done
}
# Обрабатывает команду и выбирает дальнейшую программу
function prog
{
case "$1" in
0 | "-h")
help
;;
1 | "-c")
pre_create_project $2 $3
;;
*)
prog_menu
prog $?
;;
esac
}
# Запрашивает у пользователя название проекта
function pre_create_project
{
echo -e "Type a new name for C++ project. Left empty for return to menu."
local PROJECT_NAME
while [ 1 = 1 ]; do
read -p "Project name: " PROJECT_NAME
if [ -z "$PROJECT_NAME" ]
then
# just return to menu
prog
exit 0
else
if [ -d $PROJECT_NAME ]
then
# folder exists, repeat type
echo "Folder with name $PROJECT_NAME already exists. Type another name."
pre_create_project
else
create_project $PROJECT_NAME
fi
fi
done
}
# Создает проект
function create_project
{
local NAME=$1
local TARGET_NAME="TheApplication"
echo "Creating folder $NAME"
mkdir -p $NAME/src
#---- main.cpp -------------------------------
echo "Creating $NAME/src/main.cpp"
echo "#include <iostream>
int main(int argc, char *argv[]) {
std::cout << \"Hello World!\" << std::endl;
return 0;
}" > $NAME/src/main.cpp
#---- CMakeLists.txt -------------------------------
echo "Creating $NAME/CMakeLists.txt"
echo "cmake_minimum_required(VERSION 3.5)
project($NAME VERSION 1.0.1)
set(SRC_ROOT src)
set(PROJECT_NAME $TARGET_NAME)
set(SOURCES
\${SRC_ROOT}/main.cpp)
add_executable(\${PROJECT_NAME} \${HEADERS} \${SOURCES})
set_target_properties(\${PROJECT_NAME} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON)
target_include_directories(\${PROJECT_NAME} PRIVATE
\${CMAKE_CURRENT_BINARY_DIR})" > $NAME/CMakeLists.txt
#---- clean.sh -------------------------------
echo "Creating $NAME/clean.sh"
echo "rm -rd build/" > $NAME/clean.sh
chmod +x $NAME/clean.sh
#---- build.sh -------------------------------
echo "Creating $NAME/biuld.sh"
echo "# create build dir and go into
mkdir -p $(dirname $0)/build && cd \$_
echo Current dir: $(pwd)
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . --target $TARGET_NAME -- -j 4" > $NAME/build.sh
chmod +x $NAME/build.sh
#---- test.sh -------------------------------
echo "Creating $NAME/test.sh"
echo "./build.sh && ./build/$TARGET_NAME" > $NAME/test.sh
chmod +x $NAME/test.sh
#---- README.md -------------------------------
prompt "Do you want add README.md" 1
[ "$?" = 1 ] || return
echo "Creating $NAME/README.md"
echo "# Project $NAME
## Clear
For clear start \`./clear.sh\`.
## Building
For build start \`./build.sh\`.
## Testing
For test start \`./test.sh\`. This script includes \`build.sh\`." > $NAME/README.md
echo "Type lines for add it to README.md file. Type 0 for done."
local IS_ADDED_DESC=0
while [ 1 = 1 ]; do
read LINE
[ "$LINE" = 0 ] && break
if [ $IS_ADDED_DESC = 0 ]; then
[ -z "$LINE" ] && continue
# add description block to README.sh
IS_ADDED_DESC=1
echo "
## Description
" >> $NAME/README.md
fi
echo $LINE >> $NAME/README.md
done
}
# Выводит текст запроса и ждет ответа Y[yes] или N[no].
# Результатом функции является 1 если пользователь ответил Yes и 0 если ответил No.
# Первым аргументом функция принимает на вход текст, который нужно вывести пользователю.
# Вторым аргументом функция может получать ответ по умолчанию: 1 для Yes, 0 для No.
# Примеры:
# `prompt "Files created. Do something else?"`
# `prompt "Do you want a banana?" 0`
function prompt
{
local Y="y"
[ "$2" = 1 ] && Y="Y"
local N="n"
[ "$2" = 0 ] && N="N"
printf "$1 [$Y/$N]: "
local ANSWER
while read ANSWER; do
case $ANSWER in
[yY][eE][sS]|[yY])
return 1
break
;;
[nN][oO]|[nN])
return 0
break
;;
*)
[ -n "$2" ] && return $2
printf "Please, enter Y(yes) or N(no)! "
esac
done
}
prog $1
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment