xref: /aosp_15_r20/external/f2fs-tools/VERSIONING (revision 59bfda1f02d633cd6b8b69f31eee485d40f6eef6)
1*59bfda1fSAndroid Build Coastguard Worker-------------------
2*59bfda1fSAndroid Build Coastguard WorkerWritten by Ted T'so
3*59bfda1fSAndroid Build Coastguard Worker-------------------
4*59bfda1fSAndroid Build Coastguard Worker
5*59bfda1fSAndroid Build Coastguard Worker> https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
6*59bfda1fSAndroid Build Coastguard Worker>
7*59bfda1fSAndroid Build Coastguard Worker> I understood that, if there is no interface change but some implementation
8*59bfda1fSAndroid Build Coastguard Worker> changes, I need to bump revision. If new interface is added, for example, I
9*59bfda1fSAndroid Build Coastguard Worker> need to bump current while revision=0 and age++.
10*59bfda1fSAndroid Build Coastguard Worker
11*59bfda1fSAndroid Build Coastguard WorkerSo part of the problem here is that libtool is doing something really
12*59bfda1fSAndroid Build Coastguard Workerstrange because they are trying to use some abstract concept that is
13*59bfda1fSAndroid Build Coastguard WorkerOS-independent.  I don't use libtool because I find it horribly
14*59bfda1fSAndroid Build Coastguard Workercomplex and doesn't add enough value to be worth the complexity.
15*59bfda1fSAndroid Build Coastguard Worker
16*59bfda1fSAndroid Build Coastguard WorkerSo I'll tell you how things work with respect to Linux's ELF version
17*59bfda1fSAndroid Build Coastguard Workernumbering system.  Translating this to libtool's wierd "current,
18*59bfda1fSAndroid Build Coastguard Workerrevision, age" terminology is left as an exercise to the reader.  I've
19*59bfda1fSAndroid Build Coastguard Workerlooked at the libtool documentation, and it confuses me horribly.
20*59bfda1fSAndroid Build Coastguard WorkerReading it, I suspect it's wrong, but I don't have the time to
21*59bfda1fSAndroid Build Coastguard Workerexperiment to confirm that the documentation is wrong and how it
22*59bfda1fSAndroid Build Coastguard Workerdiverges from the libtool implementation.
23*59bfda1fSAndroid Build Coastguard Worker
24*59bfda1fSAndroid Build Coastguard WorkerSo let me explain things using the ELF shared library terminology,
25*59bfda1fSAndroid Build Coastguard Workerwhich is "major version, minor version, patchlevel".  This shows up in
26*59bfda1fSAndroid Build Coastguard Workerthe library name:
27*59bfda1fSAndroid Build Coastguard Worker
28*59bfda1fSAndroid Build Coastguard Worker	libudev.so.1.6.11
29*59bfda1fSAndroid Build Coastguard Worker
30*59bfda1fSAndroid Build Coastguard WorkerSo in this example, the major version number is 1, the minor version
31*59bfda1fSAndroid Build Coastguard Workeris 6, and the patchlevel is 11.  The patchlevel is entirely optional,
32*59bfda1fSAndroid Build Coastguard Workerand many packages don't use it at all.  The minor number is also
33*59bfda1fSAndroid Build Coastguard Workermostly useless on Linux, but it's still there for historical reasons.
34*59bfda1fSAndroid Build Coastguard WorkerThe patchlevel and minor version numbers were useful back for SunOS
35*59bfda1fSAndroid Build Coastguard Worker(and Linux a.out shared library), back when there weren't rpm and dpkg
36*59bfda1fSAndroid Build Coastguard Workeras package managers.
37*59bfda1fSAndroid Build Coastguard Worker
38*59bfda1fSAndroid Build Coastguard WorkerSo many modern Linux shared libraries will only use the major and
39*59bfda1fSAndroid Build Coastguard Workerminor version numbers, e.g:
40*59bfda1fSAndroid Build Coastguard Worker
41*59bfda1fSAndroid Build Coastguard Worker	libext2fs.so.2.4
42*59bfda1fSAndroid Build Coastguard Worker
43*59bfda1fSAndroid Build Coastguard WorkerThe only thing you really need to worry about is the major version
44*59bfda1fSAndroid Build Coastguard Workernumber, really.  The minor version is *supposed* to change when new
45*59bfda1fSAndroid Build Coastguard Workerinterfaces has changed (but I and most other people don't do that any
46*59bfda1fSAndroid Build Coastguard Workermore).  But the big deal is that the major number *must* get bumped if
47*59bfda1fSAndroid Build Coastguard Workeran existing interface has *changed*.
48*59bfda1fSAndroid Build Coastguard Worker
49*59bfda1fSAndroid Build Coastguard WorkerSo let's talk about the major version number, and then we'll talk
50*59bfda1fSAndroid Build Coastguard Workerabout why the minor version number isn't really a big deal for Linux.
51*59bfda1fSAndroid Build Coastguard Worker
52*59bfda1fSAndroid Build Coastguard WorkerSo if you change any of the library's function signatures --- and this
53*59bfda1fSAndroid Build Coastguard Workerincludes changing a type from a 32-bit integer to a 64-bit integer,
54*59bfda1fSAndroid Build Coastguard Workerthat's an ABI breakage, and so you must bump the major version number
55*59bfda1fSAndroid Build Coastguard Workerso that a program that was linked against libfoo.so.4 doesn't try to
56*59bfda1fSAndroid Build Coastguard Workeruse libfoo.so.5.  That's really the key --- will a program linked
57*59bfda1fSAndroid Build Coastguard Workeragainst the previous version library break if it links against the
58*59bfda1fSAndroid Build Coastguard Workernewer version.  If it does, then you need to bump the version number.
59*59bfda1fSAndroid Build Coastguard Worker
60*59bfda1fSAndroid Build Coastguard WorkerSo for structures, if you change any of the existing fields, or if the
61*59bfda1fSAndroid Build Coastguard Workerapplication program allocates the structure --- either by declaring it
62*59bfda1fSAndroid Build Coastguard Workeron the stack, or via malloc() --- and you expand the structure,
63*59bfda1fSAndroid Build Coastguard Workerobviously that will cause problem, and so that's an ABI break.
64*59bfda1fSAndroid Build Coastguard Worker
65*59bfda1fSAndroid Build Coastguard WorkerIf however, you arrange to have structures allocated by the library,
66*59bfda1fSAndroid Build Coastguard Workerand struct members are always added at the end, then an older program
67*59bfda1fSAndroid Build Coastguard Workerwon't have any problems.  You can guarantee this by simply only using
68*59bfda1fSAndroid Build Coastguard Workera pointer to the struct in your public header files, and defining the
69*59bfda1fSAndroid Build Coastguard Workerstruct in a private header file that is not available to userspace
70*59bfda1fSAndroid Build Coastguard Workerprograms.
71*59bfda1fSAndroid Build Coastguard Worker
72*59bfda1fSAndroid Build Coastguard WorkerSimilarly, adding new functions never breaks the ABI.  That's because
73*59bfda1fSAndroid Build Coastguard Workerolder program won't try to use the newer interfaces.  So if I need to
74*59bfda1fSAndroid Build Coastguard Workerchange an interface to a function, what I'll generally do is to define
75*59bfda1fSAndroid Build Coastguard Workera new function, and then implement the older function in terms of the
76*59bfda1fSAndroid Build Coastguard Workernewer one.  For example:
77*59bfda1fSAndroid Build Coastguard Worker
78*59bfda1fSAndroid Build Coastguard Workerextern errcode_t ext2fs_open(const char *name, int flags, int superblock,
79*59bfda1fSAndroid Build Coastguard Worker			     unsigned int block_size, io_manager manager,
80*59bfda1fSAndroid Build Coastguard Worker			     ext2_filsys *ret_fs);
81*59bfda1fSAndroid Build Coastguard Worker
82*59bfda1fSAndroid Build Coastguard Workerextern errcode_t ext2fs_open2(const char *name, const char *io_options,
83*59bfda1fSAndroid Build Coastguard Worker			      int flags, int superblock,
84*59bfda1fSAndroid Build Coastguard Worker			      unsigned int block_size, io_manager manager,
85*59bfda1fSAndroid Build Coastguard Worker			      ext2_filsys *hret_fs);
86*59bfda1fSAndroid Build Coastguard Worker
87*59bfda1fSAndroid Build Coastguard WorkerAs far as the minor version numbers are concerned, the dynamic linker
88*59bfda1fSAndroid Build Coastguard Workerdoesn't use it.  In SunOS 4, if you have a DT_NEEDED for libfoo.so.4,
89*59bfda1fSAndroid Build Coastguard Workerand the dynamic linker finds in its search path:
90*59bfda1fSAndroid Build Coastguard Worker
91*59bfda1fSAndroid Build Coastguard Worker    libfoo.so.4.8
92*59bfda1fSAndroid Build Coastguard Worker    libfoo.so.4.9
93*59bfda1fSAndroid Build Coastguard Worker
94*59bfda1fSAndroid Build Coastguard WorkerIt will preferentially use libfoo.so.4.9.
95*59bfda1fSAndroid Build Coastguard Worker
96*59bfda1fSAndroid Build Coastguard WorkerThat's not how it works in Linux, though.  In Linux there will be a
97*59bfda1fSAndroid Build Coastguard Workersymlink that points libfoo.so.4 to libfoo.so.4.9, and the linker just
98*59bfda1fSAndroid Build Coastguard Workerlooks for libfoo.so.4.  One could imagine a package manager which
99*59bfda1fSAndroid Build Coastguard Workeradjusts the symlink to point at the library with the highest version,
100*59bfda1fSAndroid Build Coastguard Workerbut given that libfoo.so.4.9 is supposed to contain a superset of
101*59bfda1fSAndroid Build Coastguard Workerlibfoo.so.4.8, there's no point.  So we just in practice handle all of
102*59bfda1fSAndroid Build Coastguard Workerthis in the package manager, or via an ELF symbol map.  Or, we just
103*59bfda1fSAndroid Build Coastguard Workerassume that since vast majority of software comes from the
104*59bfda1fSAndroid Build Coastguard Workerdistribution, the distro package manager will just update libraries to
105*59bfda1fSAndroid Build Coastguard Workerthe newer version as a matter of course, and nothing special needs to
106*59bfda1fSAndroid Build Coastguard Workerbe done.
107*59bfda1fSAndroid Build Coastguard Worker
108*59bfda1fSAndroid Build Coastguard WorkerSo in practice I don't bump the minor version number for e2fsprogs
109*59bfda1fSAndroid Build Coastguard Workereach time I add new interfaces, because in practice it really doesn't
110*59bfda1fSAndroid Build Coastguard Workermatter for Linux.  We have a much better system that gets used for
111*59bfda1fSAndroid Build Coastguard WorkerDebian.
112*59bfda1fSAndroid Build Coastguard Worker
113*59bfda1fSAndroid Build Coastguard WorkerFor example in Debian there is a file that contains when each symbol
114*59bfda1fSAndroid Build Coastguard Workerwas first introduced into a library, by its package version number.
115*59bfda1fSAndroid Build Coastguard WorkerSee:
116*59bfda1fSAndroid Build Coastguard Worker
117*59bfda1fSAndroid Build Coastguard Workerhttps://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/debian/libext2fs2.symbols
118*59bfda1fSAndroid Build Coastguard Worker
119*59bfda1fSAndroid Build Coastguard WorkerThis file contains a version number for each symbol in libext2fs2, and
120*59bfda1fSAndroid Build Coastguard Workerit tells us what version of libext2fs you need to guarantee that a
121*59bfda1fSAndroid Build Coastguard Workerparticular symbol is present in the library.  Then when *other*
122*59bfda1fSAndroid Build Coastguard Workerpackages are built that depend on libext2fs2, the minimum version of
123*59bfda1fSAndroid Build Coastguard Workerlibext2fs can be calculated based on which symbols they use.
124*59bfda1fSAndroid Build Coastguard Worker
125*59bfda1fSAndroid Build Coastguard WorkerSo for example the libf2fs-format4 package has a Debian dependency of:
126*59bfda1fSAndroid Build Coastguard Worker
127*59bfda1fSAndroid Build Coastguard WorkerDepends: libblkid1 (>= 2.17.2), libc6 (>= 2.14), libf2fs5, libuuid1 (>= 2.16)
128*59bfda1fSAndroid Build Coastguard Worker
129*59bfda1fSAndroid Build Coastguard WorkerThe minimum version numbers needed for libblkid1 and libuuid1 are
130*59bfda1fSAndroid Build Coastguard Workerdetermined by figuring out all of the symbols used by the
131*59bfda1fSAndroid Build Coastguard Workerlibf2fs-format4 package, and determining the minimum version number of
132*59bfda1fSAndroid Build Coastguard Workerlibblkid1 that supports all of those blkid functions.
133*59bfda1fSAndroid Build Coastguard Worker
134*59bfda1fSAndroid Build Coastguard WorkerThis gets done automatically, so I didn't have to figure this out.
135*59bfda1fSAndroid Build Coastguard WorkerAll I have in the debian/control file is:
136*59bfda1fSAndroid Build Coastguard Worker
137*59bfda1fSAndroid Build Coastguard WorkerDepends: ${misc:Depends}, ${shlibs:Depends}
138*59bfda1fSAndroid Build Coastguard Worker
139*59bfda1fSAndroid Build Coastguard WorkerSorry this got so long, but hopefully you'll find this useful.  How
140*59bfda1fSAndroid Build Coastguard Workeryou bend libtool to your will is something you'll have to figure out,
141*59bfda1fSAndroid Build Coastguard Workerbecause I don't use libtool in my packages.[1]
142*59bfda1fSAndroid Build Coastguard Worker
143*59bfda1fSAndroid Build Coastguard WorkerCheers,
144*59bfda1fSAndroid Build Coastguard Worker
145*59bfda1fSAndroid Build Coastguard Worker					- Ted
146*59bfda1fSAndroid Build Coastguard Worker
147*59bfda1fSAndroid Build Coastguard Worker
148*59bfda1fSAndroid Build Coastguard Worker[1] If you are interested in how I do things in e2fsprogs, take a look
149*59bfda1fSAndroid Build Coastguard Workerat the Makefile.elf-lib, Makefile.solaris-lib, Makefile.darwin-lib,
150*59bfda1fSAndroid Build Coastguard Workeretc. here:
151*59bfda1fSAndroid Build Coastguard Worker
152*59bfda1fSAndroid Build Coastguard Workerhttps://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/lib
153*59bfda1fSAndroid Build Coastguard Worker
154*59bfda1fSAndroid Build Coastguard WorkerThis these Makefile fragments are then pulled into the generated
155*59bfda1fSAndroid Build Coastguard Workermakefile using autoconf's substitution rules, here:
156*59bfda1fSAndroid Build Coastguard Worker
157*59bfda1fSAndroid Build Coastguard Workerhttps://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/lib/ext2fs/Makefile.in
158*59bfda1fSAndroid Build Coastguard Worker
159*59bfda1fSAndroid Build Coastguard Worker(Search for "@MAKEFILE_ELF@" in the above Makefile.in).
160*59bfda1fSAndroid Build Coastguard Worker
161*59bfda1fSAndroid Build Coastguard WorkerSo when someone runs "configure --enable-elf-shlibs", they get the ELF
162*59bfda1fSAndroid Build Coastguard Workershared libraries built.  On BSD and MacOS systems they just have to
163*59bfda1fSAndroid Build Coastguard Workerrun "configure --enable-bsd-shlibs", and so on.
164*59bfda1fSAndroid Build Coastguard Worker
165*59bfda1fSAndroid Build Coastguard WorkerPersonally, since most people don't bother to write truly portable
166*59bfda1fSAndroid Build Coastguard Workerprograms, as their C code is full of Linux'isms, using libtool is just
167*59bfda1fSAndroid Build Coastguard Workeroverkill, because they probably can't build on any other OS *anyway*
168*59bfda1fSAndroid Build Coastguard Workerso libtool's slow and complex abstraction layer is totally wasted.
169*59bfda1fSAndroid Build Coastguard WorkerMight as well not use autoconf, automake, and libtool at all.
170*59bfda1fSAndroid Build Coastguard Worker
171*59bfda1fSAndroid Build Coastguard WorkerOn the other hand, if you really *do* worry about portability on other
172*59bfda1fSAndroid Build Coastguard WorkerOS's (e2fsprogs builds on MacOS, NetBSD, Hurd, Solaris, etc.) then
173*59bfda1fSAndroid Build Coastguard Workerusing autoconf makes sense --- but I *still* don't think the
174*59bfda1fSAndroid Build Coastguard Workercomplexity of libtool is worth it.
175*59bfda1fSAndroid Build Coastguard Worker
176*59bfda1fSAndroid Build Coastguard Worker= Add-on =
177*59bfda1fSAndroid Build Coastguard WorkerIf you are going to be making one less major update, this is the
178*59bfda1fSAndroid Build Coastguard Workerperfect time to make sure that data structures are allocated by the
179*59bfda1fSAndroid Build Coastguard Workerlibrary, and are (ideally) opaque to the calling application (so they
180*59bfda1fSAndroid Build Coastguard Workeronly manipulate structure poitners).  That is, the structure
181*59bfda1fSAndroid Build Coastguard Workerdefinition is not exposed in the public header file, and you use
182*59bfda1fSAndroid Build Coastguard Workeraccessor functions to set and get fields in the structure.
183*59bfda1fSAndroid Build Coastguard Worker
184*59bfda1fSAndroid Build Coastguard WorkerIf you can't do that for all data structures, if you can do that with
185*59bfda1fSAndroid Build Coastguard Workeryour primary data structure that's going to make your life much easier
186*59bfda1fSAndroid Build Coastguard Workerin the long term.  For ext2fs, that's the file systme handle.  It's
187*59bfda1fSAndroid Build Coastguard Workercreated by ext2fs_open(), and it's passed to all other library
188*59bfda1fSAndroid Build Coastguard Workerfunctions as the first argument.
189*59bfda1fSAndroid Build Coastguard Worker
190*59bfda1fSAndroid Build Coastguard WorkerThe other thing you might want to consider doing is adding a magic
191*59bfda1fSAndroid Build Coastguard Workernumber to the beginning of each structure.  That way you can tell if
192*59bfda1fSAndroid Build Coastguard Workerthe wrong structure gets passed to a library.  It's also helpful for
193*59bfda1fSAndroid Build Coastguard Workerdoing the equivalent of subclassing in C.
194*59bfda1fSAndroid Build Coastguard Worker
195*59bfda1fSAndroid Build Coastguard WorkerThis is how we do it in libext2fs --- we use com_err to define the
196*59bfda1fSAndroid Build Coastguard Workermagic numbers:
197*59bfda1fSAndroid Build Coastguard Worker
198*59bfda1fSAndroid Build Coastguard Worker	error_table ext2
199*59bfda1fSAndroid Build Coastguard Worker
200*59bfda1fSAndroid Build Coastguard Workerec	EXT2_ET_BASE,
201*59bfda1fSAndroid Build Coastguard Worker	"EXT2FS Library version @E2FSPROGS_VERSION@"
202*59bfda1fSAndroid Build Coastguard Worker
203*59bfda1fSAndroid Build Coastguard Workerec	EXT2_ET_MAGIC_EXT2FS_FILSYS,
204*59bfda1fSAndroid Build Coastguard Worker	"Wrong magic number for ext2_filsys structure"
205*59bfda1fSAndroid Build Coastguard Worker
206*59bfda1fSAndroid Build Coastguard Workerec	EXT2_ET_MAGIC_BADBLOCKS_LIST,
207*59bfda1fSAndroid Build Coastguard Worker	"Wrong magic number for badblocks_list structure"
208*59bfda1fSAndroid Build Coastguard Worker	...
209*59bfda1fSAndroid Build Coastguard Worker
210*59bfda1fSAndroid Build Coastguard WorkerAnd then every single structure starts like so:
211*59bfda1fSAndroid Build Coastguard Worker
212*59bfda1fSAndroid Build Coastguard Workerstruct struct_ext2_filsys {
213*59bfda1fSAndroid Build Coastguard Worker	errcode_t			magic;
214*59bfda1fSAndroid Build Coastguard Worker	...
215*59bfda1fSAndroid Build Coastguard Worker
216*59bfda1fSAndroid Build Coastguard Workerstruct ext2_struct_inode_scan {
217*59bfda1fSAndroid Build Coastguard Worker	errcode_t		magic;
218*59bfda1fSAndroid Build Coastguard Worker	...
219*59bfda1fSAndroid Build Coastguard Worker
220*59bfda1fSAndroid Build Coastguard WorkerAnd then before we use any pointer we do this:
221*59bfda1fSAndroid Build Coastguard Worker
222*59bfda1fSAndroid Build Coastguard Worker	if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
223*59bfda1fSAndroid Build Coastguard Worker		return EXT2_ET_MAGIC_EXT2_FILE;
224