From 88e9241e9f8f02bfab14835be6d7a8aa64ebe4c8 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Thu, 23 Dec 2021 17:18:12 +0100 Subject: [PATCH] Improve onboarding experience Thanks Matthaus :give: --- .github/FUNDING.yml | 1 + README.md | 29 ++++++++++++++------- cmake/cmkr.cmake | 30 +++++++++++++++++++-- docs/cmake-toml.md | 12 ++++----- docs/command-line.md | 22 ---------------- docs/getting-started.md | 27 ------------------- docs/index.md | 58 +++++++++++++++++++++++++++++++++++++++-- include/literals.hpp | 6 ++--- src/cmake_generator.cpp | 5 +++- 9 files changed, 117 insertions(+), 73 deletions(-) create mode 100644 .github/FUNDING.yml delete mode 100644 docs/command-line.md delete mode 100644 docs/getting-started.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..3c39777 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [mrexodia] diff --git a/README.md b/README.md index 24686b2..b7a6bbe 100644 --- a/README.md +++ b/README.md @@ -7,39 +7,48 @@ ```toml [project] name = "cmkr_for_beginners" -description = "A minimal cmkr project." [target.hello_world] type = "executable" sources = ["src/main.cpp"] ``` -`cmkr` can bootstrap itself from CMake and consumers of your project do not need to install anything to work with it. +`cmkr` can bootstrap itself from CMake and you only need CMake to use it. ## Getting started -The easiest way to get started is to use the [cmkr_for_beginners](https://github.com/build-cpp/cmkr_for_beginners) template repository. Either open it in [Gitpod](https://gitpod.io/#https://github.com/build-cpp/cmkr_for_beginners), or clone the repository and run: +To get started run the following commands from your project directory: + +```sh +curl https://raw.githubusercontent.com/build-cpp/cmkr/main/cmake/cmkr.cmake -o cmkr.cmake +cmake -P cmkr.cmake +``` + +After the bootstrapping process finishes, modify [`cmake.toml`](https://build-cpp.github.io/cmkr/cmake-toml) and open the project in your favorite IDE or build with CMake: ```sh cmake -B build cmake --build build ``` -Alternatively you can check out the [cmkr topic](https://github.com/topics/cmkr), the [build-cpp organization](https://github.com/build-cpp) or the [tests](https://github.com/build-cpp/cmkr/tree/main/tests) for more examples and templates. You can also check out the [documentation](https://build-cpp.github.io/cmkr). +Once bootstrapped, `cmkr` does not introduce extra steps to your workflow. After modifying `cmake.toml` you simply build/configure your CMake project and `cmkr` will automatically regenerate `CMakeLists.txt`. -### Migrating an existing project +In CI settings the `cmkr` bootstrapping process is skipped so there is no extra configure-time overhead in your pipelines. -When migrating an existing project it's easiest to download a [cmkr release](https://github.com/build-cpp/cmkr/releases) and put `cmkr` in your PATH. Then go to your project directory and run: +## Template repositories -``` -cmkr init +Another way to get started is to use the [cmkr_for_beginners](https://github.com/build-cpp/cmkr_for_beginners) template repository. Either open it in [Gitpod](https://gitpod.io/#https://github.com/build-cpp/cmkr_for_beginners), or clone the repository and run: + +```sh +cmake -B build +cmake --build build ``` -This will bootstrap `cmake.toml` and `CMakeLists.txt` that you can then build as normal with CMake. +Check out the [cmkr topic](https://github.com/topics/cmkr), the [build-cpp organization](https://github.com/build-cpp) or the [tests](https://github.com/build-cpp/cmkr/tree/main/tests) for more examples and templates. ## Command line -Optionally you can install `cmkr` in your `PATH` and use it as a utility from the command line: +Optionally you can put a [`cmkr` release](https://github.com/build-cpp/cmkr/releases) in your `PATH` and use it as a utility from the command line: ``` Usage: cmkr [arguments] diff --git a/cmake/cmkr.cmake b/cmake/cmkr.cmake index a8dde8d..7704fe6 100644 --- a/cmake/cmkr.cmake +++ b/cmake/cmkr.cmake @@ -1,7 +1,10 @@ include_guard() +# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake if(CMAKE_SCRIPT_MODE_FILE) - message(FATAL_ERROR "Running cmkr.cmake as a script is unsupported. To build your project try: cmake -B build") + set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/build") + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_BINARY_DIR}") + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}") endif() # Change these defaults to point to your infrastructure if desired @@ -23,7 +26,7 @@ if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION OR CMKR_BUILD_SKIP_GENERATION) endif() # Disable cmkr if no cmake.toml file is found -if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") +if(NOT CMAKE_SCRIPT_MODE_FILE AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") message(AUTHOR_WARNING "[cmkr] Not found: ${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") macro(cmkr) endmacro() @@ -143,6 +146,29 @@ if(NOT CMKR_EXEC_RESULT EQUAL 0) message(FATAL_ERROR "[cmkr] Failed to get version, try clearing the cache and rebuilding") endif() +# Use cmkr.cmake as a script +if(CMAKE_SCRIPT_MODE_FILE) + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake.toml") + execute_process(COMMAND "${CMKR_EXECUTABLE}" init + RESULT_VARIABLE CMKR_EXEC_RESULT + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to bootstrap cmkr project. Please report an issue: https://github.com/build-cpp/cmkr/issues/new") + else() + message(STATUS "[cmkr] Modify cmake.toml and then configure using: cmake -B build") + endif() + else() + execute_process(COMMAND "${CMKR_EXECUTABLE}" gen + RESULT_VARIABLE CMKR_EXEC_RESULT + ) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to generate project.") + else() + message(STATUS "[cmkr] Configure using: cmake -B build") + endif() + endif() +endif() + # This is the macro that contains black magic macro(cmkr) # When this macro is called from the generated file, fake some internal CMake variables diff --git a/docs/cmake-toml.md b/docs/cmake-toml.md index 4788256..5f0ac9b 100644 --- a/docs/cmake-toml.md +++ b/docs/cmake-toml.md @@ -1,15 +1,15 @@ --- layout: page -title: cmake.toml +title: Reference permalink: /cmake-toml/ -nav_order: 3 +nav_order: 1 --- -# cmake.toml +# Reference -This page is supposed to be a reference for the options in the `cmake.toml` file. If you think anything is missing or unclear, please [edit this page](https://github.com/build-cpp/cmkr/edit/main/docs/cmake-toml.md) or open an [issue](https://github.com/build-cpp/cmkr/issues). +This page is a reference for the options in the `cmake.toml` file. If you think anything is missing or unclear, please [edit this page](https://github.com/build-cpp/cmkr/edit/main/docs/cmake-toml.md) or open an [issue](https://github.com/build-cpp/cmkr/issues). -See the [examples](/examples) section for more real-world examples. +See the [examples](/examples) section for concrete examples. ## CMake configuration @@ -132,7 +132,7 @@ tag = "v0.1" [target.mytarget] condition = "linux" alias = "mytarget::mytarget" -type = "static" # executable, library, shared, static, interface, custom +type = "static" # executable, shared (DLL), static, interface, object, library, custom headers = ["src/mytarget.h"] sources = ["src/mytarget.cpp"] diff --git a/docs/command-line.md b/docs/command-line.md deleted file mode 100644 index a227225..0000000 --- a/docs/command-line.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -layout: page -title: Command line -permalink: /command-line/ -nav_order: 2 ---- - -# Command line - -Optionally you can install `cmkr` in your `PATH` and use it as a utility from the command line: - -``` -Usage: cmkr [arguments] -arguments: - 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. -``` \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index aaf26da..0000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: page -title: Getting started -permalink: /getting-started/ -nav_order: 1 ---- - -# Getting started - -The easiest way to get started is to use the [cmkr_for_beginners](https://github.com/build-cpp/cmkr_for_beginners) template repository. Either open it in [Gitpod](https://gitpod.io/#https://github.com/build-cpp/cmkr_for_beginners), or clone the repository and run: - -```sh -cmake -B build -cmake --build build -``` - -Alternatively you can check out the [cmkr topic](https://github.com/topics/cmkr) or the [build-cpp organization](https://github.com/build-cpp) for more examples and templates. - -### Migrating an existing project - -When migrating an existing project it's easiest to download a [cmkr release](https://github.com/build-cpp/cmkr/releases) and put `cmkr` in your PATH. Then go to your project directory and run: - -``` -cmkr init -``` - -This will bootstrap `cmake.toml` and `CMakeLists.txt` that you can then build as normal with CMake. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 858e9b0..cfcd18f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,11 +13,65 @@ nav_order: 0 ```toml [project] name = "cmkr_for_beginners" -description = "A minimal cmkr project." [target.hello_world] type = "executable" sources = ["src/main.cpp"] ``` -`cmkr` can bootstrap itself from CMake and consumers of your project do not need to install anything to work with it. +`cmkr` can bootstrap itself from CMake and you only need CMake to use it. + +## Getting started + +To get started run the following commands from your project directory: + +```sh +curl https://raw.githubusercontent.com/build-cpp/cmkr/main/cmake/cmkr.cmake -o cmkr.cmake +cmake -P cmkr.cmake +``` + +After the bootstrapping process finishes, modify [`cmake.toml`](https://build-cpp.github.io/cmkr/cmake-toml) and open the project in your favorite IDE or build with CMake: + +```sh +cmake -B build +cmake --build build +``` + +Once bootstrapped, `cmkr` does not introduce extra steps to your workflow. After modifying `cmake.toml` you simply build/configure your CMake project and `cmkr` will automatically regenerate `CMakeLists.txt`. + +In CI settings the `cmkr` bootstrapping process is skipped so there is no extra configure-time overhead in your pipelines. + +## Template repositories + +Another way to get started is to use the [cmkr_for_beginners](https://github.com/build-cpp/cmkr_for_beginners) template repository. Either open it in [Gitpod](https://gitpod.io/#https://github.com/build-cpp/cmkr_for_beginners), or clone the repository and run: + +```sh +cmake -B build +cmake --build build +``` + +Check out the [cmkr topic](https://github.com/topics/cmkr), the [build-cpp organization](https://github.com/build-cpp) or the [tests](https://github.com/build-cpp/cmkr/tree/main/tests) for more examples and templates. + +## Command line + +Optionally you can put a [`cmkr` release](https://github.com/build-cpp/cmkr/releases) in your `PATH` and use it as a utility from the command line: + +``` +Usage: cmkr [arguments] +arguments: + 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. +``` + +## Credits + +- https://github.com/gulrak/filesystem +- https://github.com/Tessil/ordered-map +- https://github.com/ToruNiina/toml11 +- https://github.com/mpark/variant +- https://www.svgrepo.com/svg/192268/hammer diff --git a/include/literals.hpp b/include/literals.hpp index 0c742d7..14d81f4 100644 --- a/include/literals.hpp +++ b/include/literals.hpp @@ -91,10 +91,10 @@ static const char *toml_migration = &R"lit( name = "@name" # TODO: define a target for each of your executables/libraries like this: -#[target.@name] -#type = "executable" +#[target.myexecutable] +#type = "executable" # static, shared #sources = ["src/@name/*.cpp", "include/@name/*.hpp"] #include-directories = ["include"] #compile-features = ["cxx_std_11"] -#link-libraries = ["other-targets"] +#link-libraries = ["target-or-library"] )lit"[1]; // skip initial newline diff --git a/src/cmake_generator.cpp b/src/cmake_generator.cpp index e5c917a..508dbc3 100644 --- a/src/cmake_generator.cpp +++ b/src/cmake_generator.cpp @@ -105,8 +105,11 @@ void generate_project(const std::string &type) { }; if (!fs::is_empty(fs::current_path())) { + // Make a backup of an existing CMakeLists.txt if it exists + std::error_code ec; + fs::rename("CMakeLists.txt", "CMakeLists.txt.bak", ec); + // Create an empty cmake.toml for migration purporses create_file("cmake.toml", format(toml_migration, variables)); - puts("Generated migration cmake.toml in existing project directory..."); return; }