Android NDK SDL_RW-specific functions cause 'undefined reference'

On SDL 2.0.10 and using the NDK (21.0.5935234), I’m having trouble with the linker finding SDL_RWseek and SDL_RWread. All other non-RW SDL functions are working fine, so I’m thinking I’m not including a library or file correctly that the RW functions use. Since the same functions link fine in VS2019 Preview, is there an Android library I don’t know about that I need to include in a mkfile or in the source file? (Android Studio sees the definitions of the RW functions, but the the linker can’t find them.)

Snippets of the two relevant mk files followed by an example cpp file:

main mkfile

include $(SRC)/…/sdl2/Android.mk
include $(SRC)/start/android.mk
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv3 -landroid
LOCAL_SHARED_LIBRARIES := SDL2

LOCAL_WHOLE_STATIC_LIBRARIES += libstart

include $(BUILD_SHARED_LIBRARY)

start mkfile

include $(CLEAR_VARS)

LOCAL_MODULE := libstart

LOCAL_MODULE_FILENAME := libstart

LOCAL_C_INCLUDES :=
$(call INCLUDE_PATH)
$(call TOOLS_PATH)

LOCAL_SHARED_LIBRARIES := SDL2

LOCAL_SRC_FILES +=
$(SRC_START_FILES)/android.cpp
$(SRC)/…/sdl2/src/file/SDL_rwops.c
$(SRC)/…/sdl2/src/SDL.c

include $(BUILD_STATIC_LIBRARY)

android.cpp

#include <sdl2/SDL.h>
#include <sdl2/SDL_rwops.h>
#include <jni.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

namespace {
void readFile() {
auto* file = SDL_RWFromFile(“sourcefile”, “r”); // this compiles
SDL_RWops test; // this compiles
SDL_RWread(nullptr, nullptr, 0, 0); // “undefined reference to ‘SDL_RWread’”
}
}

Thanks!

These are macros, not functions. You must either #include the relevant header file which defines the macros, or call the functions via their pointers in the SDL_RWops structure (context->seek and context->read respectively).

Thanks for the fast reply! That makes sense about the macro. I see the note now in the documentation: “SDL_RWread() is actually a macro that calls the SDL_RWops’s read method appropriately, to simplify application development.”

I’m sure this is going to make me feel dumb, but in the former option when you say I have to include the relevant header, which header is that? Do you mean that there isn’t a header in the Android version of the library that defines the macros? Rather, I can define the macros myself as basically a passthrough to SDL_RWops’s functions if I don’t need them to do more than that? (Or I can, like you said, just call the functions through the SDL_RWops structure.)

I’m used to the Windows version where I just include SDL.h and everything works.

Specifically, I’m trying to read files from the assets directory. The code I’ve found from here and StackOverflow uses SDL_RWread() without any trouble, so it’s frustrating me that I can’t get it to work.

The macros are defined in SDL_rwops.h which seemingly you are including. You may need to investigate why the compiler is not picking up those definitions (I’m not a C++ programmer so can’t help with that).

Ah. That makes me feel less stupid then.

I’ll keep looking through the SDL source to see what’s going on. I’m guessing something’s #define’d on the Windows side that isn’t #define’d on the Android side, but VS isn’t helping me find where the Windows macro is going, so I’m back to searching through it with Notepad++.

I’ll post here again with the answer if it’s something important. Thanks again for all your help!

Those macros have turned into functions recently, see https://hg.libsdl.org/SDL/rev/302904fa669a
SDL 2.0.10 should be the first release with this change.

So probably your headers are newer than the lib you’re linking against.

Really great community. Thanks for the extra info, Daniel! SDL’s a lifesaver.

I saw that in SDL_rwops.c but I don’t know why the linker isn’t picking it up. I’ve even tried adding SDL_RWops.c to LOCAL_SRC_FILES in my mkfile but it keeps giving me the same error. I’ve even switched to the direct path to SDL2-2.0.10\include in the mkfile in case it was an issue with the symbolic link–same problem.

I know it compiles successfully in VS for Windows, so the Windows version of the library is definitely working. Going to try one thing.

That was exactly it. The symbolic link I was using for the SDL mkfile was pointing to 2.0.9 while the include directory was in 2.0.10.

Everything compiles now. Thank you both very much! (And yes, now I do feel dumb.)