diff --git a/CHANGELOG.md b/CHANGELOG.md index ababb85..2425f52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,4 +3,6 @@ ## 0.1.0 - Unreleased - Add support for globbing. - Add support for find_package components. -- Add options. \ No newline at end of file +- Add options. +- Support aliases. +- Support interface libs (header-only libs). \ No newline at end of file diff --git a/README.md b/README.md index 6f1d7f2..2ce5983 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ APP_OTHER_STUFF = { comment = "does other stuff", value = false } # optional name = "app" # required type = "exe" # required (exe || shared || static) sources = ["src/*.cpp"] # required, supports globbing +alias = "" # optional include-dirs = [] # optional features = [] # optional defines = [] # optional @@ -95,18 +96,35 @@ The cmkr executable can be run from the command-line: ``` Usage: cmkr [arguments] arguments: - init [exe|shared|static] Starts a new project in the same directory. - gen Generates CMakeLists.txt file. - build Run cmake and build. - clean Clean the build directory. - help Show help. - version Current cmkr version. + init [exe|lib|shared|static|interface] Starts a new project in the same directory. + gen Generates CMakeLists.txt file. + build Run cmake and build. + clean Clean the build directory. + help Show help. + 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: ``` 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 - Support more fields. - Support conditional cmake args somehow! diff --git a/include/cmake.hpp b/include/cmake.hpp index ada7381..677b3eb 100644 --- a/include/cmake.hpp +++ b/include/cmake.hpp @@ -27,6 +27,7 @@ struct Bin { std::vector features; std::vector defines; std::vector link_libs; + std::string alias; }; struct CMake { diff --git a/include/literals.h b/include/literals.h index 162779a..592e716 100644 --- a/include/literals.h +++ b/include/literals.h @@ -33,7 +33,8 @@ version = "0.1.0" [[bin]] name = "%s" type = "%s" -sources = ["src/main.cpp"] +sources = ["src/*.cpp"] +# alias = "" # include-dirs = [] # features = [] # defines = [] diff --git a/src/cmake.cpp b/src/cmake.cpp index b1b6ca3..931d968 100644 --- a/src/cmake.cpp +++ b/src/cmake.cpp @@ -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.alias = toml::find(bin, "alias").as_string(); + if (bin.contains("include-dirs")) { b.include_dirs = detail::to_string_vec(toml::find(bin, "include-dirs").as_array()); diff --git a/src/gen.cpp b/src/gen.cpp index 50ac553..83dcf85 100644 --- a/src/gen.cpp +++ b/src/gen.cpp @@ -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); if (!strcmp(str, "exe")) { 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"); mainbuf = detail::format(hello_world, "test"); + } else if (!strcmp(str, "interface")) { + fs::create_directory("include"); } 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 (ofs.is_open()) { - ofs << mainbuf; + if (strcmp(str, "interface")) { + std::ofstream ofs("src/main.cpp"); + if (ofs.is_open()) { + ofs << mainbuf; + } + ofs.flush(); + ofs.close(); } - ofs.flush(); - ofs.close(); std::ofstream ofs2("cmake.toml"); if (ofs2.is_open()) { @@ -77,7 +82,7 @@ int generate_cmake(const char *path) { cmake::CMake cmake(path, false); std::stringstream ss; ss << "# This file was generated automatically by cmkr.\n\n"; - + if (!cmake.cmake_version.empty()) { ss << "cmake_minimum_required(VERSION " << cmake.cmake_version << ")\n\n"; @@ -130,7 +135,7 @@ int generate_cmake(const char *path) { } if (!dep.components.empty()) { ss << "COMPONENTS "; - for (const auto &comp: dep.components) { + for (const auto &comp : dep.components) { ss << comp << " "; } } @@ -151,8 +156,9 @@ int generate_cmake(const char *path) { } if (!cmake.options.empty()) { - for (const auto &opt: cmake.options) { - ss << "option(" << opt.name << " \"" << opt.comment << "\" " << (opt.val ? "ON" : "OFF") << ")\n"; + for (const auto &opt : cmake.options) { + 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") { bin_type = ""; 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); add_command = "add_library"; + } else if (bin.type == "lib") { + bin_type = ""; + add_command = "add_library"; } else { throw std::runtime_error( "Unknown binary type! Supported types are exe, shared and static"); } - ss << "set(" << detail::to_upper(bin.name) << "_SOURCES\n"; - for (const auto &src : bin.sources) { - auto path = fs::path(src); - if (path.filename().stem().string() == "*") { - auto ext = path.extension(); - for (const auto& f: fs::directory_iterator(path.parent_path())) { - if (f.path().extension() == ext) { - ss << "\t" << f.path() << "\n"; + if (!bin.sources.empty()) { + ss << "set(" << detail::to_upper(bin.name) << "_SOURCES\n"; + for (const auto &src : bin.sources) { + auto path = fs::path(src); + if (path.filename().stem().string() == "*") { + auto ext = path.extension(); + for (const auto &f : fs::directory_iterator(path.parent_path())) { + 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()) { ss << "target_include_directories(" << bin.name << " PUBLIC\n\t"; diff --git a/src/help.cpp b/src/help.cpp index bbf744b..9104d5b 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -8,12 +8,12 @@ const char *message() noexcept { return R"lit( Usage: cmkr [arguments] arguments: - init [exe|shared|static] Starts a new project in the same directory. - gen Generates CMakeLists.txt file. - build Run cmake and build. - clean Clean the build directory. - help Show help. - version Current cmkr version. + init [exe|lib|shared|static|interface] Starts a new project in the same directory. + gen Generates CMakeLists.txt file. + build Run cmake and build. + clean Clean the build directory. + help Show help. + version Current cmkr version. )lit"; } } // namespace cmkr::help