Mercurial > foo_out_sdl
comparison SDL3/SDL_dlopennote.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 /* | |
| 2 Simple DirectMedia Layer | |
| 3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | |
| 4 | |
| 5 This software is provided 'as-is', without any express or implied | |
| 6 warranty. In no event will the authors be held liable for any damages | |
| 7 arising from the use of this software. | |
| 8 | |
| 9 Permission is granted to anyone to use this software for any purpose, | |
| 10 including commercial applications, and to alter it and redistribute it | |
| 11 freely, subject to the following restrictions: | |
| 12 | |
| 13 1. The origin of this software must not be misrepresented; you must not | |
| 14 claim that you wrote the original software. If you use this software | |
| 15 in a product, an acknowledgment in the product documentation would be | |
| 16 appreciated but is not required. | |
| 17 2. Altered source versions must be plainly marked as such, and must not be | |
| 18 misrepresented as being the original software. | |
| 19 3. This notice may not be removed or altered from any source distribution. | |
| 20 */ | |
| 21 | |
| 22 /* WIKI CATEGORY: DlopenNotes */ | |
| 23 | |
| 24 /** | |
| 25 * # CategoryDlopenNotes | |
| 26 * | |
| 27 * This header allows you to annotate your code so external tools know about | |
| 28 * dynamic shared library dependencies. | |
| 29 * | |
| 30 * If you determine that your toolchain doesn't support dlopen notes, you can | |
| 31 * disable this feature by defining `SDL_DISABLE_DLOPEN_NOTES`. You can use | |
| 32 * this CMake snippet to check for support: | |
| 33 * | |
| 34 * ```cmake | |
| 35 * include(CheckCSourceCompiles) | |
| 36 * find_package(SDL3 REQUIRED CONFIG COMPONENTS Headers) | |
| 37 * list(APPEND CMAKE_REQUIRED_LIBRARIES SDL3::Headers) | |
| 38 * check_c_source_compiles([==[ | |
| 39 * #include <SDL3/SDL_dlopennote.h> | |
| 40 * SDL_ELF_NOTE_DLOPEN("sdl-video", | |
| 41 * "Support for video through SDL", | |
| 42 * SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, | |
| 43 * "libSDL-1.2.so.0", "libSDL-2.0.so.0", "libSDL3.so.0" | |
| 44 * ) | |
| 45 * int main(int argc, char *argv[]) { | |
| 46 * return argc + argv[0][1]; | |
| 47 * } | |
| 48 * ]==] COMPILER_SUPPORTS_SDL_ELF_NOTE_DLOPEN) | |
| 49 * if(NOT COMPILER_SUPPORTS_SDL_ELF_NOTE_DLOPEN) | |
| 50 * add_compile_definitions(-DSDL_DISABLE_DLOPEN_NOTE) | |
| 51 * endif() | |
| 52 * ``` | |
| 53 */ | |
| 54 | |
| 55 #ifndef SDL_dlopennote_h | |
| 56 #define SDL_dlopennote_h | |
| 57 | |
| 58 /** | |
| 59 * Use this macro with SDL_ELF_NOTE_DLOPEN() to note that a dynamic shared | |
| 60 * library dependency is optional. | |
| 61 * | |
| 62 * Optional functionality uses the dependency, the binary will work and the | |
| 63 * dependency is only needed for full-featured installations. | |
| 64 * | |
| 65 * \since This macro is available since SDL 3.4.0. | |
| 66 * | |
| 67 * \sa SDL_ELF_NOTE_DLOPEN | |
| 68 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED | |
| 69 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED | |
| 70 */ | |
| 71 #define SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED "suggested" | |
| 72 | |
| 73 /** | |
| 74 * Use this macro with SDL_ELF_NOTE_DLOPEN() to note that a dynamic shared | |
| 75 * library dependency is recommended. | |
| 76 * | |
| 77 * Important functionality needs the dependency, the binary will work but in | |
| 78 * most cases the dependency should be provided. | |
| 79 * | |
| 80 * \since This macro is available since SDL 3.4.0. | |
| 81 * | |
| 82 * \sa SDL_ELF_NOTE_DLOPEN | |
| 83 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED | |
| 84 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED | |
| 85 */ | |
| 86 #define SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED "recommended" | |
| 87 | |
| 88 /** | |
| 89 * Use this macro with SDL_ELF_NOTE_DLOPEN() to note that a dynamic shared | |
| 90 * library dependency is required. | |
| 91 * | |
| 92 * Core functionality needs the dependency, the binary will not work if it | |
| 93 * cannot be found. | |
| 94 * | |
| 95 * \since This macro is available since SDL 3.4.0. | |
| 96 * | |
| 97 * \sa SDL_ELF_NOTE_DLOPEN | |
| 98 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED | |
| 99 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED | |
| 100 */ | |
| 101 #define SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED "required" | |
| 102 | |
| 103 | |
| 104 #if !defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_ANDROID) | |
| 105 /* The dlopen note functionality isn't used on this platform */ | |
| 106 #ifndef SDL_DISABLE_DLOPEN_NOTES | |
| 107 #define SDL_DISABLE_DLOPEN_NOTES | |
| 108 #endif | |
| 109 #elif defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 1)) | |
| 110 /* gcc < 3.1 too old */ | |
| 111 #ifndef SDL_DISABLE_DLOPEN_NOTES | |
| 112 #define SDL_DISABLE_DLOPEN_NOTES | |
| 113 #endif | |
| 114 #endif /* SDL_PLATFORM_UNIX || SDL_PLATFORM_ANDROID */ | |
| 115 | |
| 116 #if defined(__ELF__) && !defined(SDL_DISABLE_DLOPEN_NOTES) | |
| 117 | |
| 118 #include <SDL3/SDL_stdinc.h> | |
| 119 | |
| 120 #define SDL_ELF_NOTE_DLOPEN_VENDOR "FDO" | |
| 121 #define SDL_ELF_NOTE_DLOPEN_TYPE 0x407c0c0aU | |
| 122 | |
| 123 #define SDL_ELF_NOTE_INTERNAL2(json, variable_name) \ | |
| 124 __attribute__((aligned(4), used, section(".note.dlopen"))) \ | |
| 125 static const struct { \ | |
| 126 struct { \ | |
| 127 Uint32 n_namesz; \ | |
| 128 Uint32 n_descsz; \ | |
| 129 Uint32 n_type; \ | |
| 130 } nhdr; \ | |
| 131 char name[4]; \ | |
| 132 __attribute__((aligned(4))) char dlopen_json[sizeof(json)]; \ | |
| 133 } variable_name = { \ | |
| 134 { \ | |
| 135 sizeof(SDL_ELF_NOTE_DLOPEN_VENDOR), \ | |
| 136 sizeof(json), \ | |
| 137 SDL_ELF_NOTE_DLOPEN_TYPE \ | |
| 138 }, \ | |
| 139 SDL_ELF_NOTE_DLOPEN_VENDOR, \ | |
| 140 json \ | |
| 141 } | |
| 142 | |
| 143 #define SDL_ELF_NOTE_INTERNAL(json, variable_name) \ | |
| 144 SDL_ELF_NOTE_INTERNAL2(json, variable_name) | |
| 145 | |
| 146 #define SDL_DLNOTE_JSON_ARRAY1(N1) "[\"" N1 "\"]" | |
| 147 #define SDL_DLNOTE_JSON_ARRAY2(N1,N2) "[\"" N1 "\",\"" N2 "\"]" | |
| 148 #define SDL_DLNOTE_JSON_ARRAY3(N1,N2,N3) "[\"" N1 "\",\"" N2 "\",\"" N3 "\"]" | |
| 149 #define SDL_DLNOTE_JSON_ARRAY4(N1,N2,N3,N4) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\"]" | |
| 150 #define SDL_DLNOTE_JSON_ARRAY5(N1,N2,N3,N4,N5) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\"]" | |
| 151 #define SDL_DLNOTE_JSON_ARRAY6(N1,N2,N3,N4,N5,N6) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\"]" | |
| 152 #define SDL_DLNOTE_JSON_ARRAY7(N1,N2,N3,N4,N5,N6,N7) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\"]" | |
| 153 #define SDL_DLNOTE_JSON_ARRAY8(N1,N2,N3,N4,N5,N6,N7,N8) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\",\"" N8 "\"]" | |
| 154 #define SDL_DLNOTE_JSON_ARRAY_GET(N1,N2,N3,N4,N5,N6,N7,N8,NAME,...) NAME | |
| 155 #define SDL_DLNOTE_JSON_ARRAY(...) \ | |
| 156 SDL_DLNOTE_JSON_ARRAY_GET( \ | |
| 157 __VA_ARGS__, \ | |
| 158 SDL_DLNOTE_JSON_ARRAY8, \ | |
| 159 SDL_DLNOTE_JSON_ARRAY7, \ | |
| 160 SDL_DLNOTE_JSON_ARRAY6, \ | |
| 161 SDL_DLNOTE_JSON_ARRAY5, \ | |
| 162 SDL_DLNOTE_JSON_ARRAY4, \ | |
| 163 SDL_DLNOTE_JSON_ARRAY3, \ | |
| 164 SDL_DLNOTE_JSON_ARRAY2, \ | |
| 165 SDL_DLNOTE_JSON_ARRAY1 \ | |
| 166 )(__VA_ARGS__) | |
| 167 | |
| 168 /* Create "unique" variable name using __LINE__, | |
| 169 * so creating multiple elf notes on the same line is not supported | |
| 170 */ | |
| 171 #define SDL_DLNOTE_JOIN2(A,B) A##B | |
| 172 #define SDL_DLNOTE_JOIN(A,B) SDL_DLNOTE_JOIN2(A,B) | |
| 173 #define SDL_DLNOTE_UNIQUE_NAME SDL_DLNOTE_JOIN(s_SDL_dlopen_note_, __LINE__) | |
| 174 | |
| 175 /** | |
| 176 * Add a note that your application has dynamic shared library dependencies. | |
| 177 * | |
| 178 * You can do this by adding the following to the global scope: | |
| 179 * | |
| 180 * ```c | |
| 181 * SDL_ELF_NOTE_DLOPEN( | |
| 182 * "png", | |
| 183 * "Support for loading PNG images using libpng (required for APNG)", | |
| 184 * SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, | |
| 185 * "libpng12.so.0" | |
| 186 * ) | |
| 187 * ``` | |
| 188 * | |
| 189 * A trailing semicolon is not needed. | |
| 190 * | |
| 191 * Or if you support multiple versions of a library, you can list them: | |
| 192 * | |
| 193 * ```c | |
| 194 * // Our app supports SDL1, SDL2, and SDL3 by dynamically loading them | |
| 195 * SDL_ELF_NOTE_DLOPEN( | |
| 196 * "SDL", | |
| 197 * "Create windows through SDL video backend", | |
| 198 * SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED | |
| 199 * "libSDL-1.2.so.0", "libSDL2-2.0.so.0", "libSDL3.so.0" | |
| 200 * ) | |
| 201 * ``` | |
| 202 * | |
| 203 * This macro is not available for compilers that do not support variadic | |
| 204 * macro's. | |
| 205 * | |
| 206 * \since This macro is available since SDL 3.4.0. | |
| 207 * | |
| 208 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED | |
| 209 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED | |
| 210 * \sa SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED | |
| 211 */ | |
| 212 #define SDL_ELF_NOTE_DLOPEN(feature, description, priority, ...) \ | |
| 213 SDL_ELF_NOTE_INTERNAL( \ | |
| 214 "[{\"feature\":\"" feature \ | |
| 215 "\",\"description\":\"" description \ | |
| 216 "\",\"priority\":\"" priority \ | |
| 217 "\",\"soname\":" SDL_DLNOTE_JSON_ARRAY(__VA_ARGS__) "}]", \ | |
| 218 SDL_DLNOTE_UNIQUE_NAME); | |
| 219 | |
| 220 #elif defined(__GNUC__) && __GNUC__ < 3 | |
| 221 | |
| 222 #define SDL_ELF_NOTE_DLOPEN(args...) | |
| 223 | |
| 224 #elif defined(_MSC_VER) && _MSC_VER < 1400 | |
| 225 | |
| 226 /* Variadic macros are not supported */ | |
| 227 | |
| 228 #else | |
| 229 | |
| 230 #define SDL_ELF_NOTE_DLOPEN(...) | |
| 231 | |
| 232 #endif | |
| 233 | |
| 234 #endif /* SDL_dlopennote_h */ |
