Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion docs/cmake-toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ tag = "v0.1"
shallow = false # shallow clone (--depth 1)
system = false
subdir = "" # folder containing CMakeLists.txt
# Set cache variables before FetchContent_MakeAvailable
options = { BUILD_TESTS = false, BUILD_EXAMPLES = false }

# Include a CMake project from a URL
[fetch-content.urlcontent]
Expand All @@ -213,10 +215,19 @@ sha1 = "502a4e25b8b209889c99c7fa0732102682c2e4ff"
condition = "mycondition"
svn = "https://svn-host.com/url"
rev = "svn_rev"

# For many options, you can also use a separate table:
# [fetch-content.bigproject.options]
# BUILD_TESTS = false
# BUILD_EXAMPLES = false
# SOME_STRING_OPTION = "value"
# SOME_LIST_OPTION = ["item1", "item2"] # becomes "item1;item2"
```

Table keys that match CMake variable names (`[A-Z_]+`) will be passed to the [`FetchContent_Declare`](https://cmake.org/cmake/help/latest/module/FetchContent.html#command:fetchcontent_declare) command.

The `options` field allows setting CACHE variables before `FetchContent_MakeAvailable` is called. This is useful for configuring options on the fetched dependency (e.g., disabling tests). Boolean values become `ON`/`OFF`, arrays become semicolon-separated strings.

## Targets

```toml
Expand Down Expand Up @@ -246,6 +257,24 @@ link-options = [""] # linker flags
private-link-options = [""]
precompile-headers = [""] # precompiled headers
private-precompile-headers = [""]
dependencies = [""] # add_dependencies(target ...)

# Keys below are for type = "custom" (add_custom_target)
all = false
command = ["${CMAKE_COMMAND}", "-E", "echo", "Hello"] # one command line
commands = [ # multiple command lines
["${CMAKE_COMMAND}", "-E", "echo", "First"],
["${CMAKE_COMMAND}", "-E", "echo", "Second"],
]
depends = ["generated.txt"] # add_custom_target(... DEPENDS ...)
byproducts = ["generated.txt"]
working-directory = "${CMAKE_CURRENT_BINARY_DIR}"
comment = "Run custom target"
job-pool = "pool"
job-server-aware = true
verbatim = true
uses-terminal = false # incompatible with job-pool when true
command-expand-lists = true

cmake-before = """
message(STATUS "CMake injected before the target")
Expand All @@ -263,6 +292,51 @@ CXX_STANDARD_REQUIRED = true
FOLDER = "MyFolder"
```

### Custom commands

Use `[[target.<name>.custom-command]]` to map directly to [`add_custom_command`](https://cmake.org/cmake/help/latest/command/add_custom_command.html). A custom command can use either the `OUTPUT` form or the `TARGET` form:

```toml
# OUTPUT form (add_custom_command(OUTPUT ...))
[[target.mytarget.custom-command]]
condition = "mycondition"
outputs = ["generated.cpp"] # relative paths are interpreted from ${CMAKE_CURRENT_BINARY_DIR}
command = [
"${CMAKE_COMMAND}",
"-DOUTPUT=${CMAKE_CURRENT_BINARY_DIR}/generated.cpp",
"-P",
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate.cmake",
]
depends = ["cmake/generate.cmake"]
byproducts = ["generated.hpp"]
main-dependency = "cmake/generate.cmake"
implicit-depends = [["CXX", "src/input.idl"]]
working-directory = "${CMAKE_CURRENT_BINARY_DIR}"
comment = "Generate source"
depfile = "${CMAKE_CURRENT_BINARY_DIR}/generated.d"
job-pool = "pool" # incompatible with uses-terminal when uses-terminal = true
job-server-aware = true
verbatim = true
append = false
uses-terminal = false
codegen = false
command-expand-lists = false
depends-explicit-only = false

# TARGET form (add_custom_command(TARGET ...))
[[target.mytarget.custom-command]]
build-event = "post-build" # pre-build, pre-link, post-build
command = ["${CMAKE_COMMAND}", "-E", "touch", "${CMAKE_CURRENT_BINARY_DIR}/post-build.stamp"]
byproducts = ["${CMAKE_CURRENT_BINARY_DIR}/post-build.stamp"]
working-directory = "${CMAKE_CURRENT_BINARY_DIR}"
comment = "Post-build step"
verbatim = true
command-expand-lists = false
uses-terminal = false
```

For each custom command entry, exactly one of `outputs` or `build-event` is required. Relative `outputs`/`byproducts` paths follow CMake and are interpreted from the current binary directory. `build-event` is only valid for non-`interface` targets, and `pre-link` is not supported for `type = "custom"`. In both `add_custom_command(OUTPUT ...)` and `add_custom_target(...)`, `job-pool` cannot be combined with `uses-terminal = true`. When `append = true` is used with the `OUTPUT` form, at least one `command`/`commands` entry or `depends` must also be provided.

A table mapping the cmkr features to the relevant CMake construct and the relevant documentation pages:

| cmkr | CMake construct | Description |
Expand All @@ -279,6 +353,9 @@ A table mapping the cmkr features to the relevant CMake construct and the releva
| `link-libraries` | [`target_link_libraries`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) | Adds library dependencies. Use `::mylib` to make sure a target exists. |
| `link-options` | [`target_link_options`](https://cmake.org/cmake/help/latest/command/target_link_options.html) | Adds linker flags. |
| `precompile-headers` | [`target_precompile_headers`](https://cmake.org/cmake/help/latest/command/target_precompile_headers.html) | Specifies precompiled headers. |
| `dependencies` | [`add_dependencies`](https://cmake.org/cmake/help/latest/command/add_dependencies.html) | Adds target-level dependencies. |
| `type = "custom"` + custom target keys | [`add_custom_target`](https://cmake.org/cmake/help/latest/command/add_custom_target.html) | Creates a custom target with command/dependency options. |
| `[[target.<name>.custom-command]]` | [`add_custom_command`](https://cmake.org/cmake/help/latest/command/add_custom_command.html) | Supports both `OUTPUT` and `TARGET` forms. |
| `properties` | [`set_target_properties`](https://cmake.org/cmake/help/latest/command/set_target_properties.html) | See [properties on targets](https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#properties-on-targets) for more information. |

The default [visibility](/basics) is as follows:
Expand Down Expand Up @@ -342,4 +419,4 @@ files = ["content/my.png"]
dirs = ["include"]
configs = ["Release", "Debug"]
optional = false
```
```
141 changes: 141 additions & 0 deletions docs/examples/custom-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
# Automatically generated from tests/custom-command/cmake.toml - DO NOT EDIT
layout: default
title: Tests add_custom_command and add_custom_target support
permalink: /examples/custom-command
parent: Examples
nav_order: 12
---

# Tests add_custom_command and add_custom_target support

This test demonstrates add_custom_command and add_custom_target support in cmkr.

```toml
#
# There are two forms of add_custom_command in CMake:
# 1. Output form: generates files that can be consumed by other targets
# 2. Target form: runs commands at build time for a specific target (pre-build, pre-link, post-build)

[project]
name = "custom-command"
description = "Tests add_custom_command and add_custom_target support"

# -----------------------------------------------------------------------------
# Simple executable demonstrating post-build events
# -----------------------------------------------------------------------------

[target.hello]
type = "executable"
sources = ["src/hello.cpp"]

# This post-build command runs after the 'hello' executable is built.
# build-event can be: "pre-build", "pre-link", or "post-build"
[[target.hello.custom-command]]
build-event = "post-build"
command = ["${CMAKE_COMMAND}", "-E", "echo", "Built executable: $<TARGET_FILE_NAME:hello>"]
comment = "Print the built executable name"

# -----------------------------------------------------------------------------
# Executable with code generation (output form custom command)
# -----------------------------------------------------------------------------

[target.custom-command]
type = "executable"
sources = ["src/main.cpp"]
include-directories = ["${CMAKE_CURRENT_BINARY_DIR}/generated"]

# Output form: This custom command generates source files before building.
# Relative outputs follow CMake and are interpreted from the binary directory.
# The outputs are automatically added as sources to the target.
[[target.custom-command.custom-command]]
outputs = ["generated/generated.cpp"]
byproducts = ["generated/generated.hpp"]
depends = ["cmake/generate_source.cmake"]
command = [
"${CMAKE_COMMAND}",
"-DOUTPUT_CPP=${CMAKE_CURRENT_BINARY_DIR}/generated/generated.cpp",
"-DOUTPUT_HPP=${CMAKE_CURRENT_BINARY_DIR}/generated/generated.hpp",
"-P",
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate_source.cmake",
]
comment = "Generate source files"
verbatim = true

# Target form: This post-build command runs after 'custom-command' is built.
[[target.custom-command.custom-command]]
build-event = "post-build"
command = [
"${CMAKE_COMMAND}",
"-E",
"touch",
"${CMAKE_CURRENT_BINARY_DIR}/custom-command-post-build.stamp",
]
byproducts = ["${CMAKE_CURRENT_BINARY_DIR}/custom-command-post-build.stamp"]
comment = "Create a post-build stamp file"
verbatim = true

# -----------------------------------------------------------------------------
# Custom target (add_custom_target)
# -----------------------------------------------------------------------------

# A custom target runs commands independently of any executable/library.
# Setting 'all = true' makes it run as part of the default build.
[target.custom-codegen]
type = "custom"
all = true
command = [
"${CMAKE_COMMAND}",
"-E",
"touch",
"${CMAKE_CURRENT_BINARY_DIR}/custom-target.stamp",
]
byproducts = ["${CMAKE_CURRENT_BINARY_DIR}/custom-target.stamp"]
comment = "Run custom target"
verbatim = true

# -----------------------------------------------------------------------------
# Template-based custom target
# -----------------------------------------------------------------------------

# Custom target options should also work when the target type comes from a template.
[template.generated-custom-target]
type = "custom"
all = true
verbatim = true

[target.custom-codegen-template]
type = "generated-custom-target"
command = [
"${CMAKE_COMMAND}",
"-DINPUT=${CMAKE_CURRENT_BINARY_DIR}/template-custom-target.stamp",
"-P",
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/verify_file_exists.cmake",
]
comment = "Verify the generated stamp exists"

# The output-form custom command should automatically become a dependency of the
# custom target, so the verification command sees the stamp file.
[[target.custom-codegen-template.custom-command]]
outputs = ["template-custom-target.stamp"]
command = [
"${CMAKE_COMMAND}",
"-E",
"touch",
"${CMAKE_CURRENT_BINARY_DIR}/template-custom-target.stamp",
]
comment = "Create a stamp file for the template-based custom target"
verbatim = true

# A target-level all = false should override the template's all = true.
# If this target is incorrectly included in the default build, the build fails.
[target.custom-codegen-template-disabled]
type = "generated-custom-target"
all = false
command = ["${CMAKE_COMMAND}", "-E", "false"]
comment = "This target must not run as part of the default build"
```



<sup><sub>This page was automatically generated from [tests/custom-command/cmake.toml](https://github.com/build-cpp/cmkr/tree/main/tests/custom-command/cmake.toml).</sub></sup>
74 changes: 74 additions & 0 deletions docs/examples/generator-executable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
# Automatically generated from tests/generator-executable/cmake.toml - DO NOT EDIT
layout: default
title: Tests using an executable to generate sources for another target
permalink: /examples/generator-executable
parent: Examples
nav_order: 13
---

# Tests using an executable to generate sources for another target

This test demonstrates a common pattern: using an executable to generate sources

for another target. The generator runs at build time and produces code that is

consumed by the main executable.

```toml
#
# CMake handles the dependency automatically: the generator executable is built
# first, then it runs to produce the generated sources, and finally the main
# executable is built using those sources.

[project]
name = "generator-executable"
description = "Tests using an executable to generate sources for another target"

# -----------------------------------------------------------------------------
# Generator executable: produces code at build time
# -----------------------------------------------------------------------------

[target.generate_numbers]
type = "executable"
sources = ["src/generate_numbers.cpp"]

# Post-build: confirm the generator was built
[[target.generate_numbers.custom-command]]
build-event = "post-build"
command = ["${CMAKE_COMMAND}", "-E", "echo", "Generator built successfully: $<TARGET_FILE_NAME:generate_numbers>"]
comment = "Confirm generator executable was built"

# -----------------------------------------------------------------------------
# Main executable: uses generated sources
# -----------------------------------------------------------------------------

[target.main]
type = "executable"
sources = ["src/main.cpp"]
include-directories = ["${CMAKE_CURRENT_BINARY_DIR}/generated"]

# Create the generated directory before the generator runs.
cmake-before = """
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/generated")
"""

# Output form custom command: runs the generate_numbers executable to generate sources.
# The outputs are automatically added as sources to this target.
# The DEPENDS on "generate_numbers" ensures the generator is built before this runs.
[[target.main.custom-command]]
outputs = ["${CMAKE_CURRENT_BINARY_DIR}/generated/numbers.cpp"]
depends = ["generate_numbers"]
command = ["$<TARGET_FILE:generate_numbers>", "${CMAKE_CURRENT_BINARY_DIR}/generated/numbers.cpp"]
comment = "Run generate_numbers to generate numbers.cpp"

# Post-build: run the executable to verify it works
[[target.main.custom-command]]
build-event = "post-build"
command = ["$<TARGET_FILE:main>"]
comment = "Run the main executable to verify generated code works"
```



<sup><sub>This page was automatically generated from [tests/generator-executable/cmake.toml](https://github.com/build-cpp/cmkr/tree/main/tests/generator-executable/cmake.toml).</sub></sup>
Loading
Loading