Last active
November 22, 2020 07:56
-
-
Save AntonioCS/81e96d20bc8538db8a2e469f01294f6f to your computer and use it in GitHub Desktop.
Small bat file to create basic project. Will create src/ dir if not present (with dummy code). Will create tests/ folder if not present (with dummy test code). Will create build/ folder (if present with a .sln file ask if you want to delete). Check if there is a CMakeLists.txt and if there isn't create a generic one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
@setlocal EnableExtensions EnableDelayedExpansion | |
:: This batch file will try to generate a minimalist project | |
:: It will create a src folder with a small cpp file^ | |
:: It will create a test folder with some mock test files for catch2/catch | |
:: It will also ask if you want to enable testing | |
:: If a solution already exists (in the build folder) it will ask if you want to remove it and rebuild | |
:: NOTE: Run this in admin mode if it doesn't work | |
set cmake_batch_version=0.8 | |
set rootDir=%~dp0% | |
set rootDir=%rootDir:\=/% | |
set srcDir=%rootDir% | |
set srcCodeDir=%rootDir%src | |
set testDir=%rootDir%tests | |
set builDir=%rootDir%build | |
set gitDir=%rootDir%.git | |
set toolChainPath=C:/vcpkg/scripts/buildsystems/vcpkg.cmake | |
set vtt=x64-windows | |
:: set vtt=x86-windows | |
set platform=x64 | |
:: set platform=Win32 | |
set created_test_dir=0 | |
set cmakeMinVersion=3.15 | |
set cmake_batch_debug=0 | |
SET create_shortcut=^ | |
$sln_file = Get-ChildItem %builDir%\*.sln -name;^ | |
$sln_file_parts = $sln_file.Split(\".\");^ | |
$sln_shortcut_name = -join($sln_file_parts[0], '.lnk');^ | |
$sln_file_full_path = -join('%builDir%/', $sln_file);^ | |
$s = (New-Object -COM WScript.Shell).CreateShortcut($sln_shortcut_name);^ | |
$s.TargetPath = $sln_file_full_path;^ | |
$s.Save(); | |
if %cmake_batch_debug% == 0 ( | |
if not exist "%gitDir%" ( | |
choice /M "Create a git repo?" | |
if !errorlevel! == 1 ( | |
git init | |
) | |
) | |
if not exist "%srcCodeDir%" ( | |
REM You need to use ^ for special chars | |
echo Creating Source Directory | |
@mkdir "%srcCodeDir%" | |
( | |
echo #include ^<iostream^> | |
echo: | |
echo int main^(int argc, char** argv^) { | |
echo: | |
echo std::cout ^<^< "Hello World!\n"; | |
echo: | |
echo } | |
) > "%srcCodeDir%/main.cpp" | |
) | |
if not exist "%testDir%" ( | |
REM You need to use ^ for special chars | |
REM This is not being set correctly | |
set created_test_dir = 1 | |
@mkdir "%testDir%" | |
( | |
echo #define CATCH_CONFIG_MAIN | |
echo #include ^<catch2/catch.hpp^> | |
) > "%testDir%/main.cpp" | |
( | |
echo #include ^<catch2/catch.hpp^> | |
echo: | |
echo TEST_CASE^("Test1", "[Example]"^) { | |
echo: | |
echo } | |
) > "%testDir%/ExampleTest.cpp" | |
) | |
if exist "%builDir%/*.sln" ( | |
CHOICE /M "Solution present. Delete it?" | |
REM set /p delete_project="Solution present. Delete it?[yes/no default yes]: " | |
REM if NOT DEFINED delete_project ( | |
if !errorlevel! == 1 ( | |
echo Removing directory | |
rmdir /S "%builDir%" | |
) | |
) | |
if exist "%rootDir%/.git/*" ( | |
if not exist "%rootDir%/.gitignore" ( | |
echo build/ > .gitignore | |
) | |
) | |
if not exist "%builDir%" mkdir "%builDir%" | |
) | |
:: Specifying the source and build dir does not work for whatever reason | |
:: cmake -S "%srcDir%" -B "%builDir%" -DCMAKE_TOOLCHAIN_FILE="%toolChainPath%" -DVCPKG_TARGET_TRIPLET="%vtt%" | |
if not exist "%rootDir%/CMakeLists.txt" ( | |
choice /M "There is no CMakeLists.txt file. Create one?" | |
if !errorlevel! == 1 goto :pname | |
goto :exit | |
:pname | |
set /p project_name="Enter Project name: " | |
if NOT DEFINED project_name ( | |
echo The name of the project is required | |
goto :pname | |
) | |
:pdesc | |
set /p project_desc="Enter Project description: " | |
if NOT DEFINED project_desc ( | |
echo A description is required | |
goto :pdesc | |
) | |
CHOICE /C EL /D E /T 15 /M "Generate exe or lib?" | |
REM ENSURE THERE ARE NO SPACES | |
if !errorlevel! == 0 goto :exit | |
if !errorlevel! == 1 set project_type=exe | |
if !errorlevel! == 2 ( | |
set project_type=lib | |
CHOICE /C SD /D S /T 15 /M "Static or Dynamic (shared) library?" | |
if !errorlevel! == 1 set project_lib_type=static | |
if !errorlevel! == 2 set project_lib_type=shared | |
if !errorlevel! == 0 goto :exit | |
) | |
set enable_testing=0 | |
CHOICE /C YN /D Y /T 15 /M "Enable testing?" | |
if !errorlevel! == 1 set enable_testing=1 | |
if !enable_testing! == 0 ( | |
REM this does not work because I am unable to get created_test_dir to be set with the value 1 when I create a test folder | |
if !created_test_dir! == 1 ( | |
rmdir /s /q %testDir% | |
) | |
) | |
set /p output_file_name="Enter output file name(leave empty to use Project Name): " | |
if NOT DEFINED output_file_name ( | |
set output_file_name=!project_name! | |
) | |
( | |
echo cmake_minimum_required^(VERSION %cmakeMinVersion% FATAL_ERROR^) | |
echo project^("!project_name!" DESCRIPTION "!project_desc!" VERSION 0.0.1 LANGUAGES CXX^) | |
echo: | |
if !enable_testing! == 1 ( | |
echo include^(CTest^) | |
echo: | |
) | |
echo set^(OUTPUT_FILE !output_file_name!^) | |
echo: | |
echo if ^(NOT DEFINED CMAKE_CXX_STANDARD^) | |
echo set^(CMAKE_CXX_STANDARD 20^) | |
echo else^(^) | |
echo if ^(CMAKE_CXX_STANDARD VERSION_LESS 20^) | |
echo message^(FATAL_ERROR "CMAKE_CXX_STANDARD of 20 or later required."^) | |
echo endif^(^) | |
echo endif^(^) | |
echo if ^(NOT DEFINED CMAKE_CXX_EXTENSIONS^) | |
echo set^(CMAKE_CXX_EXTENSIONS OFF^) | |
echo endif^(^) | |
echo: | |
echo if ^(MSVC^) | |
echo add_definitions^(-D_UNICODE -DUNICODE -DWIN32_LEAN_AND_MEAN -DNOMINMAX -DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00^) | |
echo add_definitions^(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE^) | |
echo add_definitions^(-D_ATL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS^) | |
echo endif^(^) | |
echo: | |
echo file^(GLOB_RECURSE PROJ_SRC_FILES | |
echo CONFIGURE_DEPENDS | |
echo src/*.c* src/*.h* | |
echo ^) | |
echo: | |
echo #To properly set the files in the treeview for MSVC | |
echo foreach^(source IN LISTS PROJ_SRC_FILES^) | |
echo get_filename_component^(source_path "${source}" PATH^) | |
echo string^(REPLACE "${PROJECT_SOURCE_DIR}/" "" source_path_msvc "${source_path}"^) | |
echo source_group^("${source_path_msvc}" FILES "${source}"^) | |
echo endforeach^(^) | |
echo: | |
if !project_type! == exe ( | |
echo add_executable^( | |
) else ( | |
echo add_library^( | |
) | |
echo ${OUTPUT_FILE} | |
if !project_type! == lib ( | |
if !project_lib_type! == shared ( | |
echo SHARED | |
) | |
) | |
echo ${PROJ_SRC_FILES} | |
echo ^) | |
echo: | |
echo target_compile_options^(${OUTPUT_FILE} | |
echo PRIVATE | |
echo $^<$^<OR:$^<CXX_COMPILER_ID:Clang^>,$^<CXX_COMPILER_ID:AppleClang^>,$^<CXX_COMPILER_ID:GNU^>^>: | |
echo -Werror -Wall -Wextra^> | |
echo $^<$^<CXX_COMPILER_ID:MSVC^>: | |
echo /W4^> | |
echo ^) | |
echo: | |
echo set_property^(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${OUTPUT_FILE}^) | |
echo: | |
if !project_type! == lib ( | |
if !project_lib_type! == shared ( | |
echo set^(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true^) | |
echo: | |
) | |
) | |
if !enable_testing! == 1 ( | |
echo enable_testing^(^) | |
echo: | |
echo file^(GLOB_RECURSE TEST_FILES | |
echo CONFIGURE_DEPENDS | |
echo ${PROJECT_SOURCE_DIR}/tests/*.cpp ${PROJECT_SOURCE_DIR}/tests/*.h | |
echo ^) | |
echo: | |
echo add_executable^(tests | |
echo ${TEST_FILES} | |
echo ^) | |
echo: | |
echo target_include_directories^(tests | |
echo PUBLIC | |
echo tests/ | |
echo src/ | |
echo ^) | |
echo: | |
echo find_package^(Catch2 CONFIG REQUIRED^) | |
echo target_link_libraries^(tests | |
echo PRIVATE | |
echo Catch2::Catch2 | |
if !project_type! == lib ( | |
echo ${output_file_name} | |
) | |
echo ^) | |
echo: | |
) | |
) > "%rootDir%/CMakeLists.txt" | |
) | |
:skip | |
if exist "%rootDir%/CMakeLists.txt" ( | |
echo Executing cmake command | |
cd "%builDir%" | |
REM %PROJECTS_INSTALL_DIR% is an environment variable set on my system | |
cmake .. -DCMAKE_TOOLCHAIN_FILE="%toolChainPath%" -DVCPKG_TARGET_TRIPLET="%vtt%" -DCMAKE_PREFIX_PATH="%PROJECTS_INSTALL_DIR%" -A %platform% | |
cd "%rootDir%" | |
choice /t 10 /d y /m "Create solution shortcut in current directory?" | |
if !errorlevel! == 1 ( | |
echo Creating shortcut | |
powershell "%create_shortcut%" | |
) | |
pause | |
) | |
:exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment