Mir

Merge lp:~raof/mir/new-dso-versioning-policy into lp:mir

Proposed by Chris Halse Rogers on 2015-10-02
Status: Merged
Approved by: Daniel van Vugt on 2015-10-06
Approved revision: 2984
Merged at revision: 2994
Proposed branch: lp:~raof/mir/new-dso-versioning-policy
Merge into: lp:mir
Diff against target: 137 lines (+49/-16)
3 files modified
CMakeLists.txt (+8/-0)
cmake/MirCommon.cmake (+26/-0)
doc/dso_versioning_guide.md (+15/-16)
To merge this branch: bzr merge lp:~raof/mir/new-dso-versioning-policy
Reviewer Review Type Date Requested Status
Andreas Pokorny (community) Approve on 2015-10-05
Alan Griffiths 2015-10-02 Approve on 2015-10-05
Daniel van Vugt Abstain on 2015-10-05
PS Jenkins bot continuous-integration Approve on 2015-10-02
Review via email: mp+273186@code.launchpad.net

Commit Message

New DSO versioning guide, plus a new release-checks target to help the release manager follow it.

Description of the Change

New DSO versioning guide, plus a release check.

To post a comment you must log in.
Alan Griffiths (alan-griffiths) wrote :

I don't have a strong opinion against, but this "unreleased" stuff wasn't part of the discussion I thought this was summarizing. Why has it been added?

review: Needs Information
Chris Halse Rogers (raof) wrote :

Because while writing up the discussion I thought that doing the unreleased thing would be a good idea, and so I proposed it for discussion here. :)

Specifically - this makes it very clear what to do when introducing new symbols: you add it to MIR_*_unreleased, or create the MIR_*_unreleased stanza if one does not already exist. The scheme proposed in the ML thread solves the problem of “was MIR_CLIENT_9.1 in the latest release, or do I have to bump it?”, but replaces this problem with “have we branched for release yet?”¹. This _unreleased proposal solves both problems.

That then puts a bit more burden on the release manager, which I've attempted to ameliorate with the “release-checks” target.

This *does* mean that we break ABI between development and release, but since we only ship releases, that's fine.

¹: You crazy folk on European time might have a better idea of when this happens than I do, though.

Chris Halse Rogers (raof) wrote :

Additionally: If we wanted to, I could probably wrangle an abi-check target to fail if the branch changes any ABI *except* by removal and/or addition to an _unreleased stanza. This would then require you to comment out any symbols that you change the ABI of and move them to _unreleased.

For example, adding a new method foo to the graphics::Display interface you'd need to comment out vtable?for?mir::graphics::Display; in MIRPLATFORM_11 and add it to MIRPLATFORM_unreleased in addition to adding the new mir::graphics::Display::foo*; symbol to MIR_PLATFORM_unreleased.

This would be something approximating the append-only ABI specification we've discussed in the past. I think it'd be onerous for us to use at the moment for anything but mirclient, but maybe in the golden vaguely-stable-ABI future...

Daniel van Vugt (vanvugt) wrote :

Thanks; that's my preferred design too, relating ABIs to Mir releases:
   MIR_CLIENT_0.17 {

Only one gothcha: As this now relates to Mir releases and we hope to not break ABIs every release, some unusual symlinks will be needed when it's implemented:

   libmirclient.so.0.17 -> libmirclient.so.0.18.0
   libmirclient.so.0.18.0 // contains MIR_CLIENT_0.17 and MIR_CLIENT_0.18 symbols

Slightly confusing, but good I think. It's less confusing than all the different number series we maintain today.

Chris Halse Rogers (raof) wrote :

This does not change the SONAME or filename of any of our libraries.
The MIR_CLIENT_0.17 symbols will reside inside libmirclient.so.9 as
they do now (at least until we break ABI).

Daniel van Vugt (vanvugt) wrote :

That sounds like a reasonable transition, although a little confusing. We might choose to force an ABI break to complete the transition to the new scheme. Although definitely not till after wily is done and we're sure we're targeting 16.04 only...

Chris Halse Rogers (raof) wrote :

No more confusing than std::system_error having a symbol version of
GLIBCXX_3.4.11 but being defined in libstdc++.so.6. This is a common
practice.

To be clear, in this proposal when we break mirclient ABI
libmirclient.so.9 will be replaced by libmirclient.so.10.

Daniel van Vugt (vanvugt) wrote :

If that's true then I disapprove. However since we're talking about the future, I will assume the file names will catch up as I've suggested.

review: Abstain
Alan Griffiths (alan-griffiths) wrote :

> That then puts a bit more burden on the release manager, which I've attempted
> to ameliorate with the “release-checks” target.

Yes, both in creating the release branch *and* in merging back changes to a stanza that may get updated during the release process.

> ¹: You crazy folk on European time might have a better idea of when this
> happens than I do, though.

I don't think we do.

review: Approve
Andreas Pokorny (andreas-pokorny) wrote :

ok

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-09-24 15:42:21 +0000
3+++ CMakeLists.txt 2015-10-02 08:07:06 +0000
4@@ -245,3 +245,11 @@
5 add_custom_target(ptest
6 COMMAND "${CMAKE_SOURCE_DIR}/tools/run_ctests.sh" "--cost-file" "${CMAKE_BINARY_DIR}/ptest_ctest_cost_data.txt" "sh ${CMAKE_BINARY_DIR}/discover_all_tests.sh" "--" "$$ARGS"
7 )
8+
9+add_custom_target(release-checks)
10+
11+mir_check_no_unreleased_symbols(mirclient release-checks)
12+mir_check_no_unreleased_symbols(mircookie release-checks)
13+mir_check_no_unreleased_symbols(mirplatform release-checks)
14+mir_check_no_unreleased_symbols(mirprotobuf release-checks)
15+mir_check_no_unreleased_symbols(mirserver release-checks)
16
17=== modified file 'cmake/MirCommon.cmake'
18--- cmake/MirCommon.cmake 2015-09-17 20:32:32 +0000
19+++ cmake/MirCommon.cmake 2015-10-02 08:07:06 +0000
20@@ -219,3 +219,29 @@
21 "echo \"set_tests_properties(${MAT_NAME} PROPERTIES WORKING_DIRECTORY \\\"${MAT_WORKING_DIRECTORY}\\\")\"\n")
22 endif()
23 endfunction()
24+
25+function (mir_check_no_unreleased_symbols TARGET DEPENDENT_TARGET)
26+ set(TARGET_NAME "Checking-${TARGET}-for-unreleased-symbols")
27+ add_custom_target(
28+ ${TARGET_NAME}
29+ # Some sort of documentation for this awk monstrosity:
30+ #
31+ # Objdump format is:
32+ #
33+ # $ADDRESS $FLAGS $SECTION $SIZE $SYMVER $NAME
34+ #
35+ # Sadly, $FLAGS is fixed-width but contains 1 or more fields separated by whitespace,
36+ # but the rest of the fields are *not* fixed witdth.
37+ #
38+ # So:
39+ #
40+ # We look only at the lines which start with a digit; these are the lines containing symbols.
41+ # Then, we loop through the fields until we find one matching exactly "D."; this will be the $FLAGS
42+ # section with D(ynamic symbol) then some other modifier.
43+ # Then we check that the next field ($SECTION) is not *UND* (ie: this symbol is defined in this DSO).
44+ # *Then* we check that the $SYMVER field does not match "unreleased"
45+ COMMAND /bin/sh -c "objdump -T $<TARGET_FILE:${TARGET}> | awk '/^[[:digit:]]+.*/ { for (i = 2 ; i <= NF ; i++) { if ($i ~ \"^D.\$\") { i++ ; if (\$i != \"*UND*\") { i = i+2 ; if (\$i ~ \"unreleased\") { print ; exit 1}}}}}'"
46+ VERBATIM
47+ )
48+ add_dependencies(${DEPENDENT_TARGET} ${TARGET_NAME})
49+endfunction()
50
51=== modified file 'doc/dso_versioning_guide.md'
52--- doc/dso_versioning_guide.md 2015-04-28 07:54:10 +0000
53+++ doc/dso_versioning_guide.md 2015-10-02 08:07:06 +0000
54@@ -6,14 +6,13 @@
55
56 There are more detailed descriptions below, but as a general rule:
57
58- - If you add a new symbol, add it to a _new_ dotted-decimal version stanza,
59- like `MIR_CLIENT_8.1`, `MIR_CLIENT_8.2`, etc.
60- - If you change the behaviour or signature of a symbol and not change SONAME,
61- see "Change symbols without breaking ABI" below
62- - If you change SONAME, collect all previous symbol version stanzas into a
63- single labelled with the new SOVER. For example, remove the `MIR_CLIENT_8`,
64- `MIR_CLIENT_8.1`, and `MIR_CLIENT_8.2` stanzas and consolidate their
65- contents into a single new `MIR_CLIENT_9` stanza.
66+ - If you add a new symbol, add it to the `*_unreleased` version stanza,
67+ like `MIR_CLIENT_unreleased`, `MIR_PLATFORM_unreleased`, etc.
68+ - If you change the behaviour or signature of a symbol _and_ wish to preserve
69+ backward compatibility, see "Change symbols without breaking ABI" below.
70+ - At release time, rename the current `*_unversioned` stanzas to have the
71+ version of the current release, like `MIR_CLIENT_0.17`, `MIR_PLATFORM_0.17`,
72+ etc.
73
74 Can I have some details?
75 ------------------------
76@@ -89,19 +88,19 @@
77 When you add new symbols, add them to a new `version` block in the relevant
78 `symbols.map` file, like so:
79
80- MIR_CLIENT_8 {
81+ MIR_CLIENT_0.17 {
82 global:
83 mir_connect_sync;
84 ...
85 /* Other symbols go here */
86 };
87
88- MIR_CLIENT_8.1 {
89+ MIR_CLIENT_unreleased {
90 global:
91 mir_connect_new_symbol;
92 local:
93 *;
94- } MIR_CLIENT_8;
95+ } MIR_CLIENT_0.17;
96
97 Note that the script is read top to bottom; wildcards are greedily bound when
98 first encountered, so to avoid surprises you should only have a wildcard in the
99@@ -133,33 +132,33 @@
100
101 `mir_connection_api.cpp`:
102
103- __asm__(".symver old_mir_connection_create_surface,mir_connection_create_surface@MIR_CLIENT_8");
104+ __asm__(".symver old_mir_connection_create_surface,mir_connection_create_surface@MIR_CLIENT_0.17");
105
106 extern "C" MirWaitHandle* old_mir_connection_create_surface(...)
107 /* The old implementation */
108
109 /* The @@ specifies that this is the default version */
110- __asm__(".symver mir_connection_create_surface,mir_connection_create_surface@@@MIR_CLIENT_8.1");
111+ __asm__(".symver mir_connection_create_surface,mir_connection_create_surface@@@MIR_CLIENT_unreleased");
112 MirWaitHandle* mir_connection_create_surface(...)
113 /* The new implementation */
114
115 `symbols.map`:
116
117- MIR_CLIENT_8 {
118+ MIR_CLIENT_0.17 {
119 global:
120 ...
121 mir_connection_create_surface;
122 ...
123 };
124
125- MIR_CLIENT_8.1 {
126+ MIR_CLIENT_unreleased {
127 global:
128 ...
129 mir_connection_create_surface;
130 ...
131 local:
132 *;
133- } MIR_CLIENT_8;
134+ } MIR_CLIENT_0.17;
135
136 Safely load multiple versions of a library into the same address space
137 ----------------------------------------------------------------------

Subscribers

People subscribed via source and target branches