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 */