aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/optional_packages.txt
blob: 47c8302629157b9e91637dd7f0588da92396a6a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

Optional packages
=================

Use weak symbols to implement optional packages?
- problem: DT_NEEDED will still be needed
  (but it can be specified in a dependency)
- problem: optional dependencies on newer versions?


    \slul 0.0.0
    \name test
    ...
    \depends somelib 1.2 optional
    \depends somelib 1.1

    #type optional SomeThing

    func optional SomeThing.do_new_stuff()
    {
        this.do_old_stuff()
    }

Feature-flags?
--------------

Example library:

    \slul 0.0.0
    \name somelib
    \type library
    \version 1.0
    \feature the_feature since 1.0
    \feature other_feature since 1.0
    \depends featurelib 2.1 optional(the_feature)
    \interface_depends iflib 3.5 since 1.0 optional(the_feature or other_feature)

    type SomeLib

    func optional(the_feature and other_feature) SomeLib.do_stuff(ref IfLib x)
    {
        x.do_stuff(this.xyz)
    }

Example library client:

    \slul 0.0.0
    \name test
    ...
    \depends somelib(the_feature+other_feature) 1.2
    \depends iflib 3.5

    ...

    func SlulApp.main() -> SlulExitStatus
    {
        ref SomeLib obj = .new()
        ref IfLib other = .new()
        obj.do_stuff(other)
        return .success
    }

Custom "late-loading" of optional libs via slulrt
-------------------------------------------------

We can't use DT_NEEDED and we also can't use required dynsyms.

Alternative solution: Use a custom DT_ tag, e.g. "DT_SLUL_DESIRED".
This probably requires a custom .dymsym and some kind of custom
got/plt/relro handling.

The startup code in libslulrt could then scan all loaded modules
for this DT_ tag, and if found:

1. attempt to load the libraries
    - note: they can have nested dependencies! including native libraries!
      perhaps dlopen should be used? but it can be blocked with nodlopen :(
    - note 2: they might already be loaded by the rtld (either as a nested
      dependency, or, if desired-symbols are supported by the rtld, even
      direct dependencies might have been loaded).
2. process dynamic symbols.
   perhaps these should go into a separate section (and have a separate DT_
   tag, e.g. ".dynsym.desired" / DT_SLUL_SYMTAB_DESIRED)

Service-Provider-Interface
--------------------------

Perhaps it should be possible for libraries to declare that they implement
one of more Service Provider Interfaces?

Do names of Service Provider Interfaces need namespacing?
They should probably be tied to some library (or function).

And it could use a table, referenced by DT_ tags:

    DT_SLUL_SPIIMPL     <offset>
    DT_SLUL_SPIIMPLSZ   <record size>

Table definition:

    Elf??_Xword     spi_iface_dynsym    (e.g. ImageLib_???)
    Elf??_Xword     spi_impl_ctor       (e.g. Png_create)

(perhaps merge the table and the .dynsym.desired?)