Plugin

GitHub/Graphics-Extensions-for-Solar2D/package-plugin

The following plugins are built for iOS/macOs by kwiksher


refer to @workspace/Solar2D-plugin_movie_kwiksher about the folder structure, can you setup new folders for poring @workspace/Graphics-Extensions-for-Solar2D to ios/mac?


mac_template

it is a skelton plugin for testing

  • build.sh
  • plugin_gfxe.lua
  • shared/SimulatorPluginLibrary.cpp

dependencies

resvg-0.40.0

  • iOS: ios/build_resvg_ios.sh

  • macOS: mac/build_resvg_mac.sh

    RUST_DIR="$PROJECT_DIR/dependencies/resvg-0.40.0"
    OUTPUT_DIR="$SCRIPT_DIR/lib"
    
    # For arm64
    rustup target add aarch64-apple-ios
    cargo build --release --target aarch64-apple-ios --manifest-path "$RUST_DIR/crates/c-api/Cargo.toml"
    
    # For simulator (x86_64)
    rustup target add x86_64-apple-ios
    cargo build --release --target x86_64-apple-ios --manifest-path "$RUST_DIR/crates/c-api/Cargo.toml"
    
    # Create universal binary
    lipo -create \
      "$RUST_DIR/target/aarch64-apple-ios/release/libresvg_capi.a" \
      "$RUST_DIR/target/x86_64-apple-ios/release/libresvg_capi.a" \
      -output "$OUTPUT_DIR/libresvg_universal.a"

libdebp-1.2.3

iOS

cd dependencies/libwebp-1.2.3
  • iosbuild.sh is modified for only iPhoneOS-V7-arm64

    PLATFORMS="iPhoneOS-V7-arm64"

now you can run

chmod +x iosbuild.sh
./iosbild.sh
mv iosbuild build_ios
mv build_ios/iPhoneOS-18.2-aarch64/lib/*.a ../ios/lib

Output: ios/plugin/build/plugin_gfxe/libplugin_gfxe.a

macOS

  • README_gemini.md

    xcode-select --install
    brew install cmake
    cd build_x86_64
    cmake -DCMAKE_OSX_ARCHITECTURES="x86_64" ..
    make -j4
    cd build_arm64
    cmake -DCMAKE_OSX_ARCHITECTURES="arm64" ..
    make -j4
    mkdir universal_libwebp
    cd universal_libwebp
    
    lipo ../build_arm64/libexampleutil.a ../build_x86_64/libexampleutil.a -create -output libexampleutil.a
    lipo ../build_arm64/libextras.a ../build_x86_64/libextras.a -create -output libextras.a
    lipo ../build_arm64/libimagedec.a ../build_x86_64/libimagedec.a -create -output libimagedec.a
    lipo ../build_arm64/libimageenc.a ../build_x86_64/libimageenc.a -create -output libimageenc.a
    lipo ../build_arm64/libimageioutil.a ../build_x86_64/libimageioutil.a -create -output libimageioutil.a
    lipo ../build_arm64/libwebp.a ../build_x86_64/libwebp.a -create -output libwebp.a
    lipo ../build_arm64/libwebpdecoder.a ../build_x86_64/libwebpdecoder.a -create -output libwebpdecoder.a
    lipo ../build_arm64/libwebpdemux.a ../build_x86_64/libwebpdemux.a -create -output libwebpdemux.a
    lipo ../build_arm64/libwebpmux.a ../build_x86_64/libwebpmux.a -create -output libwebpmux.a
    copy dependences/universal_libwebp/*.a mac/lib/
    copy dependences/universal_libwebp/*.a ios/lib/

ios/mac

build plugin_gfxe

chmod +x build.sh
./build.sh

Output: mac/plugin_gfxe.dylib

cp plugin_gfxe.dylib ~/Library/Application Support/Corona/Simulator/Plugins

iOS App

Output: ~/Library/Developer/Xcode/DerivedData/App-dzzooqwanjxnzvcwhdqllxdmfqxz/Build/Products

XCode Linking libraries

  • App/libplugin_gfxe.a

  • Plugin/

    - ibresvg_universal.a
    - ibwebp.a
    - ~~ibwebpdecoder.a~~
    - ibwebpdemux.a
    - libwebpmux.a
    

Simulator

you may comment out the plugin gfxe in build.settings for testring

Corona/main.lua

local gfxe = require('plugin.gfxe')

local asset_reader = require('plugin.AssetReader')

local font
local platform = system.getInfo('platform')

if platform == 'android' then
    font = asset_reader.Read('fonts/Inconsolata-Regular.ttf')
else
    local file = io.open(system.pathForFile('fonts/Inconsolata-Regular.ttf'), 'rb')
    font = file:read('*a')
    file:close()
end

-------------------------------------------------------------------

local svg1 = gfxe.newScalableImage(
    {
        filename = 'images/h350.svg'
    },
    {
        fontData = font,
        fontFamily = 'Inconsolata'
    }
)
svg1.x, svg1.y = display.contentCenterX, display.contentCenterY

Embedding Lua Bytecode in a C Plugin for Solar2D

To embed Lua bytecode in your C plugin, you’ll need to convert your plugin_library.lua to bytecode and then include it as a static resource in your C code. Here’s a step-by-step guide:

Step 1: Convert Lua to Bytecode

First, use the luac compiler (comes with Lua) to generate bytecode:

luac -o plugin_library.luac -s plugin_library.lua

The -s option strips debug information to reduce size.

Step 2: Convert Bytecode to C Array

Convert the .luac file to a C byte array using a hex dump tool:

xxd -i plugin_library.luac > plugin_library_bytecode.h

This creates a header file containing something like:

unsigned char plugin_library_luac[] = {
  0x1b, 0x4c, 0x75, 0x61, 0x53, 0x00, 0x19, 0x93, 0x0d, 0x0a, 0x1a, 0x0a,
  // ... more byte values ...
};
unsigned int plugin_library_luac_len = 123;

Step 3: Load the Bytecode in Your C Plugin

Modify your plugin_library.c to load the embedded bytecode:

#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "plugin_library_bytecode.h" // The generated header

static int luaopen_plugin_library(lua_State *L) {
    // Load the bytecode
    if (luaL_loadbuffer(L, (const char*)plugin_library_luac,
                        plugin_library_luac_len, "plugin_library.lua") != LUA_OK) {
        return lua_error(L); // Propagate error
    }

    // Run the chunk to initialize the library
    if (lua_pcall(L, 0, 1, 0) != LUA_OK) {
        return lua_error(L);
    }

    // The library table is now on top of the stack
    return 1;
}

Step 4: Building the Plugin

Compile with the embedded bytecode:

gcc -shared -fPIC -o plugin_library.so plugin_library.c -I/path/to/lua/headers

Alternative Approach: Direct String Embedding

If you prefer not to generate a separate header file, you can embed the bytecode directly:

// In plugin_library.c
static const unsigned char plugin_library_bytecode[] = {
  0x1b, 0x4c, 0x75, 0x61, 0x53, 0x00, 0x19, 0x93, 0x0d, 0x0a, 0x1a, 0x0a,
  // ... more byte values ...
};

static const size_t plugin_library_bytecode_len = sizeof(plugin_library_bytecode);

// Then use luaL_loadbuffer as shown above

Important Considerations

  1. Lua Version Compatibility: Ensure the bytecode matches the Lua version used by Solar2D
  2. Bytecode Security: Don’t load untrusted bytecode as it could execute arbitrary code
  3. Debugging: Consider keeping debug info during development (luac without -s)
  4. Solar2D Specifics: Solar2D may have additional requirements for plugin initialization

Would you like me to provide more details about any specific part of this process?