feat(apple): add support for building lite frameworks (#10130) 1fb3654049

Co-authored-by: David Skuza <david@rive.app>
This commit is contained in:
dskuza
2025-07-09 14:26:23 +00:00
parent 1612eb17e4
commit 8b8844e9a8
25 changed files with 278 additions and 46 deletions

View File

@@ -1 +1 @@
d973e8c253120fa9e9f9591a2161d6bbf5e8b4e8
1fb3654049a1bee715ea2a51558291c0b3e47358

View File

@@ -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.

13
Config/Base.xcconfig Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -238,6 +238,7 @@
F20808E12E05C3FF0082A281 /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = "<group>"; };
F21C3D1A2DDFCD93005F82F4 /* RiveRenderImage+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveRenderImage+Extensions.swift"; sourceTree = "<group>"; };
F21F08132C66526D00FFA205 /* RiveFallbackFontDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontDescriptor.swift; sourceTree = "<group>"; };
F22883752E1D61B50042FB20 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
F22CF1B02D380E3700D35779 /* data_binding_test.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = data_binding_test.riv; sourceTree = "<group>"; };
F22CF1B22D380E6900D35779 /* DataBindingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBindingTests.swift; sourceTree = "<group>"; };
F23626A92C8F90FA00727D9A /* nested_text_run.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = nested_text_run.riv; sourceTree = "<group>"; };
@@ -535,6 +536,7 @@
children = (
F2BD96D52DDCC7A200E7F49A /* Catalyst.xcconfig */,
F2BD96D62DDCC7A200E7F49A /* macOS.xcconfig */,
F22883752E1D61B50042FB20 /* Base.xcconfig */,
);
path = Config;
sourceTree = "<group>";

View File

@@ -6,6 +6,7 @@
// Copyright © 2024 Rive. All rights reserved.
//
#ifdef WITH_RIVE_TEXT
#import <Foundation/Foundation.h>
#import <rive/text/font_hb.hpp>
#import <RiveRuntime/RiveRuntime-Swift.h>
@@ -42,3 +43,4 @@ NS_ASSUME_NONNULL_BEGIN
@end
NS_ASSUME_NONNULL_END
#endif

View File

@@ -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

View File

@@ -1,3 +1,4 @@
#if WITH_RIVE_TEXT
//
// RiveFallbackFontDescriptor+UIKit.swift
// RiveRuntime
@@ -224,3 +225,4 @@ extension RiveNativeFont: RiveFontWidthProvider {
return Int(calculatedWidth)
}
}
#endif

View File

@@ -1,3 +1,4 @@
#if WITH_RIVE_TEXT
//
// RiveFallbackFontDescriptor.swift
// RiveRuntime
@@ -89,3 +90,4 @@ import SwiftUI
self.width = width
}
}
#endif // WITH_RIVE_TEXT

View File

@@ -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

View File

@@ -6,6 +6,8 @@
// Copyright © 2024 Rive. All rights reserved.
//
#ifdef WITH_RIVE_TEXT
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@@ -57,3 +59,5 @@ typedef NSArray<id<RiveFallbackFontProvider>>* _Nonnull (
@end
NS_ASSUME_NONNULL_END
#endif

View File

@@ -6,6 +6,8 @@
// Copyright © 2024 Rive. All rights reserved.
//
#ifdef WITH_RIVE_TEXT
#import "RiveFont.h"
#import "RiveFallbackFontCache.h"
#import <RiveRuntime/RiveRuntime-Swift.h>
@@ -271,3 +273,5 @@ static rive::rcp<rive::Font> findFallbackFont(const rive::Unichar missing,
}
@end
#endif

View File

@@ -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

View File

@@ -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<rive::FontAsset>())
{
RiveFontAsset* fontAsset = [[RiveFontAsset alloc]
@@ -33,7 +34,8 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset,
andData:data
andFactory:myFactory];
}
else if (asset.is<rive::ImageAsset>())
#endif
if (asset.is<rive::ImageAsset>())
{
RiveImageAsset* imageAsset = [[RiveImageAsset alloc]
initWithFileAsset:asset.as<rive::ImageAsset>()];
@@ -41,7 +43,8 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset,
andData:data
andFactory:myFactory];
}
else if (asset.is<rive::AudioAsset>())
#ifdef WITH_RIVE_AUDIO
if (asset.is<rive::AudioAsset>())
{
RiveAudioAsset* audioAsset = [[RiveAudioAsset alloc]
initWithFileAsset:asset.as<rive::AudioAsset>()];
@@ -49,6 +52,7 @@ bool rive::FileAssetLoaderAdapter::loadContents(rive::FileAsset& asset,
andData:data
andFactory:myFactory];
}
#endif
return false;
}

View File

@@ -10,14 +10,18 @@
#import <RivePrivateHeaders.h>
#import <RiveFactory.h>
#import <RiveRuntime/RiveRuntime-Swift.h>
#import <RenderContext.h>
#if WITH_RIVE_TEXT
#import <CoreText/CTFont.h>
#import <rive/text/font_hb.hpp>
#import <RenderContext.h>
#if TARGET_OS_IPHONE
#import <UIKit/UIFont.h>
#endif
#endif
#if WITH_RIVE_TEXT
static rive::rcp<rive::Font> riveFontFromNativeFont(id font,
bool useSystemShaper)
{
@@ -36,6 +40,7 @@ static rive::rcp<rive::Font> 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<rive::Font> riveFontFromNativeFont(id font,
@end
#ifdef WITH_RIVE_AUDIO
@implementation RiveAudio
{
rive::rcp<rive::AudioSource>
@@ -100,6 +106,7 @@ static rive::rcp<rive::Font> riveFontFromNativeFont(id font,
}
@end
#endif
/*
* RiveFactory
@@ -131,6 +138,7 @@ static rive::rcp<rive::Font> riveFontFromNativeFont(id font,
rive::Span<const uint8_t>(bytes, [data length]))];
}
#ifdef WITH_RIVE_TEXT
- (RiveFont*)decodeFont:(nonnull NSData*)data
{
UInt8* bytes = (UInt8*)[data bytes];
@@ -150,7 +158,9 @@ static rive::rcp<rive::Font> 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<rive::Font> riveFontFromNativeFont(id font,
initWithAudio:instance->decodeAudio(
rive::Span<const uint8_t>(bytes, [data length]))];
}
#endif
@end

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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<rive::Font>)font;
- (rive::rcp<rive::Font>)instance;
@end
#endif
@interface RiveRenderImage ()
- (instancetype)initWithImage:(rive::rcp<rive::RenderImage>)image;
- (rive::rcp<rive::RenderImage>)instance;
@end
#ifdef WITH_RIVE_AUDIO
@interface RiveAudio ()
- (instancetype)initWithAudio:(rive::rcp<rive::AudioSource>)audio;
- (rive::rcp<rive::AudioSource>)instance;
@end
#endif
@interface RiveDataBindingViewModel ()
- (instancetype)initWithViewModel:(rive::ViewModelRuntime*)viewModel;

View File

@@ -14,8 +14,10 @@
#import <RenderContextManager.h>
// 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

View File

@@ -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] {

View File

@@ -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 <all|ios|ios_sim|xros|xrsimulator|appletvos|appletvsimulator|macosx|maccatalyst> <debug|release>"
echo "USAGE: $0 [--no-audio] <all|ios|ios_sim|xros|xrsimulator|appletvos|appletvsimulator|macosx|maccatalyst> <debug|release>"
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

57
scripts/strip_symbols.sh Executable file
View File

@@ -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!"