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