Compare commits

..

3 commits

8 changed files with 628 additions and 44 deletions

View file

@ -1,11 +1,8 @@
module;
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Input.h>
#include <RmlUi/Core/Types.h>
export module rutile.core.ui.backend.rmlui_input_handler;
import wrappers.rmlui.core;
import wrappers.sdl;
export namespace rutile

View file

@ -3,15 +3,13 @@
module;
#include <RmlUi/Core/Core.h>
#include <RmlUi/Core/FileInterface.h>
#include <RmlUi/Core/RenderInterface.h>
#include <RmlUi/Core/Types.h>
#include <cassert>
#include <SDL3/SDL.h>
export module rutile.core.ui.backend.rmlui_render_interface;
import std;
import wrappers.rmlui.core;
import wrappers.sdl;
import wrappers.sdl_image;
@ -152,7 +150,7 @@ export namespace rutile
const Rml::Vector2i source_dimensions
) override
{
RMLUI_ASSERT(
assert(
source.data() && source.size() == static_cast<size_t>(source_dimensions.x * source_dimensions.y * 4)
);

View file

@ -3,14 +3,13 @@
module;
#include <RmlUi/Core/StringUtilities.h>
#include <RmlUi/Core/SystemInterface.h>
#include <RmlUi/Core/Types.h>
#include <SDL3/SDL.h>
export module rutile.core.ui.backend.rmlui_system_interface;
import std;
import utils.memory;
import wrappers.rmlui.core;
import wrappers.sdl;
// Shorthand for a unique pointer to an SDL_Cursor

View file

@ -1,8 +1,6 @@
module;
#include <cassert>
#include <RmlUi/Core.h>
#include <RmlUi/Debugger.h>
export module rutile.core.ui.ui_server;
@ -10,6 +8,8 @@ import std;
import rutile.core.ui.backend.rmlui_render_interface;
import rutile.core.ui.backend.rmlui_system_interface;
import rutile.core.ui.backend.rmlui_input_handler;
import wrappers.rmlui.core;
import wrappers.rmlui.debugger;
import wrappers.sdl;
export namespace rutile

View file

@ -1,7 +1,6 @@
module;
#include <cassert>
#include <RmlUi/Core/ElementDocument.h>
export module rutile.game.game;
@ -11,6 +10,7 @@ import rutile.core.drawing.tile_map;
import rutile.core.drawing.tile_set;
import rutile.core.engine;
import rutile.core.render_server;
import wrappers.rmlui.core;
import wrappers.sdl;
import wrappers.sdl_image;

View file

@ -0,0 +1,530 @@
module;
#include <RmlUi/Core.h>
export module wrappers.rmlui.core;
export
{
namespace Rml
{
using Rml::Animation;
using Rml::AnimationList;
using Rml::Any;
using Rml::Array;
using Rml::ArrayDefinition;
using Rml::Assert;
using Rml::AttributeNameList;
using Rml::BasePointerDefinition;
using Rml::BaseXMLParser;
using Rml::BlendMode;
using Rml::Box;
using Rml::BoxArea;
using Rml::BoxDirection;
using Rml::BoxEdge;
using Rml::BoxShadow;
using Rml::BoxShadowList;
using Rml::CallbackTexture;
using Rml::CallbackTextureFunction;
using Rml::CallbackTextureInterface;
using Rml::CallbackTextureSource;
using Rml::Character;
using Rml::ClipMaskGeometry;
using Rml::ClipMaskGeometryList;
using Rml::ClipMaskOperation;
using Rml::ColorFormat;
using Rml::ColorStop;
using Rml::ColorStopList;
using Rml::Colour;
using Rml::Colourb;
using Rml::ColourbPremultiplied;
using Rml::Colourf;
using Rml::ColumnMajorMatrix4f;
using Rml::ColumnMajorStorage;
using Rml::CompiledFilter;
using Rml::CompiledFilterHandle;
using Rml::CompiledGeometryHandle;
using Rml::CompiledShader;
using Rml::CompiledShaderHandle;
using Rml::ComputedValues;
using Rml::ContainerBox;
using Rml::Context;
using Rml::ContextInstancer;
using Rml::ContextPtr;
using Rml::ConvolutionFilter;
using Rml::CornerSizes;
using Rml::CreateContext;
using Rml::CreateString;
using Rml::DataAddress;
using Rml::DataAddressEntry;
using Rml::DataController;
using Rml::DataControllerInstancer;
using Rml::DataControllerPtr;
using Rml::DataEventFunc;
using Rml::DataGetFunc;
using Rml::DataModel;
using Rml::DataModelConstructor;
using Rml::DataModelHandle;
using Rml::DataSetFunc;
using Rml::DataTransformFunc;
using Rml::DataTypeGetFunc;
using Rml::DataTypeRegister;
using Rml::DataTypeSetFunc;
using Rml::DataVariable;
using Rml::DataVariableType;
using Rml::DataView;
using Rml::DataViewInstancer;
using Rml::DataViewPtr;
using Rml::Decorator;
using Rml::DecoratorDataHandle;
using Rml::DecoratorDeclaration;
using Rml::DecoratorDeclarationList;
using Rml::DecoratorInstancer;
using Rml::DecoratorInstancerInterface;
using Rml::DecoratorPtrList;
using Rml::DecoratorsPtr;
using Rml::DefaultActionPhase;
using Rml::DefaultStyleSheetParsers;
using Rml::Dictionary;
using Rml::DirtyVariables;
using Rml::DocumentHeader;
using Rml::EdgeSizes;
using Rml::EffectSpecification;
using Rml::Element;
using Rml::ElementAnimation;
using Rml::ElementAnimationList;
using Rml::ElementAttributes;
using Rml::ElementBackgroundBorder;
using Rml::ElementDefinition;
using Rml::ElementDocument;
using Rml::ElementForm;
using Rml::ElementFormControl;
using Rml::ElementFormControlInput;
using Rml::ElementFormControlSelect;
using Rml::ElementFormControlTextArea;
using Rml::ElementInstancer;
using Rml::ElementInstancerElement;
using Rml::ElementInstancerGeneric;
using Rml::ElementInstancerText;
using Rml::ElementList;
using Rml::ElementMeta;
using Rml::ElementProgress;
using Rml::ElementPtr;
using Rml::ElementScroll;
using Rml::ElementStyle;
using Rml::ElementTabSet;
using Rml::ElementText;
using Rml::ElementUtilities;
using Rml::EnableObserverPtr;
using Rml::Event;
using Rml::EventDispatcher;
using Rml::EventId;
using Rml::EventInstancer;
using Rml::EventListener;
using Rml::EventListenerInstancer;
using Rml::EventPhase;
using Rml::EventPtr;
using Rml::EventSpecification;
using Rml::Factory;
using Rml::Family;
using Rml::FamilyBase;
using Rml::FamilyId;
using Rml::FileHandle;
using Rml::FileInterface;
using Rml::Filter;
using Rml::FilterDeclaration;
using Rml::FilterDeclarationList;
using Rml::FilterHandleList;
using Rml::FilterInstancer;
using Rml::FilterOperation;
using Rml::FiltersPtr;
using Rml::FocusFlag;
using Rml::FontEffect;
using Rml::FontEffectInstancer;
using Rml::FontEffectList;
using Rml::FontEffects;
using Rml::FontEffectsHandle;
using Rml::FontEffectsPtr;
using Rml::FontEngineInterface;
using Rml::FontFaceHandle;
using Rml::FontGlyph;
using Rml::FontGlyphMap;
using Rml::FontMetrics;
using Rml::FormatString;
using Rml::FromString;
using Rml::FuncDefinition;
using Rml::Function;
using Rml::Geometry;
using Rml::Get;
using Rml::GetContext;
using Rml::GetFileInterface;
using Rml::GetFontEngineInterface;
using Rml::GetIf;
using Rml::GetNumContexts;
using Rml::GetRenderInterface;
using Rml::GetSystemInterface;
using Rml::GetTextInputHandler;
using Rml::GetTextureSourceList;
using Rml::GetVersion;
using Rml::Hash;
using Rml::Initialise;
using Rml::InlineLevelBox;
using Rml::InputType;
using Rml::IsVoidMemberFunc;
using Rml::KeyframeBlock;
using Rml::Keyframes;
using Rml::KeyframesMap;
using Rml::LayerHandle;
using Rml::LayoutEngine;
using Rml::List;
using Rml::LoadFontFace;
using Rml::Log;
using Rml::MakeLiteralIntVariable;
using Rml::MakeMoveIterator;
using Rml::MakeShared;
using Rml::MakeUnique;
using Rml::Matrix4;
using Rml::Matrix4f;
using Rml::MatrixStorageBase;
using Rml::MediaBlock;
using Rml::MediaBlockList;
using Rml::MediaQueryId;
using Rml::MediaQueryModifier;
using Rml::MemberGetFunc;
using Rml::MemberGetFuncDefinition;
using Rml::MemberGetterFunc;
using Rml::MemberObjectDefinition;
using Rml::MemberScalarGetSetFuncDefinition;
using Rml::MemberSetFunc;
using Rml::MemberSetterFunc;
using Rml::Mesh;
using Rml::MeshUtilities;
using Rml::ModalFlag;
using Rml::NamedDecorator;
using Rml::NamedDecoratorMap;
using Rml::NavigationSearchDirection;
using Rml::NonCopyMoveable;
using Rml::NumericValue;
using Rml::ObserverPtr;
using Rml::OwnedElementList;
using Rml::Pair;
using Rml::ParameterMap;
using Rml::Plugin;
using Rml::PointerDefinition;
using Rml::PointerTraits;
using Rml::PropertiesIterator;
using Rml::PropertiesIteratorView;
using Rml::Property;
using Rml::PropertyDefinition;
using Rml::PropertyDictionary;
using Rml::PropertyId;
using Rml::PropertyIdNameMap;
using Rml::PropertyIdSet;
using Rml::PropertyIdSetIterator;
using Rml::PropertyMap;
using Rml::PropertyParser;
using Rml::PropertySource;
using Rml::PropertySpecification;
using Rml::Queue;
using Rml::Rectangle;
using Rml::Rectanglef;
using Rml::Rectanglei;
using Rml::RegisterEventType;
using Rml::RegisterPlugin;
using Rml::RelativeTarget;
using Rml::Releasable;
using Rml::ReleaseCompiledGeometry;
using Rml::ReleaseFontResources;
using Rml::ReleaseRenderManagers;
using Rml::ReleaseTexture;
using Rml::ReleaseTextures;
using Rml::Releaser;
using Rml::ReleaserBase;
using Rml::RemoveContext;
using Rml::RenderBox;
using Rml::RenderInterface;
using Rml::RenderManager;
using Rml::RenderManagerAccess;
using Rml::RenderState;
using Rml::ReplacedBox;
using Rml::ResolveValue;
using Rml::ResolveValueOr;
using Rml::RowMajorMatrix4f;
using Rml::RowMajorStorage;
using Rml::ScalarDefinition;
using Rml::ScalarFuncDefinition;
using Rml::ScriptInterface;
using Rml::ScriptInterfacePtr;
using Rml::ScriptObject;
using Rml::ScrollAlignment;
using Rml::ScrollBehavior;
using Rml::ScrollController;
using Rml::ScrollIntoViewOptions;
using Rml::ScrollParentage;
using Rml::SetFileInterface;
using Rml::SetFontEngineInterface;
using Rml::SetRenderInterface;
using Rml::SetSystemInterface;
using Rml::SetTextInputHandler;
using Rml::SharedPtr;
using Rml::ShorthandDefinition;
using Rml::ShorthandId;
using Rml::ShorthandIdNameMap;
using Rml::ShorthandType;
using Rml::Shutdown;
using Rml::SmallOrderedMap;
using Rml::SmallOrderedSet;
using Rml::SmallUnorderedMap;
using Rml::SmallUnorderedSet;
using Rml::Span;
using Rml::Sprite;
using Rml::SpriteDefinitionList;
using Rml::SpriteMap;
using Rml::Spritesheet;
using Rml::SpritesheetList;
using Rml::StableMap;
using Rml::StableUnorderedMap;
using Rml::StableVector;
using Rml::StableVectorIndex;
using Rml::Stack;
using Rml::StackingContextChild;
using Rml::Stream;
using Rml::String;
using Rml::StringIteratorU8;
using Rml::StringList;
using Rml::StringView;
using Rml::StructDefinition;
using Rml::StructHandle;
using Rml::StyleSheet;
using Rml::StyleSheetContainer;
using Rml::StyleSheetIndex;
using Rml::StyleSheetNode;
using Rml::StyleSheetParser;
using Rml::StyleSheetSpecification;
using Rml::SystemInterface;
using Rml::TextInputHandler;
using Rml::TextShapingContext;
using Rml::Texture;
using Rml::TextureDatabase;
using Rml::TextureFileIndex;
using Rml::TextureHandle;
using Rml::TextureSource;
using Rml::TexturedMesh;
using Rml::TexturedMeshList;
using Rml::ToString;
using Rml::Touch;
using Rml::TouchId;
using Rml::TouchList;
using Rml::Transform;
using Rml::TransformFuncRegister;
using Rml::TransformPrimitive;
using Rml::TransformPtr;
using Rml::TransformState;
using Rml::Transition;
using Rml::TransitionList;
using Rml::Tween;
using Rml::TypeConverter;
using Rml::URL;
using Rml::UniquePtr;
using Rml::UniqueReleaserPtr;
using Rml::UniqueRenderResource;
using Rml::Unit;
using Rml::Units;
using Rml::UnorderedMap;
using Rml::UnorderedMultimap;
using Rml::UnorderedSet;
using Rml::UnregisterPlugin;
using Rml::VariableDefinition;
using Rml::Variant;
using Rml::VariantList;
using Rml::Vector2;
using Rml::Vector2f;
using Rml::Vector2i;
using Rml::Vector3;
using Rml::Vector3f;
using Rml::Vector3i;
using Rml::Vector4;
using Rml::Vector4f;
using Rml::Vector4i;
using Rml::Vector;
using Rml::Vertex;
using Rml::VoidMemberFunc;
using Rml::WeakPtr;
using Rml::WidgetDropDown;
using Rml::WidgetScroll;
using Rml::WidgetTextInputMultiLine;
using Rml::XMLAttributes;
using Rml::XMLDataType;
using Rml::XMLNodeHandler;
using Rml::XMLParser;
using Rml::byte;
using Rml::is_builtin_data_scalar;
using Rml::voidPtr;
namespace Input
{
using Rml::Input::KeyIdentifier;
using Rml::Input::KeyModifier;
}
namespace Math
{
using Rml::Math::ACos;
using Rml::Math::ASin;
using Rml::Math::ATan2;
using Rml::Math::Absolute;
using Rml::Math::Clamp;
using Rml::Math::Cos;
using Rml::Math::DecomposeFractionalIntegral;
using Rml::Math::DegreesToRadians;
using Rml::Math::Exp;
using Rml::Math::ExpandToPixelGrid;
using Rml::Math::HexToDecimal;
using Rml::Math::IsCloseToZero;
using Rml::Math::Lerp;
using Rml::Math::Log2;
using Rml::Math::Max;
using Rml::Math::Min;
using Rml::Math::NormaliseAngle;
using Rml::Math::RadiansToDegrees;
using Rml::Math::RandomBool;
using Rml::Math::RandomInteger;
using Rml::Math::RandomReal;
using Rml::Math::Round;
using Rml::Math::RoundDown;
using Rml::Math::RoundDownToInteger;
using Rml::Math::RoundToInteger;
using Rml::Math::RoundUp;
using Rml::Math::RoundUpToInteger;
using Rml::Math::RoundedLerp;
using Rml::Math::Sin;
using Rml::Math::SnapToPixelGrid;
using Rml::Math::SquareRoot;
using Rml::Math::Tan;
using Rml::Math::ToPowerOfTwo;
}
namespace StringUtilities
{
using Rml::StringUtilities::BytesUTF8;
using Rml::StringUtilities::ConvertByteOffsetToCharacterOffset;
using Rml::StringUtilities::ConvertCharacterOffsetToByteOffset;
using Rml::StringUtilities::DecodeRml;
using Rml::StringUtilities::EncodeRml;
using Rml::StringUtilities::EndsWith;
using Rml::StringUtilities::ExpandString;
using Rml::StringUtilities::IsWhitespace;
using Rml::StringUtilities::JoinString;
using Rml::StringUtilities::LengthUTF8;
using Rml::StringUtilities::Replace;
using Rml::StringUtilities::SeekBackwardUTF8;
using Rml::StringUtilities::SeekForwardUTF8;
using Rml::StringUtilities::StartsWith;
using Rml::StringUtilities::StringCompareCaseInsensitive;
using Rml::StringUtilities::StripWhitespace;
using Rml::StringUtilities::ToCharacter;
using Rml::StringUtilities::ToLower;
using Rml::StringUtilities::ToUTF8;
using Rml::StringUtilities::ToUpper;
using Rml::StringUtilities::TrimTrailingDotZeros;
}
namespace Style
{
using Rml::Style::AlignContent;
using Rml::Style::AlignItems;
using Rml::Style::AlignSelf;
using Rml::Style::Bottom;
using Rml::Style::BoxSizing;
using Rml::Style::Clear;
using Rml::Style::Clip;
using Rml::Style::CommonValues;
using Rml::Style::ComputedValues;
using Rml::Style::Direction;
using Rml::Style::Display;
using Rml::Style::Drag;
using Rml::Style::FlexBasis;
using Rml::Style::FlexDirection;
using Rml::Style::FlexWrap;
using Rml::Style::Float;
using Rml::Style::Focus;
using Rml::Style::FontKerning;
using Rml::Style::FontStyle;
using Rml::Style::FontWeight;
using Rml::Style::Height;
using Rml::Style::InheritedValues;
using Rml::Style::JustifyContent;
using Rml::Style::Left;
using Rml::Style::LengthPercentage;
using Rml::Style::LengthPercentageAuto;
using Rml::Style::LineHeight;
using Rml::Style::Margin;
using Rml::Style::MaxHeight;
using Rml::Style::MaxWidth;
using Rml::Style::MinHeight;
using Rml::Style::MinWidth;
using Rml::Style::Nav;
using Rml::Style::NumberAuto;
using Rml::Style::OriginX;
using Rml::Style::OriginY;
using Rml::Style::Overflow;
using Rml::Style::OverscrollBehavior;
using Rml::Style::Padding;
using Rml::Style::PerspectiveOrigin;
using Rml::Style::PointerEvents;
using Rml::Style::Position;
using Rml::Style::RareValues;
using Rml::Style::Right;
using Rml::Style::TabIndex;
using Rml::Style::TextAlign;
using Rml::Style::TextDecoration;
using Rml::Style::TextOverflow;
using Rml::Style::TextTransform;
using Rml::Style::Top;
using Rml::Style::TransformOrigin;
using Rml::Style::VerticalAlign;
using Rml::Style::Visibility;
using Rml::Style::WhiteSpace;
using Rml::Style::Width;
using Rml::Style::WordBreak;
using Rml::Style::ZIndex;
}
namespace Transforms
{
using Rml::Transforms::DecomposedMatrix4;
using Rml::Transforms::Matrix2D;
using Rml::Transforms::Matrix3D;
using Rml::Transforms::Perspective;
using Rml::Transforms::ResolvedPrimitive;
using Rml::Transforms::Rotate2D;
using Rml::Transforms::Rotate3D;
using Rml::Transforms::RotateX;
using Rml::Transforms::RotateY;
using Rml::Transforms::RotateZ;
using Rml::Transforms::Scale2D;
using Rml::Transforms::Scale3D;
using Rml::Transforms::ScaleX;
using Rml::Transforms::ScaleY;
using Rml::Transforms::ScaleZ;
using Rml::Transforms::Skew2D;
using Rml::Transforms::SkewX;
using Rml::Transforms::SkewY;
using Rml::Transforms::Translate2D;
using Rml::Transforms::Translate3D;
using Rml::Transforms::TranslateX;
using Rml::Transforms::TranslateY;
using Rml::Transforms::TranslateZ;
using Rml::Transforms::UnresolvedPrimitive;
}
namespace Utilities
{
using Rml::Utilities::HashCombine;
}
}
using ::rmlui_dynamic_cast;
using ::rmlui_static_cast;
using ::rmlui_type_name;
}

View file

@ -0,0 +1,14 @@
module;
#include <RmlUi/Debugger.h>
export module wrappers.rmlui.debugger;
export namespace Rml::Debugger
{
using Rml::Debugger::Initialise;
using Rml::Debugger::IsVisible;
using Rml::Debugger::SetContext;
using Rml::Debugger::SetVisible;
using Rml::Debugger::Shutdown;
}

View file

@ -10,7 +10,6 @@
############################################
import argparse
import copy
import json
import shlex
import subprocess
@ -18,7 +17,7 @@ import sys
from collections import namedtuple
from dataclasses import asdict, dataclass, field
from pathlib import Path
from typing import Any
from typing import Any, Self
import yaml
@ -60,6 +59,38 @@ class TargetConfig:
return f"{self.linker_args or ''} {self.linker_args_extra or ''}".strip()
@dataclass(kw_only=True)
class MergedTargetConfig(TargetConfig):
cpp_compiler: str = ''
cpp_standard: str = ''
cpp_flags: str = ''
cpp_flags_extra: str = ''
linker_flags: str = ''
linker_flags_extra: str = ''
linker_args: str = ''
linker_args_extra: str = ''
output_file: str = ''
run_command: str = ''
@classmethod
def create_from(cls, target_defaults: TargetConfig, target_config: TargetConfig) -> Self:
merged_config = cls()
merged_config.update(asdict(target_defaults))
merged_config.update(asdict(target_config))
return merged_config
def validate(self) -> None:
# Validate that all required fields are set
if not self.cpp_compiler:
raise ConfigValidationException('cpp_compiler must be set')
if not self.cpp_standard:
raise ConfigValidationException('cpp_standard must be set')
if not self.output_file:
raise ConfigValidationException('output_file must be set')
@dataclass(kw_only=True)
class ShurikenConfig:
__path_fields = ['source_dir', 'build_dir']
@ -72,9 +103,6 @@ class ShurikenConfig:
defaults: TargetConfig = field(default_factory=lambda: TargetConfig(
cpp_compiler='clang++',
cpp_standard='c++20',
cpp_flags='',
linker_flags='',
linker_args='',
))
enable_import_std: bool = False
@ -82,6 +110,9 @@ class ShurikenConfig:
default_target: str = ''
targets: dict[str, TargetConfig] = field(default_factory=dict)
# Merged target configs, generated from defaults and targets
_merged_target_configs = {}
def update(self, data: dict) -> None:
for key, value in data.items():
# Ignore unknown config keys
@ -116,6 +147,10 @@ class ShurikenConfig:
else:
setattr(self, key, str(value))
# Generate merged target configs (we generate all of them so that we can validate the full config)
for target_name, target_config in self.targets.items():
self._merged_target_configs[target_name] = MergedTargetConfig.create_from(self.defaults, target_config)
def update_from_yaml(self, file_path: Path) -> None:
with file_path.open('r') as file:
self.update(yaml.safe_load(file))
@ -137,23 +172,18 @@ class ShurikenConfig:
raise ConfigValidationException('default_target is not defined in targets')
# Validate individual build targets
for target_name, target_config in self.targets.items():
if not target_config.cpp_compiler and not self.defaults.cpp_compiler:
raise ConfigValidationException(f'Target "{target_name}": cpp_compiler must be set')
if not target_config.cpp_standard and not self.defaults.cpp_standard:
raise ConfigValidationException(f'Target "{target_name}": cpp_standard must be set')
if not target_config.output_file and not self.defaults.output_file:
raise ConfigValidationException(f'Target "{target_name}": output_file must be set')
for target_name, merged_target_config in self._merged_target_configs.items():
try:
merged_target_config.validate()
except ConfigValidationException as exc:
raise ConfigValidationException(f'Target "{target_name}": {str(exc)}')
def get_ninja_file_path(self, target: str) -> Path:
return self.build_dir / f'build.{target}.ninja'
def get_merged_target_config(self, target: str) -> TargetConfig:
def get_merged_target_config(self, target: str) -> MergedTargetConfig:
assert target in self.targets, f'Target "{target}" not defined!'
merged_config = copy.deepcopy(self.defaults)
merged_config.update(asdict(self.targets[target]))
return merged_config
return self._merged_target_configs[target]
class ShurikenArgumentParser:
@ -570,7 +600,25 @@ class NinjaFileGenerator:
config = self.config
target = self.target
target_config = self.target_config
build_dir = self.config.build_dir
build_dir = config.build_dir
ninja_file_path = config.get_ninja_file_path(config.default_target)
cpp_compiler = target_config.cpp_compiler
# Generate list of all source input files to be used as implicit dependencies for the dyndep file
dyndep_file_implicit_inputs = ' '.join(sorted(
t.src for t in self.compile_targets_cpp + self.compile_targets_cppm
))
# Generate list of all .dep files that are generated implicitly during dyndep file generation.
# This is mostly necessary so that Ninja can create the directories for these files beforehand.
dyndep_file_implicit_outputs = ' '.join(sorted(
f'{t.obj}.dep' for t in self.compile_targets_cpp + self.compile_targets_cppm
))
# Generate list of generated source files (currently just the copied std module file)
generated_source_files = ' '.join(sorted(
t.generated_src for t in self.compile_targets_std_module
))
# Generate Ninja file
return f"""
@ -596,19 +644,21 @@ rule copy
# Rule to compile a .cpp file to a .o file
rule cpp
command = {target_config.cpp_compiler} $cpp_flags -c $in -o $out
depfile = $out.dep
command = {cpp_compiler} $cpp_flags -MMD -MF $out.dep -c $in -o $out
# Rule to compile a .cppm file (C++20 module) to a .o file ($out) and a .pcm file ($pcm_out)
rule cppm
command = {target_config.cpp_compiler} $cpp_flags -c $in -o $out -fmodule-output=$pcm_out
depfile = $out.dep
command = {cpp_compiler} $cpp_flags -MMD -MF $out.dep -c $in -o $out -fmodule-output=$pcm_out
# Rule to compile a standard library module to a .pcm file (e.g. "import std")
rule std_module
command = {target_config.cpp_compiler} $cpp_std_module_flags --precompile $in -o $out
command = {cpp_compiler} $cpp_std_module_flags --precompile $in -o $out
# Rule to link several .o files to an executable
rule link
command = {target_config.cpp_compiler} $linker_flags -o $out $in $linker_args
command = {cpp_compiler} $linker_flags -o $out $in $linker_args
# Rule to generate a compilation database (JSON file) from the build targets defined in a Ninja file
rule generate_compdb
@ -622,13 +672,13 @@ rule generate_dyndeps
# -- STATIC BUILD TARGETS
# Generate compilation database from default target Ninja file
build $compdb_file: generate_compdb {self.config.get_ninja_file_path(config.default_target)} | generate_source_files
build $compdb_file: generate_compdb {ninja_file_path} | generate_source_files
# Shortcut alias to generate compilation database
build compdb: phony $compdb_file
# Generate Ninja dyndep file from compilation database
build $dyndep_file: generate_dyndeps $compdb_file
build $dyndep_file | {dyndep_file_implicit_outputs}: generate_dyndeps $compdb_file | {dyndep_file_implicit_inputs}
# -- GENERATED BUILD TARGETS
@ -638,17 +688,13 @@ build $builddir/{target_config.output_file}: link {' '.join(self.link_target_obj
default $builddir/{target_config.output_file}
# Phony target that depends on all generated source files
build generate_source_files: phony {self.list_generated_source_files()}
build generate_source_files: phony {generated_source_files}
{self.render_compile_targets()}
# End of build.{target}.ninja
""".strip()
def list_generated_source_files(self) -> str:
generated_files = [target.generated_src for target in self.compile_targets_std_module]
return ' '.join(generated_files)
def render_compile_targets(self) -> str:
rendered_targets = list(map(self.render_compile_target_std_module, self.compile_targets_std_module))
rendered_targets += list(map(self.render_compile_target_cpp, self.compile_targets_cpp))