SDL
SDL copied to clipboard
Record dynamic dependencies in .note.dlopen elf section
The data can be used with dlopen-notes.
The raw data can be viewed with objdump -j .note.dlopen -s libSDL3.so.0
Please review the features/descriptions/priorities I've given The feature string must be unique, and priority must be one of "required", "recommended" or "suggested".
The spec can be found here.
/cc @smcv
Extra embedded data
This is the output of running python dlopen-notes.py on my machine:
# libSDL3.so
[
{
"feature": "hidabi-libusb",
"description": "Support for joysticks through libusb",
"priority": "suggested",
"soname": [
"libusb-1.0.so.0"
]
},
{
"feature": "egl-opengl",
"description": "Support for OpenGL",
"priority": "suggested",
"soname": [
"libGL.so.1",
"libOpenGL.so.0"
]
},
{
"feature": "egl-egl",
"description": "Support for EGL",
"priority": "suggested",
"soname": [
"libEGL.so.1"
]
},
{
"feature": "egl-es2",
"description": "Support for EGL ES2",
"priority": "suggested",
"soname": [
"libGLESv2.so.2"
]
},
{
"feature": "egl-es-prv",
"description": "Support for EGL ES PVR",
"priority": "suggested",
"soname": [
"libGLES_CM.so.1"
]
},
{
"feature": "egl-ogl-es",
"description": "Support for OpenGL ES",
"priority": "suggested",
"soname": [
"libGLESv1_CM.so.1"
]
},
{
"feature": "audio-libalsa",
"description": "Support for audio through libalsa",
"priority": "suggested",
"soname": [
"libasound.so.2"
]
},
{
"feature": "audio-libjack",
"description": "Support for audio through libjack",
"priority": "suggested",
"soname": [
"libjack.so.0"
]
},
{
"feature": "audio-libpipewire",
"description": "Support for audio through libpipewire",
"priority": "suggested",
"soname": [
"libpipewire-0.3.so.0"
]
},
{
"feature": "camera-libpipewire",
"description": "Support for camera through libalsa",
"priority": "suggested",
"soname": [
"libpipewire-0.3.so.0"
]
},
{
"feature": "audio-libpulseaudio",
"description": "Support for audio through libpulseaudio",
"priority": "suggested",
"soname": [
"libpulse.so.0"
]
},
{
"feature": "x11",
"description": "Support for video through X11 backend",
"priority": "required",
"soname": [
"libX11.so.6",
"libXext.so.6",
"libXcursor.so.1",
"libXi.so.6",
"libXfixes.so.3",
"libXrandr.so.2",
"libXss.so.1",
"libXtst.so.6"
]
},
{
"feature": "x11-vulkan",
"description": "Support for vulkan on X11",
"priority": "suggested",
"soname": [
"libvulkan.so.1",
"libX11-xcb.so.1"
]
},
{
"feature": "video-kmsdrm",
"description": "Support for KMSDRM",
"priority": "suggested",
"soname": [
"libdrm.so.2"
]
},
{
"feature": "kmsdrm-vulkan",
"description": "Support for Vulkan on KMSDRM",
"priority": "suggested",
"soname": [
"libvulkan.so.1"
]
},
{
"feature": "wayland",
"description": "Support for Wayland video",
"priority": "required",
"soname": [
"libwayland-client.so.0",
"libwayland-egl.so.1",
"libwayland-cursor.so.0",
"libxkbcommon.so.0",
"libdecor-0.so.0"
]
},
{
"feature": "wayland-vulkan",
"description": "Support for Vulkan on wayland backend",
"priority": "suggested",
"soname": [
"libvulkan.so.1"
]
},
{
"feature": "core-libdbus",
"description": "Support for DBus RPC",
"priority": "required",
"soname": [
"libdbus-1.so.3"
]
},
{
"feature": "events-udev",
"description": "Support for events through libudev",
"priority": "suggested",
"soname": [
"libudev.so.1"
]
},
{
"feature": "io-io_uring",
"description": "Support for async IO through liburing",
"priority": "required",
"soname": [
"liburing-ffi.so.2"
]
},
{
"feature": "storage-steam",
"description": "Support for Steam storage",
"priority": "suggested",
"soname": [
"libsteam_api.so"
]
},
{
"feature": "offscreen-vulkan",
"description": "Support for offscreen Vulkan",
"priority": "suggested",
"soname": [
"libvulkan.so.1"
]
}
]
The raw embedded data can be viewed with objdump:
Output of objdump -j .note.dlopen -s libSDL3.so.0:
02fc 04000000 87000000 0a0c7c40 46444f00 ..........|@FDO.
030c 5b7b2266 65617475 7265223a 22686964 [{"feature":"hid
031c 6162692d 6c696275 7362222c 22646573 abi-libusb","des
032c 63726970 74696f6e 223a2253 7570706f cription":"Suppo
033c 72742066 6f72206a 6f797374 69636b73 rt for joysticks
034c 20746872 6f756768 206c6962 75736222 through libusb"
035c 2c227072 696f7269 7479223a 22737567 ,"priority":"sug
036c 67657374 6564222c 22736f6e 616d6522 gested","soname"
037c 3a5b226c 69627573 622d312e 302e736f :["libusb-1.0.so
038c 2e30225d 7d5d0000 04000000 7e000000 .0"]}]......~...
039c 0a0c7c40 46444f00 5b7b2266 65617475 ..|@FDO.[{"featu
03ac 7265223a 2265676c 2d6f7065 6e676c22 re":"egl-opengl"
03bc 2c226465 73637269 7074696f 6e223a22 ,"description":"
03cc 53757070 6f727420 666f7220 4f70656e Support for Open
03dc 474c222c 22707269 6f726974 79223a22 GL","priority":"
03ec 73756767 65737465 64222c22 736f6e61 suggested","sona
03fc 6d65223a 5b226c69 62474c2e 736f2e31 me":["libGL.so.1
040c 222c226c 69624f70 656e474c 2e736f2e ","libOpenGL.so.
041c 30225d7d 5d000000 04000000 68000000 0"]}].......h...
042c 0a0c7c40 46444f00 5b7b2266 65617475 ..|@FDO.[{"featu
043c 7265223a 2265676c 2d65676c 222c2264 re":"egl-egl","d
044c 65736372 69707469 6f6e223a 22537570 escription":"Sup
045c 706f7274 20666f72 2045474c 222c2270 port for EGL","p
046c 72696f72 69747922 3a227375 67676573 riority":"sugges
047c 74656422 2c22736f 6e616d65 223a5b22 ted","soname":["
048c 6c696245 474c2e73 6f2e3122 5d7d5d00 libEGL.so.1"]}].
049c 04000000 6f000000 0a0c7c40 46444f00 ....o.....|@FDO.
04ac 5b7b2266 65617475 7265223a 2265676c [{"feature":"egl
04bc 2d657332 222c2264 65736372 69707469 -es2","descripti
04cc 6f6e223a 22537570 706f7274 20666f72 on":"Support for
04dc 2045474c 20455332 222c2270 72696f72 EGL ES2","prior
04ec 69747922 3a227375 67676573 74656422 ity":"suggested"
04fc 2c22736f 6e616d65 223a5b22 6c696247 ,"soname":["libG
050c 4c455376 322e736f 2e32225d 7d5d0000 LESv2.so.2"]}]..
051c 04000000 76000000 0a0c7c40 46444f00 ....v.....|@FDO.
052c 5b7b2266 65617475 7265223a 2265676c [{"feature":"egl
053c 2d65732d 70727622 2c226465 73637269 -es-prv","descri
054c 7074696f 6e223a22 53757070 6f727420 ption":"Support
055c 666f7220 45474c20 45532050 5652222c for EGL ES PVR",
056c 22707269 6f726974 79223a22 73756767 "priority":"sugg
057c 65737465 64222c22 736f6e61 6d65223a ested","soname":
058c 5b226c69 62474c45 535f434d 2e736f2e ["libGLES_CM.so.
059c 31225d7d 5d000000 04000000 77000000 1"]}].......w...
05ac 0a0c7c40 46444f00 5b7b2266 65617475 ..|@FDO.[{"featu
05bc 7265223a 2265676c 2d6f676c 2d657322 re":"egl-ogl-es"
05cc 2c226465 73637269 7074696f 6e223a22 ,"description":"
05dc 53757070 6f727420 666f7220 4f70656e Support for Open
05ec 474c2045 53222c22 7072696f 72697479 GL ES","priority
05fc 223a2273 75676765 73746564 222c2273 ":"suggested","s
060c 6f6e616d 65223a5b 226c6962 474c4553 oname":["libGLES
061c 76315f43 4d2e736f 2e31225d 7d5d0000 v1_CM.so.1"]}]..
062c 04000000 83000000 0a0c7c40 46444f00 ..........|@FDO.
063c 5b7b2266 65617475 7265223a 22617564 [{"feature":"aud
064c 696f2d6c 6962616c 7361222c 22646573 io-libalsa","des
065c 63726970 74696f6e 223a2253 7570706f cription":"Suppo
066c 72742066 6f722061 7564696f 20746872 rt for audio thr
067c 6f756768 206c6962 616c7361 222c2270 ough libalsa","p
068c 72696f72 69747922 3a227375 67676573 riority":"sugges
069c 74656422 2c22736f 6e616d65 223a5b22 ted","soname":["
06ac 6c696261 736f756e 642e736f 2e32225d libasound.so.2"]
06bc 7d5d0000 04000000 81000000 0a0c7c40 }]............|@
06cc 46444f00 5b7b2266 65617475 7265223a FDO.[{"feature":
06dc 22617564 696f2d6c 69626a61 636b222c "audio-libjack",
06ec 22646573 63726970 74696f6e 223a2253 "description":"S
06fc 7570706f 72742066 6f722061 7564696f upport for audio
070c 20746872 6f756768 206c6962 6a61636b through libjack
071c 222c2270 72696f72 69747922 3a227375 ","priority":"su
072c 67676573 74656422 2c22736f 6e616d65 ggested","soname
073c 223a5b22 6c69626a 61636b2e 736f2e30 ":["libjack.so.0
074c 225d7d5d 00000000 04000000 91000000 "]}]............
075c 0a0c7c40 46444f00 5b7b2266 65617475 ..|@FDO.[{"featu
076c 7265223a 22617564 696f2d6c 69627069 re":"audio-libpi
077c 70657769 7265222c 22646573 63726970 pewire","descrip
078c 74696f6e 223a2253 7570706f 72742066 tion":"Support f
079c 6f722061 7564696f 20746872 6f756768 or audio through
07ac 206c6962 70697065 77697265 222c2270 libpipewire","p
07bc 72696f72 69747922 3a227375 67676573 riority":"sugges
07cc 74656422 2c22736f 6e616d65 223a5b22 ted","soname":["
07dc 6c696270 69706577 6972652d 302e332e libpipewire-0.3.
07ec 736f2e30 225d7d5d 00000000 04000000 so.0"]}]........
07fc 8f000000 0a0c7c40 46444f00 5b7b2266 ......|@FDO.[{"f
080c 65617475 7265223a 2263616d 6572612d eature":"camera-
081c 6c696270 69706577 69726522 2c226465 libpipewire","de
082c 73637269 7074696f 6e223a22 53757070 scription":"Supp
083c 6f727420 666f7220 63616d65 72612074 ort for camera t
084c 68726f75 6768206c 6962616c 7361222c hrough libalsa",
085c 22707269 6f726974 79223a22 73756767 "priority":"sugg
086c 65737465 64222c22 736f6e61 6d65223a ested","soname":
087c 5b226c69 62706970 65776972 652d302e ["libpipewire-0.
088c 332e736f 2e30225d 7d5d0000 04000000 3.so.0"]}]......
089c 8e000000 0a0c7c40 46444f00 5b7b2266 ......|@FDO.[{"f
08ac 65617475 7265223a 22617564 696f2d6c eature":"audio-l
08bc 69627075 6c736561 7564696f 222c2264 ibpulseaudio","d
08cc 65736372 69707469 6f6e223a 22537570 escription":"Sup
08dc 706f7274 20666f72 20617564 696f2074 port for audio t
08ec 68726f75 6768206c 69627075 6c736561 hrough libpulsea
08fc 7564696f 222c2270 72696f72 69747922 udio","priority"
090c 3a227375 67676573 74656422 2c22736f :"suggested","so
091c 6e616d65 223a5b22 6c696270 756c7365 name":["libpulse
092c 2e736f2e 30225d7d 5d000000 04000000 .so.0"]}].......
093c e6000000 0a0c7c40 46444f00 5b7b2266 ......|@FDO.[{"f
094c 65617475 7265223a 22783131 222c2264 eature":"x11","d
095c 65736372 69707469 6f6e223a 22537570 escription":"Sup
096c 706f7274 20666f72 20766964 656f2074 port for video t
097c 68726f75 67682058 31312062 61636b65 hrough X11 backe
098c 6e64222c 22707269 6f726974 79223a22 nd","priority":"
099c 72657175 69726564 222c2273 6f6e616d required","sonam
09ac 65223a5b 226c6962 5831312e 736f2e36 e":["libX11.so.6
09bc 222c226c 69625865 78742e73 6f2e3622 ","libXext.so.6"
09cc 2c226c69 62586375 72736f72 2e736f2e ,"libXcursor.so.
09dc 31222c22 6c696258 692e736f 2e36222c 1","libXi.so.6",
09ec 226c6962 58666978 65732e73 6f2e3322 "libXfixes.so.3"
09fc 2c226c69 62587261 6e64722e 736f2e32 ,"libXrandr.so.2
0a0c 222c226c 69625873 732e736f 2e31222c ","libXss.so.1",
0a1c 226c6962 58747374 2e736f2e 36225d7d "libXtst.so.6"]}
0a2c 5d000000 04000000 8a000000 0a0c7c40 ].............|@
0a3c 46444f00 5b7b2266 65617475 7265223a FDO.[{"feature":
0a4c 22783131 2d76756c 6b616e22 2c226465 "x11-vulkan","de
0a5c 73637269 7074696f 6e223a22 53757070 scription":"Supp
0a6c 6f727420 666f7220 76756c6b 616e206f ort for vulkan o
0a7c 6e205831 31222c22 7072696f 72697479 n X11","priority
0a8c 223a2273 75676765 73746564 222c2273 ":"suggested","s
0a9c 6f6e616d 65223a5b 226c6962 76756c6b oname":["libvulk
0aac 616e2e73 6f2e3122 2c226c69 62583131 an.so.1","libX11
0abc 2d786362 2e736f2e 31225d7d 5d000000 -xcb.so.1"]}]...
0acc 04000000 70000000 0a0c7c40 46444f00 ....p.....|@FDO.
0adc 5b7b2266 65617475 7265223a 22766964 [{"feature":"vid
0aec 656f2d6b 6d736472 6d222c22 64657363 eo-kmsdrm","desc
0afc 72697074 696f6e22 3a225375 70706f72 ription":"Suppor
0b0c 7420666f 72204b4d 5344524d 222c2270 t for KMSDRM","p
0b1c 72696f72 69747922 3a227375 67676573 riority":"sugges
0b2c 74656422 2c22736f 6e616d65 223a5b22 ted","soname":["
0b3c 6c696264 726d2e73 6f2e3222 5d7d5d00 libdrm.so.2"]}].
0b4c 04000000 7e000000 0a0c7c40 46444f00 ....~.....|@FDO.
0b5c 5b7b2266 65617475 7265223a 226b6d73 [{"feature":"kms
0b6c 64726d2d 76756c6b 616e222c 22646573 drm-vulkan","des
0b7c 63726970 74696f6e 223a2253 7570706f cription":"Suppo
0b8c 72742066 6f722056 756c6b61 6e206f6e rt for Vulkan on
0b9c 204b4d53 44524d22 2c227072 696f7269 KMSDRM","priori
0bac 7479223a 22737567 67657374 6564222c ty":"suggested",
0bbc 22736f6e 616d6522 3a5b226c 69627675 "soname":["libvu
0bcc 6c6b616e 2e736f2e 31225d7d 5d000000 lkan.so.1"]}]...
0bdc 04000000 d1000000 0a0c7c40 46444f00 ..........|@FDO.
0bec 5b7b2266 65617475 7265223a 22776179 [{"feature":"way
0bfc 6c616e64 222c2264 65736372 69707469 land","descripti
0c0c 6f6e223a 22537570 706f7274 20666f72 on":"Support for
0c1c 20576179 6c616e64 20766964 656f222c Wayland video",
0c2c 22707269 6f726974 79223a22 72657175 "priority":"requ
0c3c 69726564 222c2273 6f6e616d 65223a5b ired","soname":[
0c4c 226c6962 7761796c 616e642d 636c6965 "libwayland-clie
0c5c 6e742e73 6f2e3022 2c226c69 62776179 nt.so.0","libway
0c6c 6c616e64 2d65676c 2e736f2e 31222c22 land-egl.so.1","
0c7c 6c696277 61796c61 6e642d63 7572736f libwayland-curso
0c8c 722e736f 2e30222c 226c6962 786b6263 r.so.0","libxkbc
0c9c 6f6d6d6f 6e2e736f 2e30222c 226c6962 ommon.so.0","lib
0cac 6465636f 722d302e 736f2e30 225d7d5d decor-0.so.0"]}]
0cbc 00000000 04000000 88000000 0a0c7c40 ..............|@
0ccc 46444f00 5b7b2266 65617475 7265223a FDO.[{"feature":
0cdc 22776179 6c616e64 2d76756c 6b616e22 "wayland-vulkan"
0cec 2c226465 73637269 7074696f 6e223a22 ,"description":"
0cfc 53757070 6f727420 666f7220 56756c6b Support for Vulk
0d0c 616e206f 6e207761 796c616e 64206261 an on wayland ba
0d1c 636b656e 64222c22 7072696f 72697479 ckend","priority
0d2c 223a2273 75676765 73746564 222c2273 ":"suggested","s
0d3c 6f6e616d 65223a5b 226c6962 76756c6b oname":["libvulk
0d4c 616e2e73 6f2e3122 5d7d5d00 04000000 an.so.1"]}].....
0d5c 74000000 0a0c7c40 46444f00 5b7b2266 t.....|@FDO.[{"f
0d6c 65617475 7265223a 22636f72 652d6c69 eature":"core-li
0d7c 62646275 73222c22 64657363 72697074 bdbus","descript
0d8c 696f6e22 3a225375 70706f72 7420666f ion":"Support fo
0d9c 72204442 75732052 5043222c 22707269 r DBus RPC","pri
0dac 6f726974 79223a22 72657175 69726564 ority":"required
0dbc 222c2273 6f6e616d 65223a5b 226c6962 ","soname":["lib
0dcc 64627573 2d312e73 6f2e3322 5d7d5d00 dbus-1.so.3"]}].
0ddc 04000000 80000000 0a0c7c40 46444f00 ..........|@FDO.
0dec 5b7b2266 65617475 7265223a 22657665 [{"feature":"eve
0dfc 6e74732d 75646576 222c2264 65736372 nts-udev","descr
0e0c 69707469 6f6e223a 22537570 706f7274 iption":"Support
0e1c 20666f72 20657665 6e747320 7468726f for events thro
0e2c 75676820 6c696275 64657622 2c227072 ugh libudev","pr
0e3c 696f7269 7479223a 22737567 67657374 iority":"suggest
0e4c 6564222c 22736f6e 616d6522 3a5b226c ed","soname":["l
0e5c 69627564 65762e73 6f2e3122 5d7d5d00 ibudev.so.1"]}].
0e6c 04000000 87000000 0a0c7c40 46444f00 ..........|@FDO.
0e7c 5b7b2266 65617475 7265223a 22696f2d [{"feature":"io-
0e8c 696f5f75 72696e67 222c2264 65736372 io_uring","descr
0e9c 69707469 6f6e223a 22537570 706f7274 iption":"Support
0eac 20666f72 20617379 6e632049 4f207468 for async IO th
0ebc 726f7567 68206c69 62757269 6e67222c rough liburing",
0ecc 22707269 6f726974 79223a22 72657175 "priority":"requ
0edc 69726564 222c2273 6f6e616d 65223a5b ired","soname":[
0eec 226c6962 7572696e 672d6666 692e736f "liburing-ffi.so
0efc 2e32225d 7d5d0000 04000000 7c000000 .2"]}]......|...
0f0c 0a0c7c40 46444f00 5b7b2266 65617475 ..|@FDO.[{"featu
0f1c 7265223a 2273746f 72616765 2d737465 re":"storage-ste
0f2c 616d222c 22646573 63726970 74696f6e am","description
0f3c 223a2253 7570706f 72742066 6f722053 ":"Support for S
0f4c 7465616d 2073746f 72616765 222c2270 team storage","p
0f5c 72696f72 69747922 3a227375 67676573 riority":"sugges
0f6c 74656422 2c22736f 6e616d65 223a5b22 ted","soname":["
0f7c 6c696273 7465616d 5f617069 2e736f22 libsteam_api.so"
0f8c 5d7d5d00 04000000 81000000 0a0c7c40 ]}]...........|@
0f9c 46444f00 5b7b2266 65617475 7265223a FDO.[{"feature":
0fac 226f6666 73637265 656e2d76 756c6b61 "offscreen-vulka
0fbc 6e222c22 64657363 72697074 696f6e22 n","description"
0fcc 3a225375 70706f72 7420666f 72206f66 :"Support for of
0fdc 66736372 65656e20 56756c6b 616e222c fscreen Vulkan",
0fec 22707269 6f726974 79223a22 73756767 "priority":"sugg
0ffc 65737465 64222c22 736f6e61 6d65223a ested","soname":
100c 5b226c69 6276756c 6b616e2e 736f2e31 ["libvulkan.so.1
101c 225d7d5d 00000000 "]}]....
So the extra data adds at least 3,368 bytes to the library.
Fixes https://github.com/libsdl-org/SDL/issues/12971
(Just a brief review for now, I'm not at work today)
This doesn't seem right:
{
"feature": "x11",
"description": "Support for video through X11 backend",
"priority": "required",
"soname": [
"libX11.so.6",
"libXext.so.6",
"libXcursor.so.1",
"libXi.so.6",
"libXfixes.so.3",
"libXrandr.so.2",
"libXss.so.1",
"libXtst.so.6"
]
},
The list of SONAMEs is an "or" not an "and", so this is asking for: libX11.so.6 OR libXext.so.6 OR ...
But I think SDL needs libX11.so.6 AND libXext.so.6 AND ... for X11 video?
I believe the way you encode that is to have several JSON blobs that all say "feature": "x11".
The list of SONAMEs is an "or" not an "and", so this is asking for: libX11.so.6 OR libXext.so.6 OR ...
But I think SDL needs libX11.so.6 AND libXext.so.6 AND ... for X11 video?
I believe the way you encode that is to have several JSON blobs that all say
"feature": "x11".
Looking at the spec: yes, this.
The udev feature is doing this correctly: SDL will dlopen libudev.so.1 OR libudev.so.0 so it's correct to have them both in an array of SONAMEs. But assuming the X11 feature needs all these libraries, the spec does say it should be multiple JSON blobs:
If the feature field is used, it will identify an individual feature, and multiple entries using the same feature denote functionality that requires all of the libraries they specify in order to be enabled.
The list of SONAMEs is an "or" not an "and", so this is asking for: libX11.so.6 OR libXext.so.6 OR ... But I think SDL needs libX11.so.6 AND libXext.so.6 AND ... for X11 video? I believe the way you encode that is to have several JSON blobs that all say
"feature": "x11".Looking at the spec: yes, this.
The udev feature is doing this correctly: SDL will dlopen
libudev.so.1ORlibudev.so.0so it's correct to have them both in an array of SONAMEs. But assuming the X11 feature needs all these libraries, the spec does say it should be multiple JSON blobs:If the feature field is used, it will identify an individual feature, and multiple entries using the same feature denote functionality that requires all of the libraries they specify in order to be enabled.
Thanks for calling me out on my misunderstanding of the spec.
I think the spec is missing a way to group dynamic dependencies. I grouped them ad-hoc using e.g. x11, x11-xcursor, x11-xrandr, ... But this is in no way enforceable, because I also added audio-libpipewire and audio-libpulseaudio which can be used independent of the other.
I think the spec is missing a way to group dynamic dependencies. I grouped them ad-hoc using e.g.
x11,x11-xcursor,x11-xrandr, ...
I think the idea is that if they're all conceptually part of the same feature, then you list them as "x11", "x11" and "x11".
Example: https://sources.debian.org/src/systemd/257.5-2/src/shared/tpm2-util.c/ dlopens libtss2-esys.so.0 and libtss2-rc.so.0 (and more) for the "tpm" feature.
Small detail, is AppIndicator recorded with the Tray submodule? Should it be?
@madebr, is there any reason this is still draft and shouldn't be merged for 3.4.0?
@madebr, is there any reason this is still draft and shouldn't be merged for 3.4.0?
i wanted a review on my use of the priorities and whether the names are somewhat correct.
Looks good to me!
Typically we don't do review while PRs are in the draft stage.