refactor generate_project code

self-hosting
MoAlyousef 4 years ago
parent 76a4367b57
commit 4688ba718c

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
project(cmkr VERSION 0.1.0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(cmkr VERSION 0.1.0)
set(CMKRLIB_SOURCES set(CMKRLIB_SOURCES
"src/args.cpp" "src/args.cpp"
"src/gen.cpp" "src/gen.cpp"

@ -1,5 +1,6 @@
#include "build.h" #include "build.h"
#include "error.h" #include "error.h"
#include "gen.h"
#include <filesystem> #include <filesystem>
#include <sstream> #include <sstream>
@ -14,8 +15,10 @@ namespace cmkr::build {
int run(int argc, char **argv) { int run(int argc, char **argv) {
std::stringstream ss; std::stringstream ss;
std::string bin_dir = "bin"; std::string bin_dir = "bin";
if (!std::filesystem::exists("CMakeLists.txt")) 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"); const auto toml = toml::parse("cmake.toml");
if (toml.contains("cmake")) { if (toml.contains("cmake")) {

@ -1,14 +1,19 @@
#include "gen.h" #include "gen.h"
#include "error.h" #include "error.h"
#include "literals.h"
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <string>
#include <string_view>
#include <toml.hpp> #include <toml.hpp>
namespace fs = std::filesystem; namespace fs = std::filesystem;
namespace cmkr::gen { namespace cmkr::gen {
@ -28,47 +33,34 @@ inline std::string to_upper(const std::string &str) {
int generate_project(const char *str) { int generate_project(const char *str) {
fs::create_directory("src"); 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")) { if (!strcmp(str, "exe")) {
std::ofstream ofs("src/main.cpp"); (void)snprintf(mainbuf, 100, hello_world, "main");
if (ofs.is_open()) { } else if (!strcmp(str, "static") || !strcmp(str, "shared")) {
ofs << "#include <iostream>\n\nint main() {\n\tstd::cout << \"Hello world!\" << " fs::create_directory("include");
"std::endl;\n}"; (void)snprintf(mainbuf, 100, hello_world, "test");
} else {
throw std::runtime_error("Unknown project type. Types are exe, shared, static!");
} }
ofs.flush();
ofs.close();
std::ofstream ofs2("cmake.toml"); std::ofstream ofs("src/main.cpp");
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();
} else if (!strcmp(str, "static") || !strcmp(str, "shared")) {
std::ofstream ofs("src/lib.cpp");
if (ofs.is_open()) { if (ofs.is_open()) {
ofs << "int test() {\n\treturn 0;\n}"; ofs << mainbuf;
} }
ofs.flush(); ofs.flush();
ofs.close(); ofs.close();
std::ofstream ofs2("cmake.toml"); std::ofstream ofs2("cmake.toml");
if (ofs2.is_open()) { if (ofs2.is_open()) {
ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string() ofs2 << tomlbuf;
<< "\"\nversion = "
"\"0.1.0\"\n\n[[bin]]\nname = \""
<< dir_name.string() << "\"\nsources = [\"src/lib.cpp\"]\ntype = \"" << str
<< "\"\n";
} }
ofs2.flush(); ofs2.flush();
ofs2.close(); ofs2.close();
} else {
throw std::runtime_error("Unknown project type. Types are exe, shared, static!");
}
return 0; return 0;
} }
@ -82,11 +74,13 @@ int generate_cmake(const char *path) {
const std::string cmake_min = toml::find(cmake, "minimum").as_string(); const std::string cmake_min = toml::find(cmake, "minimum").as_string();
ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n"; ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n";
ss << "set(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n";
if (cmake.contains("cpp-flags")) { if (cmake.contains("cpp-flags")) {
ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}\""; ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}\"";
const auto flags = toml::find(cmake, "cpp-flags").as_array(); const auto flags = toml::find(cmake, "cpp-flags").as_array();
for (const auto &flag : flags) { for (const auto &flag : flags) {
ss << " " << std::string(flag.as_string()); ss << " " << std::string_view(flag.as_string());
} }
ss << "\")\n\n"; ss << "\")\n\n";
} }
@ -95,7 +89,7 @@ int generate_cmake(const char *path) {
ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}\""; ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}\"";
const auto flags = toml::find(cmake, "c-flags").as_array(); const auto flags = toml::find(cmake, "c-flags").as_array();
for (const auto &flag : flags) { for (const auto &flag : flags) {
ss << " " << std::string(flag.as_string()); ss << " " << std::string_view(flag.as_string());
} }
ss << "\")\n\n"; ss << "\")\n\n";
} }
@ -104,7 +98,7 @@ int generate_cmake(const char *path) {
ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}\""; ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}\"";
const auto flags = toml::find(cmake, "link-flags").as_array(); const auto flags = toml::find(cmake, "link-flags").as_array();
for (const auto &flag : flags) { for (const auto &flag : flags) {
ss << " " << std::string(flag.as_string()); ss << " " << std::string_view(flag.as_string());
} }
ss << "\")\n\n"; 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")) { if (toml.contains("bin")) {
const auto &bins = toml::find(toml, "bin").as_array(); const auto &bins = toml::find(toml, "bin").as_array();

@ -0,0 +1,39 @@
#pragma once
const char *hello_world = R"lit(
#include <iostream>
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";
Loading…
Cancel
Save