add globbing, package components and options

self-hosting
MoAlyousef 4 years ago
parent 12872a6f25
commit 3b09103d98

@ -0,0 +1,6 @@
# CHANGELOG
## 0.1.0 - Unreleased
- Add support for globbing.
- Add support for find_package components.
- Add options.

@ -6,19 +6,20 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(cmkr VERSION 0.1.0) project(cmkr VERSION 0.1.0)
set(CMKRLIB_SOURCES set(CMKRLIB_SOURCES
src/cmake.cpp "src/cmake.cpp"
src/gen.cpp "src/gen.cpp"
src/help.cpp "src/help.cpp"
src/build.cpp "src/build.cpp"
src/error.cpp "src/error.cpp"
) )
add_library(cmkrlib STATIC ${CMKRLIB_SOURCES}) add_library(cmkrlib STATIC ${CMKRLIB_SOURCES})
target_include_directories(cmkrlib PUBLIC target_include_directories(cmkrlib PUBLIC
include "include"
vendor "vendor"
) )
target_compile_features(cmkrlib PUBLIC target_compile_features(cmkrlib PUBLIC
@ -26,8 +27,8 @@ target_compile_features(cmkrlib PUBLIC
) )
set(CMKR_SOURCES set(CMKR_SOURCES
src/main.cpp "src/main.cpp"
src/args.cpp "src/args.cpp"
) )
add_executable(cmkr ${CMKR_SOURCES}) add_executable(cmkr ${CMKR_SOURCES})

@ -68,15 +68,19 @@ name = "app" # required
version = "0.1.0" # required version = "0.1.0" # required
[find-package] # optional, runs find_package, use "*" to ignore version [find-package] # optional, runs find_package, use "*" to ignore version
Boost = "1.74.0" # optional Boost = { version = "1.74.0", required = false, components = ["system"] } # optional
spdlog = "*"
[fetch-content] # optional, runs fetchContent [fetch-content] # optional, runs fetchContent
toml11 = { GIT_REPOSITORY = "https://github.com/ToruNiina/toml11", GIT_TAG = "v3.5.0" } # optional toml11 = { GIT_REPOSITORY = "https://github.com/ToruNiina/toml11", GIT_TAG = "v3.5.0" } # optional
[options] # optional
APP_BUILD_STUFF = false # optional
[[bin]] # required, can define several binaries [[bin]] # required, can define several binaries
name = "app" # required name = "app" # required
type = "exe" # required (exe || shared || static) type = "exe" # required (exe || shared || static)
sources = ["src/main.cpp"] # required sources = ["src/*.cpp"] # required, supports globbing
include-dirs = [] # optional include-dirs = [] # optional
features = [] # optional features = [] # optional
defines = [] # optional defines = [] # optional

@ -6,6 +6,18 @@
namespace cmkr::cmake { namespace cmkr::cmake {
struct Option {
std::string name;
bool val;
};
struct Package {
std::string name;
std::string version;
bool required = true;
std::vector<std::string> components;
};
struct Bin { struct Bin {
std::string name; std::string name;
std::string type; std::string type;
@ -28,7 +40,8 @@ struct CMake {
std::vector<std::string> build_args; std::vector<std::string> build_args;
std::string proj_name; std::string proj_name;
std::string proj_version; std::string proj_version;
std::map<std::string, std::string> packages; std::vector<Option> options;
std::vector<Package> packages;
std::map<std::string, std::map<std::string, std::string>> contents; std::map<std::string, std::map<std::string, std::string>> contents;
std::vector<Bin> binaries; std::vector<Bin> binaries;
CMake(const std::string &path, bool build); CMake(const std::string &path, bool build);

@ -28,6 +28,8 @@ version = "0.1.0"
# [fetch-content] # [fetch-content]
# [options]
[[bin]] [[bin]]
name = "%s" name = "%s"
type = "%s" type = "%s"

@ -68,9 +68,41 @@ CMake::CMake(const std::string &path, bool build) {
proj_version = toml::find(project, "version").as_string(); proj_version = toml::find(project, "version").as_string();
} }
if (toml.contains("options")) {
using opts_map = std::map<std::string, bool>;
const auto &opts = toml::find<opts_map>(toml, "options");
for (const auto opt: opts) {
Option o;
o.name = opt.first;
o.val = opt.second;
options.push_back(o);
}
}
if (toml.contains("find-package")) { if (toml.contains("find-package")) {
using pkg_map = std::map<std::string, std::string>; using pkg_map =
packages = toml::find<pkg_map>(toml, "find-package"); std::map<std::string, toml::basic_value<toml::discard_comments, std::unordered_map,
std::vector>>;
const auto &pkgs = toml::find<pkg_map>(toml, "find-package");
for (const auto &pkg : pkgs) {
Package p;
p.name = pkg.first;
if (pkg.second.is_string()) {
p.version = pkg.second.as_string();
} else {
if (pkg.second.contains("version")) {
p.version = toml::find(pkg.second, "version").as_string();
}
if (pkg.second.contains("required")) {
p.required = toml::find(pkg.second, "required").as_boolean();
}
if (pkg.second.contains("components")) {
p.components =
detail::to_string_vec(toml::find(pkg.second, "components").as_array());
}
}
packages.push_back(p);
}
} }
if (toml.contains("fetch-content")) { if (toml.contains("fetch-content")) {

@ -121,12 +121,20 @@ int generate_cmake(const char *path) {
if (!cmake.packages.empty()) { if (!cmake.packages.empty()) {
for (const auto &dep : cmake.packages) { for (const auto &dep : cmake.packages) {
ss << "find_package(" << dep.first; ss << "find_package(" << dep.name << " ";
if (dep.second != "*") { if (dep.version != "*") {
ss << " " << dep.second << " REQUIRED)\n"; ss << dep.version << " ";
} else { }
ss << " REQUIRED)\n"; if (dep.required) {
ss << "REQUIRED ";
} }
if (!dep.components.empty()) {
ss << "COMPONENTS ";
for (const auto &comp: dep.components) {
ss << comp << " ";
}
}
ss << ")\n\n";
} }
} }
@ -142,6 +150,14 @@ int generate_cmake(const char *path) {
} }
} }
if (!cmake.options.empty()) {
for (const auto &opt: cmake.options) {
ss << "option(" << opt.name << " \"" << opt.name << "\" " << (opt.val ? "ON" : "OFF") << ")\n";
}
}
ss << "\n";
if (!cmake.binaries.empty()) { if (!cmake.binaries.empty()) {
for (const auto &bin : cmake.binaries) { for (const auto &bin : cmake.binaries) {
std::string bin_type; std::string bin_type;
@ -159,7 +175,17 @@ int generate_cmake(const char *path) {
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) {
ss << "\t" << src << "\n"; 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 << "\n";
}
}
} else {
ss << "\t" << path << "\n";
}
} }
ss << "\t)\n\n" ss << "\t)\n\n"
<< add_command << "(" << bin.name << " " << bin_type << " ${" << add_command << "(" << bin.name << " " << bin_type << " ${"
@ -168,7 +194,7 @@ int generate_cmake(const char *path) {
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";
for (const auto &inc : bin.include_dirs) { for (const auto &inc : bin.include_dirs) {
ss << inc << "\n\t"; ss << fs::path(inc) << "\n\t";
} }
ss << ")\n\n"; ss << ")\n\n";
} }

Loading…
Cancel
Save