From 4688ba718ce53d1a40e0eb73eec99c7fb4cd78fb Mon Sep 17 00:00:00 2001 From: MoAlyousef Date: Fri, 11 Sep 2020 18:01:26 +0300 Subject: [PATCH] refactor generate_project code --- CMakeLists.txt | 4 +-- src/build.cpp | 5 +++- src/gen.cpp | 74 ++++++++++++++++++++++---------------------------- src/literals.h | 39 ++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 44 deletions(-) create mode 100644 src/literals.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e7cc724..a2cbfa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required(VERSION 3.14) -project(cmkr VERSION 0.1.0) - set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +project(cmkr VERSION 0.1.0) + set(CMKRLIB_SOURCES "src/args.cpp" "src/gen.cpp" diff --git a/src/build.cpp b/src/build.cpp index 7a91f5b..66ab373 100644 --- a/src/build.cpp +++ b/src/build.cpp @@ -1,5 +1,6 @@ #include "build.h" #include "error.h" +#include "gen.h" #include #include @@ -14,8 +15,10 @@ namespace cmkr::build { int run(int argc, char **argv) { std::stringstream ss; std::string bin_dir = "bin"; + if (!std::filesystem::exists("CMakeLists.txt")) - throw std::runtime_error("No valid CMakeLists.txt found!"); + if (gen::generate_cmake(".")) + throw std::runtime_error("CMake generation failure!"); const auto toml = toml::parse("cmake.toml"); if (toml.contains("cmake")) { diff --git a/src/gen.cpp b/src/gen.cpp index 1a448f5..165d0e7 100644 --- a/src/gen.cpp +++ b/src/gen.cpp @@ -1,14 +1,19 @@ #include "gen.h" #include "error.h" +#include "literals.h" #include #include #include #include #include +#include #include +#include +#include #include + namespace fs = std::filesystem; namespace cmkr::gen { @@ -28,47 +33,34 @@ inline std::string to_upper(const std::string &str) { int generate_project(const char *str) { fs::create_directory("src"); - auto dir_name = fs::current_path().stem(); + auto dir_name = fs::current_path().stem().string(); + char mainbuf[100]; + // Assuming current standards of max filename length < 270 + char tomlbuf[1000]; + (void)snprintf(tomlbuf, 1000, cmake_toml, dir_name.c_str(), dir_name.c_str(), str); if (!strcmp(str, "exe")) { - std::ofstream ofs("src/main.cpp"); - if (ofs.is_open()) { - ofs << "#include \n\nint main() {\n\tstd::cout << \"Hello world!\" << " - "std::endl;\n}"; - } - ofs.flush(); - ofs.close(); - - std::ofstream ofs2("cmake.toml"); - if (ofs2.is_open()) { - ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string() - << "\"\nversion = " - "\"0.1.0\"\n\n[[bin]]\nname = \"" - << dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\ntype = \"" << str - << "\"\n"; - } - ofs2.flush(); - ofs2.close(); + (void)snprintf(mainbuf, 100, hello_world, "main"); } else if (!strcmp(str, "static") || !strcmp(str, "shared")) { - std::ofstream ofs("src/lib.cpp"); - if (ofs.is_open()) { - ofs << "int test() {\n\treturn 0;\n}"; - } - ofs.flush(); - ofs.close(); - - std::ofstream ofs2("cmake.toml"); - if (ofs2.is_open()) { - ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string() - << "\"\nversion = " - "\"0.1.0\"\n\n[[bin]]\nname = \"" - << dir_name.string() << "\"\nsources = [\"src/lib.cpp\"]\ntype = \"" << str - << "\"\n"; - } - ofs2.flush(); - ofs2.close(); + fs::create_directory("include"); + (void)snprintf(mainbuf, 100, hello_world, "test"); } else { throw std::runtime_error("Unknown project type. Types are exe, shared, static!"); } + + std::ofstream ofs("src/main.cpp"); + if (ofs.is_open()) { + ofs << mainbuf; + } + ofs.flush(); + ofs.close(); + + std::ofstream ofs2("cmake.toml"); + if (ofs2.is_open()) { + ofs2 << tomlbuf; + } + ofs2.flush(); + ofs2.close(); + return 0; } @@ -82,11 +74,13 @@ int generate_cmake(const char *path) { const std::string cmake_min = toml::find(cmake, "minimum").as_string(); ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n"; + ss << "set(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n"; + if (cmake.contains("cpp-flags")) { ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}\""; const auto flags = toml::find(cmake, "cpp-flags").as_array(); for (const auto &flag : flags) { - ss << " " << std::string(flag.as_string()); + ss << " " << std::string_view(flag.as_string()); } ss << "\")\n\n"; } @@ -95,7 +89,7 @@ int generate_cmake(const char *path) { ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}\""; const auto flags = toml::find(cmake, "c-flags").as_array(); for (const auto &flag : flags) { - ss << " " << std::string(flag.as_string()); + ss << " " << std::string_view(flag.as_string()); } ss << "\")\n\n"; } @@ -104,7 +98,7 @@ int generate_cmake(const char *path) { ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}\""; const auto flags = toml::find(cmake, "link-flags").as_array(); for (const auto &flag : flags) { - ss << " " << std::string(flag.as_string()); + ss << " " << std::string_view(flag.as_string()); } ss << "\")\n\n"; } @@ -155,8 +149,6 @@ int generate_cmake(const char *path) { } } - ss << "set(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n"; - if (toml.contains("bin")) { const auto &bins = toml::find(toml, "bin").as_array(); diff --git a/src/literals.h b/src/literals.h new file mode 100644 index 0000000..609167a --- /dev/null +++ b/src/literals.h @@ -0,0 +1,39 @@ +#pragma once + +const char *hello_world = R"lit( +#include + +int %s() { + std::cout << "Hello World!\n"; + return 0; +} +)lit"; + +const char *cmake_toml = R"lit( +[cmake] +minimum = "3.14" +# bin-dir = "" +# cpp-flags = [] +# c-flags = [] +# link-flags = [] +# subdirs = [] +# generator = "" +# arguments = [] + +[project] +name = "%s" +version = "0.1.0" + +# [find-package] + +# [fetch-content] + +[[bin]] +name = "%s" +type = "%s" +sources = ["src/main.cpp"] +# include-dirs = [] +# features = [] +# defines = [] +# link-libs = [] +)lit";