mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-12-20 04:05:00 +08:00
build: add symbol versioning for SDL
If a program built against one version of SDL is run in an environment where there is an earlier version of the SDL .so library installed, the result varies depending on platform configuration; in the best case, it won't start at all, at worst it aborts in the middle of the user doing "something important" (systems implementing lazy symbol resolution). verdefs on the other hand are always checked on startup. The dependency information present in programs and shared libraries is not only of value to the dynamic linker, but also to a distribution's package management. If the dynamic linker is able to tell that a program is not runnable per the above, a package manager is able to come to the same conclusion — and block the installation of a nonfunctional program+library ensemble. Because there are a lot more symbols than there are libraries (I am going to throw in "10^4 to 1 or worse"), package managers generally do not evaluate symbols, but only e.g. the SONAME, NEEDED and VERNEED fields/blocks. Because the SONAME is the same between two SDL versions like 2.0.24, and 2.0.26, everything rests on having verdefs. This patch proposes the addition of verdefs.
This commit is contained in:
committed by
Sam Lantinga
parent
92cd2c0a74
commit
1878674477
@@ -80,7 +80,7 @@ LOCAL_CFLAGS += -Wno-unused-parameter -Wno-sign-compare
|
||||
|
||||
LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
|
||||
|
||||
LOCAL_LDFLAGS := -Wl,--no-undefined
|
||||
LOCAL_LDFLAGS := -Wl,--no-undefined -Wl,--version-script=$(LOCAL_PATH)/src/dynapi/SDL_dynapi.sym
|
||||
|
||||
ifeq ($(NDK_DEBUG),1)
|
||||
cmd-strip :=
|
||||
|
||||
@@ -276,6 +276,15 @@ if(WINDOWS)
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
endif()
|
||||
|
||||
check_linker_flag(C "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym" HAVE_WL_VERSION_SCRIPT)
|
||||
if(HAVE_WL_VERSION_SCRIPT)
|
||||
list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym")
|
||||
else()
|
||||
if((LINUX AND LIBC_IS_GLIBC) OR ANDROID)
|
||||
message(FATAL_ERROR "Linker does not support '-Wl,--version-script=xxx.sym'. This is required on the current host platform (${SDL_CMAKE_PLATFORM}).")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Emscripten toolchain has a nonempty default value for this, and the checks
|
||||
# in this file need to change that, so remember the original value, and
|
||||
# restore back to that afterwards. For check_function_exists() to work in
|
||||
@@ -3182,6 +3191,8 @@ if(SDL_SHARED)
|
||||
# alias target for in-tree builds
|
||||
add_library(SDL3::SDL3 ALIAS SDL3)
|
||||
set_target_properties(SDL3 PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
set_target_properties(SDL3 PROPERTIES LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym")
|
||||
set_target_properties(SDL3 PROPERTIES INTERFACE_LINK_DEPENDS "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/dynapi/SDL_dynapi.sym>")
|
||||
if(NOT SDL_LIBC)
|
||||
if(MSVC AND SDL_CPU_X86)
|
||||
# FIXME: should be added for all architectures (missing symbols for ARM)
|
||||
|
||||
@@ -110,6 +110,26 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.18)
|
||||
function(check_linker_flag LANG FLAG VAR)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${FLAG} )
|
||||
if(LANG STREQUAL "C")
|
||||
include(CheckCSourceCompiles)
|
||||
check_c_source_compiles("int main(int argc,char*argv[]){(void)argc;(void)argv;return 0;}" ${VAR} FAIL_REGEX "warning")
|
||||
elseif(LANG STREQUAL "CXX")
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles("int main(int argc,char*argv[]){(void)argc;(void)argv;return 0;}" ${VAR} FAIL_REGEX "warning")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported language: ${LANG}")
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
endfunction()
|
||||
else()
|
||||
cmake_policy(SET CMP0057 NEW) # Support new if() IN_LIST operator. (used inside check_linker_flag, used in CMake 3.18)
|
||||
include(CheckLinkerFlag)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
check_language(OBJC)
|
||||
if(NOT CMAKE_OBJC_COMPILER)
|
||||
|
||||
871
src/dynapi/SDL_dynapi.sym
Normal file
871
src/dynapi/SDL_dynapi.sym
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,7 @@ use File::Basename;
|
||||
chdir(dirname(__FILE__) . '/../..');
|
||||
my $sdl_dynapi_procs_h = "src/dynapi/SDL_dynapi_procs.h";
|
||||
my $sdl_dynapi_overrides_h = "src/dynapi/SDL_dynapi_overrides.h";
|
||||
my $sdl_dynapi_sym = "src/dynapi/SDL_dynapi.sym";
|
||||
|
||||
my %existing = ();
|
||||
if (-f $sdl_dynapi_procs_h) {
|
||||
@@ -48,6 +49,10 @@ if (-f $sdl_dynapi_procs_h) {
|
||||
open(SDL_DYNAPI_PROCS_H, '>>', $sdl_dynapi_procs_h) or die("Can't open $sdl_dynapi_procs_h: $!\n");
|
||||
open(SDL_DYNAPI_OVERRIDES_H, '>>', $sdl_dynapi_overrides_h) or die("Can't open $sdl_dynapi_overrides_h: $!\n");
|
||||
|
||||
open(SDL_DYNAPI_SYM, '<', $sdl_dynapi_sym) or die("Can't open $sdl_dynapi_sym: $!\n");
|
||||
read(SDL_DYNAPI_SYM, my $sdl_dynapi_sym_contents, -s SDL_DYNAPI_SYM);
|
||||
close(SDL_DYNAPI_SYM);
|
||||
|
||||
opendir(HEADERS, 'include/SDL3') or die("Can't open include dir: $!\n");
|
||||
while (my $d = readdir(HEADERS)) {
|
||||
next if not $d =~ /\.h\Z/;
|
||||
@@ -76,6 +81,8 @@ while (my $d = readdir(HEADERS)) {
|
||||
|
||||
next if $existing{$fn}; # already slotted into the jump table.
|
||||
|
||||
$sdl_dynapi_sym_contents =~ s/# extra symbols go here/$fn;\n # extra symbols go here/;
|
||||
|
||||
my @params = split(',', $7);
|
||||
|
||||
#print("rc == '$rc', fn == '$fn', params == '$params'\n");
|
||||
@@ -144,4 +151,8 @@ closedir(HEADERS);
|
||||
close(SDL_DYNAPI_PROCS_H);
|
||||
close(SDL_DYNAPI_OVERRIDES_H);
|
||||
|
||||
open(SDL_DYNAPI_SYM, '>', $sdl_dynapi_sym) or die("Can't open $sdl_dynapi_sym: $!\n");
|
||||
print SDL_DYNAPI_SYM $sdl_dynapi_sym_contents;
|
||||
close(SDL_DYNAPI_SYM);
|
||||
|
||||
# vi: set ts=4 sw=4 expandtab:
|
||||
|
||||
Reference in New Issue
Block a user