cxx-init 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cxx_init-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 snkio027
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.4
2
+ Name: cxx-init
3
+ Version: 0.1.0
4
+ Summary: A small modern C++ project initializer.
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.10
8
+ Project-URL: Repository, https://github.com/snkio027/cxx-init
9
+ Project-URL: Issues, https://github.com/snkio027/cxx-init/issues
10
+ Description-Content-Type: text/markdown
11
+
12
+ # cxx-init
13
+
14
+ A small personal tool for creating clean, modern C++ projects without repeating the same setup work.
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ uv tool install cxx-init
20
+ ```
21
+
22
+ Alternatively, use pipx:
23
+
24
+ ```bash
25
+ pipx install cxx-init
26
+ ```
27
+
28
+ ## Create a project
29
+
30
+ ```bash
31
+ cxx init hello
32
+ cd hello
33
+ cmake --workflow --preset dev
34
+ ```
35
+
36
+ The generated project uses normal C++ tooling directly and does not depend on `cxx` after creation.
37
+
38
+ Upgrade or uninstall the tool with:
39
+
40
+ ```bash
41
+ uv tool upgrade cxx-init
42
+ uv tool uninstall cxx-init
43
+ ```
44
+
45
+ ## Requirements
46
+
47
+ `cxx` requires Python 3.10 or newer. Generated projects require CMake 3.25 or newer,
48
+ Ninja, and a C++23 compiler.
49
+
50
+ ## Design priorities
51
+
52
+ 1. Personal developer experience first.
53
+ 2. Small, readable implementation.
54
+ 3. Minimal generated files.
55
+ 4. No hidden host mutation.
56
+ 5. No build-system wrapper.
57
+ 6. No network requirement during project creation.
58
+ 7. Prefer boring, inspectable code over framework-heavy abstractions.
59
+
60
+ ## Scope
61
+
62
+ The current product creates one canonical `app` project. Additional artifact types remain deferred
63
+ until real usage demonstrates a need for them:
64
+
65
+ ```text
66
+ lib
67
+ header-only
68
+ ```
69
+
70
+ Initial generated projects use:
71
+
72
+ ```text
73
+ C++23
74
+ Modern target-centric CMake
75
+ CMake Presets / Workflow Presets
76
+ Ninja
77
+ clangd
78
+ clang-format
79
+ clang-tidy
80
+ CTest
81
+ ASan / UBSan where supported
82
+ compile_commands.json
83
+ ```
84
+
85
+ Dependency managers, C++26, Modules, ROS, CUDA, benchmarking and fuzzing are intentionally deferred.
86
+
87
+ ## Repository documents
88
+
89
+ - `AGENTS.md` — rules for Codex and other coding agents.
90
+ - `docs/architecture.md` — architecture and boundaries.
91
+ - `docs/implementation-plan.md` — current implementation sequence.
92
+
93
+ ## Development
94
+
95
+ Build the wheel and source distribution with:
96
+
97
+ ```bash
98
+ uv build
99
+ ```
100
+
101
+ Run the black-box test suite with:
102
+
103
+ ```bash
104
+ python3 -m unittest discover -s tests -v
105
+ ```
@@ -0,0 +1,94 @@
1
+ # cxx-init
2
+
3
+ A small personal tool for creating clean, modern C++ projects without repeating the same setup work.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ uv tool install cxx-init
9
+ ```
10
+
11
+ Alternatively, use pipx:
12
+
13
+ ```bash
14
+ pipx install cxx-init
15
+ ```
16
+
17
+ ## Create a project
18
+
19
+ ```bash
20
+ cxx init hello
21
+ cd hello
22
+ cmake --workflow --preset dev
23
+ ```
24
+
25
+ The generated project uses normal C++ tooling directly and does not depend on `cxx` after creation.
26
+
27
+ Upgrade or uninstall the tool with:
28
+
29
+ ```bash
30
+ uv tool upgrade cxx-init
31
+ uv tool uninstall cxx-init
32
+ ```
33
+
34
+ ## Requirements
35
+
36
+ `cxx` requires Python 3.10 or newer. Generated projects require CMake 3.25 or newer,
37
+ Ninja, and a C++23 compiler.
38
+
39
+ ## Design priorities
40
+
41
+ 1. Personal developer experience first.
42
+ 2. Small, readable implementation.
43
+ 3. Minimal generated files.
44
+ 4. No hidden host mutation.
45
+ 5. No build-system wrapper.
46
+ 6. No network requirement during project creation.
47
+ 7. Prefer boring, inspectable code over framework-heavy abstractions.
48
+
49
+ ## Scope
50
+
51
+ The current product creates one canonical `app` project. Additional artifact types remain deferred
52
+ until real usage demonstrates a need for them:
53
+
54
+ ```text
55
+ lib
56
+ header-only
57
+ ```
58
+
59
+ Initial generated projects use:
60
+
61
+ ```text
62
+ C++23
63
+ Modern target-centric CMake
64
+ CMake Presets / Workflow Presets
65
+ Ninja
66
+ clangd
67
+ clang-format
68
+ clang-tidy
69
+ CTest
70
+ ASan / UBSan where supported
71
+ compile_commands.json
72
+ ```
73
+
74
+ Dependency managers, C++26, Modules, ROS, CUDA, benchmarking and fuzzing are intentionally deferred.
75
+
76
+ ## Repository documents
77
+
78
+ - `AGENTS.md` — rules for Codex and other coding agents.
79
+ - `docs/architecture.md` — architecture and boundaries.
80
+ - `docs/implementation-plan.md` — current implementation sequence.
81
+
82
+ ## Development
83
+
84
+ Build the wheel and source distribution with:
85
+
86
+ ```bash
87
+ uv build
88
+ ```
89
+
90
+ Run the black-box test suite with:
91
+
92
+ ```bash
93
+ python3 -m unittest discover -s tests -v
94
+ ```
@@ -0,0 +1,20 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.12.7,<0.13"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "cxx-init"
7
+ version = "0.1.0"
8
+ description = "A small modern C++ project initializer."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ dependencies = []
14
+
15
+ [project.urls]
16
+ Repository = "https://github.com/snkio027/cxx-init"
17
+ Issues = "https://github.com/snkio027/cxx-init/issues"
18
+
19
+ [project.scripts]
20
+ cxx = "cxx_init.cli:main"
@@ -0,0 +1,20 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.12.7,<0.13"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "cxx-init"
7
+ version = "0.1.0"
8
+ description = "A small modern C++ project initializer."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ dependencies = []
14
+
15
+ [project.urls]
16
+ Repository = "https://github.com/snkio027/cxx-init"
17
+ Issues = "https://github.com/snkio027/cxx-init/issues"
18
+
19
+ [project.scripts]
20
+ cxx = "cxx_init.cli:main"
@@ -0,0 +1 @@
1
+ """A small modern C++ project initializer."""
@@ -0,0 +1,147 @@
1
+ import argparse
2
+ import re
3
+ import shutil
4
+ import subprocess
5
+ import sys
6
+ import tempfile
7
+ from pathlib import Path
8
+
9
+
10
+ NAME_PATTERN = re.compile(r"[a-z][a-z0-9-]*\Z")
11
+ FIXTURE_NAME = "robot-runtime"
12
+ FIXTURE_IDENTIFIER = "robot_runtime"
13
+ LOCAL_FIXTURE_ENTRIES = ("build", "CMakeUserPresets.json", ".DS_Store", ".idea", ".vscode")
14
+ VERSION = "0.1.0"
15
+
16
+
17
+ class GenerationError(Exception):
18
+ pass
19
+
20
+
21
+ def parse_args(argv):
22
+ parser = argparse.ArgumentParser(
23
+ prog="cxx",
24
+ description="Create a clean, native C++ project.",
25
+ )
26
+ parser.add_argument("--version", action="version", version=f"%(prog)s {VERSION}")
27
+ commands = parser.add_subparsers(dest="command", required=True)
28
+
29
+ init_parser = commands.add_parser("init", help="create an executable project")
30
+ init_parser.add_argument("name", help="project name: [a-z][a-z0-9-]*")
31
+ init_parser.add_argument(
32
+ "--no-git",
33
+ action="store_true",
34
+ help="do not initialize a local Git repository",
35
+ )
36
+
37
+ return parser.parse_args(argv)
38
+
39
+
40
+ def validate_destination(name, destination):
41
+ if NAME_PATTERN.fullmatch(name) is None:
42
+ raise GenerationError(f"invalid project name {name!r}; expected [a-z][a-z0-9-]*")
43
+
44
+ if destination.is_symlink():
45
+ raise GenerationError(f"destination must not be a symbolic link: {destination}")
46
+
47
+ if not destination.exists():
48
+ return False
49
+
50
+ if not destination.is_dir():
51
+ raise GenerationError(f"destination already exists and is not a directory: {destination}")
52
+
53
+ if next(destination.iterdir(), None) is not None:
54
+ raise GenerationError(f"destination already exists and is not empty: {destination}")
55
+
56
+ return True
57
+
58
+
59
+ def render_fixture(root, name, identifier):
60
+ replacements = (
61
+ (FIXTURE_NAME, name),
62
+ (FIXTURE_IDENTIFIER, identifier),
63
+ )
64
+
65
+ for generated_file in sorted(candidate for candidate in root.rglob("*") if candidate.is_file()):
66
+ try:
67
+ content = generated_file.read_text(encoding="utf-8")
68
+ except UnicodeDecodeError as error:
69
+ raise GenerationError(f"fixture contains a non-text file: {generated_file}") from error
70
+
71
+ for source, replacement in replacements:
72
+ content = content.replace(source, replacement)
73
+
74
+ generated_file.write_text(content, encoding="utf-8")
75
+
76
+
77
+ def initialize_git(root):
78
+ try:
79
+ result = subprocess.run(
80
+ ["git", "init", "--quiet"],
81
+ cwd=root,
82
+ check=False,
83
+ capture_output=True,
84
+ text=True,
85
+ )
86
+ except FileNotFoundError as error:
87
+ raise GenerationError("git is not available; rerun with --no-git") from error
88
+
89
+ if result.returncode != 0:
90
+ detail = result.stderr.strip() or "unknown error"
91
+ raise GenerationError(f"git init failed: {detail}")
92
+
93
+
94
+ def create_app(name, use_git):
95
+ fixture = Path(__file__).resolve().parent / "fixtures" / "canonical-app"
96
+ if not fixture.is_dir():
97
+ raise GenerationError(f"bundled app fixture is missing: {fixture}")
98
+
99
+ destination = Path.cwd() / name
100
+ destination_was_empty = validate_destination(name, destination)
101
+ identifier = name.replace("-", "_")
102
+
103
+ staging = Path(tempfile.mkdtemp(prefix=f".{name}.cxx-", dir=destination.parent))
104
+ try:
105
+ shutil.copytree(
106
+ fixture,
107
+ staging,
108
+ dirs_exist_ok=True,
109
+ ignore=shutil.ignore_patterns(*LOCAL_FIXTURE_ENTRIES),
110
+ )
111
+ render_fixture(staging, name, identifier)
112
+
113
+ if use_git:
114
+ initialize_git(staging)
115
+
116
+ if destination_was_empty:
117
+ destination.rmdir()
118
+
119
+ staging.replace(destination)
120
+ except Exception:
121
+ shutil.rmtree(staging, ignore_errors=True)
122
+ if destination_was_empty and not destination.exists():
123
+ destination.mkdir()
124
+ raise
125
+
126
+ return destination
127
+
128
+
129
+ def main(argv=None):
130
+ args = parse_args(argv)
131
+
132
+ try:
133
+ destination = create_app(args.name, use_git=not args.no_git)
134
+ except (GenerationError, OSError) as error:
135
+ print(f"cxx: error: {error}", file=sys.stderr)
136
+ return 1
137
+
138
+ print(f"Created C++ project: {destination.name}")
139
+ print()
140
+ print("Next:")
141
+ print(f" cd {args.name}")
142
+ print(" cmake --workflow --preset dev")
143
+ return 0
144
+
145
+
146
+ if __name__ == "__main__":
147
+ raise SystemExit(main())
@@ -0,0 +1,263 @@
1
+ ---
2
+ # =============================================================================
3
+ # Modern C++ Systems House Style
4
+ #
5
+ # Language baseline : C++23
6
+ # Formatter baseline: clang-format 23.1.x
7
+ # Style philosophy : Google-derived, compact, explicit, type-first,
8
+ # low-diff-noise, systems-oriented.
9
+ # =============================================================================
10
+
11
+ Language: Cpp
12
+ BasedOnStyle: Google
13
+ Standard: c++23
14
+
15
+ # -----------------------------------------------------------------------------
16
+ # Core layout
17
+ # -----------------------------------------------------------------------------
18
+
19
+ ColumnLimit: 100
20
+
21
+ IndentWidth: 4
22
+ ContinuationIndentWidth: 4
23
+ TabWidth: 4
24
+ UseTab: Never
25
+
26
+ # Keep multiline expressions visually anchored to their opening delimiter.
27
+ AlignAfterOpenBracket: true
28
+
29
+ # Avoid artificial visual tables that create noisy diffs when identifiers change.
30
+ AlignTrailingComments:
31
+ Kind: Never
32
+ OverEmptyLines: 0
33
+
34
+ SpacesBeforeTrailingComments: 2
35
+
36
+ # -----------------------------------------------------------------------------
37
+ # Type spelling: T*, T&, T&&
38
+ # -----------------------------------------------------------------------------
39
+
40
+ # Do not infer pointer style from legacy code in each individual file.
41
+ DerivePointerAlignment: false
42
+
43
+ # Type-first visual model:
44
+ #
45
+ # T* ptr;
46
+ # T& ref;
47
+ # T&& ref;
48
+ #
49
+ PointerAlignment: Left
50
+ ReferenceAlignment: Left
51
+
52
+ # House style uses west-const in authored code:
53
+ #
54
+ # const T*
55
+ # const T&
56
+ #
57
+ # Do NOT ask clang-format to rewrite qualifiers automatically: clang-format
58
+ # explicitly warns that qualifier reordering can make incorrect semantic guesses.
59
+ QualifierAlignment: Leave
60
+ SpaceAroundPointerQualifiers: Default
61
+
62
+ # -----------------------------------------------------------------------------
63
+ # Classes / records
64
+ # -----------------------------------------------------------------------------
65
+
66
+ # Prefer:
67
+ #
68
+ # class Foo {
69
+ # public:
70
+ # ...
71
+ #
72
+ # private:
73
+ # ...
74
+ # };
75
+ #
76
+ IndentAccessModifiers: false
77
+ AccessModifierOffset: -4
78
+
79
+ EmptyLineBeforeAccessModifier: LogicalBlock
80
+ EmptyLineAfterAccessModifier: Never
81
+
82
+ # Empty marker/tag records may remain compact:
83
+ #
84
+ # struct EmptyTag {};
85
+ #
86
+ # Non-empty records remain multiline.
87
+ AllowShortRecordOnASingleLine: Empty
88
+
89
+ # -----------------------------------------------------------------------------
90
+ # Control flow
91
+ # -----------------------------------------------------------------------------
92
+
93
+ BreakBeforeBraces: Attach
94
+
95
+ # Never collapse control-flow bodies onto one line.
96
+ AllowShortIfStatementsOnASingleLine: Never
97
+ AllowShortLoopsOnASingleLine: false
98
+ AllowShortBlocksOnASingleLine: Never
99
+ AllowShortCaseLabelsOnASingleLine: false
100
+
101
+ # Keep switch structure shallow and visually obvious.
102
+ IndentCaseLabels: false
103
+
104
+ # -----------------------------------------------------------------------------
105
+ # Functions / lambdas
106
+ # -----------------------------------------------------------------------------
107
+
108
+ # Empty functions may stay compact; real implementations get a normal body.
109
+ AllowShortFunctionsOnASingleLine: Empty
110
+
111
+ # Small inline callback lambdas are often clearer on one line:
112
+ #
113
+ # std::ranges::find_if(values, [](int value) { return value > 0; });
114
+ #
115
+ AllowShortLambdasOnASingleLine: Inline
116
+
117
+ # If a parameter/argument list fits within 100 columns, keep it on one line.
118
+ # Once it must wrap, prefer one logical item per continuation line instead of
119
+ # dense partial bin-packing.
120
+ PackParameters:
121
+ BinPack: OnePerLine
122
+
123
+ PackArguments:
124
+ BinPack: OnePerLine
125
+
126
+ AllowAllParametersOfDeclarationOnNextLine: false
127
+ AllowAllArgumentsOnNextLine: false
128
+
129
+ # Keep noexcept attached to the function signature.
130
+ AllowBreakBeforeNoexceptSpecifier: Never
131
+
132
+ # -----------------------------------------------------------------------------
133
+ # Constructors / inheritance
134
+ # -----------------------------------------------------------------------------
135
+
136
+ # Short:
137
+ #
138
+ # Point::Point(float x, float y) : x_(x), y_(y) {}
139
+ #
140
+ # Long:
141
+ #
142
+ # RobotFrame::RobotFrame(...)
143
+ # : samples_(...),
144
+ # timestamp_(...) {}
145
+ #
146
+ BreakConstructorInitializers: BeforeColon
147
+ PackConstructorInitializers: CurrentLine
148
+
149
+ # Long inheritance lists use the same visual grammar.
150
+ BreakInheritanceList: BeforeColon
151
+
152
+ # -----------------------------------------------------------------------------
153
+ # C++20 / C++23 Concepts
154
+ # -----------------------------------------------------------------------------
155
+
156
+ # Prefer:
157
+ #
158
+ # template <typename T>
159
+ # concept Sensor = ...;
160
+ #
161
+ BreakBeforeConceptDeclarations: Always
162
+
163
+ # Prefer:
164
+ #
165
+ # template <typename T>
166
+ # requires Sensor<T>
167
+ # void process(T value);
168
+ #
169
+ RequiresClausePosition: OwnLine
170
+ IndentRequiresClause: false
171
+
172
+ # Avoid excessive indentation inside requires expressions.
173
+ RequiresExpressionIndentation: OuterScope
174
+
175
+ # Keep normal compound requirements readable and compact:
176
+ #
177
+ # { value.read() } -> std::same_as<int>;
178
+ #
179
+ AllowShortCompoundRequirementOnASingleLine: true
180
+
181
+ SpaceAfterTemplateKeyword: true
182
+
183
+ # -----------------------------------------------------------------------------
184
+ # Enums / namespaces
185
+ # -----------------------------------------------------------------------------
186
+
187
+ AllowShortEnumsOnASingleLine: false
188
+ AllowShortNamespacesOnASingleLine: false
189
+
190
+ NamespaceIndentation: None
191
+ FixNamespaceComments: true
192
+ ShortNamespaceLines: 1
193
+
194
+ # -----------------------------------------------------------------------------
195
+ # Vertical rhythm
196
+ # -----------------------------------------------------------------------------
197
+
198
+ MaxEmptyLinesToKeep: 1
199
+
200
+ KeepEmptyLines:
201
+ AtStartOfBlock: false
202
+ AtStartOfFile: false
203
+ AtEndOfFile: false
204
+
205
+ # Give top-level definitions enough breathing room without allowing arbitrary
206
+ # vertical whitespace to accumulate.
207
+ SeparateDefinitionBlocks: Always
208
+
209
+ # -----------------------------------------------------------------------------
210
+ # String literals
211
+ # -----------------------------------------------------------------------------
212
+
213
+ # Do not manufacture adjacent string literals merely to satisfy ColumnLimit.
214
+ # Long human-facing strings should be intentionally structured by the author.
215
+ BreakStringLiterals: false
216
+
217
+ # -----------------------------------------------------------------------------
218
+ # Includes
219
+ # -----------------------------------------------------------------------------
220
+
221
+ # The main header corresponding to a .cpp automatically receives category 0.
222
+ #
223
+ # Example:
224
+ #
225
+ # robot_frame.cpp
226
+ # robot_frame.hpp <- category 0 automatically
227
+ #
228
+ MainIncludeChar: Quote
229
+ IncludeIsMainRegex: "(_test)?$"
230
+
231
+ # Merge existing include blocks, sort them, then rebuild semantic groups.
232
+ IncludeBlocks: Regroup
233
+
234
+ SortIncludes:
235
+ Enabled: true
236
+ IgnoreCase: false
237
+ IgnoreExtension: false
238
+
239
+ # clang-format uses the FIRST matching regex.
240
+ #
241
+ # Resulting order:
242
+ #
243
+ # 0. Current translation unit's main header
244
+ # 1. Standard library + OS/system headers
245
+ # 2. Known third-party libraries
246
+ # 3. Project-local headers
247
+ #
248
+ IncludeCategories:
249
+ # Known third-party roots must appear before the generic <...> matcher.
250
+ - Regex: '^["<](boost|fmt|spdlog|nlohmann|gtest|gmock|benchmark|Eigen|eigen3)/'
251
+ Priority: 2
252
+ CaseSensitive: true
253
+
254
+ # Standard C/C++ library and platform/system headers.
255
+ - Regex: "^<.*>$"
256
+ Priority: 1
257
+ CaseSensitive: true
258
+
259
+ # Project-local headers.
260
+ - Regex: '^".*"$'
261
+ Priority: 3
262
+ CaseSensitive: true
263
+ ...
@@ -0,0 +1,10 @@
1
+ ---
2
+ Checks: >
3
+ -*,
4
+ bugprone-*,
5
+ clang-analyzer-*,
6
+ performance-*,
7
+ portability-*
8
+ WarningsAsErrors: ''
9
+ FormatStyle: file
10
+ ...
@@ -0,0 +1,2 @@
1
+ CompileFlags:
2
+ CompilationDatabase: build/dev
@@ -0,0 +1,3 @@
1
+ schema = 1
2
+ template = "app"
3
+ language = "c++23"
@@ -0,0 +1,5 @@
1
+ /build/
2
+ CMakeUserPresets.json
3
+ .DS_Store
4
+ .idea/
5
+ .vscode/
@@ -0,0 +1,50 @@
1
+ cmake_minimum_required(VERSION 3.25)
2
+
3
+ project(robot_runtime LANGUAGES CXX)
4
+
5
+ option(ENABLE_SANITIZERS "Enable address and undefined behavior sanitizers" OFF)
6
+
7
+ include(CTest)
8
+
9
+ add_executable(robot_runtime src/main.cpp)
10
+ target_compile_features(robot_runtime PRIVATE cxx_std_23)
11
+ set_target_properties(robot_runtime PROPERTIES CXX_EXTENSIONS OFF)
12
+
13
+ if(MSVC)
14
+ target_compile_options(robot_runtime PRIVATE /W4 /permissive-)
15
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$")
16
+ target_compile_options(robot_runtime PRIVATE -Wall -Wextra -Wpedantic)
17
+ endif()
18
+
19
+ if(ENABLE_SANITIZERS)
20
+ if(CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$")
21
+ target_compile_options(
22
+ robot_runtime PRIVATE -fsanitize=address,undefined -fno-omit-frame-pointer
23
+ )
24
+ target_link_options(robot_runtime PRIVATE -fsanitize=address,undefined)
25
+ else()
26
+ message(FATAL_ERROR "Sanitizers are only configured for Clang, AppleClang, and GCC")
27
+ endif()
28
+ endif()
29
+
30
+ if(BUILD_TESTING)
31
+ add_executable(robot_runtime_smoke_test tests/smoke_test.cpp)
32
+ target_compile_features(robot_runtime_smoke_test PRIVATE cxx_std_23)
33
+ set_target_properties(robot_runtime_smoke_test PROPERTIES CXX_EXTENSIONS OFF)
34
+
35
+ if(MSVC)
36
+ target_compile_options(robot_runtime_smoke_test PRIVATE /W4 /permissive-)
37
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(AppleClang|Clang|GNU)$")
38
+ target_compile_options(robot_runtime_smoke_test PRIVATE -Wall -Wextra -Wpedantic)
39
+ endif()
40
+
41
+ if(ENABLE_SANITIZERS)
42
+ target_compile_options(
43
+ robot_runtime_smoke_test
44
+ PRIVATE -fsanitize=address,undefined -fno-omit-frame-pointer
45
+ )
46
+ target_link_options(robot_runtime_smoke_test PRIVATE -fsanitize=address,undefined)
47
+ endif()
48
+
49
+ add_test(NAME robot_runtime.smoke COMMAND robot_runtime_smoke_test)
50
+ endif()
@@ -0,0 +1,103 @@
1
+ {
2
+ "version": 6,
3
+ "cmakeMinimumRequired": {
4
+ "major": 3,
5
+ "minor": 25,
6
+ "patch": 0
7
+ },
8
+ "configurePresets": [
9
+ {
10
+ "name": "dev",
11
+ "displayName": "Development",
12
+ "generator": "Ninja",
13
+ "binaryDir": "${sourceDir}/build/dev",
14
+ "cacheVariables": {
15
+ "BUILD_TESTING": true,
16
+ "CMAKE_BUILD_TYPE": "Debug",
17
+ "CMAKE_EXPORT_COMPILE_COMMANDS": true,
18
+ "CMAKE_OSX_SYSROOT": "macosx"
19
+ }
20
+ },
21
+ {
22
+ "name": "san",
23
+ "displayName": "Sanitizers",
24
+ "inherits": "dev",
25
+ "binaryDir": "${sourceDir}/build/san",
26
+ "cacheVariables": {
27
+ "ENABLE_SANITIZERS": true
28
+ }
29
+ }
30
+ ],
31
+ "buildPresets": [
32
+ {
33
+ "name": "dev",
34
+ "configurePreset": "dev"
35
+ },
36
+ {
37
+ "name": "san",
38
+ "configurePreset": "san"
39
+ }
40
+ ],
41
+ "testPresets": [
42
+ {
43
+ "name": "dev",
44
+ "configurePreset": "dev",
45
+ "output": {
46
+ "outputOnFailure": true
47
+ },
48
+ "execution": {
49
+ "noTestsAction": "error",
50
+ "stopOnFailure": true
51
+ }
52
+ },
53
+ {
54
+ "name": "san",
55
+ "configurePreset": "san",
56
+ "output": {
57
+ "outputOnFailure": true
58
+ },
59
+ "execution": {
60
+ "noTestsAction": "error",
61
+ "stopOnFailure": true
62
+ }
63
+ }
64
+ ],
65
+ "workflowPresets": [
66
+ {
67
+ "name": "dev",
68
+ "displayName": "Development workflow",
69
+ "steps": [
70
+ {
71
+ "type": "configure",
72
+ "name": "dev"
73
+ },
74
+ {
75
+ "type": "build",
76
+ "name": "dev"
77
+ },
78
+ {
79
+ "type": "test",
80
+ "name": "dev"
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ "name": "san",
86
+ "displayName": "Sanitizer workflow",
87
+ "steps": [
88
+ {
89
+ "type": "configure",
90
+ "name": "san"
91
+ },
92
+ {
93
+ "type": "build",
94
+ "name": "san"
95
+ },
96
+ {
97
+ "type": "test",
98
+ "name": "san"
99
+ }
100
+ ]
101
+ }
102
+ ]
103
+ }
@@ -0,0 +1,6 @@
1
+ #include <iostream>
2
+
3
+ int main() {
4
+ std::cout << "Hello from robot-runtime!\n";
5
+ return 0;
6
+ }
@@ -0,0 +1,6 @@
1
+ #include <string_view>
2
+
3
+ int main() {
4
+ constexpr std::string_view project_name{"robot-runtime"};
5
+ return project_name.empty() ? 1 : 0;
6
+ }