From 8b8844e9a80de559516f83f26e8125d6f9810912 Mon Sep 17 00:00:00 2001 From: dskuza Date: Wed, 9 Jul 2025 14:26:23 +0000 Subject: [PATCH] feat(apple): add support for building lite frameworks (#10130) 1fb3654049 Co-authored-by: David Skuza --- .rive_head | 2 +- CONTRIBUTING.md | 13 ++ Config/Base.xcconfig | 13 ++ Config/Catalyst.xcconfig | 6 +- Config/macOS.xcconfig | 4 +- RiveRuntime.xcodeproj/project.pbxproj | 2 + Source/Fonts/RiveFallbackFontCache.h | 2 + Source/Fonts/RiveFallbackFontCache.m | 2 + ...iveFallbackFontDescriptor+Extensions.swift | 2 + Source/Fonts/RiveFallbackFontDescriptor.swift | 2 + Source/Fonts/RiveFallbackFontProvider.swift | 2 + Source/Fonts/RiveFont.h | 4 + Source/Fonts/RiveFont.m | 4 + Source/Renderer/CDNFileAssetLoader.mm | 6 +- Source/Renderer/FileAssetLoaderAdapter.mm | 8 +- Source/Renderer/RiveFactory.mm | 13 +- Source/Renderer/RiveFileAsset.mm | 4 + Source/Renderer/include/RiveArtboard.h | 2 + Source/Renderer/include/RiveFactory.h | 6 + Source/Renderer/include/RiveFileAsset.h | 4 + Source/Renderer/include/RivePrivateHeaders.h | 12 ++ Source/Renderer/rive_renderer_view.mm | 8 +- Source/RiveViewModel.swift | 4 +- scripts/build.rive.sh | 142 +++++++++++++----- scripts/strip_symbols.sh | 57 +++++++ 25 files changed, 278 insertions(+), 46 deletions(-) create mode 100644 Config/Base.xcconfig create mode 100755 scripts/strip_symbols.sh diff --git a/.rive_head b/.rive_head index d0723cc..e54aad4 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -d973e8c253120fa9e9f9591a2161d6bbf5e8b4e8 +1fb3654049a1bee715ea2a51558291c0b3e47358 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba010bb..83c2e51 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,6 +39,19 @@ Note: `PATH` must be updated for the Apple runtime build scripts to find `build_ If the script completes successfully, then all necessary frameworks are built, and you can continue on to running the Example apps. +### Building lite variations + +When manually building the Apple runtime, you can choose to build with all Rive features, or without certain features, such as audio or text. To build a lite version of the Apple runtime, run the same build script as shown above, supplying additional flags as needed: + +- `--no-audio` will build all libraries without audio support +- `--no-text` will build all libraries without text support + +After running `build.sh` to build the framework dependencies, run the following script to build the final `.xcframework`: + +`./scripts/build_framework.sh -c Release` + +Running this script expects `build.sh` to be run and the resulting changes to `Base.xcconfig` to not be modified. Otherwise, the runtime will fail to successfully compile. + ## Example and Preview targets / schemes The Example app has different targets and schemes, currently for both iOS and macOS. The `Example` targets make use of the local Rive dependency (built above) and the `Preview` targets make use of a hosted version of Rive, added via Swift Package Manager, to make it easy to run without needing to do all of the local development setup above. If you're making changes to the underlying runtime and need to test the Example app, be sure to set the scheme to either `Example (iOS)` or `Example (macOS)`, depending on your platform. See [Customizing the build schemes for a project](https://developer.apple.com/documentation/xcode/customizing-the-build-schemes-for-a-project) for more information. diff --git a/Config/Base.xcconfig b/Config/Base.xcconfig new file mode 100644 index 0000000..6502105 --- /dev/null +++ b/Config/Base.xcconfig @@ -0,0 +1,13 @@ +// +// Base.xcconfig +// RiveRuntime +// +// Created by David Skuza on 5/20/25. +// Copyright © 2025 Rive. All rights reserved. +// + +// Configuration settings file format documentation can be found at: +// https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project + +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) WITH_RIVE_AUDIO WITH_RIVE_TEXT +SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) WITH_RIVE_AUDIO WITH_RIVE_TEXT diff --git a/Config/Catalyst.xcconfig b/Config/Catalyst.xcconfig index d81b7fc..d5a6d66 100644 --- a/Config/Catalyst.xcconfig +++ b/Config/Catalyst.xcconfig @@ -1,5 +1,5 @@ // -// Build.xcconfig +// Catalyst.xcconfig // RiveRuntime // // Created by David Skuza on 5/20/25. @@ -9,6 +9,8 @@ // Configuration settings file format documentation can be found at: // https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project +#include "Base.xcconfig" + SUPPORTS_MACCATALYST=YES OTHER_LDFLAGS[sdk=macosx*] = -lrive_maccatalyst -lrive_harfbuzz_maccatalyst -lrive_sheenbidi_maccatalyst -lrive_yoga_maccatalyst -lminiaudio_maccatalyst -lrive_pls_renderer_maccatalyst -lrive_cg_renderer_maccatalyst -lrive_decoders_maccatalyst -SWIFT_ACTIVE_COMPILATION_CONDITIONS = RIVE_MAC_CATALYST +SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) RIVE_MAC_CATALYST diff --git a/Config/macOS.xcconfig b/Config/macOS.xcconfig index 67da79b..29f35c6 100644 --- a/Config/macOS.xcconfig +++ b/Config/macOS.xcconfig @@ -1,5 +1,5 @@ // -// Build.xcconfig +// macOS.xcconfig // RiveRuntime // // Created by David Skuza on 5/20/25. @@ -9,5 +9,7 @@ // Configuration settings file format documentation can be found at: // https://developer.apple.com/documentation/xcode/adding-a-build-configuration-file-to-your-project +#include "Base.xcconfig" + SUPPORTS_MACCATALYST=NO OTHER_LDFLAGS[sdk=macosx*] = -lrive_macos -lrive_harfbuzz_macos -lrive_sheenbidi_macos -lrive_yoga_macos -lminiaudio_macos -lrive_pls_renderer_macos -lrive_cg_renderer_macos -lrive_decoders_macos diff --git a/RiveRuntime.xcodeproj/project.pbxproj b/RiveRuntime.xcodeproj/project.pbxproj index 85fdaf4..5221dd5 100644 --- a/RiveRuntime.xcodeproj/project.pbxproj +++ b/RiveRuntime.xcodeproj/project.pbxproj @@ -238,6 +238,7 @@ F20808E12E05C3FF0082A281 /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = ""; }; F21C3D1A2DDFCD93005F82F4 /* RiveRenderImage+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveRenderImage+Extensions.swift"; sourceTree = ""; }; F21F08132C66526D00FFA205 /* RiveFallbackFontDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontDescriptor.swift; sourceTree = ""; }; + F22883752E1D61B50042FB20 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = ""; }; F22CF1B02D380E3700D35779 /* data_binding_test.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = data_binding_test.riv; sourceTree = ""; }; F22CF1B22D380E6900D35779 /* DataBindingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBindingTests.swift; sourceTree = ""; }; F23626A92C8F90FA00727D9A /* nested_text_run.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = nested_text_run.riv; sourceTree = ""; }; @@ -535,6 +536,7 @@ children = ( F2BD96D52DDCC7A200E7F49A /* Catalyst.xcconfig */, F2BD96D62DDCC7A200E7F49A /* macOS.xcconfig */, + F22883752E1D61B50042FB20 /* Base.xcconfig */, ); path = Config; sourceTree = ""; diff --git a/Source/Fonts/RiveFallbackFontCache.h b/Source/Fonts/RiveFallbackFontCache.h index 1492045..d29b9c6 100644 --- a/Source/Fonts/RiveFallbackFontCache.h +++ b/Source/Fonts/RiveFallbackFontCache.h @@ -6,6 +6,7 @@ // Copyright © 2024 Rive. All rights reserved. // +#ifdef WITH_RIVE_TEXT #import #import #import @@ -42,3 +43,4 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END +#endif diff --git a/Source/Fonts/RiveFallbackFontCache.m b/Source/Fonts/RiveFallbackFontCache.m index 2be611b..0cf8f10 100644 --- a/Source/Fonts/RiveFallbackFontCache.m +++ b/Source/Fonts/RiveFallbackFontCache.m @@ -6,6 +6,7 @@ // Copyright © 2024 Rive. All rights reserved. // +#ifdef WITH_RIVE_TEXT #import "RiveFallbackFontCache.h" #import "RiveFont.h" @@ -81,3 +82,4 @@ } @end +#endif diff --git a/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift b/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift index 90d7acd..79e47a6 100644 --- a/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift +++ b/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift @@ -1,3 +1,4 @@ +#if WITH_RIVE_TEXT // // RiveFallbackFontDescriptor+UIKit.swift // RiveRuntime @@ -224,3 +225,4 @@ extension RiveNativeFont: RiveFontWidthProvider { return Int(calculatedWidth) } } +#endif diff --git a/Source/Fonts/RiveFallbackFontDescriptor.swift b/Source/Fonts/RiveFallbackFontDescriptor.swift index d2a8770..6aec9dc 100644 --- a/Source/Fonts/RiveFallbackFontDescriptor.swift +++ b/Source/Fonts/RiveFallbackFontDescriptor.swift @@ -1,3 +1,4 @@ +#if WITH_RIVE_TEXT // // RiveFallbackFontDescriptor.swift // RiveRuntime @@ -89,3 +90,4 @@ import SwiftUI self.width = width } } +#endif // WITH_RIVE_TEXT diff --git a/Source/Fonts/RiveFallbackFontProvider.swift b/Source/Fonts/RiveFallbackFontProvider.swift index a821e76..a021da7 100644 --- a/Source/Fonts/RiveFallbackFontProvider.swift +++ b/Source/Fonts/RiveFallbackFontProvider.swift @@ -1,3 +1,4 @@ +#if WITH_RIVE_TEXT // // RiveSystemFontProvider.swift // RiveRuntime @@ -13,3 +14,4 @@ import Foundation /// An array of possible fonts to use as fallback fonts. @objc var fallbackFont: RiveNativeFont { get } } +#endif // WITH_RIVE_TEXT diff --git a/Source/Fonts/RiveFont.h b/Source/Fonts/RiveFont.h index 17348d3..d0a1e59 100644 --- a/Source/Fonts/RiveFont.h +++ b/Source/Fonts/RiveFont.h @@ -6,6 +6,8 @@ // Copyright © 2024 Rive. All rights reserved. // +#ifdef WITH_RIVE_TEXT + #import NS_ASSUME_NONNULL_BEGIN @@ -57,3 +59,5 @@ typedef NSArray>* _Nonnull ( @end NS_ASSUME_NONNULL_END + +#endif diff --git a/Source/Fonts/RiveFont.m b/Source/Fonts/RiveFont.m index 3e2ab01..313fb77 100644 --- a/Source/Fonts/RiveFont.m +++ b/Source/Fonts/RiveFont.m @@ -6,6 +6,8 @@ // Copyright © 2024 Rive. All rights reserved. // +#ifdef WITH_RIVE_TEXT + #import "RiveFont.h" #import "RiveFallbackFontCache.h" #import @@ -271,3 +273,5 @@ static rive::rcp findFallbackFont(const rive::Unichar missing, } @end + +#endif diff --git a/Source/Renderer/CDNFileAssetLoader.mm b/Source/Renderer/CDNFileAssetLoader.mm index e0581ee..bc800b2 100644 --- a/Source/Renderer/CDNFileAssetLoader.mm +++ b/Source/Renderer/CDNFileAssetLoader.mm @@ -37,17 +37,21 @@ // Load the data into the reader NSData* data = [NSData dataWithContentsOfURL:location]; +#ifdef WITH_RIVE_TEXT if ([asset isKindOfClass:[RiveFontAsset class]]) { RiveFontAsset* fontAsset = (RiveFontAsset*)asset; [fontAsset font:[factory decodeFont:data]]; [RiveLogger logFontAssetLoad:fontAsset fromURL:URL]; + return; } - else if ([asset isKindOfClass:[RiveImageAsset class]]) +#endif + if ([asset isKindOfClass:[RiveImageAsset class]]) { RiveImageAsset* imageAsset = (RiveImageAsset*)asset; [imageAsset renderImage:[factory decodeImage:data]]; [RiveLogger logImageAssetLoad:imageAsset fromURL:URL]; + return; } } else diff --git a/Source/Renderer/FileAssetLoaderAdapter.mm b/Source/Renderer/FileAssetLoaderAdapter.mm index 309e14b..857f3c3 100644 --- a/Source/Renderer/FileAssetLoaderAdapter.mm +++ b/Source/Renderer/FileAssetLoaderAdapter.mm @@ -25,6 +25,7 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset, { NSData* data = [NSData dataWithBytes:bytes.data() length:bytes.size()]; RiveFactory* myFactory = [[RiveFactory alloc] initWithFactory:factory]; +#ifdef WITH_RIVE_TEXT if (asset.is()) { RiveFontAsset* fontAsset = [[RiveFontAsset alloc] @@ -33,7 +34,8 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset, andData:data andFactory:myFactory]; } - else if (asset.is()) +#endif + if (asset.is()) { RiveImageAsset* imageAsset = [[RiveImageAsset alloc] initWithFileAsset:asset.as()]; @@ -41,7 +43,8 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset, andData:data andFactory:myFactory]; } - else if (asset.is()) +#ifdef WITH_RIVE_AUDIO + if (asset.is()) { RiveAudioAsset* audioAsset = [[RiveAudioAsset alloc] initWithFileAsset:asset.as()]; @@ -49,6 +52,7 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset, andData:data andFactory:myFactory]; } +#endif return false; } diff --git a/Source/Renderer/RiveFactory.mm b/Source/Renderer/RiveFactory.mm index a7b2f51..12a0520 100644 --- a/Source/Renderer/RiveFactory.mm +++ b/Source/Renderer/RiveFactory.mm @@ -10,14 +10,18 @@ #import #import #import +#import + +#if WITH_RIVE_TEXT #import #import -#import #if TARGET_OS_IPHONE #import #endif +#endif +#if WITH_RIVE_TEXT static rive::rcp riveFontFromNativeFont(id font, bool useSystemShaper) { @@ -36,6 +40,7 @@ static rive::rcp riveFontFromNativeFont(id font, CTFontRef ctFont = (__bridge CTFontRef)font; return HBFont::FromSystem((void*)ctFont, useSystemShaper, weight, width); } +#endif @implementation RiveRenderImage { @@ -77,6 +82,7 @@ static rive::rcp riveFontFromNativeFont(id font, @end +#ifdef WITH_RIVE_AUDIO @implementation RiveAudio { rive::rcp @@ -100,6 +106,7 @@ static rive::rcp riveFontFromNativeFont(id font, } @end +#endif /* * RiveFactory @@ -131,6 +138,7 @@ static rive::rcp riveFontFromNativeFont(id font, rive::Span(bytes, [data length]))]; } +#ifdef WITH_RIVE_TEXT - (RiveFont*)decodeFont:(nonnull NSData*)data { UInt8* bytes = (UInt8*)[data bytes]; @@ -150,7 +158,9 @@ static rive::rcp riveFontFromNativeFont(id font, return [[RiveFont alloc] initWithFont:riveFontFromNativeFont(font, true)]; } #endif +#endif +#ifdef WITH_RIVE_AUDIO - (RiveAudio*)decodeAudio:(nonnull NSData*)data { UInt8* bytes = (UInt8*)[data bytes]; @@ -158,5 +168,6 @@ static rive::rcp riveFontFromNativeFont(id font, initWithAudio:instance->decodeAudio( rive::Span(bytes, [data length]))]; } +#endif @end diff --git a/Source/Renderer/RiveFileAsset.mm b/Source/Renderer/RiveFileAsset.mm index 72513ec..9972f30 100644 --- a/Source/Renderer/RiveFileAsset.mm +++ b/Source/Renderer/RiveFileAsset.mm @@ -96,6 +96,7 @@ @end +#ifdef WITH_RIVE_TEXT @implementation RiveFontAsset - (instancetype)initWithFileAsset:(const rive::FontAsset*)fileAsset { @@ -107,7 +108,9 @@ ((rive::FontAsset*)[self getInstance])->font([font instance]); } @end +#endif +#ifdef WITH_RIVE_AUDIO @implementation RiveAudioAsset - (instancetype)initWithFileAsset:(const rive::AudioAsset*)fileAsset { @@ -119,3 +122,4 @@ ((rive::AudioAsset*)[self getInstance])->audioSource([audio instance]); } @end +#endif diff --git a/Source/Renderer/include/RiveArtboard.h b/Source/Renderer/include/RiveArtboard.h index 8b2485f..b976341 100644 --- a/Source/Renderer/include/RiveArtboard.h +++ b/Source/Renderer/include/RiveArtboard.h @@ -54,8 +54,10 @@ NS_ASSUME_NONNULL_BEGIN error:(NSError**)error; - (RiveStateMachineInstance* __nullable)defaultStateMachine; +#if WITH_RIVE_TEXT - (RiveTextValueRun* __nullable)textRun:(NSString*)name; - (RiveTextValueRun* __nullable)textRun:(NSString*)name path:(NSString*)path; +#endif - (void)advanceBy:(double)elapsedSeconds; - (void)draw:(RiveRenderer*)renderer; diff --git a/Source/Renderer/include/RiveFactory.h b/Source/Renderer/include/RiveFactory.h index d3b4b04..09f07b8 100644 --- a/Source/Renderer/include/RiveFactory.h +++ b/Source/Renderer/include/RiveFactory.h @@ -25,21 +25,27 @@ NS_ASSUME_NONNULL_BEGIN - (nullable instancetype)initWithData:(NSData*)data; @end +#ifdef WITH_RIVE_AUDIO @interface RiveAudio : NSObject @end +#endif /* * RiveFactory */ @interface RiveFactory : NSObject +#ifdef WITH_RIVE_TEXT - (RiveFont*)decodeFont:(NSData*)data; #if TARGET_OS_IPHONE || TARGET_OS_VISION || TARGET_OS_TV - (RiveFont*)decodeUIFont:(UIFont*)data NS_SWIFT_NAME(decodeFont(_:)); #else - (RiveFont*)decodeNSFont:(NSFont*)data NS_SWIFT_NAME(decodeFont(_:)); #endif +#endif - (RiveRenderImage*)decodeImage:(NSData*)data; +#ifdef WITH_RIVE_AUDIO - (RiveAudio*)decodeAudio:(NSData*)data; +#endif @end NS_ASSUME_NONNULL_END diff --git a/Source/Renderer/include/RiveFileAsset.h b/Source/Renderer/include/RiveFileAsset.h index b246b36..9049a36 100644 --- a/Source/Renderer/include/RiveFileAsset.h +++ b/Source/Renderer/include/RiveFileAsset.h @@ -13,7 +13,9 @@ @class RiveRenderImage; @class RiveFont; +#ifdef WITH_RIVE_AUDIO @class RiveAudio; +#endif NS_ASSUME_NONNULL_BEGIN @@ -45,12 +47,14 @@ NS_ASSUME_NONNULL_BEGIN - (void)font:(RiveFont*)font; @end +#ifdef WITH_RIVE_AUDIO /* * RiveAudioAsset */ @interface RiveAudioAsset : RiveFileAsset - (void)audio:(RiveAudio*)audio; @end +#endif NS_ASSUME_NONNULL_END diff --git a/Source/Renderer/include/RivePrivateHeaders.h b/Source/Renderer/include/RivePrivateHeaders.h index 000b4e8..7c7f7d4 100644 --- a/Source/Renderer/include/RivePrivateHeaders.h +++ b/Source/Renderer/include/RivePrivateHeaders.h @@ -29,8 +29,12 @@ #import "rive/text/text_value_run.hpp" #import "rive/event.hpp" #import "rive/assets/image_asset.hpp" +#ifdef WITH_RIVE_TEXT #import "rive/assets/font_asset.hpp" +#endif +#ifdef WITH_RIVE_AUDIO #import "rive/assets/audio_asset.hpp" +#endif #import "rive/assets/file_asset.hpp" #import "rive/file_asset_loader.hpp" #import "rive/viewmodel/runtime/viewmodel_instance_runtime.hpp" @@ -139,19 +143,23 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithFileAsset:(const rive::ImageAsset*)fileAsset; @end +#ifdef WITH_RIVE_TEXT /* * RiveFontAsset */ @interface RiveFontAsset () - (instancetype)initWithFileAsset:(const rive::FontAsset*)fileAsset; @end +#endif +#ifdef WITH_RIVE_AUDIO /* * RiveAudioAsset */ @interface RiveAudioAsset () - (instancetype)initWithFileAsset:(const rive::AudioAsset*)fileAsset; @end +#endif /* * RiveFileAsset @@ -160,20 +168,24 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithFactory:(rive::Factory*)factory; @end +#ifdef WITH_RIVE_TEXT @interface RiveFont () - (instancetype)initWithFont:(rive::rcp)font; - (rive::rcp)instance; @end +#endif @interface RiveRenderImage () - (instancetype)initWithImage:(rive::rcp)image; - (rive::rcp)instance; @end +#ifdef WITH_RIVE_AUDIO @interface RiveAudio () - (instancetype)initWithAudio:(rive::rcp)audio; - (rive::rcp)instance; @end +#endif @interface RiveDataBindingViewModel () - (instancetype)initWithViewModel:(rive::ViewModelRuntime*)viewModel; diff --git a/Source/Renderer/rive_renderer_view.mm b/Source/Renderer/rive_renderer_view.mm index 00b3048..bb817d0 100644 --- a/Source/Renderer/rive_renderer_view.mm +++ b/Source/Renderer/rive_renderer_view.mm @@ -14,8 +14,10 @@ #import // We manually need to provide this as our build-time config isn't shared with // xcode. -#define WITH_RIVE_AUDIO + +#ifdef WITH_RIVE_AUDIO #include "rive/audio/audio_engine.hpp" +#endif #if TARGET_OS_VISION @implementation RiveMTKView @@ -157,20 +159,24 @@ - (void)didEnterBackground:(NSNotification*)notification { +#ifdef WITH_RIVE_AUDIO auto engine = rive::AudioEngine::RuntimeEngine(false); if (engine != nil) { engine->stop(); } +#endif } - (void)didEnterForeground:(NSNotification*)notification { +#ifdef WITH_RIVE_AUDIO auto engine = rive::AudioEngine::RuntimeEngine(false); if (engine != nil) { engine->start(); } +#endif } - (instancetype)initWithCoder:(NSCoder*)decoder diff --git a/Source/RiveViewModel.swift b/Source/RiveViewModel.swift index be85bae..aa54c44 100644 --- a/Source/RiveViewModel.swift +++ b/Source/RiveViewModel.swift @@ -459,7 +459,8 @@ import Combine RiveLogger.log(viewModel: self, event: .doubleInput(inputName, path, value)) setInput(inputName, value: Float(value), path: path) } - + +#if WITH_RIVE_TEXT /// Get a text value from a specified text run /// - Parameters: /// - textRunName: The name of a `Text Run` on the active Artboard @@ -522,6 +523,7 @@ import Combine throw RiveError.textValueRunError(errorMessage) } } +#endif // TODO: Replace this with a more robust structure of the file's contents @objc open func artboardNames() -> [String] { diff --git a/scripts/build.rive.sh b/scripts/build.rive.sh index 1faab14..07dda01 100755 --- a/scripts/build.rive.sh +++ b/scripts/build.rive.sh @@ -13,6 +13,76 @@ fi export RIVE_PLS_DIR="$RIVE_RUNTIME_DIR/renderer" +if [ -z "${RIVE_PREMAKE_ARGS+null_detector_string}" ]; then + RIVE_PREMAKE_ARGS="--with_rive_layout" +fi + +NO_AUDIO=false +NO_TEXT=false +PLATFORM="" +CONFIG="" + +while [[ $# -gt 0 ]]; do + case $1 in + --no-audio) + NO_AUDIO=true + shift + ;; + --no-text) + NO_TEXT=true + shift + ;; + all|macosx|ios|ios_sim|xros|xrsimulator|appletvos|appletvsimulator|maccatalyst) + PLATFORM="$1" + shift + ;; + debug|release) + CONFIG="$1" + shift + ;; + *) + echo "Unknown option: $1" + usage + ;; + esac +done + +# Add audio flag to RIVE_PREMAKE_ARGS if --no-audio is not passed +if [ "$NO_AUDIO" = false ]; then + RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS --with_rive_audio=system" +fi + +# Add text flag to RIVE_PREMAKE_ARGS if --no-text is not passed +if [ "$NO_TEXT" = false ]; then + RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS --with_rive_text" +fi + +# Handle preprocessor definitions for audio and text +# Build the definitions string +DEFINITIONS="" +if [ "$NO_AUDIO" = false ]; then + DEFINITIONS="$DEFINITIONS WITH_RIVE_AUDIO" +fi +if [ "$NO_TEXT" = false ]; then + DEFINITIONS="$DEFINITIONS WITH_RIVE_TEXT" +fi + +# Set the preprocessor definitions line +if [ -n "$DEFINITIONS" ]; then + # Remove leading space + DEFINITIONS=$(echo "$DEFINITIONS" | sed 's/^ //') + # Update the active GCC_PREPROCESSOR_DEFINITIONS line (not commented ones) + sed -i '' "/^GCC_PREPROCESSOR_DEFINITIONS = /s/= .*/= \$(inherited) $DEFINITIONS/" $DEV_SCRIPT_DIR/../Config/Base.xcconfig + # Update the active SWIFT_ACTIVE_COMPILATION_CONDITIONS line (not commented ones) + sed -i '' "/^SWIFT_ACTIVE_COMPILATION_CONDITIONS = /s/= .*/= \$(inherited) $DEFINITIONS/" $DEV_SCRIPT_DIR/../Config/Base.xcconfig +else + # Update the active GCC_PREPROCESSOR_DEFINITIONS line (not commented ones) + sed -i '' '/^GCC_PREPROCESSOR_DEFINITIONS = /s/= .*/= $(inherited)/' $DEV_SCRIPT_DIR/../Config/Base.xcconfig + # Update the active SWIFT_ACTIVE_COMPILATION_CONDITIONS line (not commented ones) + sed -i '' '/^SWIFT_ACTIVE_COMPILATION_CONDITIONS = /s/= .*/= $(inherited)/' $DEV_SCRIPT_DIR/../Config/Base.xcconfig +fi + + make_dependency_directories() { rm -fr $DEV_SCRIPT_DIR/../dependencies @@ -28,7 +98,7 @@ make_dependency_directories() { build_runtime() { # Build the rive runtime. - build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua ios $1 --with_rive_audio=system universal clean + RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua ios $1 $AUDIO_FLAG universal clean cp -r out/ios_universal_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz.a cp -r out/ios_universal_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga.a @@ -67,7 +137,7 @@ build_runtime() { build_runtime_sim() { # Build the rive runtime. - build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua iossim $1 --with_rive_audio=system clean + RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua iossim $1 $AUDIO_FLAG clean cp -r out/iossim_universal_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_sim.a cp -r out/iossim_universal_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_sim.a @@ -107,7 +177,7 @@ build_runtime_sim() { build_runtime_macosx() { # Build the rive runtime. - build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua $1 universal --with_rive_audio=system clean + RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua $1 universal $AUDIO_FLAG clean cp -r out/universal_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_macos.a cp -r out/universal_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_macos.a @@ -146,7 +216,7 @@ build_runtime_macosx() { build_runtime_xros() { # Build the rive runtime. - RIVE_OUT=out/xros_$1 build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua xros $1 --with_rive_audio=system clean + RIVE_OUT=out/xros_$1 RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua xros $1 $AUDIO_FLAG clean cp -r out/xros_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_xros.a cp -r out/xros_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_xros.a @@ -185,7 +255,7 @@ build_runtime_xros() { build_runtime_xrsimulator() { # Build the rive runtime. - RIVE_OUT=out/xrsimulator_universal_$1 build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua xrsimulator $1 --with_rive_audio=system clean + RIVE_OUT=out/xrsimulator_universal_$1 RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua xrsimulator $1 $AUDIO_FLAG clean cp -r out/xrsimulator_universal_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_xrsimulator.a cp -r out/xrsimulator_universal_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_xrsimulator.a @@ -224,7 +294,7 @@ build_runtime_xrsimulator() { } build_runtime_appletvos() { - RIVE_OUT=out/appletvos_$1 build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua appletvos $1 --with_rive_audio=system clean + RIVE_OUT=out/appletvos_$1 RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua appletvos $1 $AUDIO_FLAG clean cp -r out/appletvos_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_appletvos.a cp -r out/appletvos_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_appletvos.a @@ -264,7 +334,7 @@ build_runtime_appletvos() { } build_runtime_appletvsimulator() { - RIVE_OUT=out/appletvsimulator_universal_$1 build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua appletvsimulator $1 --with_rive_audio=system clean + RIVE_OUT=out/appletvsimulator_universal_$1 RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua appletvsimulator $1 $AUDIO_FLAG clean cp -r out/appletvsimulator_universal_$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_appletvsimulator.a cp -r out/appletvsimulator_universal_$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_appletvsimulator.a @@ -310,7 +380,7 @@ build_runtime_maccatalyst() { local arch=$2 # Build the rive runtime. - RIVE_OUT=out/maccatalyst_${arch}_${config} build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua ${config} ${arch} --with_rive_audio=system --variant=maccatalyst clean + RIVE_OUT=out/maccatalyst_${arch}_${config} RIVE_PREMAKE_ARGS="$RIVE_PREMAKE_ARGS" build_rive.sh --file=$RIVE_RUNTIME_DIR/premake5_v2.lua ${config} ${arch} $AUDIO_FLAG --variant=maccatalyst clean cp -r out/maccatalyst_${arch}_${config}/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/${config}/librive_harfbuzz_maccatalyst_${arch}.a cp -r out/maccatalyst_${arch}_${config}/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/${config}/librive_yoga_maccatalyst_${arch}.a @@ -380,11 +450,11 @@ build_runtime_maccatalyst() { } usage() { - echo "USAGE: $0 " + echo "USAGE: $0 [--no-audio] " exit 1 } -if (($# < 1)); then +if [ -z "$PLATFORM" ]; then usage fi @@ -403,9 +473,9 @@ build_all() { build_runtime_maccatalyst $1 } -case $1 in +case $PLATFORM in all) - case $2 in + case $CONFIG in "debug") echo "Building all Apple runtimes in debug..." make_dependency_directories @@ -428,13 +498,13 @@ all) esac ;; macosx) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_macosx $2 + build_runtime_macosx $CONFIG ;; *) usage @@ -442,13 +512,13 @@ macosx) esac ;; ios) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime $2 + build_runtime $CONFIG ;; *) usage @@ -456,13 +526,13 @@ ios) esac ;; ios_sim) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_sim $2 + build_runtime_sim $CONFIG # TODO: # to build for the example you need debug, but to profile you need release. # each time you build, both version are removed. to imnprove this only remove @@ -476,13 +546,13 @@ ios_sim) esac ;; xros) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_xros $2 + build_runtime_xros $CONFIG ;; *) usage @@ -490,13 +560,13 @@ xros) esac ;; xrsimulator) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_xrsimulator $2 + build_runtime_xrsimulator $CONFIG # TODO: # to build for the example you need debug, but to profile you need release. # each time you build, both version are removed. to imnprove this only remove @@ -510,13 +580,13 @@ xrsimulator) esac ;; appletvos) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_appletvos $2 + build_runtime_appletvos $CONFIG ;; *) usage @@ -524,13 +594,13 @@ appletvos) esac ;; appletvsimulator) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_appletvsimulator $2 + build_runtime_appletvsimulator $CONFIG # TODO: # to build for the example you need debug, but to profile you need release. # each time you build, both version are removed. to imnprove this only remove @@ -544,13 +614,13 @@ appletvsimulator) esac ;; maccatalyst) - if (($# < 2)); then + if [ -z "$CONFIG" ]; then usage fi - case $2 in + case $CONFIG in release | debug) make_dependency_directories - build_runtime_maccatalyst $2 + build_runtime_maccatalyst $CONFIG ;; *) usage diff --git a/scripts/strip_symbols.sh b/scripts/strip_symbols.sh new file mode 100755 index 0000000..77b8a2f --- /dev/null +++ b/scripts/strip_symbols.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Strip symbols from RiveRuntime.xcframework binaries +# This script iterates through all platform directories and strips symbols from each binary in-place +# See the Emerge Tools blog for more details: https://docs.emergetools.com/docs/strip-binary-symbols + +set -e # Exit on any error + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +FRAMEWORK_DIR="$SCRIPT_DIR/../archive/RiveRuntime.xcframework" + +# Check if the framework directory exists +if [ ! -d "$FRAMEWORK_DIR" ]; then + echo "Error: RiveRuntime.xcframework not found at $FRAMEWORK_DIR" + echo "Make sure the framework has been built and is in the archive directory." + exit 1 +fi + +echo "Found RiveRuntime.xcframework at: $FRAMEWORK_DIR" +echo "Starting symbol stripping process..." + +# Iterate through all platform directories +for platform_dir in "$FRAMEWORK_DIR"/*/; do + if [ -d "$platform_dir" ]; then + platform_name=$(basename "$platform_dir") + echo "Processing platform: $platform_name" + + # Look for the framework directory within each platform + framework_path="$platform_dir/RiveRuntime.framework" + if [ -d "$framework_path" ]; then + binary_path="$framework_path/RiveRuntime" + + if [ -f "$binary_path" ]; then + echo " Stripping symbols from: $binary_path" + + # Create a temporary file for the stripped binary + temp_binary="$binary_path.tmp" + + # Strip symbols and save to temporary file + strip -rSTx "$binary_path" -o "$temp_binary" + + # Replace the original binary with the stripped version + mv "$temp_binary" "$binary_path" + + echo " ✓ Successfully stripped symbols from $platform_name" + else + echo " ⚠ Warning: Binary not found at $binary_path" + fi + else + echo " ⚠ Warning: Framework directory not found at $framework_path" + fi + fi +done + +echo "Symbol stripping completed!" \ No newline at end of file