|
|
|
|
@ -17,6 +17,11 @@
|
|
|
|
|
#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)
|
|
|
|
|
@ -35,6 +40,10 @@ int main(int argc, char** argv)
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
@ -52,6 +61,62 @@ int main(int argc, char** argv)
|
|
|
|
|
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
|
|
|
|
|
@ -92,6 +157,37 @@ int main(int argc, char** argv)
|
|
|
|
|
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 << "\nCould 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 << "\nCould not create submodule directory: " << location.c_str();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GenerateSubmodCMakeFile(submods[i], location, libraries) > 0)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
// Generate CMake files
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
@ -127,20 +223,56 @@ int main(int argc, char** argv)
|
|
|
|
|
ofs << "\nset(CMAKE_CXX_STANDARD " << cversion << ")";
|
|
|
|
|
ofs << "\nset(CMAKE_CXX_STANDARD_REQUIRED True)";
|
|
|
|
|
|
|
|
|
|
ofs << "\n# setup target output directories";
|
|
|
|
|
ofs << "\nset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)";
|
|
|
|
|
ofs << "\nset(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)";
|
|
|
|
|
ofs << "\nset(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\nconfigure_file(" << project_name << "Config.h.in " << project_name << "Config.h)";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\n# specify the project source files";
|
|
|
|
|
ofs << "\nset( " << jpUtils::StringManip::ToUpper(project_name) << "_SRC";
|
|
|
|
|
ofs << "\n\tsrc/main.cpp";
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
// remove root executable if the option is set
|
|
|
|
|
if (!argParser.ContainsOption("-r"))
|
|
|
|
|
{
|
|
|
|
|
ofs << "\n\n# specify the project source files";
|
|
|
|
|
ofs << "\nset( " << jpUtils::StringManip::ToUpper(project_name) << "_SRC";
|
|
|
|
|
ofs << "\n\tsrc/main.cpp";
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\n# add the executable";
|
|
|
|
|
ofs << "\nadd_executable(${PROJECT_NAME} ${" << jpUtils::StringManip::ToUpper(project_name) << "_SRC})";
|
|
|
|
|
ofs << "\n\n# add the executable";
|
|
|
|
|
ofs << "\nadd_executable(${PROJECT_NAME} ${" << jpUtils::StringManip::ToUpper(project_name) << "_SRC})";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\ntarget_include_directories(${PROJECT_NAME}";
|
|
|
|
|
ofs << "\n\tPUBLIC \"${PROJECT_BINARY_DIR}\"";
|
|
|
|
|
ofs << "\n\tPUBLIC src";
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
ofs << "\n\ntarget_include_directories(${PROJECT_NAME}";
|
|
|
|
|
ofs << "\n\tPUBLIC \"${PROJECT_BINARY_DIR}\"";
|
|
|
|
|
ofs << "\n\tPUBLIC src";
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
|
|
|
|
|
// Link to any libs that exist
|
|
|
|
|
ofs << "\n\ntarget_link_directories(${PROJECT_NAME} ";
|
|
|
|
|
for (int i = 0; i < libraries.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
ofs << "\n\tPRIVATE ../" << libraries[i].c_str();
|
|
|
|
|
}
|
|
|
|
|
ofs << ")";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\ntarget_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 << "\nadd_subdirectory(src/" << libraries[i].c_str() << ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < submods.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
ofs << "\nadd_subdirectory(src/" << submods[i].c_str() << ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ofs.close();
|
|
|
|
|
ofs.clear();
|
|
|
|
|
@ -283,6 +415,16 @@ int main(int argc, char** argv)
|
|
|
|
|
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";
|
|
|
|
|
|
|
|
|
|
@ -303,7 +445,7 @@ int main(int argc, char** argv)
|
|
|
|
|
ofs << "\nREM This script expects to be run from the parent directory";
|
|
|
|
|
ofs << "\nREM ex. scripts/cmconfig.bat";
|
|
|
|
|
ofs << "\n@echo off";
|
|
|
|
|
ofs << "\n\ncmake -Wno-dev -B build/ -S . -G \"Visual Studio 16 2019\" -A x64";
|
|
|
|
|
ofs << "\n\ncmake -Wno-dev -B build/ -S . -G " << vs_version.c_str() << " -A x64";
|
|
|
|
|
ofs.close();
|
|
|
|
|
ofs.clear();
|
|
|
|
|
|
|
|
|
|
@ -353,6 +495,7 @@ int main(int argc, char** argv)
|
|
|
|
|
ofs << "\n\necho Removing the build directory";
|
|
|
|
|
ofs << "\ndel /s /q build";
|
|
|
|
|
ofs << "\nrd /s /q build";
|
|
|
|
|
ofs << "\nmkdir build";
|
|
|
|
|
ofs << "\n\n:END";
|
|
|
|
|
ofs.close();
|
|
|
|
|
ofs.clear();
|
|
|
|
|
@ -374,7 +517,7 @@ int main(int argc, char** argv)
|
|
|
|
|
ofs << "#! /bin/sh";
|
|
|
|
|
ofs << "\n# This script expects to be run from the parent directory";
|
|
|
|
|
ofs << "\n# ex. scripts/cmconfig.sh";
|
|
|
|
|
ofs << "\n\ncmake -Wno-dev -DBOX2D_BUILD_TESTBED=OFF -S . -B build/";
|
|
|
|
|
ofs << "\n\ncmake -S . -B build/";
|
|
|
|
|
ofs.close();
|
|
|
|
|
ofs.clear();
|
|
|
|
|
|
|
|
|
|
@ -392,36 +535,155 @@ int main(int argc, char** argv)
|
|
|
|
|
ofs << "#! /bin/sh";
|
|
|
|
|
ofs << "\n# This script expects to be run from the parent directory";
|
|
|
|
|
ofs << "\n# ex. scripts/build.sh";
|
|
|
|
|
ofs << "\n\nmake -C build/";
|
|
|
|
|
ofs << "\n\ncmake -C build/";
|
|
|
|
|
ofs.close();
|
|
|
|
|
ofs.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
// Generate Main.cpp
|
|
|
|
|
// Generate Main.cpp files
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
std::filesystem::path main_file = root / "src/main.cpp";
|
|
|
|
|
ofs = std::ofstream(main_file.string().c_str());
|
|
|
|
|
|
|
|
|
|
// 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\nNew 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 << "\nCould not generate the CMake file: " << cmake_file.string().c_str();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "\nGenerating CMake file: " << cmake_file.string().c_str();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ofs << "\n\nset(MODULE_NAME " << name << ")";
|
|
|
|
|
|
|
|
|
|
ofs << "\n# specify the libraries source files";
|
|
|
|
|
ofs << "\nset( " << name << "_SRC";
|
|
|
|
|
ofs << "\n\tmain.cpp";
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ofs << "\n\n# add the library";
|
|
|
|
|
ofs << "\nadd_library(${MODULE_NAME} ${" << name << "_SRC})";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\ntarget_include_directories(${MODULE_NAME}";
|
|
|
|
|
ofs << "\n\tPUBLIC \"${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 << "\nCould not generate the CMake file: " << cmake_file.string().c_str();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "\nGenerating CMake file: " << cmake_file.string().c_str();
|
|
|
|
|
|
|
|
|
|
ofs << "\n\nset(MODULE_NAME " << name << ")";
|
|
|
|
|
|
|
|
|
|
ofs << "\n# specify the libraries source files";
|
|
|
|
|
ofs << "\nset( " << name << "_SRC";
|
|
|
|
|
ofs << "\n\tmain.cpp";
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ofs << "\n\n# add the executable";
|
|
|
|
|
ofs << "\nadd_executable(${MODULE_NAME} ${" << name << "_SRC})";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\ntarget_include_directories(${MODULE_NAME}";
|
|
|
|
|
ofs << "\n\tPUBLIC \"${PROJECT_BINARY_DIR}\"";
|
|
|
|
|
for (int i = 0; i < libraries.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
ofs << "\n\tPUBLIC ../" << libraries[i].c_str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
|
|
|
|
|
// link to libs
|
|
|
|
|
ofs << "\n\ntarget_link_directories(${MODULE_NAME} ";
|
|
|
|
|
for (int i = 0; i < libraries.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
ofs << "\n\tPRIVATE ../" << libraries[i].c_str();
|
|
|
|
|
}
|
|
|
|
|
ofs << "\n)";
|
|
|
|
|
|
|
|
|
|
ofs << "\n\ntarget_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 << "\nCould not generate the config script file: " << main_file.string().c_str();
|
|
|
|
|
std::cout << "\nCould not generate the config script file: " << location.string().c_str();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "\nGenerating config script file: " << main_file.string().c_str();
|
|
|
|
|
std::cout << "\nGenerating main.cpp file: " << location.string().c_str();
|
|
|
|
|
|
|
|
|
|
ofs << "\n\n#include <iostream>";
|
|
|
|
|
ofs << "\n#include <" << project_name << "Config.h>";
|
|
|
|
|
ofs << "\n\nint main(int argc, char** argv)";
|
|
|
|
|
ofs << "\n{";
|
|
|
|
|
ofs << "\n\tstd::cout << \"Hello, World!\";";
|
|
|
|
|
ofs << "\n\tstd::cout << \"\\nThis is " << project_name << " version: \" << " << project_name << "_VERSION_MAJOR << \".\" << " << project_name << "_VERSION_MINOR << \".\" << " << project_name << "_VERSION_PATCH;";
|
|
|
|
|
ofs << "\n\tstd::cout << \"\\nThis is " << mod_name << " version: \" << " << project_name << "_VERSION_MAJOR << \".\" << " << project_name << "_VERSION_MINOR << \".\" << " << project_name << "_VERSION_PATCH;";
|
|
|
|
|
ofs << "\n\treturn 0;";
|
|
|
|
|
ofs << "\n}";
|
|
|
|
|
ofs.close();
|
|
|
|
|
ofs.clear();
|
|
|
|
|
|
|
|
|
|
std::cout << "\n\nNew project generated!";
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|