Sane C++ Libraries
C++ Platform Abstraction Libraries
Build.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Containers/Array.h"
5#include "../Containers/VectorSet.h"
6#include "../Foundation/Result.h"
7#include "../Foundation/TaggedUnion.h"
8#include "../Strings/String.h"
9#include "Internal/TaggedMap.h"
10
11namespace SC
12{
14namespace Build
15{
18
21struct Parameters;
24{
25 enum Type
26 {
27 Unknown = 0,
28 Windows,
29 Apple,
30 Linux,
31 Wasm
32 };
33
35 static constexpr StringView toString(Type type)
36 {
37 switch (type)
38 {
39 case Unknown: return "unknown";
40 case Windows: return "windows";
41 case Apple: return "apple";
42 case Linux: return "linux";
43 case Wasm: return "wasm";
44 }
45 Assert::unreachable();
46 }
47};
48
51{
52 enum Type
53 {
54 Any = 0,
55 Intel32,
56 Intel64,
57 Arm64,
58 Wasm
59 };
60
62 static constexpr StringView toString(Type type)
63 {
64 switch (type)
65 {
66 case Any: return "Any";
67 case Intel32: return "Intel32";
68 case Intel64: return "Intel64";
69 case Arm64: return "Arm64";
70 case Wasm: return "Wasm";
71 }
72 Assert::unreachable();
73 }
74};
75
78{
79 enum Type
80 {
85 };
86
88 static constexpr StringView toString(Type type)
89 {
90 switch (type)
91 {
92 case XCode: return "XCode";
93 case VisualStudio2022: return "VisualStudio2022";
94 case VisualStudio2019: return "VisualStudio2019";
95 case Make: return "Make";
96 }
97 Assert::unreachable();
98 }
99};
100
103{
104 enum Type
105 {
108 };
109
111 static constexpr StringView toString(Type type)
112 {
113 switch (type)
114 {
115 case Debug: return "Debug"_a8;
116 case Release: return "Release"_a8;
117 }
118 Assert::unreachable();
119 }
120};
121
124{
125 enum Type
126 {
135 };
136
139 {
140 StringView name;
141 StringView description;
142 };
143
145 static constexpr NameDescription typeToString(Type type)
146 {
147 switch (type)
148 {
149 case includePaths: return {"includePaths", "Include paths"};
150 case preprocessorDefines: return {"preprocessorDefines", "Preprocessor defines"};
151 case optimizationLevel: return {"optimizationLevel", "Optimization level"};
152 case enableASAN: return {"enableASAN", "Address Sanitizer"};
153 case enableRTTI: return {"enableRTTI", "Runtime Type Identification"};
154 case enableExceptions: return {"enableExceptions", "C++ Exceptions"};
155 case enableStdCpp: return {"enableStdCpp", "C++ Standard Library"};
156 case enableCoverage: return {"enableCoverage", "Code coverage instrumentation"};
157 }
158 Assert::unreachable();
159 }
160 template <Type E, typename T>
161 using Tag = TaggedType<Type, E, T>; // Helper to save some typing
162
164 Tag<preprocessorDefines, Vector<String>>, //
165 Tag<optimizationLevel, Optimization::Type>, //
166 Tag<enableASAN, bool>, //
167 Tag<enableRTTI, bool>, //
168 Tag<enableExceptions, bool>, //
169 Tag<enableCoverage, bool>, //
170 Tag<enableStdCpp, bool>>;
171
172 using Union = TaggedUnion<Compile>;
173};
174
176struct CompileFlags : public TaggedMap<Compile::Type, Compile::Union>
177{
179 [[nodiscard]] bool addIncludes(Span<const StringView> includes)
180 {
181 return getOrCreate<Compile::includePaths>()->append(includes);
182 }
183
185 [[nodiscard]] bool addDefines(Span<const StringView> defines)
186 {
187 return getOrCreate<Compile::preprocessorDefines>()->append(defines);
188 }
189};
190
192struct Link
193{
194 enum Type
195 {
205 };
206
208 static constexpr StringView typeToString(Type type)
209 {
210 switch (type)
211 {
212 case libraryPaths: return "libraryPaths";
213 case linkFrameworksAny: return "linkFrameworksAny";
214 case linkFrameworksMacOS: return "linkFrameworksMacOS";
215 case linkFrameworksIOS: return "linkFrameworksIOS";
216 case linkLibraries: return "linkLibraries";
217 case guiApplication: return "guiApplication";
218 case enableLTO: return "enableLTO";
219 case enableASAN: return "enableASAN";
220 case enableStdCpp: return "enableStdCpp";
221 }
222 Assert::unreachable();
223 }
224 template <Type E, typename T>
225 using Tag = TaggedType<Type, E, T>; // Helper to save some typing
226
228 Tag<linkFrameworksAny, Vector<String>>, //
229 Tag<linkFrameworksMacOS, Vector<String>>, //
230 Tag<linkFrameworksIOS, Vector<String>>, //
231 Tag<linkLibraries, Vector<String>>, //
232 Tag<guiApplication, bool>, //
233 Tag<enableLTO, bool>, //
234 Tag<enableASAN, bool>, //
235 Tag<enableStdCpp, bool> //
236 >;
237
238 using Union = TaggedUnion<Link>;
239};
240
241enum class PlatformApple
242{
243 Any,
244 macOS,
245 iOS
246};
248struct LinkFlags : public TaggedMap<Link::Type, Link::Union>
249{
251 [[nodiscard]] bool addSearchPath(Span<const StringView> libraries)
252 {
253 return getOrCreate<Link::libraryPaths>()->append(libraries);
254 }
255
257 [[nodiscard]] bool addFrameworks(Span<const StringView> frameworks, PlatformApple appleOS = PlatformApple::Any)
258 {
259 switch (appleOS)
260 {
261 case PlatformApple::macOS: return getOrCreate<Link::linkFrameworksMacOS>()->append(frameworks);
262 case PlatformApple::iOS: return getOrCreate<Link::linkFrameworksIOS>()->append(frameworks);
263 default: return getOrCreate<Link::linkFrameworksAny>()->append(frameworks);
264 }
265 }
266
268 [[nodiscard]] bool addLibraries(Span<const StringView> libraries)
269 {
270 return getOrCreate<Link::linkLibraries>()->append(libraries);
271 }
272};
273
276{
278 enum class Preset
279 {
280 None,
281 Debug,
283 Release,
284 };
285
288 {
289 StringView platformToolset;
290 };
291
293
295 [[nodiscard]] static constexpr StringView PresetToString(Preset preset)
296 {
297 switch (preset)
298 {
299 case Configuration::Preset::Debug: return "Debug";
300 case Configuration::Preset::DebugCoverage: return "DebugCoverage";
301 case Configuration::Preset::Release: return "Release";
302 case Configuration::Preset::None: return "None";
303 }
304 Assert::unreachable();
305 }
306
308 [[nodiscard]] bool applyPreset(Preset newPreset, const Parameters& parameters);
309
310 [[nodiscard]] static constexpr StringView getStandardBuildDirectory()
311 {
312 return "$(TARGET_OS)-$(TARGET_ARCHITECTURES)-$(BUILD_SYSTEM)-$(COMPILER)-$(CONFIGURATION)";
313 }
314
318
321
323 Architecture::Type architecture = Architecture::Any;
324
326};
327
330{
332 enum Type
333 {
337 };
338
340 static constexpr StringView typeToString(Type type)
341 {
342 switch (type)
343 {
344 case Executable: return "Executable";
345 case DynamicLibrary: return "DynamicLibrary";
346 case StaticLibrary: return "StaticLibrary";
347 }
348 Assert::unreachable();
349 }
350};
351
354{
356 struct File
357 {
360 {
362 Remove
363 };
367
368 bool operator==(const File& other) const
369 {
370 // collectUniqueRootPaths doesn't care about de-duplicating also operation
371 return base == other.base and mask == other.mask;
372 }
373 };
374
375 Project() = default;
377
379
384
388
390
392 [[nodiscard]] bool setRootDirectory(StringView file);
393
395 [[nodiscard]] bool addPresetConfiguration(Configuration::Preset preset, const Parameters& parameters,
396 StringView configurationName = StringView());
397
399 [[nodiscard]] Configuration* getConfiguration(StringView configurationName);
401 [[nodiscard]] const Configuration* getConfiguration(StringView configurationName) const;
402
406 [[nodiscard]] bool addDirectory(StringView subdirectory, StringView filter);
407
409 [[nodiscard]] bool addFile(StringView singleFile);
410
415 [[nodiscard]] bool removeFiles(StringView subdirectory, StringView filter);
416
418 [[nodiscard]] Result validate() const;
419};
420
423{
424 Workspace() = default;
426
431
433 [[nodiscard]] Result validate() const;
434};
435
437{
438 String projectsDirectory;
439 String intermediatesDirectory;
440 String outputsDirectory;
441 String packagesCacheDirectory;
442 String packagesInstallDirectory;
443 String libraryDirectory;
444};
445
448{
449 Platform::Type platform;
450 Architecture::Type architecture;
452
453 Parameters()
454 {
455 platform = Platform::Linux;
456 architecture = Architecture::Any;
458 }
459 Directories directories;
460};
461
464{
466
470 Result configure(StringView projectName, const Parameters& parameters) const;
471};
472
475{
477
478 const Build::Definition& definition;
479 DefinitionCompiler(const Build::Definition& definition) : definition(definition) {}
480
481 [[nodiscard]] Result validate();
482 [[nodiscard]] Result build();
483
484 private:
485 [[nodiscard]] static Result fillPathsList(StringView path, const VectorSet<Project::File>& filters,
486 VectorMap<String, Vector<String>>& filtersToFiles);
487 [[nodiscard]] Result collectUniqueRootPaths(VectorMap<String, VectorSet<Project::File>>& paths);
488};
490
491//-----------------------------------------------------------------------------------------------------------------------
492// Implementations Details
493//-----------------------------------------------------------------------------------------------------------------------
494
495struct Action
496{
497 enum Type
498 {
499 Configure,
500 Compile,
501 Run,
502 Print,
503 Coverage
504 };
505 using ConfigureFunction = Result (*)(Build::Definition& definition, const Build::Parameters& parameters);
506
507 static Result execute(const Action& action, ConfigureFunction configure, StringView projectName);
508
509 Type action = Configure;
510
511 Parameters parameters;
512 StringView configuration;
513 StringView target;
514
515 private:
516 struct Internal;
517};
518
519// Defined inside SC-Build.cpp
520Result executeAction(const Action& action);
521} // namespace Build
522} // namespace SC
Definition: Build.h:496
Build Architecture (Processor / Instruction set)
Definition: Build.h:51
static constexpr StringView toString(Type type)
Get StringView from Architecture::Type.
Definition: Build.h:62
Two StringViews representing name and description.
Definition: Build.h:139
Map of SC::Build::Compile flags (include paths, preprocessor defines etc.)
Definition: Build.h:177
bool addDefines(Span< const StringView > defines)
Add define to preprocessor definitions.
Definition: Build.h:185
bool addIncludes(Span< const StringView > includes)
Add paths to includes search paths list.
Definition: Build.h:179
Compilation switches (include paths, preprocessor defines, etc.)
Definition: Build.h:124
static constexpr NameDescription typeToString(Type type)
Get name and description from Compile::Type.
Definition: Build.h:145
Type
Definition: Build.h:126
@ enableRTTI
Runtime Type Identification.
Definition: Build.h:131
@ enableStdCpp
C++ Standard Library.
Definition: Build.h:133
@ enableExceptions
C++ Exceptions.
Definition: Build.h:132
@ preprocessorDefines
Preprocessor defines.
Definition: Build.h:128
@ enableASAN
Address Sanitizer.
Definition: Build.h:130
@ includePaths
Include paths.
Definition: Build.h:127
@ enableCoverage
Enables code coverage instrumentation.
Definition: Build.h:134
@ optimizationLevel
Optimization Level (debug / release)
Definition: Build.h:129
Visual Studio platform toolset.
Definition: Build.h:288
Groups SC::Build::CompileFlags and SC::Build::LinkFlags for a given SC::Build::Architecture.
Definition: Build.h:276
Preset preset
Build preset applied to this configuration.
Definition: Build.h:322
String intermediatesPath
Obj path. If relative, it's appended to _Intermediates relative to .
Definition: Build.h:317
String outputPath
Exe path. If relative, it's appended to _Outputs relative to .
Definition: Build.h:316
bool applyPreset(Preset newPreset, const Parameters &parameters)
Set compile flags depending on the given Preset.
CompileFlags compile
Configuration compile flags.
Definition: Build.h:319
String name
Configuration name.
Definition: Build.h:315
static constexpr StringView PresetToString(Preset preset)
Convert Preset to StringView.
Definition: Build.h:295
LinkFlags link
Configuration link flags.
Definition: Build.h:320
Architecture::Type architecture
Restrict this configuration to a specific architecture.
Definition: Build.h:323
Preset
A pre-made preset with pre-configured set of options.
Definition: Build.h:279
@ None
Custom configuration.
@ Debug
Debug configuration.
@ Release
Release configuration.
@ DebugCoverage
Debug coverage configuration.
VisualStudio visualStudio
Customize VisualStudio platformToolset.
Definition: Build.h:292
Caches file paths by pre-resolving directory filter search masks.
Definition: Build.h:475
Top level build description holding all Workspace objects.
Definition: Build.h:464
Result configure(StringView projectName, const Parameters &parameters) const
Generates projects for all workspaces, with specified parameters at given root path.
Vector< Workspace > workspaces
Workspaces to be generated.
Definition: Build.h:465
Definition: Build.h:437
Build system generator (Xcode / Visual Studio)
Definition: Build.h:78
static constexpr StringView toString(Type type)
Get StringView from Generator::Type.
Definition: Build.h:88
Type
Definition: Build.h:80
@ Make
Generate posix makefiles.
Definition: Build.h:84
@ VisualStudio2022
Generate projects for Visual Studio 2022.
Definition: Build.h:82
@ VisualStudio2019
Generate projects for Visual Studio 2019.
Definition: Build.h:83
@ XCode
Generate projects for XCode (Version 14+)
Definition: Build.h:81
Optimization level (Debug / Release)
Definition: Build.h:103
static constexpr StringView toString(Type type)
Get StringView from Optimization::Type.
Definition: Build.h:111
Type
Definition: Build.h:105
@ Debug
Optimizations set to debug.
Definition: Build.h:106
@ Release
Optimizations set to release.
Definition: Build.h:107
Describes a specific set of platforms, architectures and build generators to generate projects for.
Definition: Build.h:448
Platform::Type platform
Platform to generate.
Definition: Build.h:449
Generator::Type generator
Build system types to generate.
Definition: Build.h:451
Architecture::Type architecture
Architecture to generate.
Definition: Build.h:450
Build Platform (Operating System)
Definition: Build.h:24
static constexpr StringView toString(Type type)
Get StringView from Platform::Type.
Definition: Build.h:35
Project list of files.
Definition: Build.h:357
Operation
Indicates if this is an additive or subtractive files operation.
Definition: Build.h:360
@ Remove
Remove files.
Definition: Build.h:362
@ Add
Add files.
Definition: Build.h:361
Operation operation
Operation type (add or remove files)
Definition: Build.h:364
String mask
Mask suffix (can contain *)
Definition: Build.h:366
String base
Base path (not containing *)
Definition: Build.h:365
Groups multiple Configuration and source files with their compile and link flags.
Definition: Build.h:354
const Configuration * getConfiguration(StringView configurationName) const
Get Configuration with the matching configurationName
Configuration * getConfiguration(StringView configurationName)
Get Configuration with the matching configurationName
TargetType::Type targetType
Type of build artifact.
Definition: Build.h:378
Result validate() const
Validates this project for it to contain a valid combination of flags.
String rootDirectory
Project root directory.
Definition: Build.h:381
String targetName
Project target name.
Definition: Build.h:382
CompileFlags compile
Shared CompileFlags for all files in the project.
Definition: Build.h:386
bool addDirectory(StringView subdirectory, StringView filter)
Add all files from specific subdirectory (relative to project root) matching given filter.
bool setRootDirectory(StringView file)
Set root directory for this project (all relative paths will be relative to this one)
Vector< Configuration > configurations
Build configurations created inside the project.
Definition: Build.h:389
bool removeFiles(StringView subdirectory, StringView filter)
Remove files matching the given filter.
LinkFlags link
Shared LinkFlags for all files in the project.
Definition: Build.h:387
String name
Project name.
Definition: Build.h:380
bool addPresetConfiguration(Configuration::Preset preset, const Parameters &parameters, StringView configurationName=StringView())
Add a configuration with a given name, started by cloning options of a specific Preset.
String iconPath
Icon location.
Definition: Build.h:383
Vector< File > files
Files that belong to the project.
Definition: Build.h:385
bool addFile(StringView singleFile)
Add a single file to the project.
Type of target artifact to build (executable, library)
Definition: Build.h:330
static constexpr StringView typeToString(Type type)
Convert TargetType to StringView.
Definition: Build.h:340
Type
Type of artifact.
Definition: Build.h:333
@ StaticLibrary
Create static library.
Definition: Build.h:336
@ Executable
Create executable program.
Definition: Build.h:334
@ DynamicLibrary
Create dynamic library.
Definition: Build.h:335
Groups multiple Project together with shared compile and link flags.
Definition: Build.h:423
String name
Workspace name.
Definition: Build.h:427
LinkFlags link
Global workspace link flags for all projects.
Definition: Build.h:430
Vector< Project > projects
List of projects in this workspace.
Definition: Build.h:428
CompileFlags compile
Global workspace compile flags for all projects.
Definition: Build.h:429
Result validate() const
Validates all projects in this workspace.
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition: Result.h:12
View over a contiguous sequence of items (pointer + size in elements).
Definition: Span.h:21
A non-modifiable owning string with associated encoding.
Definition: String.h:30
Non-owning view over a range of characters with UTF Encoding.
Definition: StringView.h:47
Associate a Type to an Enum, as required by TaggedUnion.
Definition: TaggedUnion.h:24
Type safe union with an enum type, where each type has an associated enum value.
Definition: TaggedUnion.h:38
Represents a variadic template type list.
Definition: TypeList.h:19
A contiguous sequence of heap allocated elements.
Definition: Vector.h:51
A map holding VectorMapItem key-value pairs in an unsorted Vector.
Definition: VectorMap.h:33
A set built on an unsorted Vector, ensuring no item duplication.
Definition: VectorSet.h:20