do the required only

self-hosting
MoAlyousef 4 years ago
parent 3ca8866752
commit 9782c40832

2
.gitignore vendored

@ -1,2 +1,4 @@
bin
compile_commands.json
.clangd
temp.*

@ -1,12 +1,18 @@
cmake_minimum_required(VERSION 3.0)
project(cmk)
project(cmkr)
project(cmkr VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMK_SRCS
set(cmkr_SOURCES
src/main.cpp
src/args.cpp
src/gen.cpp
)
add_executable(cmk ${CMK_SRCS})
target_compile_features(cmk PRIVATE cxx_std_17)
target_include_directories(cmk PRIVATE ${CMAKE_CURRENT_LIST_DIR}/vendor)
add_executable(cmkr ${cmkr_SOURCES})
target_compile_features(cmkr PRIVATE cxx_std_17)
target_include_directories(cmkr PRIVATE ${CMAKE_CURRENT_LIST_DIR}/vendor)

@ -1,13 +1,28 @@
[cmake]
minimum_required = "3.0"
[cmake] # required
minimum_required = "3.0" # required
arguments = [""] # optional
cpp_flags = [""] # optional
c_flags = [""] # optional
link_flags = [""] # optional
prefix_path = [""] # optional
export_compile_commands = true # optional
[project]
name = "cmk"
version = "0.1.0"
authors = ["MoAlyousef <mohammed.alyousef@neurosrg.com>"]
[project] # required
name = "cmkr" # required
version = "0.1.0" # required
languages = [""] # optional (C, CXX, OBJC, OBJCXX)
[[executable]]
name = "cmk"
sources = ["src/main.cpp"]
include_directories = ["vendor"]
compile_features = ["cxx_std_17"]
[[app]] # optional
name = "cmkr" # required
sources = ["src/main.cpp", "src/args.cpp", "src/gen.cpp", "src/help.cpp"] # required
headers = [""] # optional
include_directories = ["vendor"] # optional
compile_features = ["cxx_std_17"] # optional
# [[lib]] # optional
# name = "cmkr" # required
# sources = ["src/args.cpp", "src/gen.cpp", "src/help.cpp"] # required
# type = "shared" # required
# headers = [""] # optional
# include_directories = ["vendor"] # optional
# compile_features = ["cxx_std_17"] # optional

@ -0,0 +1,38 @@
#include "args.hpp"
#include "gen.hpp"
#include "help.hpp"
#include <cstdlib>
#include <stdexcept>
namespace cmkr::args {
std::string handle_args(std::vector<std::string> args) {
if (args.size() < 2)
throw std::runtime_error("Please provide command line arguments!");
std::string main_arg = args[1];
if (main_arg == "gen") {
cmkr::gen::generate_cmake();
return "Generation successful!";
} else if (main_arg == "help") {
return cmkr::help::help_msg;
} else if (main_arg == "version") {
return cmkr::help::version;
} else if (main_arg == "init") {
if (args.size() < 3)
throw std::runtime_error("Please provide a project type!");
cmkr::gen::generate_project(args[2]);
return "Directory initialized!";
} else if (main_arg == "run") {
std::string command = "cmake -S. -Bbin ";
if (args.size() > 2) {
for (int i = 2; i < args.size(); ++i) {
command += args[i] + " ";
}
}
command += "&& cmake --build bin";
system(command.c_str());
return "Run completed!";
} else {
return "Unknown argument!";
}
}
} // namespace cmkr::args

@ -0,0 +1,8 @@
#pragma once
#include <string>
#include <vector>
namespace cmkr::args {
std::string handle_args(std::vector<std::string> args);
}

@ -0,0 +1,129 @@
#include "gen.hpp"
#include <filesystem>
#include <fstream>
#include <sstream>
#include <stdexcept>
#include <toml.hpp>
namespace fs = std::filesystem;
namespace cmkr::gen {
namespace detail {
inline std::string to_upper(const std::string &str) {
std::string temp;
temp.reserve(str.size());
for (auto c : str) {
temp.push_back(toupper(c));
}
return temp;
}
} // namespace detail
void generate_project(const std::string &str) {
fs::create_directory("src");
auto dir_name = fs::current_path().stem();
if (str == "app") {
std::ofstream ofs("src/main.cpp");
if (ofs.is_open()) {
ofs << "#include <iostream>\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_required = \"3.0\"\n\n[project]\nname = \""
<< dir_name.string()
<< "\"\nversion = "
"\"0.1.0\"\n\n[[app]]\nname = \""
<< dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\n";
}
ofs2.flush();
ofs2.close();
} else if (str == "static") {
std::ofstream ofs2("cmake.toml");
if (ofs2.is_open()) {
ofs2 << "[cmake]\nminimum_required = \"3.0\"\n\n[project]\nname = \""
<< dir_name.string()
<< "\"\nversion = "
"\"0.1.0\"\n\n[[lib]]\nname = \""
<< dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\ntype = \"static\"\n";
}
ofs2.flush();
ofs2.close();
} else if (str == "shared") {
std::ofstream ofs2("cmake.toml");
if (ofs2.is_open()) {
ofs2 << "[cmake]\nminimum_required = \"3.0\"\n\n[project]\nname = \""
<< dir_name.string()
<< "\"\nversion = "
"\"0.1.0\"\n\n[[lib]]\nname = \""
<< dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\ntype = \"shared\"\n";
}
ofs2.flush();
ofs2.close();
} else {
throw std::runtime_error("Unknown project type. Types are app, shared, static!");
}
}
void generate_cmake() {
std::stringstream ss;
const auto toml = toml::parse("cmake.toml");
const auto &cmake = toml::find(toml, "cmake");
const std::string cmake_min = toml::find(cmake, "minimum_required").as_string();
const auto &project = toml::find(toml, "project");
const std::string proj_name = toml::find(project, "name").as_string();
const std::string proj_version = toml::find(project, "version").as_string();
ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n"
<< "project(" << proj_name << " VERSION " << proj_version << ")\n\n";
if (toml.contains("app")) {
const auto &bins = toml::find(toml, "app");
for (auto i = 0; i < bins.size(); ++i) {
const auto bin = toml::find(bins, i);
const std::string bin_name = toml::find(bin, "name").as_string();
const auto srcs = toml::find(bin, "sources");
ss << "set(" << detail::to_upper(bin_name) << "_SOURCES\n";
for (auto j = 0; j < srcs.size(); ++j) {
const std::string source = toml::find(srcs, i).as_string();
ss << "\t" << source << "\n";
}
ss << "\t)\n\n"
<< "add_executable(" << bin_name << " ${" << detail::to_upper(bin_name)
<< "_SOURCES})\n\n";
}
}
if (toml.contains("lib")) {
const auto &libs = toml::find(toml, "lib");
for (auto i = 0; i < libs.size(); ++i) {
const auto lib = toml::find(libs, i);
const std::string lib_name = toml::find(lib, "name").as_string();
const std::string type = toml::find(lib, "type").as_string();
const auto srcs = toml::find(lib, "sources");
ss << "set(" << detail::to_upper(lib_name) << "_SOURCES\n";
for (auto j = 0; j < srcs.size(); ++j) {
const std::string source = toml::find(srcs, i).as_string();
ss << "\t" << source << "\n";
}
ss << "\t)\n\n"
<< "add_library(" << lib_name << " " << detail::to_upper(type) << " ${"
<< detail::to_upper(lib_name) << "_SOURCES})\n\n";
}
}
std::ofstream ofs("CMakeLists.txt");
if (ofs.is_open()) {
ofs << ss.rdbuf();
}
ofs.flush();
ofs.close();
}
} // namespace cmkr::gen

@ -0,0 +1,9 @@
#pragma once
#include <string>
namespace cmkr::gen {
void generate_project(const std::string &str);
void generate_cmake();
} // namespace cmkr::gen

@ -0,0 +1,17 @@
#pragma once
namespace cmkr::help {
const char *version = "cmkr version 0.1.0";
const char *help_msg = R"lit(
Usage: cmk [argument]
arguments:
init [app|shared|static] Starts a new project in the same directory.
gen Generates CMakeLists.txt file.
run Run cmake.
help Show help.
version Current cmkr version.
)lit";
}

@ -1,26 +1,20 @@
#include "args.hpp"
#include <iostream>
#include <string>
#include <toml.hpp>
#include <vector>
int main(int argc, char **argv) try {
std::vector<std::string> args;
for (int i = 0; i < argc; ++i)
args.push_back(argv[i]);
const auto data = toml::parse("../cmake.toml");
const auto &cmake = toml::find(data, "cmake");
const auto cmake_min = toml::find(cmake, "minimum_required");
const auto &project = toml::find(data, "project");
const auto name = toml::find(project, "name");
const auto version = toml::find(project, "version");
const auto &bin = toml::find(data, "executable");
const auto bin1 = toml::find(bin, 0);
const auto bin1_name = toml::find(bin1, "name");
std::cout << cmake_min << std::endl;
std::cout << name << std::endl;
std::cout << version << std::endl;
std::cout << bin.size() << std::endl;
std::cout << bin1_name << std::endl;
auto output = cmkr::args::handle_args(args);
std::cout << output << std::endl;
return 0;
} catch (const std::exception &e) {
std::cerr << e.what() << std::endl;
}
Loading…
Cancel
Save