Fix OfflineAISystem iOS build issues #43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Roblox Executor iOS Dynamic Library | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| runs-on: macos-latest # Use macOS for iOS compatible builds | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v3 | |
| - name: Install dependencies | |
| run: | | |
| echo "Installing dependencies..." | |
| # Install Homebrew packages | |
| brew install cmake pkg-config | |
| brew install openssl sqlite3 | |
| brew install libzip json-c | |
| # Install Luau via Homebrew | |
| brew install luau | |
| # Install iOS development dependencies | |
| brew install llvm || true | |
| brew install libomp || true | |
| # Configure compiler paths for Homebrew-installed LLVM and libomp | |
| if [ -d "/opt/homebrew/opt/llvm/bin" ]; then | |
| echo "Using Homebrew LLVM" | |
| export PATH="/opt/homebrew/opt/llvm/bin:$PATH" | |
| # Store individual paths for CMake to use directly | |
| LLVM_LIB_PATH="/opt/homebrew/opt/llvm/lib" | |
| LLVM_INCLUDE_PATH="/opt/homebrew/opt/llvm/include" | |
| # Also add libomp paths if available | |
| if [ -d "/opt/homebrew/opt/libomp" ]; then | |
| echo "Adding libomp paths to environment" | |
| LIBOMP_LIB_PATH="/opt/homebrew/opt/libomp/lib" | |
| LIBOMP_INCLUDE_PATH="/opt/homebrew/opt/libomp/include" | |
| fi | |
| # Make these environment variables available to subsequent steps | |
| echo "PATH=$PATH" >> $GITHUB_ENV | |
| echo "LLVM_LIB_PATH=$LLVM_LIB_PATH" >> $GITHUB_ENV | |
| echo "LLVM_INCLUDE_PATH=$LLVM_INCLUDE_PATH" >> $GITHUB_ENV | |
| if [ -n "$LIBOMP_LIB_PATH" ]; then | |
| echo "LIBOMP_LIB_PATH=$LIBOMP_LIB_PATH" >> $GITHUB_ENV | |
| echo "LIBOMP_INCLUDE_PATH=$LIBOMP_INCLUDE_PATH" >> $GITHUB_ENV | |
| fi | |
| fi | |
| # Set up Luau paths | |
| LUAU_PREFIX=$(brew --prefix luau) | |
| echo "Using Homebrew Luau from $LUAU_PREFIX" | |
| # Check actual library and include structure | |
| echo "Checking Luau installation structure..." | |
| ls -la $LUAU_PREFIX/include/ || echo "Include directory not found" | |
| ls -la $LUAU_PREFIX/lib/ || echo "Lib directory not found" | |
| # Find the actual library file | |
| LUAU_LIBRARY=$(find $LUAU_PREFIX/lib -name "*.dylib" | head -1) | |
| if [ -z "$LUAU_LIBRARY" ]; then | |
| LUAU_LIBRARY=$(find $LUAU_PREFIX/lib -name "*.a" | head -1) | |
| fi | |
| if [ -z "$LUAU_LIBRARY" ]; then | |
| echo "Warning: Could not find Luau library, using default path assumption" | |
| LUAU_LIBRARY="$LUAU_PREFIX/lib/liblua.dylib" | |
| fi | |
| echo "Found Luau library: $LUAU_LIBRARY" | |
| # Set environment variables for Luau | |
| echo "LUAU_INCLUDE_DIR=$LUAU_PREFIX/include" >> $GITHUB_ENV | |
| echo "LUAU_LIB_DIR=$LUAU_PREFIX/lib" >> $GITHUB_ENV | |
| echo "LUA_INCLUDE_DIR=$LUAU_PREFIX/include" >> $GITHUB_ENV | |
| echo "LUA_LIBRARIES=$LUAU_LIBRARY" >> $GITHUB_ENV | |
| # Set compiler flags to include Luau headers - include both Homebrew and project headers | |
| echo "CFLAGS=-I$LUAU_PREFIX/include -I$GITHUB_WORKSPACE -I$GITHUB_WORKSPACE/source" >> $GITHUB_ENV | |
| echo "CXXFLAGS=-I$LUAU_PREFIX/include -I$GITHUB_WORKSPACE -I$GITHUB_WORKSPACE/source" >> $GITHUB_ENV | |
| # Also pass these to subsequent commands - use project headers as fallback | |
| export LUA_INCLUDE_DIR="$GITHUB_WORKSPACE/source/cpp/luau" | |
| export LUA_LIBRARIES=$LUAU_LIBRARY | |
| # Create directories for project resources (only once) | |
| mkdir -p Resources/AIData/LocalModels | |
| mkdir -p Resources/AIData/Vulnerabilities | |
| mkdir -p lib | |
| mkdir -p cmake | |
| # Fix permissions if needed | |
| chmod -R 755 cmake || true | |
| # Handle CMake modules with better error checking | |
| echo "Setting up CMake modules..." | |
| # Create simplified Find*.cmake files for building | |
| # First, create FindLuaFileSystem.cmake | |
| echo "# FindLuaFileSystem.cmake - Using Homebrew Luau" > cmake/FindLuaFileSystem.cmake | |
| echo "# Create a target for lfs.c that ensures it can find the Luau headers" >> cmake/FindLuaFileSystem.cmake | |
| echo "function(add_lfs_target)" >> cmake/FindLuaFileSystem.cmake | |
| echo " if(TARGET lfs_obj)" >> cmake/FindLuaFileSystem.cmake | |
| echo " return()" >> cmake/FindLuaFileSystem.cmake | |
| echo " endif()" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " message(STATUS \"Setting up LuaFileSystem with Homebrew Luau headers\")" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " add_library(lfs_obj OBJECT \${CMAKE_SOURCE_DIR}/source/lfs.c)" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " # Get Luau include directory from environment or find it" >> cmake/FindLuaFileSystem.cmake | |
| echo " if(DEFINED ENV{LUAU_INCLUDE_DIR})" >> cmake/FindLuaFileSystem.cmake | |
| echo " set(LUAU_INCLUDE_DIR \$ENV{LUAU_INCLUDE_DIR})" >> cmake/FindLuaFileSystem.cmake | |
| echo " else()" >> cmake/FindLuaFileSystem.cmake | |
| echo " # Try to find it using brew" >> cmake/FindLuaFileSystem.cmake | |
| echo " execute_process(" >> cmake/FindLuaFileSystem.cmake | |
| echo " COMMAND brew --prefix luau" >> cmake/FindLuaFileSystem.cmake | |
| echo " OUTPUT_VARIABLE LUAU_PREFIX" >> cmake/FindLuaFileSystem.cmake | |
| echo " OUTPUT_STRIP_TRAILING_WHITESPACE" >> cmake/FindLuaFileSystem.cmake | |
| echo " )" >> cmake/FindLuaFileSystem.cmake | |
| echo " set(LUAU_INCLUDE_DIR \"\${LUAU_PREFIX}/include\")" >> cmake/FindLuaFileSystem.cmake | |
| echo " endif()" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " target_include_directories(lfs_obj PRIVATE" >> cmake/FindLuaFileSystem.cmake | |
| echo " \${LUAU_INCLUDE_DIR}" >> cmake/FindLuaFileSystem.cmake | |
| echo " \${CMAKE_SOURCE_DIR}/source" >> cmake/FindLuaFileSystem.cmake | |
| echo " )" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " # No need for special compile definitions with Homebrew Luau" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " set_target_properties(lfs_obj PROPERTIES" >> cmake/FindLuaFileSystem.cmake | |
| echo " C_STANDARD 99" >> cmake/FindLuaFileSystem.cmake | |
| echo " POSITION_INDEPENDENT_CODE ON" >> cmake/FindLuaFileSystem.cmake | |
| echo " )" >> cmake/FindLuaFileSystem.cmake | |
| echo "" >> cmake/FindLuaFileSystem.cmake | |
| echo " message(STATUS \"Using Homebrew Luau headers from \${LUAU_INCLUDE_DIR}\")" >> cmake/FindLuaFileSystem.cmake | |
| echo "endfunction()" >> cmake/FindLuaFileSystem.cmake | |
| # Then create FindLua.cmake | |
| echo "# FindLua.cmake - Using Homebrew Luau" > cmake/FindLua.cmake | |
| echo "# This is a minimal finder that points to Homebrew Luau" >> cmake/FindLua.cmake | |
| echo "" >> cmake/FindLua.cmake | |
| echo "# Try to get from environment first" >> cmake/FindLua.cmake | |
| echo "if(DEFINED ENV{LUAU_INCLUDE_DIR} AND DEFINED ENV{LUA_LIBRARIES})" >> cmake/FindLua.cmake | |
| echo " set(LUA_INCLUDE_DIR \$ENV{LUAU_INCLUDE_DIR})" >> cmake/FindLua.cmake | |
| echo " set(LUA_LIBRARIES \$ENV{LUA_LIBRARIES})" >> cmake/FindLua.cmake | |
| echo " set(LUA_FOUND TRUE)" >> cmake/FindLua.cmake | |
| echo "else()" >> cmake/FindLua.cmake | |
| echo " # Try to find it using brew" >> cmake/FindLua.cmake | |
| echo " execute_process(" >> cmake/FindLua.cmake | |
| echo " COMMAND brew --prefix luau" >> cmake/FindLua.cmake | |
| echo " OUTPUT_VARIABLE LUAU_PREFIX" >> cmake/FindLua.cmake | |
| echo " OUTPUT_STRIP_TRAILING_WHITESPACE" >> cmake/FindLua.cmake | |
| echo " )" >> cmake/FindLua.cmake | |
| echo "" >> cmake/FindLua.cmake | |
| echo " if(LUAU_PREFIX)" >> cmake/FindLua.cmake | |
| echo " set(LUA_INCLUDE_DIR \"\${LUAU_PREFIX}/include\")" >> cmake/FindLua.cmake | |
| echo " set(LUA_LIBRARIES \"\${LUAU_PREFIX}/lib/libluau.dylib\")" >> cmake/FindLua.cmake | |
| echo " set(LUA_FOUND TRUE)" >> cmake/FindLua.cmake | |
| echo " endif()" >> cmake/FindLua.cmake | |
| echo "endif()" >> cmake/FindLua.cmake | |
| echo "" >> cmake/FindLua.cmake | |
| echo "message(STATUS \"Using Homebrew Luau headers from \${LUA_INCLUDE_DIR}\")" >> cmake/FindLua.cmake | |
| echo "message(STATUS \"Using Homebrew Luau libraries: \${LUA_LIBRARIES}\")" >> cmake/FindLua.cmake | |
| echo "Created CMake module files" | |
| # For debugging - show what we've created | |
| echo "CMake directory contents:" | |
| ls -la cmake/ | |
| # Show Luau version and paths | |
| echo "Luau location in PATH:" | |
| which luau || echo "Luau not found in PATH (this is unexpected)" | |
| echo "Luau include directory: $LUAU_INCLUDE_DIR" | |
| echo "Luau library directory: $LUAU_LIB_DIR" | |
| - name: Install Dobby (Optional) | |
| id: install-dobby | |
| continue-on-error: true | |
| run: | | |
| echo "Building Dobby from source..." | |
| # Clone with error handling | |
| git clone --depth=1 https://github.com/jmpews/Dobby.git || { echo "Failed to clone Dobby repo, continuing without it"; exit 0; } | |
| cd Dobby | |
| mkdir -p build && cd build | |
| # Configure for iOS | |
| cmake .. \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DDOBBY_BUILD_SHARED_LIBRARY=OFF \ | |
| -DDOBBY_BUILD_STATIC_LIBRARY=ON || { echo "Failed to configure Dobby, continuing without it"; cd $GITHUB_WORKSPACE; exit 0; } | |
| # Build Dobby | |
| cmake --build . --config Release || { echo "Failed to build Dobby, continuing without it"; cd $GITHUB_WORKSPACE; exit 0; } | |
| # Create directory structure for CMake to find Dobby | |
| mkdir -p $GITHUB_WORKSPACE/external/dobby/lib | |
| mkdir -p $GITHUB_WORKSPACE/external/dobby/include | |
| # Copy the library and header files with error handling | |
| if [ -f "libdobby.a" ]; then | |
| cp libdobby.a $GITHUB_WORKSPACE/external/dobby/lib/ | |
| cp -r ../include/* $GITHUB_WORKSPACE/external/dobby/include/ | |
| # Set env variable for CMake to find Dobby | |
| echo "DOBBY_DIR=$GITHUB_WORKSPACE/external/dobby" >> $GITHUB_ENV | |
| echo "Dobby installation completed successfully" | |
| else | |
| echo "Dobby build didn't produce expected files, continuing without Dobby" | |
| cd $GITHUB_WORKSPACE | |
| fi | |
| - name: Setup Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: latest-stable | |
| - name: Build Dynamic Library | |
| id: build | |
| run: | | |
| echo "Building the iOS dynamic library..." | |
| # Create build directory | |
| mkdir -p build | |
| # Set additional CMake args for dependencies | |
| EXTRA_CMAKE_ARGS="" | |
| # Add Dobby args if available | |
| if [ -d "$DOBBY_DIR" ]; then | |
| echo "Dobby found at $DOBBY_DIR, enabling Dobby support" | |
| EXTRA_CMAKE_ARGS="$EXTRA_CMAKE_ARGS -DDobby_DIR=$DOBBY_DIR -DUSE_DOBBY=ON" | |
| else | |
| echo "Dobby not found, building without hooking functionality" | |
| EXTRA_CMAKE_ARGS="$EXTRA_CMAKE_ARGS -DNO_DOBBY_HOOKS=ON" | |
| fi | |
| # We're now using the internal Luau headers instead of external Lua | |
| echo "Using internal Luau headers from source/cpp/luau" | |
| EXTRA_CMAKE_ARGS="$EXTRA_CMAKE_ARGS -DCMAKE_MODULE_PATH=$PWD/cmake" | |
| # Apply compiler and linker flags - going back to simpler approach | |
| echo "Setting up compiler and linker flags for LLVM and libomp" | |
| # We'll use a simpler approach without trying to modify compiler flags | |
| # This should be enough to find the module files without quoting issues | |
| # Use Dobby if found | |
| if [ -d "$DOBBY_DIR" ]; then | |
| echo "Dobby found at $DOBBY_DIR, enabling Dobby support" | |
| EXTRA_CMAKE_ARGS="$EXTRA_CMAKE_ARGS -DDobby_DIR=$DOBBY_DIR -DUSE_DOBBY=ON" | |
| else | |
| echo "Dobby not found, building without hooking functionality" | |
| EXTRA_CMAKE_ARGS="$EXTRA_CMAKE_ARGS -DNO_DOBBY_HOOKS=ON" | |
| fi | |
| # Configure CMake for iOS build with standard options | |
| echo "CMake args: $EXTRA_CMAKE_ARGS" | |
| set -x # Echo commands | |
| cmake -S . -B build \ | |
| -DCMAKE_OSX_ARCHITECTURES="arm64" \ | |
| -DCMAKE_OSX_DEPLOYMENT_TARGET="15.0" \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCMAKE_SYSTEM_NAME=iOS \ | |
| -DENABLE_AI_FEATURES=ON \ | |
| -DENABLE_LOCAL_TRAINING=ON \ | |
| ${EXTRA_CMAKE_ARGS} | |
| # Print config and diagnostics with expanded debugging | |
| echo "CMake configuration from cache:" | |
| cat build/CMakeCache.txt | grep -E "AI_FEATURES|LOCAL_TRAINING|DOBBY|NO_DOBBY|LUA|FLAGS|MODULE_PATH" | |
| # Show key variables for debugging | |
| echo "== CMake Module Path ==" | |
| grep CMAKE_MODULE_PATH build/CMakeCache.txt || echo "CMAKE_MODULE_PATH not found in cache" | |
| echo "== Lua Variables ==" | |
| grep -E "LUA_|Lua_" build/CMakeCache.txt || echo "No Lua variables found in cache" | |
| echo "== Linker and Compiler Flags ==" | |
| grep -E "LINKER_FLAGS|C_FLAGS|CXX_FLAGS" build/CMakeCache.txt || echo "No flag variables found in cache" | |
| # List key directories | |
| echo "== Source directory structure ==" | |
| find $GITHUB_WORKSPACE/source/cpp/luau -name "*.h" | head -5 | |
| echo "== CMake directory ==" | |
| ls -la cmake/ | |
| # Build the dynamic library with better error handling | |
| echo "Building the dynamic library now..." | |
| cmake --build build --config Release -j4 || { | |
| echo "======== CMAKE BUILD ERROR ANALYSIS ========" | |
| if [ -f "build/CMakeFiles/CMakeError.log" ]; then | |
| echo "CMakeError.log contents:" | |
| cat build/CMakeFiles/CMakeError.log | |
| fi | |
| echo "======== CMAKE COMPILER TEST LOG ========" | |
| for f in build/CMakeFiles/CMakeTmp/*.log; do | |
| if [ -f "$f" ]; then | |
| echo "Log file: $f" | |
| cat "$f" | |
| fi | |
| done || echo "No compiler test logs found" | |
| echo "======== SOURCE FILE CHECK ========" | |
| echo "Looking for source/lfs.c" | |
| ls -la source/lfs.c || echo "lfs.c not found" | |
| echo "Looking for internal Lua headers in source/cpp/luau" | |
| ls -la source/cpp/luau/*lua*.h || echo "Lua headers not found" | |
| echo "======== BUILD DIRECTORY STRUCTURE ========" | |
| find build -name "CMakeCache.txt" | xargs dirname | xargs ls -la | |
| echo "Failed to build dynamic library" | |
| exit 1 | |
| } | |
| # Set the built library path | |
| echo "OUTPUT_LIB_PATH=${PWD}/lib/libmylibrary.dylib" >> $GITHUB_ENV | |
| - name: Export built library | |
| run: | | |
| echo "Exporting the built library..." | |
| mkdir -p output | |
| # Enhanced export with better error handling and diagnostic info | |
| echo "===== POST-BUILD FILE LOCATION CHECK =====" | |
| echo "Checking lib directory:" | |
| ls -la lib/ || echo "lib directory not found or empty" | |
| echo "Checking build directory for library files:" | |
| find build -name "*.dylib" -o -name "*.a" || echo "No libraries found in build directory" | |
| # Try both paths since the build output might be in different locations | |
| if [ -f "${PWD}/lib/libmylibrary.dylib" ]; then | |
| echo "Found library in lib directory" | |
| cp "${PWD}/lib/libmylibrary.dylib" output/ | |
| elif [ -f "build/libmylibrary.dylib" ]; then | |
| echo "Found library in build root directory" | |
| cp "build/libmylibrary.dylib" output/ | |
| else | |
| # Search for the dylib with more verbose output | |
| echo "Searching for libmylibrary.dylib in entire repository..." | |
| find ${PWD} -name "libmylibrary.dylib" | tee found_libraries.txt | |
| if [ -s found_libraries.txt ]; then | |
| echo "Found libraries, copying to output" | |
| cat found_libraries.txt | xargs -I{} cp {} output/ | |
| else | |
| echo "WARNING: No libraries found, build may have failed" | |
| echo "Checking for partial build artifacts:" | |
| find ${PWD} -name "*.o" | head -5 || echo "No object files found" | |
| fi | |
| fi | |
| # Create and copy AI data directories with enhanced logging | |
| echo "Creating AI data directories in output" | |
| mkdir -p output/Resources/AIData | |
| mkdir -p output/Resources/AIData/LocalModels | |
| mkdir -p output/Resources/AIData/Vulnerabilities | |
| # Create some sample data | |
| echo "{\"version\":\"1.0.0\",\"created\":\"$(date -u '+%Y-%m-%dT%H:%M:%SZ')\"}" > output/Resources/AIData/config.json | |
| - name: Check Build Output | |
| run: | | |
| echo "Checking the build output..." | |
| if [ -f "output/libmylibrary.dylib" ]; then | |
| echo "✅ libmylibrary.dylib exists." | |
| # Show file info | |
| file output/libmylibrary.dylib | |
| # Show architecture info | |
| lipo -info output/libmylibrary.dylib | |
| # Show symbols (filtering for AI-related functions) | |
| nm -g output/libmylibrary.dylib | grep -i "AI" || echo "No AI symbols found" | |
| else | |
| echo "❌ libmylibrary.dylib does not exist." | |
| echo "Files in output directory:" | |
| ls -la output/ | |
| echo "Build directory contents:" | |
| find build -name "*.dylib" -o -name "*.a" | |
| exit 1 # Exit with error if the library does not exist | |
| fi | |
| - name: Generate debug symbols | |
| run: | | |
| echo "Generating debug symbols..." | |
| if [ -f "output/libmylibrary.dylib" ]; then | |
| dsymutil output/libmylibrary.dylib -o output/libmylibrary.dSYM | |
| zip -r output/libmylibrary.dSYM.zip output/libmylibrary.dSYM | |
| fi | |
| - name: Upload dynamic library | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: roblox-executor-ios | |
| path: output/libmylibrary.dylib | |
| if-no-files-found: error | |
| - name: Upload debug symbols | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: debug-symbols | |
| path: output/libmylibrary.dSYM.zip | |
| if-no-files-found: warn | |
| - name: Upload resources | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: resources | |
| path: output/Resources/ | |
| if-no-files-found: warn |