support interfaces and aliases

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

@ -3,4 +3,6 @@
## 0.1.0 - Unreleased ## 0.1.0 - Unreleased
- 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,18 +96,35 @@ 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.
help Show help. help Show help.
version Current cmkr version. version Current cmkr version.
``` ```
The build command invokes cmake and the default build-system on your platform (unless a generator is specified), it also accepts extra cmake build arguments: The build command invokes cmake and the default build-system on your platform (unless a generator is specified), it also accepts extra cmake build arguments:
``` ```
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!");
} }
std::ofstream ofs("src/main.cpp"); if (strcmp(str, "interface")) {
if (ofs.is_open()) { std::ofstream ofs("src/main.cpp");
ofs << mainbuf; if (ofs.is_open()) {
ofs << mainbuf;
}
ofs.flush();
ofs.close();
} }
ofs.flush();
ofs.close();
std::ofstream ofs2("cmake.toml"); std::ofstream ofs2("cmake.toml");
if (ofs2.is_open()) { if (ofs2.is_open()) {
@ -77,7 +82,7 @@ int generate_cmake(const char *path) {
cmake::CMake cmake(path, false); cmake::CMake cmake(path, false);
std::stringstream ss; std::stringstream ss;
ss << "# This file was generated automatically by cmkr.\n\n"; ss << "# This file was generated automatically by cmkr.\n\n";
if (!cmake.cmake_version.empty()) { if (!cmake.cmake_version.empty()) {
ss << "cmake_minimum_required(VERSION " << cmake.cmake_version << ")\n\n"; ss << "cmake_minimum_required(VERSION " << cmake.cmake_version << ")\n\n";
@ -130,7 +135,7 @@ int generate_cmake(const char *path) {
} }
if (!dep.components.empty()) { if (!dep.components.empty()) {
ss << "COMPONENTS "; ss << "COMPONENTS ";
for (const auto &comp: dep.components) { for (const auto &comp : dep.components) {
ss << comp << " "; ss << comp << " ";
} }
} }
@ -151,8 +156,9 @@ 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,31 +171,47 @@ 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");
} }
ss << "set(" << detail::to_upper(bin.name) << "_SOURCES\n"; if (!bin.sources.empty()) {
for (const auto &src : bin.sources) { ss << "set(" << detail::to_upper(bin.name) << "_SOURCES\n";
auto path = fs::path(src); for (const auto &src : bin.sources) {
if (path.filename().stem().string() == "*") { auto path = fs::path(src);
auto ext = path.extension(); if (path.filename().stem().string() == "*") {
for (const auto& f: fs::directory_iterator(path.parent_path())) { auto ext = path.extension();
if (f.path().extension() == ext) { for (const auto &f : fs::directory_iterator(path.parent_path())) {
ss << "\t" << f.path() << "\n"; if (f.path().extension() == ext) {
ss << "\t" << f.path() << "\n";
}
} }
} else {
ss << "\t" << path << "\n";
} }
} else {
ss << "\t" << path << "\n";
} }
ss << "\t)\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";
} }
ss << "\t)\n\n"
<< add_command << "(" << bin.name << " " << bin_type << " ${"
<< detail::to_upper(bin.name) << "_SOURCES})\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,12 +8,12 @@ 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.
help Show help. help Show help.
version Current cmkr version. version Current cmkr version.
)lit"; )lit";
} }
} // namespace cmkr::help } // namespace cmkr::help

Loading…
Cancel
Save