···4444* @ref implementing-extension
4545* @ref how-to-release
4646* @ref winbuild
4747+* @ref packaging-notes - for people maintaining Linux packages of Monado
47484849## Design Documentation
4950
+84
doc/packaging-notes.md
···11+# Packaging Notes {#packaging-notes}
22+33+<!--
44+Copyright 2023-2024, Collabora, Ltd. and the Monado contributors
55+SPDX-License-Identifier: BSL-1.0
66+-->
77+88+## The SONAME and library location question
99+1010+_AKA, "Why does `libopenxr_monado.so` not have a versioned SONAME? Can I move it
1111+to a subdirectory of the library path?"_
1212+1313+To understand this, it helps to keep in mind how OpenXR works from an
1414+application point of view. Applications are intended to be runtime-independent
1515+and portable, using the user's current runtime wherever they are executed. The
1616+[OpenXR Loader][] is the library that applications link against to achieve this:
1717+it provides a layer of indirection. It also allows for the use of API layers
1818+with runtimes, and handles runtime finding. Follow that link for more
1919+information from the design documents.
2020+2121+The TL;DR version is this: `libopenxr_monado` not having a versioned SONAME yet
2222+being installed in the default library path is **not an error or oversight**,
2323+but a carefully-reasoned technical decision. Do not patch this or change it in
2424+distribution packages without understanding what design choices and features you
2525+break by doing so.
2626+2727+[OpenXR Loader]: https://registry.khronos.org/OpenXR/specs/1.1/loader.html
2828+2929+### My package linter is complaining that `libopenxr_monado.so` does not have a versioned SONAME
3030+3131+Monado (as well as OpenXR API layers) are like Vulkan drivers (technically ICDs)
3232+and API layers, in that they are only used behind a loader doing runtime dynamic
3333+linking/late loading. A versioned `SONAME` makes no real sense for them, but
3434+sometimes you do want them in the default dynamic library load path.
3535+3636+You never link against the OpenXR runtime interface of Monado directly, it's
3737+loaded dynamically at runtime by the OpenXR loader after reading configurations
3838+and manifest files. The OpenXR loader _does_ have a versioned SONAME on Linux,
3939+where it might be system installed. This is why it makes no sense to have a
4040+SONAME for the runtime SO: the compatibility of that SO is defined by the
4141+manifest that is installed and the OpenXR spec itself.
4242+4343+At some point we might give up and set a versioned SONAME for
4444+`libopenxr_monado`, but it would not improve anything about the software other
4545+than its compliance with external rules that do not consider how the software is
4646+designed or used. Furthermore, it would likely lead to increased
4747+misunderstandings in how OpenXR and Monado are intended to be used by
4848+developers. The only public interface of that `libopenxr_monado.so` is strictly
4949+specified by the [OpenXR specification][] in general, with its exported symbols
5050+specified by the [Runtime Interface Negotiation][] section.
5151+5252+[OpenXR specification]: https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html
5353+[Runtime Interface Negotiation]: https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#api-initialization-runtime-interface-negotiation
5454+5555+Note: `libmonado`, which _does_ have a public API as a management interface for
5656+software serving as a Monado front-end or dashboard, _does_ have a versioned
5757+SONAME.
5858+5959+### My package linter is complaining that without a versioned SONAME, `libopenxr_monado.so` should move to a private subdirectory of `/usr/lib/...`
6060+6161+Why can we not move that library off of the main dynamic loader path? It is true
6262+that OpenXR API layers can live in a subdirectory of the dynamic library path,
6363+because the loader will try to load layers from all the manifests and ignore the
6464+ones whose library it cannot load, resolving multi-arch issues by trying all
6565+architectures. However, until a change to the OpenXR loader in OpenXR SDK 1.0.29
6666+(from late 2023), the only way to get multi-arch support with an OpenXR
6767+_runtime_ on Linux was to:
6868+6969+- Place the binary in the correct library directory for the architecture
7070+- Put only the library name in the runtime manifest (rather than a relative or
7171+ absolute path) - turn off both `XRT_OPENXR_INSTALL_ABSOLUTE_RUNTIME_PATH` and
7272+ `XRT_OPENXR_INSTALL_ABSOLUTE_RUNTIME_PATH` for this to happen.
7373+7474+When this is done, the loader uses the normal library search path to find the
7575+runtime, which gives you the right architecture for the application.
7676+Essentially, it lets the loader use the same argument to `dlopen` regardless of
7777+architecture, and get the right library. This allows, e.g. a 32-bit application
7878+to use the 32-bit version of `libopenxr_monado`, typically to talk to the 64-bit
7979+`monado-service` instance.
8080+8181+At some point it would be nice to generate the architecture-specific runtime
8282+manifests for Monado. However, it makes selecting runtimes system-wide using
8383+`alternatives` or similar more complex, as you would need to update multiple
8484+symlinks.