Compare commits

...

96 Commits

Author SHA1 Message Date
Duncan Ogilvie c76956450a Initial draft of [package] support 2022-03-20 21:19:07 +01:00
Duncan Ogilvie 1596a8143d Bump to 0.2.12 2022-03-06 06:07:55 +01:00
Duncan Ogilvie 9b0f18ee94 Fix a bug in fetch-content generation 2022-03-06 06:05:17 +01:00
Duncan Ogilvie 887086dc05 Credits 2022-02-23 21:32:58 +01:00
Duncan Ogilvie edc8e1e02e Bump to 0.2.11 2022-02-12 04:42:19 +01:00
Duncan Ogilvie 1f6e31e0ef Add optional CMKR_COMMIT_HASH for the paranoid 2022-02-12 04:39:34 +01:00
Duncan Ogilvie 4de1500bb3 Refactor cmake injection 2022-02-12 04:14:47 +01:00
Duncan Ogilvie 85370968f8 Improved fetch-content support
Closes #38
2022-02-12 04:05:51 +01:00
Duncan Ogilvie 06a4c04df6 Add support for 'shallow' in fetch-content 2022-02-12 03:10:25 +01:00
Duncan Ogilvie fef2a0215b Error when recursively globbing in the project root
Closes #48
2022-02-12 03:03:57 +01:00
Duncan Ogilvie fc74a5e802 Bump to 0.2.10 2022-02-12 02:45:10 +01:00
Duncan Ogilvie e48d402e21 Improve version bumping script 2022-02-12 02:44:45 +01:00
Duncan Ogilvie f6a245618e Merge pull request #53 from build-cpp/better-validation
Better TOML validation
2022-02-12 02:44:05 +01:00
Duncan Ogilvie c713606fd4 Error when using an unknown key in the root of the TOML
[error] Unknown key 'fetch-cntent'
 --> cmake.toml:2
   |
 2 | [fetch-cntent.blah]
   |  ~~~~~~~~~~~~
2022-02-12 02:19:37 +01:00
Duncan Ogilvie fe9b6587a9 Error when trying to parse an empty cmake.toml file 2022-02-12 02:07:30 +01:00
Duncan Ogilvie a2f8d9e5c9 Bump to 0.2.9 2022-02-11 02:51:18 +01:00
Duncan Ogilvie c7925e7110 Merge pull request #52 from build-cpp/fix-options
Do not omit non-optional documentation in option()
2022-02-11 02:49:21 +01:00
Duncan Ogilvie c778a5fe2b Do not omit non-optional documentation in option() 2022-02-11 02:42:20 +01:00
Duncan Ogilvie 16b2cbbb57 Add sitemap.xml and robots.txt 2022-02-10 01:20:54 +01:00
Duncan Ogilvie 2f5c7823be Redirect /getting-started to https://cmkr.build 2022-02-10 00:54:32 +01:00
Duncan Ogilvie a29b6a8aaa SEO-friendly permalink 2022-02-10 00:15:28 +01:00
Duncan Ogilvie 5ac8b15c9a Bump to 0.2.8 2022-02-02 17:25:10 +01:00
Duncan Ogilvie e7d9faa6bb Merge pull request #51 from cursey/improvement/install-component
Allow specifying install component name
2022-01-29 11:31:29 +01:00
cursey 6f8b07a801 Allow specifying install component name 2022-01-28 17:16:19 -08:00
Duncan Ogilvie e8c6ccb698 Minor improvements to bootstrapping code 2022-01-26 01:07:18 +01:00
Duncan Ogilvie 539ebc8f4b Host documentation on https://cmkr.build 2022-01-14 18:06:04 +01:00
Duncan Ogilvie 37ca385673 Show vcpkg version when configuring 2022-01-14 13:42:03 +01:00
Duncan Ogilvie 8ae029dab1 Bump to 0.2.7 2022-01-14 01:04:11 +01:00
Duncan Ogilvie fb16cc34b1 Fix a regression with invalid names being generated in vcpkg.json 2022-01-14 01:03:37 +01:00
Duncan Ogilvie 47703871e1 Bump to 0.2.6 2022-01-13 00:35:13 +01:00
Duncan Ogilvie a8d6b15dcb Merge pull request #47 from cursey/templates
Add support for target templates
2022-01-13 00:33:05 +01:00
Duncan Ogilvie 87b3c7ec6c Document template targets 2022-01-13 00:24:04 +01:00
Duncan Ogilvie d905be1d13 Final touches 2022-01-12 23:57:14 +01:00
Duncan Ogilvie 8d13ccbeaa Delete driver test to add later 2022-01-12 23:56:53 +01:00
cursey bcbc9d2b20 Remove use of std::make_unique for C++11 compliance 2022-01-11 00:12:02 -08:00
cursey 05324f593b Improve code reuse for target cmds 2022-01-11 00:04:01 -08:00
cursey 2b7ee72e86 Separate template parsing and generation
* Reuse type for specifying template to use
* Add support for template add-function
* Add support for template pass-sources-to-add-function
2022-01-10 23:29:26 -08:00
cursey 61d5e64d87 Fix parser expecting to always find templates 2022-01-10 18:59:34 -08:00
cursey eed1e38407 Add support for target templates 2022-01-10 18:59:33 -08:00
Duncan Ogilvie 61851d2bee Bump to 0.2.5 2022-01-07 19:45:08 +01:00
Duncan Ogilvie c0d665095e Add script to automatically bump the version
Closes #44
2022-01-07 19:44:33 +01:00
Duncan Ogilvie 6c1e388391 Add root, x64 and x32 conditions 2021-12-30 14:27:07 +01:00
Duncan Ogilvie 04905371b8 Bump to 0.2.4 2021-12-30 02:45:02 +01:00
Duncan Ogilvie 5a6ac44fcf Merge pull request #46 from build-cpp/expanded-conditions
Support conditions everywhere
2021-12-30 02:44:02 +01:00
Duncan Ogilvie 9db82dfd05 Update toml reference 2021-12-30 02:43:17 +01:00
Duncan Ogilvie 459ebb14b5 Support conditions everywhere
Closes #36
2021-12-30 02:35:59 +01:00
Duncan Ogilvie 490869b9a2 Bump to 0.2.3 2021-12-28 12:08:16 +01:00
Duncan Ogilvie 8ae2754994 Merge pull request #45 from cursey/bootstrap-vcpkg-early
Bootstrap Vcpkg prior to FetchContent
2021-12-28 07:01:05 +01:00
cursey 18419297f4 Bootstrap Vcpkg prior to FetchContent 2021-12-27 16:49:11 -08:00
Duncan Ogilvie bdaf5c94e6 Bump to 0.2.2 2021-12-27 11:49:22 +01:00
Duncan Ogilvie fa3b7a346c Emit options and settings before the project() 2021-12-27 11:45:23 +01:00
Duncan Ogilvie df1dbf7953 Bump to 0.2.1 2021-12-27 11:17:20 +01:00
Duncan Ogilvie 5951f6930e Update documentation for vcpkg features 2021-12-27 11:12:28 +01:00
Duncan Ogilvie a6d5f1c99b Merge pull request #41 from cursey/vcpkg-package-features
Add support for vcpkg package features
2021-12-27 11:01:04 +01:00
Duncan Ogilvie dc852b9a2f Run clang-format 2021-12-27 10:54:46 +01:00
cursey 66621a9818 Fix spacing 2021-12-27 01:50:25 -08:00
cursey 2cd8ad0f18 Add missing const 2021-12-27 01:13:16 -08:00
cursey 084cbd6159 Cleanup vcpkg.json generation a little 2021-12-27 01:08:56 -08:00
cursey b4b0f533a9 Validate vcpkg features 2021-12-27 01:02:05 -08:00
cursey 0acc9b4e5a Report the badly formed package name to the user 2021-12-27 00:57:48 -08:00
cursey 61dfb0eb60 Fix tabbing in vcpkg.json for packages that have features 2021-12-26 16:32:38 -08:00
cursey 3201fd052e Add support for vcpkg package features 2021-12-26 15:40:45 -08:00
Duncan Ogilvie 83087ff06e Release v0.2.0 (finally) 2021-12-23 20:13:12 +01:00
Duncan Ogilvie 88e9241e9f Improve onboarding experience
Thanks Matthaus :give:
2021-12-23 18:04:54 +01:00
Duncan Ogilvie eff967277d Update README with a migration guide 2021-12-23 13:32:46 +01:00
Duncan Ogilvie ea01497246 Bump CMKR_TAG 2021-12-23 04:01:18 +01:00
Duncan Ogilvie 04bf40a5a6 Generate resources/version.hpp with the project version 2021-12-23 03:53:07 +01:00
Duncan Ogilvie 4d14395994 Implement support a CMKR_CACHE environment variable
Closes #17
2021-12-23 03:52:20 +01:00
Duncan Ogilvie 3dd3368e4e Build in Debug with CMAKE_UNITY_BUILD
This gives the fastest bootstrapping times and cmkr isn't noticeably slower during generation.
2021-12-23 01:56:11 +01:00
Duncan Ogilvie bb7874a6df Improve compilation times
Compilation with make went from 13 -> 10 seconds.
CMAKE_UNITY_BUILD went even lower to 6 seconds.

Closes #11
2021-12-23 01:54:57 +01:00
Duncan Ogilvie 91dbf2986e Remove dependency on nlohmann json 2021-12-23 00:55:20 +01:00
Duncan Ogilvie 2bcf15c4ed Add support for object libraries
Closes #34
2021-12-23 00:01:18 +01:00
Duncan Ogilvie 6a825e15a0 Slightly improve cmkr init #24 2021-12-22 18:29:13 +01:00
Duncan Ogilvie cc2b984aa5 Update documentation for conditions 2021-12-22 18:28:38 +01:00
Duncan Ogilvie 56a88c41e2 Merge pull request #35 from build-cpp/toml-checker
Proper error messages for invalid keys/conditions
2021-12-22 17:14:05 +01:00
Duncan Ogilvie 6809e8da41 Refactor and add checking for conditions 2021-12-22 16:51:55 +01:00
Duncan Ogilvie 9f9934e9a5 Implemented checking of keys in conditions 2021-12-22 13:31:52 +01:00
Duncan Ogilvie 77f4bf7da0 Some minor fixes related to newlines and formatting 2021-12-22 13:30:59 +01:00
Duncan Ogilvie 09c9c28934 Initial implementation of TomlChecker
This is to error when the user specifies an invalid key.

Closes #31
2021-12-19 02:34:48 +01:00
Duncan Ogilvie f02ccc2309 Refactor fetch-content to vector<Content> 2021-12-12 20:11:20 +01:00
Duncan Ogilvie 37e9a1f1a0 Merge pull request #33 from pmeerw/fix-linux
Ceating a directory with no name apparently fails on Linux, but silen…
2021-12-10 18:59:23 +01:00
Duncan Ogilvie a28e63fddc Merge pull request #32 from pmeerw/cleanup
Some cleanup
2021-12-10 18:59:09 +01:00
Peter Meerwald-Stadler 156fc961ec Ceating a directory with no name apparently fails on Linux, but silently succeeds on Windows 2021-12-10 17:39:36 +01:00
Peter Meerwald-Stadler 31cc1c9481 Avoid explicit number of error strings in cmkr_error_status() 2021-12-10 17:10:06 +01:00
Peter Meerwald-Stadler 19101cd726 Reduce scope of err_string; add missing error codes 2021-12-10 17:10:06 +01:00
Peter Meerwald-Stadler 8ebf69da7e Use C++ includes 2021-12-10 17:10:06 +01:00
Duncan Ogilvie 1c23469c8c Bump CMKR_TAG 2021-12-08 14:40:41 +01:00
Duncan Ogilvie 52671dcf5b Improve documentation for conditions 2021-12-08 14:39:48 +01:00
Duncan Ogilvie 094bab1b81 Add clarification that the system compiler is used when building cmkr 2021-12-08 14:39:35 +01:00
Duncan Ogilvie 0f559bc803 Do not make Package.config default to true 2021-12-08 14:39:18 +01:00
Duncan Ogilvie 491486075d Error when running cmkr.cmake as a script 2021-11-28 22:18:14 +01:00
Duncan Ogilvie ed84fc0251 Merge pull request #29 from build-cpp/fix-actions-pr
Fix a bug in the logic to skip building pull requests from the same repo
2021-10-27 18:11:24 +02:00
Duncan Ogilvie 8b6780fe1a Fix a bug in the logic to skip building pull requests from the same repository 2021-10-27 18:03:17 +02:00
Duncan Ogilvie 9ebcb1fb06 Bump CMKR_TAG 2021-10-24 16:19:50 +02:00
Duncan Ogilvie 7c7144b183 Also generate CMakeLists.txt when calling cmkr init 2021-10-24 16:19:08 +02:00
Duncan Ogilvie 07797988b5 Fix a critical bug in generate_resources.cmake 2021-10-24 16:19:03 +02:00
48 changed files with 1866 additions and 887 deletions
+1
View File
@@ -0,0 +1 @@
github: [mrexodia]
+4 -4
View File
@@ -5,7 +5,7 @@ on: [push, pull_request]
jobs:
build:
# Skip building pull requests from the same repository
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != '${{ github.repository }}'
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -23,7 +23,7 @@ jobs:
- name: Build
run: |
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_UNITY_BUILD=ON
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
cmake --install build --prefix ./install --config ${{ env.BUILD_TYPE }}
@@ -35,7 +35,7 @@ jobs:
- name: Test
run: |
cd build/tests
ctest -C ${{ env.BUILD_TYPE }}
ctest -C ${{ env.BUILD_TYPE }} --verbose
- name: Upload artifacts
uses: actions/upload-artifact@v2
@@ -50,7 +50,7 @@ jobs:
string: ${{ runner.os }}
- name: Compress artifacts
uses: papeloto/action-zip@v1
uses: vimtor/action-zip@v1
with:
files: install/bin/
dest: ${{ github.event.repository.name }}-${{ steps.osname.outputs.lowercase }}.zip
+2 -2
View File
@@ -25,7 +25,7 @@ project(cmkr
LANGUAGES
CXX
VERSION
0.1.4
0.2.12
DESCRIPTION
"CMakeLists generator from TOML"
)
@@ -86,13 +86,13 @@ list(APPEND cmkr_SOURCES
"include/arguments.hpp"
"include/build.hpp"
"include/cmake_generator.hpp"
"include/enum_helper.hpp"
"include/error.hpp"
"include/fs.hpp"
"include/help.hpp"
"include/literals.hpp"
"include/project_parser.hpp"
"cmake/cmkr.cmake"
"cmake/version.hpp.in"
)
list(APPEND cmkr_SOURCES
+25 -5
View File
@@ -7,29 +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`.
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 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]
@@ -50,3 +69,4 @@ arguments:
- https://github.com/ToruNiina/toml11
- https://github.com/mpark/variant
- https://www.svgrepo.com/svg/192268/hammer
- https://github.com/can1357 for buying `cmkr.build` ❤️
+3 -2
View File
@@ -4,7 +4,7 @@ cmkr-include = false
[project]
name = "cmkr"
version = "0.1.4"
version = "0.2.12"
description = "CMakeLists generator from TOML"
languages = ["CXX"]
subdirs = ["third_party", "tests"]
@@ -25,6 +25,7 @@ sources = [
"src/*.cpp",
"include/*.hpp",
"cmake/cmkr.cmake",
"cmake/version.hpp.in",
]
include-directories = [
"include",
@@ -35,7 +36,7 @@ link-libraries = [
"ghc_filesystem",
"mpark_variant",
"ordered_map",
"nlohmann_json"
"nlohmann_json",
]
cmake-after = """
generate_resources(${CMKR_TARGET})
+78
View File
@@ -0,0 +1,78 @@
cmake_minimum_required(VERSION 3.20)
if(NOT CMAKE_SCRIPT_MODE_FILE)
message(FATAL_ERROR "Usage: cmake -P bump_version.cmake [1.2.3]")
endif()
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake.toml")
message(FATAL_ERROR "Cannot find cmake.toml")
endif()
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake/cmkr.cmake")
message(FATAL_ERROR "Cannot find cmkr.cmake")
endif()
# Validate branch
find_package(Git REQUIRED)
execute_process(COMMAND "${GIT_EXECUTABLE}" branch --show-current OUTPUT_VARIABLE GIT_BRANCH)
string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
if(NOT GIT_BRANCH STREQUAL "main")
message(FATAL_ERROR "You need to be on the main branch, you are on: ${GIT_BRANCH}")
endif()
file(READ "${CMAKE_SOURCE_DIR}/cmake.toml" CMAKE_TOML)
string(FIND "${CMAKE_TOML}" "[project]" PROJECT_INDEX)
string(SUBSTRING "${CMAKE_TOML}" ${PROJECT_INDEX} -1 CMAKE_TOML_PROJECT)
set(SEMVER_REGEX "([0-9]+)\\.([0-9]+)\\.([0-9]+)")
set(VERSION_REGEX "version = \"${SEMVER_REGEX}\"")
if(CMAKE_TOML_PROJECT MATCHES "${VERSION_REGEX}")
set(MAJOR "${CMAKE_MATCH_1}")
set(MINOR "${CMAKE_MATCH_2}")
set(PATCH "${CMAKE_MATCH_3}")
set(OLDVERSION "${MAJOR}.${MINOR}.${PATCH}")
else()
message(FATAL_ERROR "Failed to match semantic version in cmake.toml")
endif()
if(CMAKE_ARGV3)
if(NOT CMAKE_ARGV3 MATCHES "${SEMVER_REGEX}")
message(FATAL_ERROR "Invalid semantic version number '${CMAKE_ARGV3}'")
endif()
set(NEWVERSION "${CMAKE_ARGV3}")
else()
math(EXPR NEWPATCH "${PATCH} + 1")
set(NEWVERSION "${MAJOR}.${MINOR}.${NEWPATCH}")
endif()
message(STATUS "Version ${OLDVERSION} -> ${NEWVERSION}")
find_program(CMKR_EXECUTABLE "cmkr" PATHS "${CMAKE_SOURCE_DIR}/build" PATH_SUFFIXES Debug Release RelWithDebInfo MinSizeRel NO_CACHE REQUIRED)
message(STATUS "Found cmkr: ${CMKR_EXECUTABLE}")
# Replace version in cmake.toml
string(REPLACE "version = \"${OLDVERSION}\"" "version = \"${NEWVERSION}\"" CMAKE_TOML "${CMAKE_TOML}")
file(CONFIGURE
OUTPUT "${CMAKE_SOURCE_DIR}/cmake.toml"
CONTENT "${CMAKE_TOML}"
@ONLY
NEWLINE_STYLE LF
)
# Run cmkr gen
execute_process(COMMAND "${CMKR_EXECUTABLE}" gen RESULT_VARIABLE CMKR_EXEC_RESULT)
if(NOT CMKR_EXEC_RESULT EQUAL 0)
message(FATAL_ERROR "cmkr gen failed (exit code ${CMKR_EXEC_RESULT})")
endif()
# Replace version in cmkr.cmake
file(READ "${CMAKE_SOURCE_DIR}/cmake/cmkr.cmake" CMKR_CMAKE)
string(REGEX REPLACE "CMKR_TAG \"[^\"]+\"" "CMKR_TAG \"v${NEWVERSION}\"" CMKR_CMAKE "${CMKR_CMAKE}")
file(CONFIGURE
OUTPUT "${CMAKE_SOURCE_DIR}/cmake/cmkr.cmake"
CONTENT "${CMKR_CMAKE}"
@ONLY
NEWLINE_STYLE LF
)
# Print git commands
message(STATUS "Git commands to create new version:\ngit commit -a -m \"Bump to ${NEWVERSION}\"\ngit tag v${NEWVERSION}\ngit push origin main v${NEWVERSION}")
+90 -16
View File
@@ -2,22 +2,33 @@ include_guard()
# Change these defaults to point to your infrastructure if desired
set(CMKR_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE)
set(CMKR_TAG "archive_9e1fa5dc" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
set(CMKR_TAG "v0.2.12" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE)
set(CMKR_COMMIT_HASH "" CACHE STRING "cmkr git commit hash (optional)" FORCE)
# To bootstrap/generate a cmkr project: cmake -P cmkr.cmake
if(CMAKE_SCRIPT_MODE_FILE)
set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/build")
set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_BINARY_DIR}")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}")
endif()
# Set these from the command line to customize for development/debugging purposes
set(CMKR_EXECUTABLE "" CACHE FILEPATH "cmkr executable")
set(CMKR_SKIP_GENERATION OFF CACHE BOOL "skip automatic cmkr generation")
set(CMKR_BUILD_TYPE "Debug" CACHE STRING "cmkr build configuration")
mark_as_advanced(CMKR_REPO CMKR_TAG CMKR_COMMIT_HASH CMKR_EXECUTABLE CMKR_SKIP_GENERATION CMKR_BUILD_TYPE)
# Disable cmkr if generation is disabled
if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION)
if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION OR CMKR_BUILD_SKIP_GENERATION)
message(STATUS "[cmkr] Skipping automatic cmkr generation")
unset(CMKR_BUILD_SKIP_GENERATION CACHE)
macro(cmkr)
endmacro()
return()
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()
@@ -47,22 +58,51 @@ else()
endif()
# Use cached cmkr if found
set(CMKR_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_cmkr_${CMKR_TAG}")
if(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}")
set(CMKR_DIRECTORY_PREFIX "$ENV{CMKR_CACHE}")
string(REPLACE "\\" "/" CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}")
if(NOT CMKR_DIRECTORY_PREFIX MATCHES "\\/$")
set(CMKR_DIRECTORY_PREFIX "${CMKR_DIRECTORY_PREFIX}/")
endif()
# Build in release mode for the cache
set(CMKR_BUILD_TYPE "Release")
else()
set(CMKR_DIRECTORY_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/_cmkr_")
endif()
set(CMKR_DIRECTORY "${CMKR_DIRECTORY_PREFIX}${CMKR_TAG}")
set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}")
if(NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE AND CMKR_EXECUTABLE MATCHES "^${CMAKE_CURRENT_BINARY_DIR}/_cmkr")
message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
unset(CMKR_EXECUTABLE CACHE)
# Handle upgrading logic
if(CMKR_EXECUTABLE AND NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE)
if(CMKR_EXECUTABLE MATCHES "^${CMAKE_CURRENT_BINARY_DIR}/_cmkr")
if(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}")
message(AUTHOR_WARNING "[cmkr] Switching to cached cmkr: '${CMKR_CACHED_EXECUTABLE}'")
if(EXISTS "${CMKR_CACHED_EXECUTABLE}")
set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE)
else()
unset(CMKR_EXECUTABLE CACHE)
endif()
else()
message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
unset(CMKR_EXECUTABLE CACHE)
endif()
elseif(DEFINED ENV{CMKR_CACHE} AND EXISTS "$ENV{CMKR_CACHE}" AND CMKR_EXECUTABLE MATCHES "^${CMKR_DIRECTORY_PREFIX}")
message(AUTHOR_WARNING "[cmkr] Upgrading cached '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'")
unset(CMKR_EXECUTABLE CACHE)
endif()
endif()
if(CMKR_EXECUTABLE AND EXISTS "${CMKR_EXECUTABLE}")
message(VERBOSE "[cmkr] Found cmkr: '${CMKR_EXECUTABLE}'")
elseif(CMKR_EXECUTABLE AND NOT CMKR_EXECUTABLE STREQUAL CMKR_CACHED_EXECUTABLE)
message(FATAL_ERROR "[cmkr] '${CMKR_EXECUTABLE}' not found")
elseif(NOT CMKR_EXECUTABLE AND EXISTS "${CMKR_CACHED_EXECUTABLE}")
set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE)
message(STATUS "[cmkr] Found cached cmkr: '${CMKR_EXECUTABLE}'")
else()
set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE)
message(VERBOSE "[cmkr] Bootstrapping '${CMKR_EXECUTABLE}'")
message(STATUS "[cmkr] Fetching cmkr...")
if(EXISTS "${CMKR_DIRECTORY}")
cmkr_exec("${CMAKE_COMMAND}" -E rm -rf "${CMKR_DIRECTORY}")
@@ -76,23 +116,34 @@ else()
${CMKR_REPO}
"${CMKR_DIRECTORY}"
)
message(STATUS "[cmkr] Building cmkr...")
if(CMKR_COMMIT_HASH)
execute_process(
COMMAND "${GIT_EXECUTABLE}" checkout -q "${CMKR_COMMIT_HASH}"
RESULT_VARIABLE CMKR_EXEC_RESULT
WORKING_DIRECTORY "${CMKR_DIRECTORY}"
)
if(NOT CMKR_EXEC_RESULT EQUAL 0)
message(FATAL_ERROR "Tag '${CMKR_TAG}' hash is not '${CMKR_COMMIT_HASH}'")
endif()
endif()
message(STATUS "[cmkr] Building cmkr (using system compiler)...")
cmkr_exec("${CMAKE_COMMAND}"
--no-warn-unused-cli
"${CMKR_DIRECTORY}"
"-B${CMKR_DIRECTORY}/build"
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_BUILD_TYPE=${CMKR_BUILD_TYPE}"
"-DCMAKE_UNITY_BUILD=ON"
"-DCMAKE_INSTALL_PREFIX=${CMKR_DIRECTORY}"
"-DCMKR_GENERATE_DOCUMENTATION=OFF"
)
cmkr_exec("${CMAKE_COMMAND}"
--build "${CMKR_DIRECTORY}/build"
--config Release
--config "${CMKR_BUILD_TYPE}"
--parallel
)
cmkr_exec("${CMAKE_COMMAND}"
--install "${CMKR_DIRECTORY}/build"
--config Release
--config "${CMKR_BUILD_TYPE}"
--prefix "${CMKR_DIRECTORY}"
--component cmkr
)
@@ -109,6 +160,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
@@ -142,18 +216,18 @@ macro(cmkr)
# Copy the now-generated CMakeLists.txt to CMakerLists.txt
# This is done because you cannot include() a file you are currently in
configure_file(CMakeLists.txt "${CMKR_TEMP_FILE}" COPYONLY)
# Add the macro required for the hack at the start of the cmkr macro
set_source_files_properties("${CMKR_TEMP_FILE}" PROPERTIES
CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}"
)
# 'Execute' the newly-generated CMakeLists.txt
include("${CMKR_TEMP_FILE}")
# Delete the generated file
file(REMOVE "${CMKR_TEMP_FILE}")
# Do not execute the rest of the original CMakeLists.txt
return()
endif()
+2 -2
View File
@@ -46,14 +46,14 @@ function(generate_documentation)
string(REGEX MATCH "^(\n*(#[^\n]+\n)+\n*)" EXAMPLE_HEADER "${test_contents}")
string(LENGTH "${EXAMPLE_HEADER}" header_length)
string(STRIP "${EXAMPLE_HEADER}" EXAMPLE_HEADER)
string(REGEX REPLACE "\n# ?" "\n" EXAMPLE_HEADER "\n${EXAMPLE_HEADER}")
string(REGEX REPLACE "\n# ?" "\n\n" EXAMPLE_HEADER "\n${EXAMPLE_HEADER}")
string(STRIP "${EXAMPLE_HEADER}" EXAMPLE_HEADER)
# Extract footer text
string(REGEX MATCH "(((#[^\n]+)(\n+|$))+)$" EXAMPLE_FOOTER "${test_contents}")
string(LENGTH "${EXAMPLE_FOOTER}" footer_length)
string(STRIP "${EXAMPLE_FOOTER}" EXAMPLE_FOOTER)
string(REGEX REPLACE "\n# ?" "\n" EXAMPLE_FOOTER "\n${EXAMPLE_FOOTER}")
string(REGEX REPLACE "\n# ?" "\n\n" EXAMPLE_FOOTER "\n${EXAMPLE_FOOTER}")
string(STRIP "${EXAMPLE_FOOTER}" EXAMPLE_FOOTER)
# Extract toml body
+11 -8
View File
@@ -5,15 +5,18 @@ function(generate_resources target)
PROPERTY SOURCES
)
foreach(SOURCE ${TARGET_SOURCES})
get_filename_component(RESOURCE_NAME "${SOURCE}" NAME_WE)
set(RESOURCE_HEADER "include/resources/${RESOURCE_NAME}.hpp")
if(SOURCE MATCHES ".cmake$")
get_filename_component(RESOURCE_NAME "${SOURCE}" NAME_WE)
set(RESOURCE_HEADER "include/resources/${RESOURCE_NAME}.h")
configure_file("${SOURCE}" "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_HEADER}")
file(READ "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_HEADER}" RESOURCE_CONTENTS)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${RESOURCE_HEADER}"
CONTENT "namespace cmkr {\nnamespace resources {\nstatic const char* ${RESOURCE_NAME} = R\"RESOURCE(${RESOURCE_CONTENTS})RESOURCE\";\n}\n}"
)
# Add configure-time dependency on the source file
configure_file("${SOURCE}" "${RESOURCE_HEADER}" COPYONLY)
# Generate the actual resource into the header
file(READ "${SOURCE}" RESOURCE_CONTENTS)
configure_file("${PROJECT_SOURCE_DIR}/cmake/resource.hpp.in" "${RESOURCE_HEADER}" @ONLY)
message(STATUS "[cmkr] Generated ${RESOURCE_HEADER}")
elseif(SOURCE MATCHES ".in$")
configure_file("${SOURCE}" "${RESOURCE_HEADER}" @ONLY)
message(STATUS "[cmkr] Generated ${RESOURCE_HEADER}")
endif()
endforeach()
+7
View File
@@ -0,0 +1,7 @@
namespace cmkr {
namespace resources {
static const char* @RESOURCE_NAME@ = R"RESOURCE(@RESOURCE_CONTENTS@)RESOURCE";
}
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
#define CMKR_VERSION "@PROJECT_VERSION@"
+1
View File
@@ -1,2 +1,3 @@
_site/
.jekyll-metadata
assets/
+1
View File
@@ -0,0 +1 @@
cmkr.build
+1
View File
@@ -3,6 +3,7 @@ gem "minima", "~> 2.5"
gem "github-pages", group: :jekyll_plugins
gem "jekyll-remote-theme"
gem "jekyll-sitemap", "~> 1.4.0"
platforms :mingw, :x64_mingw, :mswin, :jruby do
gem "tzinfo", "~> 1.2"
+1
View File
@@ -271,6 +271,7 @@ PLATFORMS
DEPENDENCIES
github-pages
jekyll-remote-theme
jekyll-sitemap (~> 1.4.0)
just-the-docs
minima (~> 2.5)
tzinfo (~> 1.2)
+5 -2
View File
@@ -2,6 +2,7 @@ title: cmkr
plugins:
- jekyll-remote-theme
- jekyll-sitemap
# Automatically deduce dark theme preference https://github.com/pmarsceill/just-the-docs/pull/464
remote_theme: build-cpp/just-the-docs@light-switch
@@ -9,7 +10,7 @@ search_enabled: true
color_scheme: light-or-dark
heading_anchors: true
aux_links:
"cmkr":
"GitHub":
- "https://github.com/build-cpp/cmkr"
aux_links_new_tab: true
@@ -18,4 +19,6 @@ gh_edit_link_text: "Edit this page on GitHub."
gh_edit_repository: "https://github.com/build-cpp/cmkr"
gh_edit_branch: "main"
gh_edit_view_mode: "edit"
gh_edit_source: docs
gh_edit_source: docs
production_url : https://cmkr.build
+55 -19
View File
@@ -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
@@ -39,17 +39,47 @@ include-after = ["cmake/after-project.cmake"]
## Conditions
You can specify your own conditions and use them in any `condition` field:
```toml
[conditions]
arch64 = "CMAKE_SIZEOF_VOID_P EQUALS 8"
arch32 = "CMAKE_SIZEOF_VOID_P EQUALS 4"
```
This will make the `arch64` and `arch32` conditions available with their respective CMake expressions.
You can also prefix most keys with `condition.` to represent a conditional:
```toml
[target]
type = "executable"
sources = ["src/main.cpp"]
windows.sources = ["src/windows_specific.cpp"]
```
The following conditions are predefined (you can override them if you desire):
```toml
[conditions]
windows = "WIN32"
macos = "CMAKE_SYSTEM_NAME MATCHES \"Darwin\""
unix = "UNIX"
bsd = "CMAKE_SYSTEM_NAME MATCHES \"BSD\""
linux = "CMAKE_SYSTEM_NAME MATCHES \"Linux\""
gcc = "CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" OR CMAKE_C_COMPILER_ID STREQUAL \"GNU\""
clang = "CMAKE_CXX_COMPILER_ID MATCHES \"Clang\" OR CMAKE_C_COMPILER_ID MATCHES \"Clang\""
msvc = "MSVC"
root = "CMKR_ROOT_PROJECT"
x64 = "CMAKE_SIZEOF_VOID_P EQUAL 8"
x32 = "CMAKE_SIZEOF_VOID_P EQUAL 4"
```
## Subdirectories
```toml
[subdir.mysubdir]
condition = "linux"
condition = "mycondition"
cmake-before = """
message(STATUS "CMake injected before the add_subdirectory() call"
"""
@@ -69,16 +99,15 @@ url = "https://github.com/microsoft/vcpkg/archive/refs/tags/2021.05.12.tar.gz"
packages = ["fmt", "zlib"]
```
The vcpkg `version` will automatically generate the `url` from the official repository. For a custom registry you can specify your own `url` (and omit the `version`).
The vcpkg `version` will automatically generate the `url` from the [official repository](https://github.com/microsoft/vcpkg/releases). For a custom registry you can specify your own `url` (and omit the `version`). You can browse available packages on [vcpkg.io](https://vcpkg.io/en/packages.html).
To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`.
## Packages
```toml
[find-package]
mypackage = { version = "1.0", required = true, config = true, components = ["mycomponent"] }
# Alternative syntax
[find-package.mypackage]
condition = "mycondition"
version = "1.0"
required = true
config = true
@@ -90,24 +119,29 @@ components = ["mycomponent"]
**Note**: The `[fetch-content]` feature is unpolished and will likely change in a future release.
```toml
[fetch-content]
gitcontent = { git = "https://github.com/myuser/gitcontent", tag = "v0.1" }
svncontent = { svn = "https://svn-host.com/url", rev = "svn_rev" }
urlcontent = { url = "https://content-host.com/urlcontent.zip", hash = "123123123123" }
# Alternative syntax
[fetch-content.gitcontent]
condition = "mycondition"
git = "https://github.com/myuser/gitcontent"
tag = "v0.1"
[fetch-content.svncontent]
condition = "mycondition"
svn = "https://svn-host.com/url"
rev = "svn_rev"
[fetch-content.urlcontent]
condition = "mycondition"
url = "https://content-host.com/urlcontent.zip"
hash = "123123123123"
```
## Targets
```toml
[target.mytarget]
condition = "linux"
condition = "mycondition"
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"]
@@ -153,6 +187,7 @@ FOLDER = "MyFolder"
```toml
# You can declare as many as you want like this, but the name has to be unique
[[test]]
condition = "mycondition"
name = "mytest"
command = "$<TARGET_FILE:mytest>"
arguments = ["arg1", "arg2"]
@@ -162,6 +197,7 @@ working-directory = "mytest-dir"
```toml
[[install]]
condition = "mycondition"
targets = ["mytarget", "mytest"]
destination = ["bin"]
files = ["content/my.png"]
-22
View File
@@ -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 <extra cmake args> Run cmake and build.
install Run cmake --install. Needs admin privileges.
clean Clean the build directory.
help Show help.
version Current cmkr version.
```
+1
View File
@@ -19,6 +19,7 @@ description = "Header-only library"
[target.mylib]
type = "interface"
include-directories = ["include"]
compile-features = ["cxx_std_11"]
[target.example]
type = "executable"
+40
View File
@@ -0,0 +1,40 @@
---
# Automatically generated from tests/templates/cmake.toml - DO NOT EDIT
layout: default
title: Target templates
permalink: /examples/templates
parent: Examples
nav_order: 7
---
# Target templates
To avoid repeating yourself in targets you can create your own target type (template). All properties of the template are inherited when used as a target type.
```toml
[project]
name = "templates"
description = "Target templates"
[template.app]
type = "executable"
sources = ["src/templates.cpp"]
compile-definitions = ["IS_APP"]
# Unlike interface targets you can also inherit properties
[template.app.properties]
CXX_STANDARD = "11"
CXX_STANDARD_REQUIRED = true
[target.app-a]
type = "app"
compile-definitions = ["APP_A"]
[target.app-b]
type = "app"
compile-definitions = ["APP_B"]
```
**Note**: In most cases you probably want to use an [interface](/examples/interface) target instead.
<sup><sub>This page was automatically generated from [tests/templates/cmake.toml](https://github.com/build-cpp/cmkr/tree/main/tests/templates/cmake.toml).</sub></sup>
+2
View File
@@ -33,4 +33,6 @@ link-libraries = ["fmt::fmt"]
The bootstrapping of vcpkg is fully automated and no user interaction is necessary. You can disable vcpkg by setting `CMKR_DISABLE_VCPKG=ON`.
To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`.
<sup><sub>This page was automatically generated from [tests/vcpkg/cmake.toml](https://github.com/build-cpp/cmkr/tree/main/tests/vcpkg/cmake.toml).</sub></sup>
+10
View File
@@ -0,0 +1,10 @@
---
layout: null
permalink: /getting-started/
---
<html>
<head>
<meta http-equiv="refresh" content="0;url=https://cmkr.build">
</head>
</html>
-17
View File
@@ -1,17 +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.
+1
View File
@@ -0,0 +1 @@
google-site-verification: google13f7c659b54c069f.html
+57 -3
View File
@@ -6,18 +6,72 @@ nav_order: 0
# Index
`cmkr`, pronounced "cmaker", is a modern build system based on [CMake](https://cmake.org/) and [TOML](https://toml.io). It was originally created by [Mohammed Alyousef](https://github.com/MoAlyousef).
`cmkr`, pronounced "cmaker", is a modern build system based on [CMake](https://cmake.org/) and [TOML](https://toml.io).
`cmkr` parses `cmake.toml` files and generates a modern, idiomatic `CMakeLists.txt` for you. A minimal example:
```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 <extra cmake args> 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
+2 -6
View File
@@ -5,13 +5,9 @@
namespace cmkr {
namespace gen {
int generate_project(const char *typ);
void generate_project(const std::string &type);
int generate_cmake(const char *path, const parser::Project *parent_project = nullptr);
void generate_cmake(const char *path, const parser::Project *parent_project = nullptr);
} // namespace gen
} // namespace cmkr
int cmkr_gen_generate_project(const char *typ);
int cmkr_gen_generate_cmake(const char *path);
-69
View File
@@ -1,69 +0,0 @@
// https://codereview.stackexchange.com/a/14315
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
// This is the type that will hold all the strings.
// Each enumeration type will declare its own specialization.
// Any enum that does not have a specialization will generate a compiler error
// indicating that there is no definition of this variable (as there should be
// be no definition of a generic version).
template <typename T>
struct enumStrings {
static char const *data[];
};
// This is a utility type.
// Created automatically. Should not be used directly.
template <typename T>
struct enumRefHolder {
T &enumVal;
enumRefHolder(T &enumVal) : enumVal(enumVal) {}
};
template <typename T>
struct enumConstRefHolder {
T const &enumVal;
enumConstRefHolder(T const &enumVal) : enumVal(enumVal) {}
};
// The next two functions do the actual work of reading/writing an
// enum as a string.
template <typename T>
std::ostream &operator<<(std::ostream &str, enumConstRefHolder<T> const &data) {
return str << enumStrings<T>::data[data.enumVal];
}
template <typename T>
std::istream &operator>>(std::istream &str, enumRefHolder<T> const &data) {
std::string value;
str >> value;
// These two can be made easier to read in C++11
// using std::begin() and std::end()
//
static auto begin = std::begin(enumStrings<T>::data);
static auto end = std::end(enumStrings<T>::data);
auto find = std::find(begin, end, value);
if (find != end) {
data.enumVal = static_cast<T>(std::distance(begin, find));
} else {
throw std::invalid_argument("");
}
return str;
}
// This is the public interface:
// use the ability of function to deduce their template type without
// being explicitly told to create the correct type of enumRefHolder<T>
template <typename T>
enumConstRefHolder<T> enumToString(T const &e) {
return enumConstRefHolder<T>(e);
}
template <typename T>
enumRefHolder<T> enumFromString(T &e) {
return enumRefHolder<T>(e);
}
+88 -33
View File
@@ -1,45 +1,100 @@
#pragma once
static const char *hello_world = &R"lit(
static const char *cpp_executable = &R"lit(
#include <iostream>
#include <cstdlib>
int %s() {
std::cout << "Hello World!\n";
return 0;
int main() {
std::cout << "Hello from cmkr!\n";
return EXIT_SUCCESS;
}
)lit"[1]; // skip initial newline
static const char *cmake_toml = &R"lit(
[cmake]
version = "3.15"
# subdirs = []
# build-dir = ""
# cpp-flags = []
# c-flags = []
# link-flags = []
# generator = ""
# arguments = []
static const char *cpp_library = &R"lit(
#include <@name/@name.hpp>
[project]
name = "%s"
version = "0.1.0"
#include <iostream>
# [find-package]
namespace @name {
# [fetch-content]
void hello() {
std::cout << "Hello from cmkr!\n";
}
# [options]
[target.%s]
type = "%s"
sources = ["src/*.cpp"]
include-directories = ["include"]
# alias = ""
# compile-features = []
# compile-definitions = []
# link-libraries = []
[[install]]
%s = ["%s"]
destination = "${CMAKE_INSTALL_PREFIX}/%s"
} // namespace @name
)lit"[1]; // skip initial newline
static const char *hpp_library = &R"lit(
#pragma once
namespace @name {
void hello();
} // namespace @name
)lit"[1]; // skip initial newline
static const char *hpp_interface = &R"lit(
#pragma once
#include <iostream>
namespace @name {
inline void hello() {
std::cout << "Hello from cmkr!\n";
}
} // namespace @name
)lit"[1]; // skip initial newline
static const char *toml_executable = &R"lit(
# Reference: https://build-cpp.github.io/cmkr/cmake-toml
[project]
name = "@name"
[target.@name]
type = "executable"
sources = ["src/@name/main.cpp"]
compile-features = ["cxx_std_11"]
)lit"[1]; // skip initial newline
static const char *toml_library = &R"lit(
# Reference: https://build-cpp.github.io/cmkr/cmake-toml
[project]
name = "@name"
[target.@name]
type = "@type"
sources = [
"src/@name/@name.cpp",
"include/@name/@name.hpp"
]
include-directories = ["include"]
compile-features = ["cxx_std_11"]
)lit"[1]; // skip initial newline
static const char *toml_interface = &R"lit(
# Reference: https://build-cpp.github.io/cmkr/cmake-toml
[project]
name = "@name"
[target.@name]
type = "interface"
include-directories = ["include"]
compile-features = ["cxx_std_11"]
)lit"[1]; // skip initial newline
static const char *toml_migration = &R"lit(
# Reference: https://build-cpp.github.io/cmkr/cmake-toml
[project]
name = "@name"
# TODO: define a target for each of your executables/libraries like this:
#[target.myexecutable]
#type = "executable" # static, shared
#sources = ["src/@name/*.cpp", "include/@name/*.hpp"]
#include-directories = ["include"]
#compile-features = ["cxx_std_11"]
#link-libraries = ["target-or-library"]
)lit"[1]; // skip initial newline
+54 -12
View File
@@ -1,8 +1,6 @@
#pragma once
#include <map>
#include <mpark/variant.hpp>
#include <stdexcept>
#include <string>
#include <tsl/ordered_map.h>
#include <vector>
@@ -10,6 +8,11 @@
namespace cmkr {
namespace parser {
template <typename T>
using Condition = tsl::ordered_map<std::string, T>;
using ConditionVector = Condition<std::vector<std::string>>;
struct Setting {
std::string name;
std::string comment;
@@ -24,18 +27,25 @@ struct Option {
bool val = false;
};
struct Package {
struct FindPackage {
std::string name;
std::string condition;
std::string version;
bool required = true;
bool config = true;
bool config = false;
std::vector<std::string> components;
};
struct Vcpkg {
std::string version;
std::string url;
std::vector<std::string> packages;
struct Package {
std::string name;
std::vector<std::string> features;
};
std::vector<Package> packages;
};
enum TargetType {
@@ -45,16 +55,17 @@ enum TargetType {
target_static,
target_interface,
target_custom,
target_object,
target_template,
target_last,
};
template <typename T>
using Condition = tsl::ordered_map<std::string, T>;
using ConditionVector = Condition<std::vector<std::string>>;
extern const char *targetTypeNames[target_last];
struct Target {
std::string name;
TargetType type = {};
TargetType type = target_last;
std::string type_name;
ConditionVector headers;
ConditionVector sources;
@@ -94,8 +105,15 @@ struct Target {
ConditionVector include_after;
};
struct Template {
Target outline;
std::string add_function;
bool pass_sources_to_add_function = false;
};
struct Test {
std::string name;
std::string condition;
std::vector<std::string> configurations;
std::string working_directory;
std::string command;
@@ -103,22 +121,44 @@ struct Test {
};
struct Install {
std::string condition;
std::vector<std::string> targets;
std::vector<std::string> files;
std::vector<std::string> dirs;
std::vector<std::string> configs;
std::string destination;
std::string component;
};
struct Subdir {
std::string name;
std::string condition;
Condition<std::string> cmake_before;
Condition<std::string> cmake_after;
ConditionVector include_before;
ConditionVector include_after;
};
struct Content {
std::string name;
std::string condition;
tsl::ordered_map<std::string, std::string> arguments;
Condition<std::string> cmake_before;
Condition<std::string> cmake_after;
ConditionVector include_before;
ConditionVector include_after;
};
struct Package {
std::string name;
std::vector<std::string> targets;
std::vector<std::string> headers;
std::vector<std::string> dependencies;
std::string namespace_name;
};
struct Project {
// This is the CMake version required to use all cmkr versions.
std::string cmake_version = "3.15";
@@ -143,9 +183,11 @@ struct Project {
ConditionVector include_after;
std::vector<Setting> settings;
std::vector<Option> options;
std::vector<Package> packages;
std::vector<FindPackage> packages;
Vcpkg vcpkg;
tsl::ordered_map<std::string, std::map<std::string, std::string>> contents;
Package package;
std::vector<Content> contents;
std::vector<Template> templates;
std::vector<Target> targets;
std::vector<Test> tests;
std::vector<Install> installs;
+4 -7
View File
@@ -21,9 +21,7 @@ const char *handle_args(int argc, char **argv) {
throw std::runtime_error(cmkr::help::message());
std::string main_arg = args[1];
if (main_arg == "gen") {
auto ret = cmkr::gen::generate_cmake(fs::current_path().string().c_str());
if (ret)
return "CMake generation error!";
cmkr::gen::generate_cmake(fs::current_path().string().c_str());
return "CMake generation successful!";
} else if (main_arg == "help") {
return cmkr::help::message();
@@ -33,15 +31,14 @@ const char *handle_args(int argc, char **argv) {
std::string type = "executable";
if (args.size() > 2)
type = args[2];
auto ret = cmkr::gen::generate_project(type.c_str());
if (ret)
return "Initialization failure!";
cmkr::gen::generate_project(type.c_str());
cmkr::gen::generate_cmake(fs::current_path().string().c_str());
return "Directory initialized!";
} else if (main_arg == "build") {
auto ret = build::run(argc, argv);
if (ret)
return "CMake build error!";
return "CMake run completed!";
return "CMake build completed!";
} else if (main_arg == "install") {
auto ret = build::install();
if (ret)
+5 -6
View File
@@ -4,10 +4,10 @@
#include "project_parser.hpp"
#include "fs.hpp"
#include <cstddef>
#include <cstdlib>
#include <sstream>
#include <stddef.h>
#include <stdexcept>
#include <stdlib.h>
#include <system_error>
namespace cmkr {
@@ -22,10 +22,9 @@ int run(int argc, char **argv) {
}
std::stringstream ss;
if (gen::generate_cmake(fs::current_path().string().c_str()))
throw std::runtime_error("CMake generation failure!");
gen::generate_cmake(fs::current_path().string().c_str());
ss << "cmake -S. -DCMKR_SKIP_GENERATION=ON -B" << project.build_dir << " ";
ss << "cmake -DCMKR_BUILD_SKIP_GENERATION=ON -B" << project.build_dir << " ";
if (!project.generator.empty()) {
ss << "-G \"" << project.generator << "\" ";
@@ -94,4 +93,4 @@ int cmkr_build_install(void) {
} catch (...) {
return cmkr::error::Status(cmkr::error::Status::Code::InstallError);
}
}
}
+526 -311
View File
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -1,6 +1,6 @@
#include "error.hpp"
#include <assert.h>
#include <cassert>
namespace cmkr {
namespace error {
@@ -14,11 +14,12 @@ Status::Code Status::code() const noexcept { return ec_; }
} // namespace error
} // namespace cmkr
const char *err_string[] = {
"Success", "Runtime error", "Initialization error", "CMake generation error", "Build error",
// strings for cmkr::error::Status::Code
static const char *err_string[] = {
"Success", "Runtime error", "Initialization error", "CMake generation error", "Build error", "Clean error", "Install error",
};
const char *cmkr_error_status(int i) {
assert(i >= 0 && i < 5);
assert(i >= 0 && i < (sizeof(err_string) / sizeof(*(err_string))));
return err_string[i];
}
}
+2 -1
View File
@@ -1,9 +1,10 @@
#include "help.hpp"
#include <resources/version.hpp>
namespace cmkr {
namespace help {
const char *version() noexcept { return "cmkr version 0.1.3"; }
const char *version() noexcept { return "cmkr version " CMKR_VERSION; }
const char *message() noexcept {
return R"lit(
+649 -316
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -78,3 +78,13 @@ add_test(
build
)
add_test(
NAME
templates
WORKING_DIRECTORY
"${CMAKE_CURRENT_LIST_DIR}/templates"
COMMAND
$<TARGET_FILE:cmkr>
build
)
+19 -7
View File
@@ -1,41 +1,53 @@
[[test]]
name = "basic"
command = "$<TARGET_FILE:cmkr>"
working-directory = "basic"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "interface"
command = "$<TARGET_FILE:cmkr>"
working-directory = "interface"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "fetch-content"
command = "$<TARGET_FILE:cmkr>"
working-directory = "fetch-content"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "conditions"
command = "$<TARGET_FILE:cmkr>"
working-directory = "conditions"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "vcpkg"
command = "$<TARGET_FILE:cmkr>"
working-directory = "vcpkg"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "cxx-standard"
command = "$<TARGET_FILE:cmkr>"
working-directory = "cxx-standard"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "globbing"
command = "$<TARGET_FILE:cmkr>"
working-directory = "globbing"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "templates"
working-directory = "templates"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
[[test]]
name = "package"
working-directory = "package"
command = "$<TARGET_FILE:cmkr>"
arguments = ["build"]
+1
View File
@@ -5,6 +5,7 @@ description = "Header-only library"
[target.mylib]
type = "interface"
include-directories = ["include"]
compile-features = ["cxx_std_11"]
[target.example]
type = "executable"
+20
View File
@@ -0,0 +1,20 @@
[project]
name = "Utility"
version = "1.2"
[target.Utility]
type = "static"
alias = "Utility::Utility" # autogenerate this alias as ${PROJECT_NAME}::TargetName
sources = [
"src/Utility/*.cpp",
"include/Utility/*.hpp",
]
include-directories = ["include"]
compile-features = ["cxx_std_11"]
[package]
name = "Utility" # defaults to ${PROJECT_NAME}
targets = ["Utility"] # required
headers = ["include/**.hpp", "include/**.h"] # required
dependencies = [] # defaults to all the required packages
namespace = "Utility::" # defaults to ${PROJECT_NAME}::
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <string>
namespace String
{
bool startsWith(const std::string& str, const std::string& prefix);
std::string reverse(const std::string& str);
}
+19
View File
@@ -0,0 +1,19 @@
#include <cctype>
#include <algorithm>
#include <Utility/String.hpp>
namespace String
{
bool startsWith(const std::string& str, const std::string& prefix)
{
return str.find(prefix) == 0;
}
std::string reverse(const std::string& str)
{
auto result = str;
std::reverse(result.begin(), result.end());
return result;
}
}
+25
View File
@@ -0,0 +1,25 @@
# To avoid repeating yourself in targets you can create your own target type (template). All properties of the template are inherited when used as a target type.
[project]
name = "templates"
description = "Target templates"
[template.app]
type = "executable"
sources = ["src/templates.cpp"]
compile-definitions = ["IS_APP"]
# Unlike interface targets you can also inherit properties
[template.app.properties]
CXX_STANDARD = "11"
CXX_STANDARD_REQUIRED = true
[target.app-a]
type = "app"
compile-definitions = ["APP_A"]
[target.app-b]
type = "app"
compile-definitions = ["APP_B"]
# **Note**: In most cases you probably want to use an [interface](/examples/interface) target instead.
+13
View File
@@ -0,0 +1,13 @@
#include <cstdio>
#if !defined(IS_APP)
#error Something went wrong with the template
#endif // IS_APP
int main() {
#if defined(APP_A)
puts("Hello from app A!");
#elif defined(APP_B)
puts("Hello from app B!");
#endif
}
+2 -1
View File
@@ -18,4 +18,5 @@ type = "executable"
sources = ["src/main.cpp"]
link-libraries = ["fmt::fmt"]
# The bootstrapping of vcpkg is fully automated and no user interaction is necessary. You can disable vcpkg by setting `CMKR_DISABLE_VCPKG=ON`.
# The bootstrapping of vcpkg is fully automated and no user interaction is necessary. You can disable vcpkg by setting `CMKR_DISABLE_VCPKG=ON`.
# To specify package features you can use the following syntax: `imgui[docking-experimental,freetype,sdl2-binding,opengl3-binding]`.
+11 -11
View File
@@ -1,11 +1,11 @@
{
"$cmkr": "This file is automatically generated from cmake.toml - DO NOT EDIT",
"$cmkr-url": "https://github.com/build-cpp/cmkr",
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"dependencies": [
"fmt"
],
"description": "Dependencies from vcpkg",
"name": "vcpkg",
"version-string": ""
}
{
"$cmkr": "This file is automatically generated from cmake.toml - DO NOT EDIT",
"$cmkr-url": "https://github.com/build-cpp/cmkr",
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"dependencies": [
"fmt"
],
"description": "Dependencies from vcpkg",
"name": "vcpkg",
"version-string": ""
}