diff --git a/src/rutile/core/ui/backend/rmlui_input_handler.cppm b/src/rutile/core/ui/backend/rmlui_input_handler.cppm index 2dedff2..41622ff 100644 --- a/src/rutile/core/ui/backend/rmlui_input_handler.cppm +++ b/src/rutile/core/ui/backend/rmlui_input_handler.cppm @@ -1,8 +1,11 @@ module; +#include +#include +#include + export module rutile.core.ui.backend.rmlui_input_handler; -import wrappers.rmlui.core; import wrappers.sdl; export namespace rutile diff --git a/src/rutile/core/ui/backend/rmlui_render_interface.cppm b/src/rutile/core/ui/backend/rmlui_render_interface.cppm index 28724c9..f64528f 100644 --- a/src/rutile/core/ui/backend/rmlui_render_interface.cppm +++ b/src/rutile/core/ui/backend/rmlui_render_interface.cppm @@ -3,13 +3,15 @@ module; -#include +#include +#include +#include +#include #include export module rutile.core.ui.backend.rmlui_render_interface; import std; -import wrappers.rmlui.core; import wrappers.sdl; import wrappers.sdl_image; @@ -150,7 +152,7 @@ export namespace rutile const Rml::Vector2i source_dimensions ) override { - assert( + RMLUI_ASSERT( source.data() && source.size() == static_cast(source_dimensions.x * source_dimensions.y * 4) ); diff --git a/src/rutile/core/ui/backend/rmlui_system_interface.cppm b/src/rutile/core/ui/backend/rmlui_system_interface.cppm index 3f2ac72..6c74193 100644 --- a/src/rutile/core/ui/backend/rmlui_system_interface.cppm +++ b/src/rutile/core/ui/backend/rmlui_system_interface.cppm @@ -3,13 +3,14 @@ module; +#include +#include +#include #include 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 diff --git a/src/rutile/core/ui/ui_server.cppm b/src/rutile/core/ui/ui_server.cppm index 3e5d3ab..66eb4c9 100644 --- a/src/rutile/core/ui/ui_server.cppm +++ b/src/rutile/core/ui/ui_server.cppm @@ -1,6 +1,8 @@ module; #include +#include +#include export module rutile.core.ui.ui_server; @@ -8,8 +10,6 @@ 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 diff --git a/src/rutile/game/game.cppm b/src/rutile/game/game.cppm index 9f8ca08..8b7a1ff 100644 --- a/src/rutile/game/game.cppm +++ b/src/rutile/game/game.cppm @@ -1,6 +1,7 @@ module; #include +#include export module rutile.game.game; @@ -10,7 +11,6 @@ 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; diff --git a/src/wrappers/rmlui/core.cppm b/src/wrappers/rmlui/core.cppm deleted file mode 100644 index fa209d4..0000000 --- a/src/wrappers/rmlui/core.cppm +++ /dev/null @@ -1,530 +0,0 @@ -module; - -#include - -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; -} diff --git a/src/wrappers/rmlui/debugger.cppm b/src/wrappers/rmlui/debugger.cppm deleted file mode 100644 index 7dd319a..0000000 --- a/src/wrappers/rmlui/debugger.cppm +++ /dev/null @@ -1,14 +0,0 @@ -module; - -#include - -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; -} diff --git a/tools/shuriken.py b/tools/shuriken.py index b7f38a7..e5a1943 100755 --- a/tools/shuriken.py +++ b/tools/shuriken.py @@ -10,6 +10,7 @@ ############################################ import argparse +import copy import json import shlex import subprocess @@ -17,7 +18,7 @@ import sys from collections import namedtuple from dataclasses import asdict, dataclass, field from pathlib import Path -from typing import Any, Self +from typing import Any import yaml @@ -59,38 +60,6 @@ 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'] @@ -103,6 +72,9 @@ 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 @@ -110,9 +82,6 @@ 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 @@ -147,10 +116,6 @@ 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)) @@ -172,18 +137,23 @@ class ShurikenConfig: raise ConfigValidationException('default_target is not defined in targets') # Validate individual build targets - 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)}') + 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') 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) -> MergedTargetConfig: + def get_merged_target_config(self, target: str) -> TargetConfig: assert target in self.targets, f'Target "{target}" not defined!' - return self._merged_target_configs[target] + + merged_config = copy.deepcopy(self.defaults) + merged_config.update(asdict(self.targets[target])) + return merged_config class ShurikenArgumentParser: @@ -600,25 +570,7 @@ class NinjaFileGenerator: config = self.config target = self.target target_config = self.target_config - 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 - )) + build_dir = self.config.build_dir # Generate Ninja file return f""" @@ -644,21 +596,19 @@ rule copy # Rule to compile a .cpp file to a .o file rule cpp - depfile = $out.dep - command = {cpp_compiler} $cpp_flags -MMD -MF $out.dep -c $in -o $out + command = {target_config.cpp_compiler} $cpp_flags -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 - depfile = $out.dep - command = {cpp_compiler} $cpp_flags -MMD -MF $out.dep -c $in -o $out -fmodule-output=$pcm_out + command = {target_config.cpp_compiler} $cpp_flags -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 = {cpp_compiler} $cpp_std_module_flags --precompile $in -o $out + command = {target_config.cpp_compiler} $cpp_std_module_flags --precompile $in -o $out # Rule to link several .o files to an executable rule link - command = {cpp_compiler} $linker_flags -o $out $in $linker_args + command = {target_config.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 @@ -672,13 +622,13 @@ rule generate_dyndeps # -- STATIC BUILD TARGETS # Generate compilation database from default target Ninja file -build $compdb_file: generate_compdb {ninja_file_path} | generate_source_files +build $compdb_file: generate_compdb {self.config.get_ninja_file_path(config.default_target)} | generate_source_files # Shortcut alias to generate compilation database build compdb: phony $compdb_file # Generate Ninja dyndep file from compilation database -build $dyndep_file | {dyndep_file_implicit_outputs}: generate_dyndeps $compdb_file | {dyndep_file_implicit_inputs} +build $dyndep_file: generate_dyndeps $compdb_file # -- GENERATED BUILD TARGETS @@ -688,13 +638,17 @@ 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 {generated_source_files} +build generate_source_files: phony {self.list_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))