support interfaces and aliases

self-hosting
Mohammed Alyousef 4 years ago
parent bce39a944d
commit 221003f199

@ -4,3 +4,5 @@
- Add support for globbing. - Add support for globbing.
- Add support for find_package components. - Add support for find_package components.
- Add options. - Add options.
- Support aliases.
- Support interface libs (header-only libs).

@ -85,6 +85,7 @@ APP_OTHER_STUFF = { comment = "does other stuff", value = false } # optional
name = "app" # required name = "app" # required
type = "exe" # required (exe || shared || static) type = "exe" # required (exe || shared || static)
sources = ["src/*.cpp"] # required, supports globbing sources = ["src/*.cpp"] # required, supports globbing
alias = "" # optional
include-dirs = [] # optional include-dirs = [] # optional
features = [] # optional features = [] # optional
defines = [] # optional defines = [] # optional
@ -95,7 +96,7 @@ The cmkr executable can be run from the command-line:
``` ```
Usage: cmkr [arguments] Usage: cmkr [arguments]
arguments: arguments:
init [exe|shared|static] Starts a new project in the same directory. init [exe|lib|shared|static|interface] Starts a new project in the same directory.
gen Generates CMakeLists.txt file. gen Generates CMakeLists.txt file.
build <extra cmake args> Run cmake and build. build <extra cmake args> Run cmake and build.
clean Clean the build directory. clean Clean the build directory.
@ -107,6 +108,23 @@ The build command invokes cmake and the default build-system on your platform (u
cmkr build --config Release cmkr build --config Release
``` ```
## Binary types
### exe
Executable binary.
### lib
Library, can be static or shared depending on the BUILD_SHARED_LIBS variable.
### static
Static library/archive.
### shared
Shared/dynamic library.
### interface
Header only library.
## Roadmap ## Roadmap
- Support more fields. - Support more fields.
- Support conditional cmake args somehow! - Support conditional cmake args somehow!

@ -27,6 +27,7 @@ struct Bin {
std::vector<std::string> features; std::vector<std::string> features;
std::vector<std::string> defines; std::vector<std::string> defines;
std::vector<std::string> link_libs; std::vector<std::string> link_libs;
std::string alias;
}; };
struct CMake { struct CMake {

@ -33,7 +33,8 @@ version = "0.1.0"
[[bin]] [[bin]]
name = "%s" name = "%s"
type = "%s" type = "%s"
sources = ["src/main.cpp"] sources = ["src/*.cpp"]
# alias = ""
# include-dirs = [] # include-dirs = []
# features = [] # features = []
# defines = [] # defines = []

@ -131,6 +131,8 @@ CMake::CMake(const std::string &path, bool build) {
b.sources = detail::to_string_vec(toml::find(bin, "sources").as_array()); b.sources = detail::to_string_vec(toml::find(bin, "sources").as_array());
b.alias = toml::find(bin, "alias").as_string();
if (bin.contains("include-dirs")) { if (bin.contains("include-dirs")) {
b.include_dirs = b.include_dirs =
detail::to_string_vec(toml::find(bin, "include-dirs").as_array()); detail::to_string_vec(toml::find(bin, "include-dirs").as_array());

@ -48,19 +48,24 @@ int generate_project(const char *str) {
const auto tomlbuf = detail::format(cmake_toml, dir_name.c_str(), dir_name.c_str(), str); const auto tomlbuf = detail::format(cmake_toml, dir_name.c_str(), dir_name.c_str(), str);
if (!strcmp(str, "exe")) { if (!strcmp(str, "exe")) {
mainbuf = detail::format(hello_world, "main"); mainbuf = detail::format(hello_world, "main");
} else if (!strcmp(str, "static") || !strcmp(str, "shared")) { } else if (!strcmp(str, "static") || !strcmp(str, "shared") !strcmp(str, "lib")) {
fs::create_directory("include"); fs::create_directory("include");
mainbuf = detail::format(hello_world, "test"); mainbuf = detail::format(hello_world, "test");
} else if (!strcmp(str, "interface")) {
fs::create_directory("include");
} else { } else {
throw std::runtime_error("Unknown project type. Types are exe, shared, static!"); throw std::runtime_error(
"Unknown project type. Types are exe, lib, shared, static, interface!");
} }
if (strcmp(str, "interface")) {
std::ofstream ofs("src/main.cpp"); std::ofstream ofs("src/main.cpp");
if (ofs.is_open()) { if (ofs.is_open()) {
ofs << mainbuf; 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()) {
@ -152,7 +157,8 @@ int generate_cmake(const char *path) {
if (!cmake.options.empty()) { if (!cmake.options.empty()) {
for (const auto &opt : cmake.options) { for (const auto &opt : cmake.options) {
ss << "option(" << opt.name << " \"" << opt.comment << "\" " << (opt.val ? "ON" : "OFF") << ")\n"; ss << "option(" << opt.name << " \"" << opt.comment << "\" "
<< (opt.val ? "ON" : "OFF") << ")\n";
} }
} }
@ -165,14 +171,19 @@ int generate_cmake(const char *path) {
if (bin.type == "exe") { if (bin.type == "exe") {
bin_type = ""; bin_type = "";
add_command = "add_executable"; add_command = "add_executable";
} else if (bin.type == "shared" || bin.type == "static") { } else if (bin.type == "shared" || bin.type == "static" ||
bin.type == "interface") {
bin_type = detail::to_upper(bin.type); bin_type = detail::to_upper(bin.type);
add_command = "add_library"; add_command = "add_library";
} else if (bin.type == "lib") {
bin_type = "";
add_command = "add_library";
} else { } else {
throw std::runtime_error( throw std::runtime_error(
"Unknown binary type! Supported types are exe, shared and static"); "Unknown binary type! Supported types are exe, shared and static");
} }
if (!bin.sources.empty()) {
ss << "set(" << detail::to_upper(bin.name) << "_SOURCES\n"; ss << "set(" << detail::to_upper(bin.name) << "_SOURCES\n";
for (const auto &src : bin.sources) { for (const auto &src : bin.sources) {
auto path = fs::path(src); auto path = fs::path(src);
@ -187,9 +198,20 @@ int generate_cmake(const char *path) {
ss << "\t" << path << "\n"; ss << "\t" << path << "\n";
} }
} }
ss << "\t)\n\n" ss << "\t)\n\n";
<< add_command << "(" << bin.name << " " << bin_type << " ${" }
<< detail::to_upper(bin.name) << "_SOURCES})\n\n";
ss << add_command << "(" << bin.name << " " << bin_type;
if (!bin.sources.empty()) {
ss << " ${" << detail::to_upper(bin.name) << "_SOURCES})\n\n";
} else {
ss << ")\n\n";
}
if (!bin.alias.empty()) {
ss << "add_library(" << bin.alias << " ALIAS " << bin.name << ")\n\n";
}
if (!bin.include_dirs.empty()) { if (!bin.include_dirs.empty()) {
ss << "target_include_directories(" << bin.name << " PUBLIC\n\t"; ss << "target_include_directories(" << bin.name << " PUBLIC\n\t";

@ -8,7 +8,7 @@ const char *message() noexcept {
return R"lit( return R"lit(
Usage: cmkr [arguments] Usage: cmkr [arguments]
arguments: arguments:
init [exe|shared|static] Starts a new project in the same directory. init [exe|lib|shared|static|interface] Starts a new project in the same directory.
gen Generates CMakeLists.txt file. gen Generates CMakeLists.txt file.
build <extra cmake args> Run cmake and build. build <extra cmake args> Run cmake and build.
clean Clean the build directory. clean Clean the build directory.

Loading…
Cancel
Save