Add flexible module loading and complete file embedding
- Support any folder structure (no hard-coded folders) - Embed all file types recursively from any folder - Fix require() dot-to-slash conversion for embedded modules - Clean build folder for fresh builds every time - Generate empty headers for Lua-only projects Backward compatible with existing projects.
This commit is contained in:
@@ -97,15 +97,15 @@ if( WIN32 )
|
||||
list( APPEND SOURCES ${CMAKE_SOURCE_DIR}/resources.rc )
|
||||
endif()
|
||||
|
||||
# Embed Lua files if EMBED_MAIN is ON
|
||||
# Embed Lua files if EMBED_MAIN is ON (recursively from all subdirectories)
|
||||
if( EMBED_MAIN )
|
||||
file( GLOB LUA_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.lua" )
|
||||
file( GLOB_RECURSE LUA_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.lua" )
|
||||
if( LUA_FILES )
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/embed_lua.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h ${LUA_FILES}
|
||||
DEPENDS ${LUA_FILES}
|
||||
COMMENT "Embedding Lua files into executable..."
|
||||
COMMENT "Embedding Lua files from all subdirectories into executable..."
|
||||
)
|
||||
list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h )
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_MAIN" )
|
||||
@@ -114,21 +114,60 @@ if( EMBED_MAIN )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Embed asset files if EMBED_ASSETS is ON
|
||||
# Embed all non-Lua data files if EMBED_ASSETS is ON (from all subdirectories except CMake dirs)
|
||||
# Always create embedded_assets.h to prevent compilation errors
|
||||
if( EMBED_ASSETS )
|
||||
file( GLOB_RECURSE ASSET_FILES "${CMAKE_CURRENT_BINARY_DIR}/assets/*" )
|
||||
# Find all non-Lua files recursively, excluding build system files
|
||||
file( GLOB_RECURSE ALL_DATA_FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/*"
|
||||
)
|
||||
# Filter out unwanted files
|
||||
set( ASSET_FILES "" )
|
||||
foreach( FILE_PATH ${ALL_DATA_FILES} )
|
||||
# Exclude: .lua files (handled separately), build artifacts, and CMake files
|
||||
if( NOT FILE_PATH MATCHES "\\.lua$"
|
||||
AND NOT FILE_PATH MATCHES "CMakeFiles"
|
||||
AND NOT FILE_PATH MATCHES "\\.cmake$"
|
||||
AND NOT FILE_PATH MATCHES "CMakeCache"
|
||||
AND NOT FILE_PATH MATCHES "Makefile$"
|
||||
AND NOT FILE_PATH MATCHES "\\.a$"
|
||||
AND NOT FILE_PATH MATCHES "\\.o$"
|
||||
AND NOT FILE_PATH MATCHES "embedded_.*\\.h$"
|
||||
AND NOT FILE_PATH MATCHES "\\.exe$"
|
||||
AND NOT FILE_PATH MATCHES "ReiLua$" )
|
||||
list( APPEND ASSET_FILES ${FILE_PATH} )
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if( ASSET_FILES )
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/embed_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h ${ASSET_FILES}
|
||||
DEPENDS ${ASSET_FILES}
|
||||
COMMENT "Embedding asset files into executable..."
|
||||
COMMENT "Embedding data files from all subdirectories into executable..."
|
||||
)
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" )
|
||||
message( STATUS "Embedding ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h with asset files" )
|
||||
else()
|
||||
# Create empty embedded_assets.h to prevent compilation errors
|
||||
message( STATUS "EMBED_ASSETS is ON but no data files found, creating empty embedded_assets.h" )
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/create_empty_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
|
||||
COMMENT "Creating empty embedded_assets.h (no data files to embed)"
|
||||
)
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" )
|
||||
endif()
|
||||
list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h )
|
||||
else()
|
||||
# EMBED_ASSETS is OFF - create empty header for compatibility
|
||||
message( STATUS "EMBED_ASSETS is OFF, creating empty embedded_assets.h" )
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/create_empty_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h
|
||||
COMMENT "Creating empty embedded_assets.h (EMBED_ASSETS is OFF)"
|
||||
)
|
||||
list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h )
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" )
|
||||
else()
|
||||
message( WARNING "EMBED_ASSETS is ON but no files found in build/assets/ directory!" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_executable( ${PROJECT_NAME} ${SOURCES} )
|
||||
|
||||
@@ -18,60 +18,25 @@ if errorlevel 1 (
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Clean old embedded files (important for dev builds!)
|
||||
echo Cleaning old embedded files...
|
||||
del /Q embedded_main.h embedded_assets.h 2>nul
|
||||
REM ALWAYS clean build folder for fresh build
|
||||
echo Cleaning build directory for fresh build...
|
||||
del /Q /S * >nul 2>&1
|
||||
for /d %%p in (*) do rmdir "%%p" /s /q >nul 2>&1
|
||||
echo * Build directory cleaned
|
||||
echo.
|
||||
|
||||
REM Warn about Lua files in build directory
|
||||
dir /b *.lua >nul 2>&1
|
||||
if not errorlevel 1 (
|
||||
echo.
|
||||
echo WARNING: Found Lua files in build directory!
|
||||
echo Development builds should load from file system, not embed.
|
||||
echo.
|
||||
dir /b *.lua
|
||||
echo.
|
||||
set /p REMOVE="Remove these files from build directory? (Y/n): "
|
||||
if /i not "%REMOVE%"=="n" (
|
||||
del /Q *.lua
|
||||
echo Lua files removed.
|
||||
)
|
||||
echo.
|
||||
)
|
||||
|
||||
REM Warn about assets folder in build directory
|
||||
if exist "assets" (
|
||||
echo.
|
||||
echo WARNING: Found assets folder in build directory!
|
||||
echo Development builds should load from file system, not embed.
|
||||
echo.
|
||||
set /p REMOVE="Remove assets folder from build directory? (Y/n): "
|
||||
if /i not "%REMOVE%"=="n" (
|
||||
rmdir /S /Q assets
|
||||
echo Assets folder removed.
|
||||
)
|
||||
echo.
|
||||
)
|
||||
|
||||
REM Clean old configuration if requested
|
||||
if "%1"=="clean" (
|
||||
echo Cleaning build directory...
|
||||
del /Q CMakeCache.txt *.o *.a 2>nul
|
||||
rmdir /S /Q CMakeFiles 2>nul
|
||||
echo Clean complete!
|
||||
echo.
|
||||
)
|
||||
|
||||
REM Configure with MinGW
|
||||
REM Configure
|
||||
echo Configuring CMake for development...
|
||||
cmake -G "MinGW Makefiles" ..
|
||||
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo ERROR: CMake configuration failed!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Build
|
||||
echo.
|
||||
echo Building ReiLua...
|
||||
mingw32-make
|
||||
@@ -79,6 +44,7 @@ mingw32-make
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo ERROR: Build failed!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
|
||||
@@ -62,49 +62,15 @@ fi
|
||||
mkdir -p build
|
||||
cd build || exit 1
|
||||
|
||||
# Clean old embedded files (important for dev builds!)
|
||||
echo "Cleaning old embedded files..."
|
||||
rm -f embedded_main.h embedded_assets.h
|
||||
|
||||
# Warn about Lua files in build directory
|
||||
LUA_COUNT=$(ls *.lua 2>/dev/null | wc -l)
|
||||
if [ "$LUA_COUNT" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "WARNING: Found Lua files in build directory!"
|
||||
echo "Development builds should load from file system, not embed."
|
||||
echo ""
|
||||
ls -1 *.lua
|
||||
echo ""
|
||||
read -p "Remove these files from build directory? (Y/n): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
rm -f *.lua
|
||||
echo "Lua files removed."
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Warn about assets folder in build directory
|
||||
if [ -d "assets" ]; then
|
||||
echo ""
|
||||
echo "WARNING: Found assets folder in build directory!"
|
||||
echo "Development builds should load from file system, not embed."
|
||||
echo ""
|
||||
read -p "Remove assets folder from build directory? (Y/n): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
rm -rf assets
|
||||
echo "Assets folder removed."
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
# ALWAYS clean build folder for fresh build
|
||||
echo "Cleaning build directory for fresh build..."
|
||||
rm -rf ./* 2>/dev/null
|
||||
echo "✓ Build directory cleaned"
|
||||
echo ""
|
||||
|
||||
# Clean old configuration if requested
|
||||
if [ "$1" == "clean" ]; then
|
||||
echo "Cleaning build directory..."
|
||||
rm -rf CMakeCache.txt CMakeFiles/ *.o *.a
|
||||
echo "Clean complete!"
|
||||
echo ""
|
||||
echo "Extra clean flag detected (already cleaned)"
|
||||
fi
|
||||
|
||||
# Detect platform and set appropriate generator
|
||||
|
||||
@@ -24,21 +24,48 @@ if errorlevel 1 (
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM ALWAYS clean build folder for fresh build
|
||||
echo Cleaning build directory for fresh build...
|
||||
del /Q /S * >nul 2>&1
|
||||
for /d %%p in (*) do rmdir "%%p" /s /q >nul 2>&1
|
||||
echo * Build directory cleaned
|
||||
echo.
|
||||
|
||||
REM Clean old embedded files
|
||||
echo Cleaning old embedded files...
|
||||
echo Ready for fresh build...
|
||||
del /Q embedded_main.h embedded_assets.h 2>nul
|
||||
|
||||
REM Check for Lua files
|
||||
REM Auto-copy from game folder if it exists
|
||||
echo.
|
||||
if exist "..\game" (
|
||||
echo Found game/ folder - auto-copying ALL contents to build...
|
||||
|
||||
REM Copy all files from game folder recursively, excluding LSP files
|
||||
xcopy /E /I /Y /EXCLUDE:..\game\ReiLua_API.lua+..\game\.luarc.json "..\game\*" . >nul 2>&1
|
||||
if exist "..\game\ReiLua_API.lua" del /Q "ReiLua_API.lua" 2>nul
|
||||
if exist "..\game\.luarc.json" del /Q ".luarc.json" 2>nul
|
||||
|
||||
echo * Copied ALL game files and folders
|
||||
echo * All folder structures preserved ^(user-created folders included^)
|
||||
echo.
|
||||
)
|
||||
|
||||
REM Check for Lua files
|
||||
echo Checking for Lua files...
|
||||
dir /b *.lua >nul 2>&1
|
||||
if errorlevel 1 (
|
||||
echo.
|
||||
echo WARNING: No Lua files found in build directory!
|
||||
echo.
|
||||
echo Please copy your Lua files:
|
||||
if exist "..\game" (
|
||||
echo No Lua files found in game/ folder.
|
||||
echo Add your main.lua to game/ folder and try again.
|
||||
) else (
|
||||
echo Tip: Create a game/ folder in project root and add main.lua there.
|
||||
echo Or manually copy files:
|
||||
echo cd build
|
||||
echo copy ..\your_game\*.lua .
|
||||
)
|
||||
echo.
|
||||
set /p CONTINUE="Do you want to continue anyway? (y/N): "
|
||||
if /i not "%CONTINUE%"=="y" exit /b 1
|
||||
@@ -47,24 +74,22 @@ if errorlevel 1 (
|
||||
dir /b *.lua
|
||||
)
|
||||
|
||||
REM Check for assets folder
|
||||
REM Check for non-Lua data files (any folder, any file type)
|
||||
echo.
|
||||
echo Checking for assets...
|
||||
if not exist "assets" (
|
||||
echo.
|
||||
echo WARNING: No assets folder found!
|
||||
echo.
|
||||
echo To embed assets, create the folder and copy files:
|
||||
echo cd build
|
||||
echo mkdir assets
|
||||
echo copy ..\your_game\assets\* assets\
|
||||
echo.
|
||||
set /p CONTINUE="Do you want to continue without assets? (y/N): "
|
||||
if /i not "%CONTINUE%"=="y" exit /b 1
|
||||
set EMBED_ASSETS=OFF
|
||||
) else (
|
||||
echo Found assets folder
|
||||
echo Checking for data files to embed...
|
||||
set DATA_COUNT=0
|
||||
for /r %%f in (*) do (
|
||||
echo %%~nxf | findstr /i /v ".lua .exe .o .a CMake Makefile" >nul
|
||||
if not errorlevel 1 set /a DATA_COUNT+=1
|
||||
)
|
||||
|
||||
if %DATA_COUNT% GTR 0 (
|
||||
echo Found data files to embed
|
||||
echo ^(includes: images, sounds, config, data, and any other files^)
|
||||
set EMBED_ASSETS=ON
|
||||
) else (
|
||||
echo No non-Lua files found ^(only Lua code will be embedded^)
|
||||
set EMBED_ASSETS=OFF
|
||||
)
|
||||
|
||||
echo.
|
||||
@@ -72,7 +97,7 @@ echo ================================
|
||||
echo Build Configuration
|
||||
echo ================================
|
||||
echo Lua Embedding: ON
|
||||
echo Asset Embedding: %EMBED_ASSETS%
|
||||
echo Data Embedding: %EMBED_ASSETS%
|
||||
echo Build Type: Release
|
||||
echo ================================
|
||||
echo.
|
||||
|
||||
@@ -68,38 +68,50 @@ fi
|
||||
mkdir -p build
|
||||
cd build || exit 1
|
||||
|
||||
# ALWAYS clean build folder for fresh build
|
||||
echo "Cleaning build directory for fresh build..."
|
||||
rm -rf ./* 2>/dev/null
|
||||
echo "✓ Build directory cleaned"
|
||||
echo ""
|
||||
|
||||
# Clean old embedded files
|
||||
echo "Cleaning old embedded files..."
|
||||
rm -f embedded_main.h embedded_assets.h
|
||||
echo "Ready for fresh build..."
|
||||
rm -f embedded_main.h embedded_assets.h 2>/dev/null
|
||||
|
||||
# Auto-copy from game folder if it exists
|
||||
echo ""
|
||||
if [ -d "../game" ]; then
|
||||
echo "Found game/ folder - auto-copying contents to build..."
|
||||
echo "Found game/ folder - auto-copying ALL contents to build..."
|
||||
|
||||
# Copy all Lua files from game folder EXCEPT ReiLua_API.lua
|
||||
if ls ../game/*.lua 1> /dev/null 2>&1; then
|
||||
for lua_file in ../game/*.lua; do
|
||||
filename=$(basename "$lua_file")
|
||||
if [ "$filename" != "ReiLua_API.lua" ]; then
|
||||
cp "$lua_file" .
|
||||
fi
|
||||
done
|
||||
LUA_COUNT=$(ls *.lua 2>/dev/null | wc -l)
|
||||
echo " ✓ Copied $LUA_COUNT Lua file(s)"
|
||||
# Copy everything from game folder recursively, excluding:
|
||||
# - ReiLua_API.lua (LSP only)
|
||||
# - .luarc.json (LSP config)
|
||||
# - .DS_Store (macOS)
|
||||
# - Hidden files starting with . (except .gitkeep if present)
|
||||
|
||||
# Use rsync if available for better copying, otherwise use cp
|
||||
if command -v rsync &> /dev/null; then
|
||||
rsync -av --exclude='ReiLua_API.lua' --exclude='.luarc.json' --exclude='.DS_Store' --exclude='.*' --include='.gitkeep' ../game/ . 2>/dev/null
|
||||
else
|
||||
echo " ⚠ No Lua files found in game/"
|
||||
# Fallback to find + cp - Copy ALL files and directories
|
||||
(cd ../game && find . -type f \
|
||||
! -name 'ReiLua_API.lua' \
|
||||
! -name '.luarc.json' \
|
||||
! -name '.DS_Store' \
|
||||
! -path '*/\.*' -o -name '.gitkeep' \
|
||||
-exec sh -c 'mkdir -p "../build/$(dirname "{}")" && cp -p "{}" "../build/{}"' \; 2>/dev/null)
|
||||
fi
|
||||
|
||||
# Copy assets folder if it exists
|
||||
if [ -d "../game/assets" ]; then
|
||||
rm -rf assets
|
||||
cp -r ../game/assets .
|
||||
ASSET_COUNT=$(find assets -type f 2>/dev/null | wc -l)
|
||||
echo " ✓ Copied assets/ ($ASSET_COUNT files)"
|
||||
else
|
||||
echo " ℹ No assets folder in game/"
|
||||
fi
|
||||
# Count what was copied
|
||||
LUA_COUNT=$(find . -maxdepth 10 -name "*.lua" -type f 2>/dev/null | wc -l)
|
||||
ASSET_COUNT=$(find assets -type f 2>/dev/null | wc -l || echo "0")
|
||||
TOTAL_FILES=$(find . -type f ! -path './CMakeFiles/*' ! -path './.cmake/*' ! -name 'CMake*' ! -name '*.a' ! -name '*.o' 2>/dev/null | wc -l)
|
||||
|
||||
echo " ✓ Copied ALL game files and folders:"
|
||||
echo " - $LUA_COUNT Lua file(s) (including all subdirectories)"
|
||||
echo " - $ASSET_COUNT Asset file(s) (if assets folder exists)"
|
||||
echo " - $TOTAL_FILES total file(s)"
|
||||
echo " - All folder structures preserved (user-created folders included)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
@@ -131,34 +143,18 @@ else
|
||||
ls -1 *.lua
|
||||
fi
|
||||
|
||||
# Check for assets folder
|
||||
# Check for non-Lua data files (any folder, any file type)
|
||||
echo ""
|
||||
echo "Checking for assets..."
|
||||
if [ ! -d "assets" ]; then
|
||||
echo ""
|
||||
echo "WARNING: No assets folder found!"
|
||||
echo ""
|
||||
if [ -d "../game" ]; then
|
||||
echo "No assets found in game/assets/ folder."
|
||||
echo "Add assets to game/assets/ if you need them embedded."
|
||||
else
|
||||
echo "Tip: Create game/assets/ in project root for auto-copy."
|
||||
echo "Or manually:"
|
||||
echo " cd build"
|
||||
echo " mkdir assets"
|
||||
echo " cp ../your_game/assets/* assets/"
|
||||
fi
|
||||
echo ""
|
||||
read -p "Do you want to continue without assets? (y/N): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
EMBED_ASSETS="OFF"
|
||||
else
|
||||
ASSET_FILES=$(find assets -type f 2>/dev/null | wc -l)
|
||||
echo "Found $ASSET_FILES asset file(s) in assets folder"
|
||||
echo "Checking for data files to embed..."
|
||||
NON_LUA_FILES=$(find . -type f ! -name "*.lua" ! -path "./CMakeFiles/*" ! -path "./.cmake/*" ! -name "CMake*" ! -name "Makefile*" ! -name "*.o" ! -name "*.a" 2>/dev/null | wc -l)
|
||||
|
||||
if [ "$NON_LUA_FILES" -gt 0 ]; then
|
||||
echo "Found $NON_LUA_FILES non-Lua file(s) to embed"
|
||||
echo " (includes: images, sounds, config, data, and any other files)"
|
||||
EMBED_ASSETS="ON"
|
||||
else
|
||||
echo "No non-Lua files found (only Lua code will be embedded)"
|
||||
EMBED_ASSETS="OFF"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -166,7 +162,7 @@ echo "================================"
|
||||
echo "Build Configuration"
|
||||
echo "================================"
|
||||
echo "Lua Embedding: ON"
|
||||
echo "Asset Embedding: $EMBED_ASSETS"
|
||||
echo "Data Embedding: $EMBED_ASSETS"
|
||||
echo "Build Type: Release"
|
||||
echo "================================"
|
||||
echo ""
|
||||
|
||||
24
scripts/create_empty_assets.py
Normal file
24
scripts/create_empty_assets.py
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create an empty embedded_assets.h file for compatibility.
|
||||
Usage: python create_empty_assets.py <output.h>
|
||||
"""
|
||||
import sys
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print('Usage: python create_empty_assets.py <output.h>')
|
||||
sys.exit(1)
|
||||
|
||||
output_file = sys.argv[1]
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
f.write('#ifndef EMBEDDED_ASSETS_H\n')
|
||||
f.write('#define EMBEDDED_ASSETS_H\n')
|
||||
f.write('/* No assets to embed */\n')
|
||||
f.write('typedef struct { const char* name; const unsigned char* data; unsigned int size; } EmbeddedAsset;\n')
|
||||
f.write('static const EmbeddedAsset embedded_assets[] = {};\n')
|
||||
f.write('static const int embedded_asset_count = 0;\n')
|
||||
f.write('#endif\n')
|
||||
|
||||
print(f'Created empty {output_file}')
|
||||
@@ -40,17 +40,18 @@ def embed_files(output_file, input_files):
|
||||
data = inf.read()
|
||||
|
||||
var_name = sanitize_name(input_file)
|
||||
# Extract relative path from 'assets/' onwards if present
|
||||
if 'assets' in input_file.replace('\\', '/'):
|
||||
parts = input_file.replace('\\', '/').split('assets/')
|
||||
# Extract relative path from build directory
|
||||
relative_name = input_file
|
||||
for prefix in ['build/', 'build\\']:
|
||||
if prefix in input_file:
|
||||
parts = input_file.split(prefix, 1)
|
||||
if len(parts) > 1:
|
||||
relative_name = 'assets/' + parts[-1]
|
||||
else:
|
||||
relative_name = os.path.basename(input_file)
|
||||
else:
|
||||
relative_name = os.path.basename(input_file)
|
||||
relative_name = parts[1]
|
||||
break
|
||||
# Normalize path separators
|
||||
relative_name = relative_name.replace('\\', '/')
|
||||
|
||||
f.write(f'/* Embedded asset: {input_file} ({len(data)} bytes) */\n')
|
||||
f.write(f'/* Embedded file: {relative_name} ({len(data)} bytes) */\n')
|
||||
f.write(f'static const unsigned char embedded_asset_{idx}_{var_name}[] = {{\n')
|
||||
|
||||
for i, byte in enumerate(data):
|
||||
@@ -78,15 +79,16 @@ def embed_files(output_file, input_files):
|
||||
f.write('static const EmbeddedAsset embedded_assets[] = {\n')
|
||||
for idx, input_file in enumerate(input_files):
|
||||
var_name = sanitize_name(input_file)
|
||||
# Extract relative path from 'assets/' onwards if present
|
||||
if 'assets' in input_file.replace('\\', '/'):
|
||||
parts = input_file.replace('\\', '/').split('assets/')
|
||||
# Extract relative path from build directory
|
||||
relative_name = input_file
|
||||
for prefix in ['build/', 'build\\']:
|
||||
if prefix in input_file:
|
||||
parts = input_file.split(prefix, 1)
|
||||
if len(parts) > 1:
|
||||
relative_name = 'assets/' + parts[-1]
|
||||
else:
|
||||
relative_name = os.path.basename(input_file)
|
||||
else:
|
||||
relative_name = os.path.basename(input_file)
|
||||
relative_name = parts[1]
|
||||
break
|
||||
# Normalize path separators
|
||||
relative_name = relative_name.replace('\\', '/')
|
||||
f.write(f' {{ "{relative_name}", embedded_asset_{idx}_{var_name}, embedded_asset_{idx}_{var_name}_len }},\n')
|
||||
f.write('};\n\n')
|
||||
|
||||
|
||||
@@ -27,7 +27,17 @@ def embed_files(output_file, input_files):
|
||||
data = inf.read()
|
||||
|
||||
var_name = sanitize_name(input_file)
|
||||
f.write(f'/* Embedded file: {input_file} */\n')
|
||||
# Get relative path for better module loading
|
||||
# Try to extract path relative to common directories
|
||||
relative_name = input_file
|
||||
for prefix in ['build/', 'build\\']:
|
||||
if prefix in input_file:
|
||||
parts = input_file.split(prefix, 1)
|
||||
if len(parts) > 1:
|
||||
relative_name = parts[1]
|
||||
break
|
||||
|
||||
f.write(f'/* Embedded file: {relative_name} */\n')
|
||||
f.write(f'static const unsigned char embedded_lua_{idx}_{var_name}[] = {{\n')
|
||||
|
||||
for i, byte in enumerate(data):
|
||||
@@ -55,18 +65,32 @@ def embed_files(output_file, input_files):
|
||||
f.write('static const EmbeddedLuaFile embedded_lua_files[] = {\n')
|
||||
for idx, input_file in enumerate(input_files):
|
||||
var_name = sanitize_name(input_file)
|
||||
# Store both original filename and basename for require compatibility
|
||||
basename = os.path.basename(input_file)
|
||||
f.write(f' {{ "{basename}", embedded_lua_{idx}_{var_name}, embedded_lua_{idx}_{var_name}_len }},\n')
|
||||
# Store relative path for proper require() support
|
||||
relative_name = input_file
|
||||
for prefix in ['build/', 'build\\']:
|
||||
if prefix in input_file:
|
||||
parts = input_file.split(prefix, 1)
|
||||
if len(parts) > 1:
|
||||
relative_name = parts[1]
|
||||
break
|
||||
# Normalize path separators
|
||||
relative_name = relative_name.replace('\\', '/')
|
||||
f.write(f' {{ "{relative_name}", embedded_lua_{idx}_{var_name}, embedded_lua_{idx}_{var_name}_len }},\n')
|
||||
f.write('};\n\n')
|
||||
|
||||
f.write(f'static const int embedded_lua_file_count = {len(input_files)};\n\n')
|
||||
|
||||
# Main entry point (first file)
|
||||
var_name = sanitize_name(input_files[0])
|
||||
# Main entry point (first file with 'main.lua' in name, or first file)
|
||||
main_idx = 0
|
||||
for idx, input_file in enumerate(input_files):
|
||||
if 'main.lua' in input_file.lower():
|
||||
main_idx = idx
|
||||
break
|
||||
|
||||
var_name = sanitize_name(input_files[main_idx])
|
||||
f.write('/* Main entry point */\n')
|
||||
f.write(f'#define embedded_main_lua embedded_lua_0_{var_name}\n')
|
||||
f.write(f'#define embedded_main_lua_len embedded_lua_0_{var_name}_len\n\n')
|
||||
f.write(f'#define embedded_main_lua embedded_lua_{main_idx}_{var_name}\n')
|
||||
f.write(f'#define embedded_main_lua_len embedded_lua_{main_idx}_{var_name}_len\n\n')
|
||||
|
||||
f.write('#endif /* EMBEDDED_MAIN_H */\n')
|
||||
|
||||
|
||||
@@ -124,16 +124,31 @@ static int embedded_lua_loader( lua_State* L ) {
|
||||
const char* name = lua_tostring( L, 1 );
|
||||
if ( name == NULL ) return 0;
|
||||
|
||||
/* Convert module name dots to slashes (e.g., "lib.gamestate" -> "lib/gamestate") */
|
||||
char converted_name[512];
|
||||
strncpy( converted_name, name, sizeof(converted_name) - 1 );
|
||||
converted_name[sizeof(converted_name) - 1] = '\0';
|
||||
for ( char* p = converted_name; *p; p++ ) {
|
||||
if ( *p == '.' ) *p = '/';
|
||||
}
|
||||
|
||||
/* Try both converted name and original name */
|
||||
const char* names_to_try[] = { converted_name, name };
|
||||
|
||||
for ( int n = 0; n < 2; n++ ) {
|
||||
const char* try_name = names_to_try[n];
|
||||
|
||||
for ( int i = 0; i < embedded_lua_file_count; i++ ) {
|
||||
const EmbeddedLuaFile* file = &embedded_lua_files[i];
|
||||
|
||||
const char* basename = file->name;
|
||||
size_t name_len = strlen( name );
|
||||
size_t name_len = strlen( try_name );
|
||||
size_t base_len = strlen( basename );
|
||||
|
||||
if ( strcmp( basename, name ) == 0 ||
|
||||
/* Match exactly, or match without .lua extension */
|
||||
if ( strcmp( basename, try_name ) == 0 ||
|
||||
( base_len > 4 && strcmp( basename + base_len - 4, ".lua" ) == 0 &&
|
||||
strncmp( basename, name, base_len - 4 ) == 0 && name_len == base_len - 4 ) ) {
|
||||
strncmp( basename, try_name, base_len - 4 ) == 0 && name_len == base_len - 4 ) ) {
|
||||
|
||||
if ( luaL_loadbuffer( L, (const char*)file->data, file->size, file->name ) == 0 ) {
|
||||
return 1;
|
||||
@@ -144,6 +159,7 @@ static int embedded_lua_loader( lua_State* L ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushfstring( L, "\n\tno embedded file '%s'", name );
|
||||
return 1;
|
||||
@@ -1530,6 +1546,25 @@ bool luaInit( int argn, const char** argc ) {
|
||||
TraceLog( LOG_WARNING, "%s", "Failed to init Lua" );
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Configure package.path to include basePath and all subdirectories */
|
||||
if ( state->basePath != NULL && strlen( state->basePath ) > 0 ) {
|
||||
lua_getglobal( L, "package" );
|
||||
lua_getfield( L, -1, "path" );
|
||||
const char* currentPath = lua_tostring( L, -1 );
|
||||
lua_pop( L, 1 );
|
||||
|
||||
/* Add basePath and recursive subdirectory patterns for flexible module loading */
|
||||
char newPath[STRING_LEN * 4];
|
||||
snprintf( newPath, sizeof(newPath),
|
||||
"%s?.lua;%s?/init.lua;%s?/?.lua;%s?/?/init.lua;%s",
|
||||
state->basePath, state->basePath, state->basePath, state->basePath, currentPath );
|
||||
|
||||
lua_pushstring( L, newPath );
|
||||
lua_setfield( L, -2, "path" );
|
||||
lua_pop( L, 1 );
|
||||
}
|
||||
|
||||
/* Define object types. */
|
||||
defineBuffer();
|
||||
defineImage();
|
||||
|
||||
Reference in New Issue
Block a user