Optionally link libopenal at compile time

In Linux distributions, having the executable depend on the right
libraries and arrange for them to be installed is straightforward,
and there's a lot of infrastructure for tracking which library
version a particular executable needs, including making sure we have
a version that contains all of the symbols that were used. Loading
libopenal at runtime defeats that infrastructure.

The ability to substitute a different-but-compatible libopenal,
or operate with reduced functionality without libopenal, might
still be desirable for generic/portable binary releases.

The CMake build system already linked the executable to
${OPENAL_LIBRARY} anyway, so it is already a hard dependency in that
build system.
This commit is contained in:
Simon McVittie 2016-06-30 09:41:57 +01:00
parent 6d38cc8609
commit 5887a9e79e
3 changed files with 138 additions and 101 deletions

View file

@ -44,6 +44,12 @@ WITH_OGG:=yes
# installed # installed
WITH_OPENAL:=yes WITH_OPENAL:=yes
# Enables optional runtime loading of OpenAL (dlopen
# or similar).
# If set to "no", the library is linked in at compile
# time in the normal way.
DLOPEN_OPENAL:=yes
# Use SDL2 instead of SDL1.2. Disables CD audio support, # Use SDL2 instead of SDL1.2. Disables CD audio support,
# because SDL2 has none. Use OGG/Vorbis music instead :-) # because SDL2 has none. Use OGG/Vorbis music instead :-)
# On Windows sdl-config isn't used, so make sure that # On Windows sdl-config isn't used, so make sure that
@ -398,15 +404,20 @@ release/quake2 : LDFLAGS += -lvorbis -lvorbisfile -logg
endif endif
ifeq ($(WITH_OPENAL),yes) ifeq ($(WITH_OPENAL),yes)
ifeq ($(DLOPEN_OPENAL),yes)
ifeq ($(OSTYPE), OpenBSD) ifeq ($(OSTYPE), OpenBSD)
release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.so"' release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.so"' -DDLOPEN_OPENAL
else ifeq ($(OSTYPE), Darwin) else ifeq ($(OSTYPE), Darwin)
release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.dylib"' -I/usr/local/opt/openal-soft/include release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.dylib"' -I/usr/local/opt/openal-soft/include
release/quake2 : LDFLAGS += -L/usr/local/opt/openal-soft/lib release/quake2 : LDFLAGS += -L/usr/local/opt/openal-soft/lib
else else
release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.so.1"' release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.so.1"' -DDLOPEN_OPENAL
endif
endif endif
else # !DLOPEN_OPENAL
release/quake2 : CFLAGS += -DUSE_OPENAL
release/quake2 : LDFLAGS += -lopenal
endif # !DLOPEN_OPENAL
endif # WITH_OPENAL
ifeq ($(WITH_ZIP),yes) ifeq ($(WITH_ZIP),yes)
release/quake2 : CFLAGS += -DZIP -DNOUNCRYPT release/quake2 : CFLAGS += -DZIP -DNOUNCRYPT

View file

@ -43,7 +43,9 @@
static ALCcontext *context; static ALCcontext *context;
static ALCdevice *device; static ALCdevice *device;
static cvar_t *al_device; static cvar_t *al_device;
#ifdef DLOPEN_OPENAL
static cvar_t *al_driver; static cvar_t *al_driver;
#endif
static void *handle; static void *handle;
/* Function pointers for OpenAL management */ /* Function pointers for OpenAL management */
@ -322,9 +324,12 @@ QAL_Shutdown()
qalFilterf = NULL; qalFilterf = NULL;
qalDeleteFilters = NULL; qalDeleteFilters = NULL;
if (handle)
{
/* Unload the shared lib */ /* Unload the shared lib */
Sys_FreeLibrary(handle); Sys_FreeLibrary(handle);
handle = NULL; handle = NULL;
}
} }
/* /*
@ -334,9 +339,11 @@ QAL_Shutdown()
qboolean qboolean
QAL_Init() QAL_Init()
{ {
al_device = Cvar_Get("al_device", "", CVAR_ARCHIVE);
#ifdef DLOPEN_OPENAL
/* DEFAULT_OPENAL_DRIVER is defined at compile time via the compiler */ /* DEFAULT_OPENAL_DRIVER is defined at compile time via the compiler */
al_driver = Cvar_Get("al_driver", DEFAULT_OPENAL_DRIVER, CVAR_ARCHIVE); al_driver = Cvar_Get("al_driver", DEFAULT_OPENAL_DRIVER, CVAR_ARCHIVE);
al_device = Cvar_Get("al_device", "", CVAR_ARCHIVE);
Com_Printf("LoadLibrary(%s)\n", al_driver->string); Com_Printf("LoadLibrary(%s)\n", al_driver->string);
@ -348,104 +355,109 @@ QAL_Init()
Com_Printf("Loading %s failed! Disabling OpenAL.\n", al_driver->string); Com_Printf("Loading %s failed! Disabling OpenAL.\n", al_driver->string);
return false; return false;
} }
# define ALSYMBOL(handle, sym) Sys_GetProcAddress(handle, #sym)
#else
handle = NULL;
# define ALSYMBOL(handle, sym) sym
#endif
/* Connect function pointers to management functions */ /* Connect function pointers to management functions */
qalcCreateContext = Sys_GetProcAddress(handle, "alcCreateContext"); qalcCreateContext = ALSYMBOL(handle, alcCreateContext);
qalcMakeContextCurrent = Sys_GetProcAddress(handle, "alcMakeContextCurrent"); qalcMakeContextCurrent = ALSYMBOL(handle, alcMakeContextCurrent);
qalcProcessContext = Sys_GetProcAddress(handle, "alcProcessContext"); qalcProcessContext = ALSYMBOL(handle, alcProcessContext);
qalcSuspendContext = Sys_GetProcAddress(handle, "alcSuspendContext"); qalcSuspendContext = ALSYMBOL(handle, alcSuspendContext);
qalcDestroyContext = Sys_GetProcAddress(handle, "alcDestroyContext"); qalcDestroyContext = ALSYMBOL(handle, alcDestroyContext);
qalcGetCurrentContext = Sys_GetProcAddress(handle, "alcGetCurrentContext"); qalcGetCurrentContext = ALSYMBOL(handle, alcGetCurrentContext);
qalcGetContextsDevice = Sys_GetProcAddress(handle, "alcGetContextsDevice"); qalcGetContextsDevice = ALSYMBOL(handle, alcGetContextsDevice);
qalcOpenDevice = Sys_GetProcAddress(handle, "alcOpenDevice"); qalcOpenDevice = ALSYMBOL(handle, alcOpenDevice);
qalcCloseDevice = Sys_GetProcAddress(handle, "alcCloseDevice"); qalcCloseDevice = ALSYMBOL(handle, alcCloseDevice);
qalcGetError = Sys_GetProcAddress(handle, "alcGetError"); qalcGetError = ALSYMBOL(handle, alcGetError);
qalcIsExtensionPresent = Sys_GetProcAddress(handle, "alcIsExtensionPresent"); qalcIsExtensionPresent = ALSYMBOL(handle, alcIsExtensionPresent);
qalcGetProcAddress = Sys_GetProcAddress(handle, "alcGetProcAddress"); qalcGetProcAddress = ALSYMBOL(handle, alcGetProcAddress);
qalcGetEnumValue = Sys_GetProcAddress(handle, "alcGetEnumValue"); qalcGetEnumValue = ALSYMBOL(handle, alcGetEnumValue);
qalcGetString = Sys_GetProcAddress(handle, "alcGetString"); qalcGetString = ALSYMBOL(handle, alcGetString);
qalcGetIntegerv = Sys_GetProcAddress(handle, "alcGetIntegerv"); qalcGetIntegerv = ALSYMBOL(handle, alcGetIntegerv);
qalcCaptureOpenDevice = Sys_GetProcAddress(handle, "alcCaptureOpenDevice"); qalcCaptureOpenDevice = ALSYMBOL(handle, alcCaptureOpenDevice);
qalcCaptureCloseDevice = Sys_GetProcAddress(handle, "alcCaptureCloseDevice"); qalcCaptureCloseDevice = ALSYMBOL(handle, alcCaptureCloseDevice);
qalcCaptureStart = Sys_GetProcAddress(handle, "alcCaptureStart"); qalcCaptureStart = ALSYMBOL(handle, alcCaptureStart);
qalcCaptureStop = Sys_GetProcAddress(handle, "alcCaptureStop"); qalcCaptureStop = ALSYMBOL(handle, alcCaptureStop);
qalcCaptureSamples = Sys_GetProcAddress(handle, "alcCaptureSamples"); qalcCaptureSamples = ALSYMBOL(handle, alcCaptureSamples);
/* Connect function pointers to /* Connect function pointers to
to OpenAL API functions */ to OpenAL API functions */
qalEnable = Sys_GetProcAddress(handle, "alEnable"); qalEnable = ALSYMBOL(handle, alEnable);
qalDisable = Sys_GetProcAddress(handle, "alDisable"); qalDisable = ALSYMBOL(handle, alDisable);
qalIsEnabled = Sys_GetProcAddress(handle, "alIsEnabled"); qalIsEnabled = ALSYMBOL(handle, alIsEnabled);
qalGetString = Sys_GetProcAddress(handle, "alGetString"); qalGetString = ALSYMBOL(handle, alGetString);
qalGetBooleanv = Sys_GetProcAddress(handle, "alGetBooleanv"); qalGetBooleanv = ALSYMBOL(handle, alGetBooleanv);
qalGetIntegerv = Sys_GetProcAddress(handle, "alGetIntegerv"); qalGetIntegerv = ALSYMBOL(handle, alGetIntegerv);
qalGetFloatv = Sys_GetProcAddress(handle, "alGetFloatv"); qalGetFloatv = ALSYMBOL(handle, alGetFloatv);
qalGetDoublev = Sys_GetProcAddress(handle, "alGetDoublev"); qalGetDoublev = ALSYMBOL(handle, alGetDoublev);
qalGetBoolean = Sys_GetProcAddress(handle, "alGetBoolean"); qalGetBoolean = ALSYMBOL(handle, alGetBoolean);
qalGetInteger = Sys_GetProcAddress(handle, "alGetInteger"); qalGetInteger = ALSYMBOL(handle, alGetInteger);
qalGetFloat = Sys_GetProcAddress(handle, "alGetFloat"); qalGetFloat = ALSYMBOL(handle, alGetFloat);
qalGetDouble = Sys_GetProcAddress(handle, "alGetDouble"); qalGetDouble = ALSYMBOL(handle, alGetDouble);
qalGetError = Sys_GetProcAddress(handle, "alGetError"); qalGetError = ALSYMBOL(handle, alGetError);
qalIsExtensionPresent = Sys_GetProcAddress(handle, "alIsExtensionPresent"); qalIsExtensionPresent = ALSYMBOL(handle, alIsExtensionPresent);
qalGetProcAddress = Sys_GetProcAddress(handle, "alGetProcAddress"); qalGetProcAddress = ALSYMBOL(handle, alGetProcAddress);
qalGetEnumValue = Sys_GetProcAddress(handle, "alGetEnumValue"); qalGetEnumValue = ALSYMBOL(handle, alGetEnumValue);
qalListenerf = Sys_GetProcAddress(handle, "alListenerf"); qalListenerf = ALSYMBOL(handle, alListenerf);
qalListener3f = Sys_GetProcAddress(handle, "alListener3f"); qalListener3f = ALSYMBOL(handle, alListener3f);
qalListenerfv = Sys_GetProcAddress(handle, "alListenerfv"); qalListenerfv = ALSYMBOL(handle, alListenerfv);
qalListeneri = Sys_GetProcAddress(handle, "alListeneri"); qalListeneri = ALSYMBOL(handle, alListeneri);
qalListener3i = Sys_GetProcAddress(handle, "alListener3i"); qalListener3i = ALSYMBOL(handle, alListener3i);
qalListeneriv = Sys_GetProcAddress(handle, "alListeneriv"); qalListeneriv = ALSYMBOL(handle, alListeneriv);
qalGetListenerf = Sys_GetProcAddress(handle, "alGetListenerf"); qalGetListenerf = ALSYMBOL(handle, alGetListenerf);
qalGetListener3f = Sys_GetProcAddress(handle, "alGetListener3f"); qalGetListener3f = ALSYMBOL(handle, alGetListener3f);
qalGetListenerfv = Sys_GetProcAddress(handle, "alGetListenerfv"); qalGetListenerfv = ALSYMBOL(handle, alGetListenerfv);
qalGetListeneri = Sys_GetProcAddress(handle, "alGetListeneri"); qalGetListeneri = ALSYMBOL(handle, alGetListeneri);
qalGetListener3i = Sys_GetProcAddress(handle, "alGetListener3i"); qalGetListener3i = ALSYMBOL(handle, alGetListener3i);
qalGetListeneriv = Sys_GetProcAddress(handle, "alGetListeneriv"); qalGetListeneriv = ALSYMBOL(handle, alGetListeneriv);
qalGenSources = Sys_GetProcAddress(handle, "alGenSources"); qalGenSources = ALSYMBOL(handle, alGenSources);
qalDeleteSources = Sys_GetProcAddress(handle, "alDeleteSources"); qalDeleteSources = ALSYMBOL(handle, alDeleteSources);
qalIsSource = Sys_GetProcAddress(handle, "alIsSource"); qalIsSource = ALSYMBOL(handle, alIsSource);
qalSourcef = Sys_GetProcAddress(handle, "alSourcef"); qalSourcef = ALSYMBOL(handle, alSourcef);
qalSource3f = Sys_GetProcAddress(handle, "alSource3f"); qalSource3f = ALSYMBOL(handle, alSource3f);
qalSourcefv = Sys_GetProcAddress(handle, "alSourcefv"); qalSourcefv = ALSYMBOL(handle, alSourcefv);
qalSourcei = Sys_GetProcAddress(handle, "alSourcei"); qalSourcei = ALSYMBOL(handle, alSourcei);
qalSource3i = Sys_GetProcAddress(handle, "alSource3i"); qalSource3i = ALSYMBOL(handle, alSource3i);
qalSourceiv = Sys_GetProcAddress(handle, "alSourceiv"); qalSourceiv = ALSYMBOL(handle, alSourceiv);
qalGetSourcef = Sys_GetProcAddress(handle, "alGetSourcef"); qalGetSourcef = ALSYMBOL(handle, alGetSourcef);
qalGetSource3f = Sys_GetProcAddress(handle, "alGetSource3f"); qalGetSource3f = ALSYMBOL(handle, alGetSource3f);
qalGetSourcefv = Sys_GetProcAddress(handle, "alGetSourcefv"); qalGetSourcefv = ALSYMBOL(handle, alGetSourcefv);
qalGetSourcei = Sys_GetProcAddress(handle, "alGetSourcei"); qalGetSourcei = ALSYMBOL(handle, alGetSourcei);
qalGetSource3i = Sys_GetProcAddress(handle, "alGetSource3i"); qalGetSource3i = ALSYMBOL(handle, alGetSource3i);
qalGetSourceiv = Sys_GetProcAddress(handle, "alGetSourceiv"); qalGetSourceiv = ALSYMBOL(handle, alGetSourceiv);
qalSourcePlayv = Sys_GetProcAddress(handle, "alSourcePlayv"); qalSourcePlayv = ALSYMBOL(handle, alSourcePlayv);
qalSourceStopv = Sys_GetProcAddress(handle, "alSourceStopv"); qalSourceStopv = ALSYMBOL(handle, alSourceStopv);
qalSourceRewindv = Sys_GetProcAddress(handle, "alSourceRewindv"); qalSourceRewindv = ALSYMBOL(handle, alSourceRewindv);
qalSourcePausev = Sys_GetProcAddress(handle, "alSourcePausev"); qalSourcePausev = ALSYMBOL(handle, alSourcePausev);
qalSourcePlay = Sys_GetProcAddress(handle, "alSourcePlay"); qalSourcePlay = ALSYMBOL(handle, alSourcePlay);
qalSourceStop = Sys_GetProcAddress(handle, "alSourceStop"); qalSourceStop = ALSYMBOL(handle, alSourceStop);
qalSourceRewind = Sys_GetProcAddress(handle, "alSourceRewind"); qalSourceRewind = ALSYMBOL(handle, alSourceRewind);
qalSourcePause = Sys_GetProcAddress(handle, "alSourcePause"); qalSourcePause = ALSYMBOL(handle, alSourcePause);
qalSourceQueueBuffers = Sys_GetProcAddress(handle, "alSourceQueueBuffers"); qalSourceQueueBuffers = ALSYMBOL(handle, alSourceQueueBuffers);
qalSourceUnqueueBuffers = Sys_GetProcAddress(handle, "alSourceUnqueueBuffers"); qalSourceUnqueueBuffers = ALSYMBOL(handle, alSourceUnqueueBuffers);
qalGenBuffers = Sys_GetProcAddress(handle, "alGenBuffers"); qalGenBuffers = ALSYMBOL(handle, alGenBuffers);
qalDeleteBuffers = Sys_GetProcAddress(handle, "alDeleteBuffers"); qalDeleteBuffers = ALSYMBOL(handle, alDeleteBuffers);
qalIsBuffer = Sys_GetProcAddress(handle, "alIsBuffer"); qalIsBuffer = ALSYMBOL(handle, alIsBuffer);
qalBufferData = Sys_GetProcAddress(handle, "alBufferData"); qalBufferData = ALSYMBOL(handle, alBufferData);
qalBufferf = Sys_GetProcAddress(handle, "alBufferf"); qalBufferf = ALSYMBOL(handle, alBufferf);
qalBuffer3f = Sys_GetProcAddress(handle, "alBuffer3f"); qalBuffer3f = ALSYMBOL(handle, alBuffer3f);
qalBufferfv = Sys_GetProcAddress(handle, "alBufferfv"); qalBufferfv = ALSYMBOL(handle, alBufferfv);
qalBufferi = Sys_GetProcAddress(handle, "alBufferi"); qalBufferi = ALSYMBOL(handle, alBufferi);
qalBuffer3i = Sys_GetProcAddress(handle, "alBuffer3i"); qalBuffer3i = ALSYMBOL(handle, alBuffer3i);
qalBufferiv = Sys_GetProcAddress(handle, "alBufferiv"); qalBufferiv = ALSYMBOL(handle, alBufferiv);
qalGetBufferf = Sys_GetProcAddress(handle, "alGetBufferf"); qalGetBufferf = ALSYMBOL(handle, alGetBufferf);
qalGetBuffer3f = Sys_GetProcAddress(handle, "alGetBuffer3f"); qalGetBuffer3f = ALSYMBOL(handle, alGetBuffer3f);
qalGetBufferfv = Sys_GetProcAddress(handle, "alGetBufferfv"); qalGetBufferfv = ALSYMBOL(handle, alGetBufferfv);
qalGetBufferi = Sys_GetProcAddress(handle, "alGetBufferi"); qalGetBufferi = ALSYMBOL(handle, alGetBufferi);
qalGetBuffer3i = Sys_GetProcAddress(handle, "alGetBuffer3i"); qalGetBuffer3i = ALSYMBOL(handle, alGetBuffer3i);
qalGetBufferiv = Sys_GetProcAddress(handle, "alGetBufferiv"); qalGetBufferiv = ALSYMBOL(handle, alGetBufferiv);
qalDopplerFactor = Sys_GetProcAddress(handle, "alDopplerFactor"); qalDopplerFactor = ALSYMBOL(handle, alDopplerFactor);
qalDopplerVelocity = Sys_GetProcAddress(handle, "alDopplerVelocity"); qalDopplerVelocity = ALSYMBOL(handle, alDopplerVelocity);
qalSpeedOfSound = Sys_GetProcAddress(handle, "alSpeedOfSound"); qalSpeedOfSound = ALSYMBOL(handle, alSpeedOfSound);
qalDistanceModel = Sys_GetProcAddress(handle, "alDistanceModel"); qalDistanceModel = ALSYMBOL(handle, alDistanceModel);
/* Open the OpenAL device */ /* Open the OpenAL device */
Com_Printf("...opening OpenAL device:"); Com_Printf("...opening OpenAL device:");

View file

@ -480,6 +480,20 @@ Sys_GetHomeDir(void)
void * void *
Sys_GetProcAddress(void *handle, const char *sym) Sys_GetProcAddress(void *handle, const char *sym)
{ {
if (handle == NULL)
{
#ifdef RTLD_DEFAULT
return dlsym(RTLD_DEFAULT, sym);
#else
/* POSIX suggests that this is a portable equivalent */
static void *global_namespace = NULL;
if (global_namespace == NULL)
global_namespace = dlopen(NULL, RTLD_GLOBAL|RTLD_LAZY);
return dlsym(global_namespace, sym);
#endif
}
return dlsym(handle, sym); return dlsym(handle, sym);
} }