/******************************************************************************
* File - main . cpp
* Author - Joey Pollack
* Date - 2021 / 12 / 03 ( y / m / d )
* Mod Date - 2021 / 12 / 03 ( y / m / d )
* Description - Generates a new C + + project with CMake
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// TODO: Generate a clean.sh script for linux
# include <utils/CmdArgParser.h>
# include <utils/StringManip.h>
# include <iostream>
# include <filesystem>
# include <string>
# include <fstream>
# include <ctime>
int GenerateLibCMakeFile ( std : : string name , std : : filesystem : : path location ) ;
int GenerateSubmodCMakeFile ( std : : string name , std : : filesystem : : path location , std : : vector < std : : string > & libraries ) ;
int GenerateMainFile ( std : : string project_name , std : : string mod_name , std : : filesystem : : path location ) ;
void CleanUp ( std : : filesystem : : path root ) ;
typedef jpUtils : : CmdArgParser : : ArgDesc ArgDesc ;
int main ( int argc , char * * argv )
{
jpUtils : : CmdArgParser argParser ( argc , argv , " Generates a new C++ project with CMake. " ) ;
// Required args
argParser . AddArg ( ArgDesc ( " ProjectName " , false , 1 , " The name of the project to generate. " ) ) ;
// Options
argParser . AddArg ( ArgDesc ( " -h " , true , 0 , " Displays this help messasge. " ) ) ;
argParser . AddArg ( ArgDesc ( " -v " , true , 0 , " Verbose - Print extra info while running. " ) ) ;
argParser . AddArg ( ArgDesc ( " -p " , true , 1 , " Platform - Can be one of: win, linux, both. Default is win. " ) ) ;
argParser . AddArg ( ArgDesc ( " -l " , true , 1 , " License - Generate an MIT license file with the given name. " ) ) ;
argParser . AddArg ( ArgDesc ( " -d " , true , 1 , " Path to the location to generate the project at. Defaults to the current dirctory. " ) ) ;
argParser . AddArg ( ArgDesc ( " -i " , true , 0 , " Generate a .gitignore file " ) ) ;
argParser . AddArg ( ArgDesc ( " -m " , true , 1 , " Specify the CMake version to require. Default is 3.16.3 " ) ) ;
argParser . AddArg ( ArgDesc ( " -c " , true , 1 , " Specify the C++ version to require. Default is 17 " ) ) ;
argParser . AddArg ( ArgDesc ( " -s " , true , 1 , " Specify the visual studio version to use (17, 19, 22). Default is 19 " ) ) ;
argParser . AddArg ( ArgDesc ( " -a " , true , 1 , " Add library projects, separated by ',' (ex: -a first,second,third) " ) ) ;
argParser . AddArg ( ArgDesc ( " -x " , true , 1 , " Add executable submodule projects, separated by ',' (ex: -x first,second,third) " ) ) ;
argParser . AddArg ( ArgDesc ( " -r " , true , 0 , " Remove the root project executable " ) ) ;
bool result = argParser . Parse ( ) ;
if ( ! result )
{
if ( argParser . ContainsOption ( " -h " ) )
{
std : : cout < < argParser . GetUsageText ( ) < < std : : endl ;
return 0 ;
}
else
{
std : : cout < < argParser . GetErrorMessage ( ) ;
std : : cout < < " \n " < < argParser . GetUsageText ( ) < < std : : endl ;
return 1 ;
}
}
////////////////////////////////////////////////////////////
// Parse the submodules/libraries
////////////////////////////////////////////////////////////
// Libraries
std : : vector < std : : string > libraries ;
if ( argParser . ContainsOption ( " -a " ) )
{
std : : string list = argParser . GetOptionValue ( " -a " ) . values [ 0 ] ;
std : : string current_name ;
for ( int i = 0 ; i < list . size ( ) ; i + + )
{
if ( list [ i ] = = ' , ' )
{
libraries . push_back ( current_name ) ;
current_name . clear ( ) ;
}
else if ( i + 1 = = list . size ( ) )
{
current_name + = list [ i ] ;
libraries . push_back ( current_name ) ;
current_name . clear ( ) ;
}
else
{
current_name + = list [ i ] ;
}
}
}
// Submodules
std : : vector < std : : string > submods ;
if ( argParser . ContainsOption ( " -x " ) )
{
std : : string list = argParser . GetOptionValue ( " -x " ) . values [ 0 ] ;
std : : string current_name ;
for ( int i = 0 ; i < list . size ( ) ; i + + )
{
if ( list [ i ] = = ' , ' )
{
submods . push_back ( current_name ) ;
current_name . clear ( ) ;
}
else if ( i + 1 = = list . size ( ) )
{
current_name + = list [ i ] ;
submods . push_back ( current_name ) ;
current_name . clear ( ) ;
}
else
{
current_name + = list [ i ] ;
}
}
}
////////////////////////////////////////////////////////////
// Generate directory structure
////////////////////////////////////////////////////////////
std : : filesystem : : path root = std : : filesystem : : current_path ( ) ;
if ( argParser . ContainsOption ( " -d " ) )
{
if ( std : : filesystem : : exists ( argParser . GetOptionValue ( " -d " ) . values [ 0 ] ) )
{
root = argParser . GetOptionValue ( " -d " ) . values [ 0 ] ;
}
}
std : : cout < < " \n Generating project at location: " < < root . string ( ) . c_str ( ) ;
std : : string project_name = argParser . GetPositionalArg ( 0 ) . values [ 0 ] ;
root / = std : : filesystem : : path ( project_name ) ;
if ( ! std : : filesystem : : create_directory ( root ) )
{
std : : cout < < " \n Could not create directory: " < < root . string ( ) . c_str ( ) ;
return 1 ;
}
if ( ! std : : filesystem : : create_directory ( root / " build " ) )
{
std : : cout < < " \n Could not create build directory " ;
return 1 ;
}
if ( ! std : : filesystem : : create_directory ( root / " scripts " ) )
{
std : : cout < < " \n Could not create scripts directory " ;
return 1 ;
}
if ( ! std : : filesystem : : create_directory ( root / " src " ) )
{
std : : cout < < " \n Could not create src directory " ;
return 1 ;
}
// Generate folders/files for any submodules/libraries
std : : filesystem : : path src = root / " src " ;
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
std : : filesystem : : path location = src / libraries [ i ] ;
if ( ! std : : filesystem : : create_directory ( location ) )
{
std : : cout < < " \n Could not create library directory: " < < location . c_str ( ) ;
return 1 ;
}
if ( GenerateLibCMakeFile ( libraries [ i ] , location ) > 0 )
return 1 ;
}
src = root / " src " ;
for ( int i = 0 ; i < submods . size ( ) ; i + + )
{
std : : filesystem : : path location = src / submods [ i ] ;
if ( ! std : : filesystem : : create_directory ( location ) )
{
std : : cout < < " \n Could not create submodule directory: " < < location . c_str ( ) ;
return 1 ;
}
if ( GenerateSubmodCMakeFile ( submods [ i ] , location , libraries ) > 0 )
return 1 ;
}
////////////////////////////////////////////////////////////
// Generate CMake files
////////////////////////////////////////////////////////////
std : : filesystem : : path cmake_file = root / std : : filesystem : : path ( " CMakeLists.txt " ) ;
std : : ofstream ofs ( cmake_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the CMake file: " < < cmake_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating CMake file: " < < cmake_file . string ( ) . c_str ( ) ;
std : : string cmversion = " 3.16.3 " ;
if ( argParser . ContainsOption ( " -m " ) )
{
cmversion = argParser . GetOptionValue ( " -m " ) . values [ 0 ] ;
}
std : : string cversion = " 17 " ;
if ( argParser . ContainsOption ( " -c " ) )
{
cversion = argParser . GetOptionValue ( " -c " ) . values [ 0 ] ;
}
ofs < < " cmake_minimum_required(VERSION " < < cmversion < < " ) " ;
ofs < < " \n \n # set the project name and version " ;
ofs < < " \n project( " < < project_name < < " VERSION 0.1.0) " ;
ofs < < " \n \n # specify the C++ standard " ;
ofs < < " \n set(CMAKE_CXX_STANDARD " < < cversion < < " ) " ;
ofs < < " \n set(CMAKE_CXX_STANDARD_REQUIRED True) " ;
ofs < < " \n # setup target output directories " ;
ofs < < " \n set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) " ;
ofs < < " \n set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) " ;
ofs < < " \n set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) " ;
ofs < < " \n \n configure_file( " < < project_name < < " Config.h.in " < < project_name < < " Config.h) " ;
// remove root executable if the option is set
if ( ! argParser . ContainsOption ( " -r " ) )
{
ofs < < " \n \n # specify the project source files " ;
ofs < < " \n set( " < < jpUtils : : StringManip : : ToUpper ( project_name ) < < " _SRC " ;
ofs < < " \n \t src/main.cpp " ;
ofs < < " \n ) " ;
ofs < < " \n \n # add the executable " ;
ofs < < " \n add_executable(${PROJECT_NAME} ${ " < < jpUtils : : StringManip : : ToUpper ( project_name ) < < " _SRC}) " ;
ofs < < " \n \n target_include_directories(${PROJECT_NAME} " ;
ofs < < " \n \t PUBLIC \" ${PROJECT_BINARY_DIR} \" " ;
ofs < < " \n \t PUBLIC src " ;
ofs < < " \n ) " ;
// Link to any libs that exist
ofs < < " \n \n target_link_directories(${PROJECT_NAME} " ;
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
ofs < < " \n \t PRIVATE ../ " < < libraries [ i ] . c_str ( ) ;
}
ofs < < " ) " ;
ofs < < " \n \n target_link_libraries(${PROJECT_NAME} " ;
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
ofs < < " " < < libraries [ i ] . c_str ( ) ;
}
ofs < < " ) " ;
}
// include the libraries and submodules
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
ofs < < " \n add_subdirectory(src/ " < < libraries [ i ] . c_str ( ) < < " ) " ;
}
for ( int i = 0 ; i < submods . size ( ) ; i + + )
{
ofs < < " \n add_subdirectory(src/ " < < submods [ i ] . c_str ( ) < < " ) " ;
}
ofs . close ( ) ;
ofs . clear ( ) ;
////////////////////////////////////////////////////////////
// Generate Config file
////////////////////////////////////////////////////////////
std : : string config_name = project_name ;
config_name + = " Config.h.in " ;
std : : filesystem : : path config_file = root / config_name ;
ofs = std : : ofstream ( config_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the Config file: " < < config_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating Config file: " < < config_file . string ( ) . c_str ( ) ;
ofs < < " #define " < < project_name < < " _VERSION_MAJOR @ " < < project_name < < " _VERSION_MAJOR@ " ;
ofs < < " \n #define " < < project_name < < " _VERSION_MINOR @ " < < project_name < < " _VERSION_MINOR@ " ;
ofs < < " \n #define " < < project_name < < " _VERSION_PATCH @ " < < project_name < < " _VERSION_PATCH@ " ;
ofs . close ( ) ;
ofs . clear ( ) ;
////////////////////////////////////////////////////////////
// Generate License file
////////////////////////////////////////////////////////////
if ( argParser . ContainsOption ( " -l " ) )
{
std : : filesystem : : path license_file = root / " LICENSE " ;
ofs = std : : ofstream ( license_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the License file: " < < license_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating License file: " < < license_file . string ( ) . c_str ( ) ;
time_t now = time ( 0 ) ;
tm * gmtm = gmtime ( & now ) ;
ofs < < " Copyright " < < gmtm - > tm_year + 1900 < < " " < < argParser . GetOptionValue ( " -l " ) . values [ 0 ] ;
ofs < < " \n \n Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \" Software \" ), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: " ;
ofs < < " \n \n The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. " ;
ofs < < " \n \n THE SOFTWARE IS PROVIDED \" AS IS \" , WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. " ;
ofs . close ( ) ;
ofs . clear ( ) ;
}
////////////////////////////////////////////////////////////
// Generate .gitignore file
////////////////////////////////////////////////////////////
if ( argParser . ContainsOption ( " -i " ) )
{
std : : filesystem : : path ignore_file = root / " .gitignore " ;
ofs = std : : ofstream ( ignore_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the .gitignore file: " < < ignore_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating .gitignore file: " < < ignore_file . string ( ) . c_str ( ) ;
ofs < < " ######################## VSCODE IGNORES " ;
ofs < < " \n .vscode/ " ;
ofs < < " \n " ;
ofs < < " \n " ;
ofs < < " \n ######################## C++ IGNORES " ;
ofs < < " \n # Prerequisites " ;
ofs < < " \n *.d " ;
ofs < < " \n " ;
ofs < < " \n # Compiled Object files " ;
ofs < < " \n *.slo " ;
ofs < < " \n *.lo " ;
ofs < < " \n *.o " ;
ofs < < " \n *.obj " ;
ofs < < " \n " ;
ofs < < " \n # Precompiled Headers " ;
ofs < < " \n *.gch " ;
ofs < < " \n *.pch " ;
ofs < < " \n " ;
ofs < < " \n # Compiled Dynamic libraries " ;
ofs < < " \n *.so " ;
ofs < < " \n *.dylib " ;
ofs < < " \n *.dll " ;
ofs < < " \n " ;
ofs < < " \n # Fortran module files " ;
ofs < < " \n *.mod " ;
ofs < < " \n *.smod " ;
ofs < < " \n " ;
ofs < < " \n # Compiled Static libraries " ;
ofs < < " \n *.lai " ;
ofs < < " \n *.la " ;
ofs < < " \n *.a " ;
ofs < < " \n *.lib " ;
ofs < < " \n " ;
ofs < < " \n # Executables " ;
ofs < < " \n *.exe " ;
ofs < < " \n *.out " ;
ofs < < " \n *.app " ;
ofs < < " \n " ;
ofs < < " \n # other " ;
ofs < < " \n *.log " ;
ofs < < " \n *.zip " ;
ofs < < " \n *.ini " ;
ofs < < " \n " ;
ofs < < " \n ######################## CMAKE IGNORES " ;
ofs < < " \n CMakeLists.txt.user " ;
ofs < < " \n CMakeCache.txt " ;
ofs < < " \n CMakeFiles " ;
ofs < < " \n CMakeScripts " ;
ofs < < " \n Testing " ;
ofs < < " \n Makefile " ;
ofs < < " \n cmake_install.cmake " ;
ofs < < " \n install_manifest.txt " ;
ofs < < " \n compile_commands.json " ;
ofs < < " \n CTestTestfile.cmake " ;
ofs < < " \n _deps " ;
ofs < < " \n " ;
ofs < < " \n ######################## BUILD IGNORES " ;
ofs < < " \n build/ " ;
ofs . close ( ) ;
ofs . clear ( ) ;
}
////////////////////////////////////////////////////////////
// Generate Script files
////////////////////////////////////////////////////////////
bool have_platform_option = argParser . ContainsOption ( " -p " ) ;
bool gen_windows = ( ! have_platform_option | | ( argParser . GetOptionValue ( " -p " ) . values [ 0 ] = = " win " | | argParser . GetOptionValue ( " -p " ) . values [ 0 ] = = " both " ) ) ;
bool gen_linux = ( have_platform_option & & ( argParser . GetOptionValue ( " -p " ) . values [ 0 ] = = " linux " | | argParser . GetOptionValue ( " -p " ) . values [ 0 ] = = " both " ) ) ;
std : : string vs_version = " \" Visual Studio 16 2019 \" " ;
if ( argParser . ContainsOption ( " -s " ) )
{
if ( argParser . GetOptionValue ( " -s " ) . values [ 0 ] = = " 17 " )
vs_version = " \" Visual Studio 15 2017 \" " ;
if ( argParser . GetOptionValue ( " -s " ) . values [ 0 ] = = " 22 " )
vs_version = " \" Visual Studio 17 2022 \" " ;
}
std : : filesystem : : path script_dir = root / " scripts " ;
if ( gen_windows )
{
// CONFIG
std : : filesystem : : path config_file = script_dir / " config.bat " ;
ofs = std : : ofstream ( config_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the config script file: " < < config_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating config script file: " < < config_file . string ( ) . c_str ( ) ;
ofs < < " @echo off " ;
ofs < < " \n REM This script expects to be run from the parent directory " ;
ofs < < " \n REM ex. scripts/cmconfig.bat " ;
ofs < < " \n @echo off " ;
ofs < < " \n \n cmake -Wno-dev -B build/ -S . -G " < < vs_version . c_str ( ) < < " -A x64 " ;
ofs . close ( ) ;
ofs . clear ( ) ;
// BUILD
std : : filesystem : : path build_file = script_dir / " build.bat " ;
ofs = std : : ofstream ( build_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the build script file: " < < build_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating build script file: " < < build_file . string ( ) . c_str ( ) ;
ofs < < " @echo off " ;
ofs < < " \n REM This script expects to be run from the parent directory " ;
ofs < < " \n REM ex. scripts/build.bat " ;
ofs < < " \n \n IF not exist build/ ( " ;
ofs < < " \n \t echo This script needs to be run from the directory above build/ " ;
ofs < < " \n \t goto END " ;
ofs < < " \n ) " ;
ofs < < " \n \n IF \" %~1 \" == \" r \" ( " ;
ofs < < " \n \t cmake --build build/ --target ALL_BUILD --config Release " ;
ofs < < " \n ) ELSE ( " ;
ofs < < " \n \t cmake --build build/ --target ALL_BUILD --config Debug " ;
ofs < < " \n ) " ;
ofs < < " \n \n :END " ;
ofs . close ( ) ;
ofs . clear ( ) ;
// CLEAN
std : : filesystem : : path clean_file = script_dir / " clean.bat " ;
ofs = std : : ofstream ( clean_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the clean script file: " < < clean_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating clean script file: " < < clean_file . string ( ) . c_str ( ) ;
ofs < < " @echo off " ;
ofs < < " \n \n IF not exist build/ ( " ;
ofs < < " \n \t echo This script needs to be run from the directory above build/ " ;
ofs < < " \n \t goto END " ;
ofs < < " \n ) " ;
ofs < < " \n \n echo Removing the build directory " ;
ofs < < " \n del /s /q build " ;
ofs < < " \n rd /s /q build " ;
ofs < < " \n mkdir build " ;
ofs < < " \n \n :END " ;
ofs . close ( ) ;
ofs . clear ( ) ;
}
if ( gen_linux )
{
// CONFIG
std : : filesystem : : path config_file = script_dir / " config.sh " ;
ofs = std : : ofstream ( config_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the config script file: " < < config_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating config script file: " < < config_file . string ( ) . c_str ( ) ;
ofs < < " #! /bin/sh " ;
ofs < < " \n # This script expects to be run from the parent directory " ;
ofs < < " \n # ex. scripts/cmconfig.sh " ;
ofs < < " \n \n cmake -S . -B build/ " ;
ofs . close ( ) ;
ofs . clear ( ) ;
// BUILD
std : : filesystem : : path build_file = script_dir / " build.sh " ;
ofs = std : : ofstream ( build_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the build script file: " < < build_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating build script file: " < < build_file . string ( ) . c_str ( ) ;
ofs < < " #! /bin/sh " ;
ofs < < " \n # This script expects to be run from the parent directory " ;
ofs < < " \n # ex. scripts/build.sh " ;
ofs < < " \n \n cmake -C build/ " ;
ofs . close ( ) ;
ofs . clear ( ) ;
}
////////////////////////////////////////////////////////////
// Generate Main.cpp files
////////////////////////////////////////////////////////////
// Check if there is a root project executable
if ( ! argParser . ContainsOption ( " -r " ) )
{
if ( GenerateMainFile ( project_name , project_name , root / " src/main.cpp " ) > 0 )
return 1 ;
}
// Generate Main files for all libraries/submodules
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
std : : filesystem : : path location = root / " src " ;
location / = libraries [ i ] ;
if ( GenerateMainFile ( project_name , libraries [ i ] , location / " main.cpp " ) > 0 )
return 1 ;
}
// Generate Main files for all libraries/submodules
for ( int i = 0 ; i < submods . size ( ) ; i + + )
{
std : : filesystem : : path location = root / " src " ;
location / = submods [ i ] ;
if ( GenerateMainFile ( project_name , submods [ i ] , location / " main.cpp " ) > 0 )
return 1 ;
}
std : : cout < < " \n \n New project generated! " ;
return 0 ;
}
int GenerateLibCMakeFile ( std : : string name , std : : filesystem : : path location )
{
std : : filesystem : : path cmake_file = location / std : : filesystem : : path ( " CMakeLists.txt " ) ;
std : : ofstream ofs ( cmake_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the CMake file: " < < cmake_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating CMake file: " < < cmake_file . string ( ) . c_str ( ) ;
ofs < < " \n \n set(MODULE_NAME " < < name < < " ) " ;
ofs < < " \n # specify the libraries source files " ;
ofs < < " \n set( " < < name < < " _SRC " ;
ofs < < " \n \t main.cpp " ;
ofs < < " \n ) " ;
ofs < < " \n \n # add the library " ;
ofs < < " \n add_library(${MODULE_NAME} ${ " < < name < < " _SRC}) " ;
ofs < < " \n \n target_include_directories(${MODULE_NAME} " ;
ofs < < " \n \t PUBLIC \" ${PROJECT_BINARY_DIR} \" " ;
ofs < < " \n ) " ;
ofs . close ( ) ;
ofs . clear ( ) ;
return 0 ;
}
int GenerateSubmodCMakeFile ( std : : string name , std : : filesystem : : path location , std : : vector < std : : string > & libraries )
{
std : : filesystem : : path cmake_file = location / std : : filesystem : : path ( " CMakeLists.txt " ) ;
std : : ofstream ofs ( cmake_file . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the CMake file: " < < cmake_file . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating CMake file: " < < cmake_file . string ( ) . c_str ( ) ;
ofs < < " \n \n set(MODULE_NAME " < < name < < " ) " ;
ofs < < " \n # specify the libraries source files " ;
ofs < < " \n set( " < < name < < " _SRC " ;
ofs < < " \n \t main.cpp " ;
ofs < < " \n ) " ;
ofs < < " \n \n # add the executable " ;
ofs < < " \n add_executable(${MODULE_NAME} ${ " < < name < < " _SRC}) " ;
ofs < < " \n \n target_include_directories(${MODULE_NAME} " ;
ofs < < " \n \t PUBLIC \" ${PROJECT_BINARY_DIR} \" " ;
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
ofs < < " \n \t PUBLIC ../ " < < libraries [ i ] . c_str ( ) ;
}
ofs < < " \n ) " ;
// link to libs
ofs < < " \n \n target_link_directories(${MODULE_NAME} " ;
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
ofs < < " \n \t PRIVATE ../ " < < libraries [ i ] . c_str ( ) ;
}
ofs < < " \n ) " ;
ofs < < " \n \n target_link_libraries(${MODULE_NAME} " ;
for ( int i = 0 ; i < libraries . size ( ) ; i + + )
{
ofs < < " " < < libraries [ i ] . c_str ( ) ;
}
ofs < < " ) " ;
ofs . close ( ) ;
ofs . clear ( ) ;
return 0 ;
}
int GenerateMainFile ( std : : string project_name , std : : string mod_name , std : : filesystem : : path location )
{
std : : ofstream ofs = std : : ofstream ( location . string ( ) . c_str ( ) ) ;
if ( ! ofs . is_open ( ) )
{
std : : cout < < " \n Could not generate the config script file: " < < location . string ( ) . c_str ( ) ;
return 1 ;
}
std : : cout < < " \n Generating main.cpp file: " < < location . string ( ) . c_str ( ) ;
ofs < < " \n \n #include <iostream> " ;
ofs < < " \n #include < " < < project_name < < " Config.h> " ;
ofs < < " \n \n int main(int argc, char** argv) " ;
ofs < < " \n { " ;
ofs < < " \n \t std::cout << \" Hello, World! \" ; " ;
ofs < < " \n \t std::cout << \" \\ nThis is " < < mod_name < < " version: \" << " < < project_name < < " _VERSION_MAJOR << \" . \" << " < < project_name < < " _VERSION_MINOR << \" . \" << " < < project_name < < " _VERSION_PATCH; " ;
ofs < < " \n \t return 0; " ;
ofs < < " \n } " ;
ofs . close ( ) ;
ofs . clear ( ) ;
return 0 ;
}