diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d7f5ca..04cbec4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ endif() cmake_minimum_required(VERSION 3.15) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) set(cmkr_PROJECT_VERSION 0.1.3) project(cmkr VERSION ${cmkr_PROJECT_VERSION}) @@ -19,21 +19,21 @@ include(FetchContent) FetchContent_Declare( filesystem GIT_REPOSITORY https://github.com/gulrak/filesystem - ) +) FetchContent_MakeAvailable(filesystem) FetchContent_Declare( mpark_variant URL https://github.com/mpark/variant/archive/v1.4.0.tar.gz - ) +) FetchContent_MakeAvailable(mpark_variant) FetchContent_Declare( toml11 GIT_REPOSITORY https://github.com/ToruNiina/toml11 - ) +) FetchContent_MakeAvailable(toml11) @@ -43,7 +43,7 @@ set(CMKRLIB_SOURCES src/help.cpp src/build.cpp src/error.cpp - ) +) add_library(cmkrlib STATIC ${CMKRLIB_SOURCES}) @@ -64,9 +64,9 @@ target_compile_features(cmkrlib PUBLIC set(CMKR_SOURCES src/main.cpp src/args.cpp - ) +) -add_executable(cmkr ${CMKR_SOURCES}) +add_executable(cmkr ${CMKR_SOURCES}) target_link_libraries(cmkr PUBLIC cmkrlib @@ -76,7 +76,7 @@ install( TARGETS cmkr DESTINATION ${CMAKE_INSTALL_PREFIX}/bin COMPONENT cmkr - ) +) diff --git a/README.md b/README.md index a30239f..357329c 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ minimum = "3.15" name = "app" version = "0.1.0" -[[bin]] +[[target]] name = "app" -type = "exe" +type = "executable" sources = ["src/main.cpp"] ``` @@ -42,19 +42,19 @@ toml11 = { git = "https://github.com/ToruNiina/toml11" } filesystem = { git = "https://github.com/gulrak/filesystem" } mpark_variant = { url = "https://github.com/mpark/variant/archive/v1.4.0.tar.gz" } -[[bin]] +[[target]] name = "cmkrlib" type = "static" sources = ["src/cmake.cpp", "src/gen.cpp", "src/help.cpp", "src/build.cpp", "src/error.cpp"] -include-dirs = ["include"] -features = ["cxx_std_11"] -link-libs = ["toml11::toml11", "ghc_filesystem"] +include-directories = ["include"] +compile-features = ["cxx_std_11"] +link-libraries = ["toml11::toml11", "ghc_filesystem"] -[[bin]] +[[target]] name = "cmkr" -type = "exe" +type = "executable" sources = ["src/main.cpp", "src/args.cpp"] -link-libs = ["cmkrlib"] +link-libraries = ["cmkrlib"] [[install]] targets = ["cmkr"] @@ -66,7 +66,7 @@ Currently supported fields: [cmake] # required for top-level project minimum = "3.15" # required subdirs = [] # optional -bin-dir = "bin" # optional +build-dir = "build" # optional cpp-flags = [] # optional c-flags = [] # optional link-flags = [] # optional @@ -95,15 +95,15 @@ toml11 = { git = "https://github.com/ToruNiina/toml11", tag = "v3.5.0" } # optio APP_BUILD_STUFF = false # optional APP_OTHER_STUFF = { comment = "does other stuff", value = false } # optional -[[bin]] # required, can define several binaries +[[target]] # required, can define several binaries name = "app" # required -type = "exe" # required (exe || lib || shared || static || interface) +type = "executable" # required (executable || library || shared || static || interface) sources = ["src/*.cpp"] # required, supports globbing -include-dirs = ["include"] # optional +include-directories = ["include"] # optional alias = "" # optional -features = [] # optional -defines = [] # optional -link-libs = [] # optional +compile-features = [] # optional +compile-definitions = [] # optional +link-libraries = [] # optional properties = { PROPERTY1 = "property1", ... } # optional [[test]] # optional, can define several @@ -123,13 +123,13 @@ The cmkr executable can be run from the command-line: ``` Usage: cmkr [arguments] arguments: - init [exe|lib|shared|static|interface] Starts a new project in the same directory. - gen Generates CMakeLists.txt file. - build Run cmake and build. - install Run cmake --install. Needs admin privileges. - clean Clean the build directory. - help Show help. - version Current cmkr version. + init [executable|library|shared|static|interface] Starts a new project in the same directory. + gen Generates CMakeLists.txt file. + build Run cmake and build. + install Run cmake --install. Needs admin privileges. + 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: ``` @@ -138,20 +138,20 @@ cmkr build --config Release ## Binary types -### exe -Executable binary. +### executable +Executable binary. Equivalent to [add_executable(name)](https://cmake.org/cmake/help/latest/command/add_executable.html). -### lib -Library, can be static or shared depending on the BUILD_SHARED_LIBS variable. +### library +Library, can be static or shared depending on the BUILD_SHARED_LIBS variable. Equivalent to [add_library()](https://cmake.org/cmake/help/latest/command/add_library.html). ### static -Static library/archive. +Static library/archive. Equivalent to [add_library(name STATIC)](https://cmake.org/cmake/help/latest/command/add_library.html). ### shared -Shared/dynamic library. +Shared/dynamic library. Equivalent to [add_library(name SHARED)](https://cmake.org/cmake/help/latest/command/add_library.html). ### interface -Header-only library. +Header-only library. Equivalent to [add_library(name INTERFACE)](https://cmake.org/cmake/help/latest/command/add_library.html). ## Roadmap - Support more cmake fields. diff --git a/cmake.toml b/cmake.toml index bf63a7a..be05a27 100644 --- a/cmake.toml +++ b/cmake.toml @@ -10,19 +10,19 @@ toml11 = { git = "https://github.com/ToruNiina/toml11" } filesystem = { git = "https://github.com/gulrak/filesystem" } mpark_variant = { url = "https://github.com/mpark/variant/archive/v1.4.0.tar.gz" } -[[bin]] +[[target]] name = "cmkrlib" type = "static" sources = ["src/cmake.cpp", "src/gen.cpp", "src/help.cpp", "src/build.cpp", "src/error.cpp"] -include-dirs = ["include"] -features = ["cxx_std_11"] -link-libs = ["toml11::toml11", "ghc_filesystem", "mpark_variant"] +include-directories = ["include"] +compile-features = ["cxx_std_11"] +link-libraries = ["toml11::toml11", "ghc_filesystem", "mpark_variant"] -[[bin]] +[[target]] name = "cmkr" -type = "exe" +type = "executable" sources = ["src/main.cpp", "src/args.cpp"] -link-libs = ["cmkrlib"] +link-libraries = ["cmkrlib"] [[install]] targets = ["cmkr"] diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 68219a3..b460abd 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,24 +1,25 @@ -# This file was generated automatically by cmkr. - -# Regenerate CMakeLists.txt file when necessary -include(cmkr.cmake OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT) - -if(CMKR_INCLUDE_RESULT) - cmkr() -endif() - -cmake_minimum_required(VERSION 3.15) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -set(example_PROJECT_VERSION 0.1.0) -project(example VERSION ${example_PROJECT_VERSION}) - -set(EXAMPLE_SOURCES - src/example.cpp - ) - -add_executable(example ${EXAMPLE_SOURCES}) - - - +# This file was generated automatically by cmkr. + +# Regenerate CMakeLists.txt file when necessary +include(cmkr.cmake OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT) + +if(CMKR_INCLUDE_RESULT) + cmkr() +endif() + +cmake_minimum_required(VERSION 3.15) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set(example_PROJECT_VERSION 0.1.0) +project(example VERSION ${example_PROJECT_VERSION}) + +set(EXAMPLE_SOURCES + src/example.cpp +) + +add_executable(example ${EXAMPLE_SOURCES}) + + + diff --git a/cmake/cmake.toml b/cmake/cmake.toml index b8089b3..267e481 100644 --- a/cmake/cmake.toml +++ b/cmake/cmake.toml @@ -7,7 +7,7 @@ minimum = "3.15" name = "example" version = "0.1.0" -[[bin]] +[[target]] name = "example" -type = "exe" +type = "executable" sources = ["src/example.cpp"] \ No newline at end of file diff --git a/cmake/cmkr.cmake b/cmake/cmkr.cmake index be50bd3..14b5556 100644 --- a/cmake/cmkr.cmake +++ b/cmake/cmkr.cmake @@ -50,23 +50,19 @@ else() if(NOT EXISTS ${CMKR_EXECUTABLE}) message(FATAL_ERROR "[cmkr] Failed to bootstrap '${CMKR_EXECUTABLE}'") endif() - cmkr_exec(${CMKR_EXECUTABLE} version OUTPUT_VARIABLE CMKR_VERSION) - string(STRIP ${CMKR_VERSION} CMKR_VERSION) + cmkr_exec(${CMKR_EXECUTABLE} version) message(STATUS "[cmkr] Bootstrapped ${CMKR_EXECUTABLE}") else() message(VERBOSE "[cmkr] Found cmkr: '${CMKR_EXECUTABLE}'") endif() endif() execute_process(COMMAND ${CMKR_EXECUTABLE} version - OUTPUT_VARIABLE CMKR_VERSION RESULT_VARIABLE CMKR_EXEC_RESULT ) if(NOT CMKR_EXEC_RESULT EQUAL 0) unset(CMKR_EXECUTABLE CACHE) message(FATAL_ERROR "[cmkr] Failed to get version, try clearing the cache and rebuilding") endif() -string(STRIP ${CMKR_VERSION} CMKR_VERSION) -message(STATUS "[cmkr] Using ${CMKR_VERSION}") # This is the macro that contains black magic macro(cmkr) @@ -83,12 +79,9 @@ macro(cmkr) set_source_files_properties(${CMAKE_CURRENT_LIST_FILE} PROPERTIES CMKR_INCLUDE_GUARD TRUE) # Generate CMakeLists.txt - cmkr_exec(${CMKR_EXECUTABLE} gen -y + cmkr_exec(${CMKR_EXECUTABLE} gen WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - OUTPUT_VARIABLE CMKR_GEN_OUTPUT ) - string(STRIP ${CMKR_GEN_OUTPUT} CMKR_GEN_OUTPUT) - message(STATUS "[cmkr] ${CMKR_GEN_OUTPUT}") # Copy the now-generated CMakeLists.txt to CMakerLists.txt # This is done because you cannot include() a file you are currently in diff --git a/include/literals.h b/include/literals.h index 9af61d0..8e63c4b 100644 --- a/include/literals.h +++ b/include/literals.h @@ -14,7 +14,7 @@ const char *cmake_toml = R"lit( [cmake] minimum = "3.15" # subdirs = [] -# bin-dir = "" +# build-dir = "" # cpp-flags = [] # c-flags = [] # link-flags = [] @@ -31,15 +31,15 @@ version = "0.1.0" # [options] -[[bin]] +[[target]] name = "%s" type = "%s" sources = ["src/*.cpp"] -include-dirs = ["include"] +include-directories = ["include"] # alias = "" -# features = [] -# defines = [] -# link-libs = [] +# compile-features = [] +# compile-definitions = [] +# link-libraries = [] [[install]] %s = ["%s"] diff --git a/src/args.cpp b/src/args.cpp index e8476f1..1a5d94a 100644 --- a/src/args.cpp +++ b/src/args.cpp @@ -18,23 +18,10 @@ const char *handle_args(int argc, char **argv) { args.push_back(argv[i]); if (args.size() < 2) - return "Please provide command line arguments!"; + throw std::runtime_error(cmkr::help::message()); std::string main_arg = args[1]; if (main_arg == "gen") { - bool cont = false; - if (args.size() > 2 && args[2] == "-y") - cont = true; auto current_path = fs::current_path(); - if (fs::exists(current_path / "CMakeLists.txt") && cont == false) { - std::cout - << "A CMakeLists.txt file already exists in the current directory.\nWould you " - "like to overwrite it?[y/n]" - << std::endl; - std::string resp; - std::cin >> resp; - if (resp != "y") - return "CMake generation aborted!"; - } auto ret = cmkr::gen::generate_cmake(current_path.string().c_str()); if (ret) return "CMake generation error!"; @@ -44,10 +31,10 @@ const char *handle_args(int argc, char **argv) { } else if (main_arg == "version") { return cmkr::help::version(); } else if (main_arg == "init") { - std::string typ = "exe"; + std::string type = "executable"; if (args.size() > 2) - typ = args[2]; - auto ret = cmkr::gen::generate_project(typ.c_str()); + type = args[2]; + auto ret = cmkr::gen::generate_project(type.c_str()); if (ret) return "Initialization failure!"; return "Directory initialized!"; @@ -67,7 +54,7 @@ const char *handle_args(int argc, char **argv) { return "CMake clean error!"; return "Cleaned build directory!"; } else { - return "Unknown argument!"; + throw std::runtime_error(cmkr::help::message()); } } } // namespace args diff --git a/src/build.cpp b/src/build.cpp index e82d2c1..4609238 100644 --- a/src/build.cpp +++ b/src/build.cpp @@ -24,9 +24,9 @@ int run(int argc, char **argv) { if (!fs::exists("CMakeLists.txt")) if (gen::generate_cmake(".")) - throw std::runtime_error("[cmkr] error: CMake generation failure!"); + throw std::runtime_error("CMake generation failure!"); - ss << "cmake -S. -B" << cmake.bin_dir << " "; + ss << "cmake -S. -B" << cmake.build_dir << " "; if (!cmake.generator.empty()) { ss << "-G \"" << cmake.generator << "\" "; @@ -39,7 +39,7 @@ int run(int argc, char **argv) { ss << "-D" << arg << " "; } } - ss << "&& cmake --build " << cmake.bin_dir << " --parallel"; + ss << "&& cmake --build " << cmake.build_dir << " --parallel"; if (argc > 2) { for (const auto &arg : cmake.build_args) { ss << " " << arg; @@ -52,16 +52,16 @@ int run(int argc, char **argv) { int clean() { bool ret = false; cmake::CMake cmake(".", true); - if (fs::exists(cmake.bin_dir)) { - ret = fs::remove_all(cmake.bin_dir); - fs::create_directory(cmake.bin_dir); + if (fs::exists(cmake.build_dir)) { + ret = fs::remove_all(cmake.build_dir); + fs::create_directory(cmake.build_dir); } return !ret; } int install() { cmake::CMake cmake(".", false); - auto cmd = "cmake --install " + cmake.bin_dir; + auto cmd = "cmake --install " + cmake.build_dir; return ::system(cmd.c_str()); } } // namespace build diff --git a/src/cmake.cpp b/src/cmake.cpp index 29343ac..ea3b80e 100644 --- a/src/cmake.cpp +++ b/src/cmake.cpp @@ -20,7 +20,7 @@ std::vector to_string_vec( CMake::CMake(const std::string &path, bool build) { if (!fs::exists(fs::path(path) / "cmake.toml")) { - throw std::runtime_error("[cmkr] error: No cmake.toml was found!"); + throw std::runtime_error("No cmake.toml was found!"); } const auto toml = toml::parse((fs::path(path) / "cmake.toml").string()); if (build) { @@ -28,7 +28,11 @@ CMake::CMake(const std::string &path, bool build) { const auto &cmake = toml::find(toml, "cmake"); if (cmake.contains("bin-dir")) { - bin_dir = toml::find(cmake, "bin-dir").as_string(); + throw std::runtime_error("bin-dir has been renamed to build-dir"); + } + + if (cmake.contains("build-dir")) { + build_dir = toml::find(cmake, "build-dir").as_string(); } if (cmake.contains("generator")) { @@ -160,42 +164,61 @@ CMake::CMake(const std::string &path, bool build) { } if (toml.contains("bin")) { - const auto &bins = toml::find(toml, "bin").as_array(); + throw std::runtime_error("[[bin]] has been renamed to [[target]]"); + } + + if (toml.contains("target")) { + const auto &ts = toml::find(toml, "target").as_array(); + + for (const auto &t : ts) { + Target target; + target.name = toml::find(t, "name").as_string(); + target.type = toml::find(t, "type").as_string(); + + target.sources = detail::to_string_vec(toml::find(t, "sources").as_array()); + +#define renamed(from, to) \ + if (t.contains(from)) { \ + throw std::runtime_error(from "has been renamed to " to); \ + } - for (const auto &bin : bins) { - Bin b; - b.name = toml::find(bin, "name").as_string(); - b.type = toml::find(bin, "type").as_string(); + renamed("include-dirs", "include-directories"); + renamed("link-libs", "link-libraries"); + renamed("defines", "compile-definitions"); + renamed("features", "compile-features"); - b.sources = detail::to_string_vec(toml::find(bin, "sources").as_array()); +#undef renamed - if (bin.contains("include-dirs")) { - b.include_dirs = - detail::to_string_vec(toml::find(bin, "include-dirs").as_array()); + if (t.contains("include-directories")) { + target.include_directories = + detail::to_string_vec(toml::find(t, "include-directories").as_array()); } - if (bin.contains("link-libs")) { - b.link_libs = detail::to_string_vec(toml::find(bin, "link-libs").as_array()); + if (t.contains("link-libraries")) { + target.link_libraries = + detail::to_string_vec(toml::find(t, "link-libraries").as_array()); } - if (bin.contains("features")) { - b.features = detail::to_string_vec(toml::find(bin, "features").as_array()); + if (t.contains("compile-features")) { + target.compile_features = + detail::to_string_vec(toml::find(t, "compile-features").as_array()); } - if (bin.contains("defines")) { - b.defines = detail::to_string_vec(toml::find(bin, "defines").as_array()); + if (t.contains("compile-definitions")) { + target.compile_definitions = + detail::to_string_vec(toml::find(t, "compile-definitions").as_array()); } - if (bin.contains("alias")) { - b.alias = toml::find(bin, "alias").as_string(); + if (t.contains("alias")) { + target.alias = toml::find(t, "alias").as_string(); } - if (bin.contains("properties")) { + if (t.contains("properties")) { using prop_map = std::map; - b.properties = toml::find(bin, "properties"); + target.properties = toml::find(t, "properties"); } - binaries.push_back(b); + binaries.push_back(target); } } diff --git a/src/cmake.hpp b/src/cmake.hpp index 215b873..22932be 100644 --- a/src/cmake.hpp +++ b/src/cmake.hpp @@ -30,14 +30,14 @@ struct Package { std::vector components; }; -struct Bin { +struct Target { std::string name; std::string type; std::vector sources; - std::vector include_dirs; - std::vector features; - std::vector defines; - std::vector link_libs; + std::vector include_directories; + std::vector compile_features; + std::vector compile_definitions; + std::vector link_libraries; std::string alias; std::map properties; }; @@ -57,8 +57,8 @@ struct Install { }; struct CMake { - std::string cmake_version = "3.15"; - std::string bin_dir = "bin"; + std::string cmake_version; + std::string build_dir = "build"; std::string generator; std::string config; std::vector subdirs; @@ -73,7 +73,7 @@ struct CMake { std::vector