Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ if (${PLATFORM} MATCHES "Web")
endif()
endif()

if (${PLATFORM} MATCHES "Android")
# Wrap fopen at link time so all code (including third-party libs) goes
# through __wrap_fopen, which handles Android APK asset loading
target_link_options(raylib INTERFACE -Wl,--wrap=fopen)
endif()

set_target_properties(raylib PROPERTIES
PUBLIC_HEADER "${raylib_public_headers}"
VERSION ${PROJECT_VERSION}
Expand Down
3 changes: 3 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,9 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
LDFLAGS += -Lsrc
# Avoid unresolved symbol pointing to external main()
LDFLAGS += -Wl,-undefined,dynamic_lookup
# Wrap fopen at link time so all code (including third-party libs) goes
# through __wrap_fopen, which handles Android APK asset loading
LDFLAGS += -Wl,--wrap=fopen
endif

# Define libraries required on linking: LDLIBS
Expand Down
31 changes: 12 additions & 19 deletions src/platforms/rcore_android.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,12 @@ static int android_write(void *cookie, const char *buf, int size);
static fpos_t android_seek(void *cookie, fpos_t offset, int whence);
static int android_close(void *cookie);

FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen() -> Read-only!
FILE *__real_fopen(const char *fileName, const char *mode); // Real fopen, provided by the linker (--wrap=fopen)
FILE *__wrap_fopen(const char *fileName, const char *mode); // Replacement for fopen()

FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int),
fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *));

#define fopen(name, mode) android_fopen(name, mode)

//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
Expand Down Expand Up @@ -1524,25 +1524,20 @@ static void SetupFramebuffer(int width, int height)
}
}

// Replacement for fopen()
// Replacement for fopen(), used as linker wrap entry point (-Wl,--wrap=fopen)
// REF: https://developer.android.com/ndk/reference/group/asset
FILE *android_fopen(const char *fileName, const char *mode)
FILE *__wrap_fopen(const char *fileName, const char *mode)
{
FILE *file = NULL;


// NOTE: AAsset provides access to read-only asset, write operations use regular fopen
if (mode[0] == 'w')
{
// NOTE: fopen() is mapped to android_fopen() that only grants read access to
// assets directory through AAssetManager but it could be required to write data
// using the standard stdio FILE access functions
// REF: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only
#undef fopen
file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
#define fopen(name, mode) android_fopen(name, mode)
file = __real_fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
if (file == NULL) file = __real_fopen(fileName, mode);
}
else
{
// NOTE: AAsset provides access to read-only asset
AAsset *asset = AAssetManager_open(platform.app->activity->assetManager, fileName, AASSET_MODE_UNKNOWN);

if (asset != NULL)
Expand All @@ -1552,14 +1547,12 @@ FILE *android_fopen(const char *fileName, const char *mode)
}
else
{
#undef fopen
// Just do a regular open if file is not found in the assets
file = fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
if (file == NULL) file = fopen(fileName, mode);
#define fopen(name, mode) android_fopen(name, mode)
file = __real_fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
if (file == NULL) file = __real_fopen(fileName, mode);
}
}

return file;
}

Expand Down
5 changes: 0 additions & 5 deletions src/raudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,6 @@ typedef struct tagBITMAPINFOHEADER {
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
#include <string.h> // Required for: strcmp() [Used in IsFileExtension(), LoadWaveFromMemory(), LoadMusicStreamFromMemory()]

#if defined(PLATFORM_ANDROID)
FILE *android_fopen(const char *fileName, const char *mode);
#define fopen(name, mode) android_fopen(name, mode)
#endif

#if defined(RAUDIO_STANDALONE)
#ifndef TRACELOG
#define TRACELOG(level, ...) printf(__VA_ARGS__)
Expand Down
Loading