diff options
author | Carsten Brandt <mail@cebe.cc> | 2017-01-15 21:22:35 +0100 |
---|---|---|
committer | Sergey 'Jin' Bostandzhyan <jin at mediatomb dot cc> | 2017-01-18 11:20:07 +0100 |
commit | 3520eee05d9828f16434f1c3591ea0f9a2153596 (patch) | |
tree | af87e5291c7eaedf3b04616ebc46ffbe95efc7c6 | |
parent | 3f24f048762736e1a5d785a080fec7e84172e708 (diff) |
SO versions for cmake and libtool
this updates the version-sync script to generate proper SO versions
which will be used by cmake and libtool to create version symlinks
on the system when a library is installed as well as setting the SO
version in the binary.
To see what this does, you have to configure tox with a prefix:
./configure --prefix=/tmp/tox-with-libtool
mkdir cbuild && cd cbuild && cmake -DCMAKE_INSTALL_PREFIX=/tmp/tox-with-cmake ..
Then run `make && make install`.
in both instances you should see the following installed in `lib/`:
libtoxcore.so -> libtoxcore.so.1.4.0
libtoxcore.so.1 -> libtoxcore.so.1.4.0
libtoxcore.so.1.4.0
inside the binary the soname should be the one with .1 and it should not
contain the full version:
$ objdump -p libtoxcore.so.1.4.0 | grep SONAME
SONAME libtoxcore.so.1
-rw-r--r-- | CMakeLists.txt | 55 | ||||
-rw-r--r-- | cmake/ModulePackage.cmake | 6 | ||||
-rwxr-xr-x | other/version-sync | 100 |
3 files changed, 136 insertions, 25 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 16f607c0..e5722ad7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -2,15 +2,47 @@ cmake_minimum_required(VERSION 2.8.6) | |||
2 | project(toxcore) | 2 | project(toxcore) |
3 | include(CTest) | 3 | include(CTest) |
4 | 4 | ||
5 | set(CMAKE_MODULE_PATH ${toxcore_SOURCE_DIR}/cmake) | ||
6 | |||
7 | ################################################################################ | ||
8 | # | ||
9 | # :: Version management | ||
10 | # | ||
11 | ################################################################################ | ||
12 | |||
5 | # This version is for the entire project. All libraries (core, av, ...) move in | 13 | # This version is for the entire project. All libraries (core, av, ...) move in |
6 | # versions in a synchronised way. | 14 | # versions in a synchronised way. |
7 | set(PROJECT_VERSION_MAJOR "0") | 15 | set(PROJECT_VERSION_MAJOR "0") |
8 | set(PROJECT_VERSION_MINOR "1") | 16 | set(PROJECT_VERSION_MINOR "1") |
9 | set(PROJECT_VERSION_PATCH "4") | 17 | set(PROJECT_VERSION_PATCH "4") |
10 | set(PROJECT_VERSION | 18 | set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") |
11 | "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") | 19 | |
20 | # Update versions in various places | ||
21 | # This must be run before setting SOVERSION, because SOVERSION is read from | ||
22 | # a file generated by this script | ||
23 | find_program(SHELL NAMES sh dash bash zsh) | ||
24 | if(SHELL) | ||
25 | execute_process( | ||
26 | COMMAND ${SHELL} ${toxcore_SOURCE_DIR}/other/version-sync | ||
27 | ${toxcore_SOURCE_DIR} | ||
28 | ${PROJECT_VERSION_MAJOR} | ||
29 | ${PROJECT_VERSION_MINOR} | ||
30 | ${PROJECT_VERSION_PATCH}) | ||
31 | endif() | ||
32 | |||
33 | # set .so library version / following libtool scheme | ||
34 | # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info | ||
35 | file(STRINGS ${toxcore_SOURCE_DIR}/so.version SOVERSION_CURRENT REGEX "^CURRENT=[0-9]+$") | ||
36 | string(SUBSTRING "${SOVERSION_CURRENT}" 8 -1 SOVERSION_CURRENT) | ||
37 | file(STRINGS ${toxcore_SOURCE_DIR}/so.version SOVERSION_REVISION REGEX "^REVISION=[0-9]+$") | ||
38 | string(SUBSTRING "${SOVERSION_REVISION}" 9 -1 SOVERSION_REVISION) | ||
39 | file(STRINGS ${toxcore_SOURCE_DIR}/so.version SOVERSION_AGE REGEX "^AGE=[0-9]+$") | ||
40 | string(SUBSTRING "${SOVERSION_AGE}" 4 -1 SOVERSION_AGE) | ||
41 | # account for some libtool magic, see other/version-sync script for details | ||
42 | math(EXPR SOVERSION_MAJOR ${SOVERSION_CURRENT}-${SOVERSION_AGE}) | ||
43 | set(SOVERSION "${SOVERSION_MAJOR}.${SOVERSION_AGE}.${SOVERSION_REVISION}") | ||
44 | message("SOVERSION: ${SOVERSION}") | ||
12 | 45 | ||
13 | set(CMAKE_MODULE_PATH ${toxcore_SOURCE_DIR}/cmake) | ||
14 | 46 | ||
15 | ################################################################################ | 47 | ################################################################################ |
16 | # | 48 | # |
@@ -593,23 +625,6 @@ endif() | |||
593 | 625 | ||
594 | ################################################################################ | 626 | ################################################################################ |
595 | # | 627 | # |
596 | # :: Update versions in various places | ||
597 | # | ||
598 | ################################################################################ | ||
599 | |||
600 | find_program(SHELL NAMES sh dash bash zsh) | ||
601 | |||
602 | if(SHELL) | ||
603 | execute_process( | ||
604 | COMMAND ${SHELL} ${toxcore_SOURCE_DIR}/other/version-sync | ||
605 | ${toxcore_SOURCE_DIR} | ||
606 | ${PROJECT_VERSION_MAJOR} | ||
607 | ${PROJECT_VERSION_MINOR} | ||
608 | ${PROJECT_VERSION_PATCH}) | ||
609 | endif() | ||
610 | |||
611 | ################################################################################ | ||
612 | # | ||
613 | # :: Strict ABI | 628 | # :: Strict ABI |
614 | # | 629 | # |
615 | # Enabling the STRICT_ABI flag will generate and use an LD version script. | 630 | # Enabling the STRICT_ABI flag will generate and use an LD version script. |
diff --git a/cmake/ModulePackage.cmake b/cmake/ModulePackage.cmake index f6e7e31a..38f841ba 100644 --- a/cmake/ModulePackage.cmake +++ b/cmake/ModulePackage.cmake | |||
@@ -56,10 +56,8 @@ function(add_module lib) | |||
56 | add_library(${lib}_shared SHARED ${ARGN}) | 56 | add_library(${lib}_shared SHARED ${ARGN}) |
57 | set_target_properties(${lib}_shared PROPERTIES | 57 | set_target_properties(${lib}_shared PROPERTIES |
58 | OUTPUT_NAME ${lib} | 58 | OUTPUT_NAME ${lib} |
59 | VERSION ${PROJECT_VERSION} | 59 | VERSION ${SOVERSION} |
60 | # While on 0.x, the x behaves like the major version. 0.2 will be | 60 | SOVERSION ${SOVERSION_MAJOR} |
61 | # incompatible with 0.1. Change this, when releasing 1.0! | ||
62 | SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} | ||
63 | ) | 61 | ) |
64 | install(TARGETS ${lib}_shared DESTINATION "lib") | 62 | install(TARGETS ${lib}_shared DESTINATION "lib") |
65 | endif() | 63 | endif() |
diff --git a/other/version-sync b/other/version-sync index 3fb1aa80..fdfe91d9 100755 --- a/other/version-sync +++ b/other/version-sync | |||
@@ -17,7 +17,9 @@ update() { | |||
17 | if diff "$file" "$file.updated-version"; then | 17 | if diff "$file" "$file.updated-version"; then |
18 | rm "$file.updated-version" | 18 | rm "$file.updated-version" |
19 | else | 19 | else |
20 | mv "$file.updated-version" "$file" | 20 | # use cat > and rm instead of move to keep file permissions |
21 | cat "$file.updated-version" > "$file" | ||
22 | rm "$file.updated-version" | ||
21 | fi | 23 | fi |
22 | } | 24 | } |
23 | 25 | ||
@@ -26,3 +28,99 @@ update 'configure.ac' 's/AC_INIT(\[tox\], \[.*\])/AC_INIT([tox], ['$VER'])/' | |||
26 | update 'toxcore/tox.api.h' 's/\(const VERSION_MAJOR *= \).*;/\1'$MAJOR';/' | 28 | update 'toxcore/tox.api.h' 's/\(const VERSION_MAJOR *= \).*;/\1'$MAJOR';/' |
27 | update 'toxcore/tox.api.h' 's/\(const VERSION_MINOR *= \).*;/\1'$MINOR';/' | 29 | update 'toxcore/tox.api.h' 's/\(const VERSION_MINOR *= \).*;/\1'$MINOR';/' |
28 | update 'toxcore/tox.api.h' 's/\(const VERSION_PATCH *= \).*;/\1'$PATCH';/' | 30 | update 'toxcore/tox.api.h' 's/\(const VERSION_PATCH *= \).*;/\1'$PATCH';/' |
31 | |||
32 | # | ||
33 | # calculating the SO version | ||
34 | # | ||
35 | # The SO version reflects changes in the ABI compatibility of the libary [1]. | ||
36 | # The general convention on this is that the SO version is a monotonically | ||
37 | # increasing number. The major version reflects breaking changes and the minor | ||
38 | # number reflect non-breaking updates [2]. | ||
39 | # | ||
40 | # The SO version for tox libraries consists of two parts: `A.B`. | ||
41 | # - incrementing A reflects an ABI breaking change. | ||
42 | # - incrementing B reflects a non-ABI-breaking update. B is set to 0 when A is incremented. | ||
43 | # | ||
44 | # As the tox versioning scheme directly reflects ABI compatibility, we can use it | ||
45 | # to construct the SO version. | ||
46 | # | ||
47 | # In the `0.y.z` release cycle, breaking changes are allowed in every increment of `y`, | ||
48 | # so we can build the SO version just by taking `y.z`. | ||
49 | # In the `x.y.z` release cycle with `x > 0` the SO version must be calculated by taking | ||
50 | # the major of the tox version and add a hardcoded number that is the last A of the 0.y.z | ||
51 | # release cycle. | ||
52 | # | ||
53 | # References: | ||
54 | # | ||
55 | # [1]: https://autotools.io/libtool/version.html | ||
56 | # [2]: http://www.ibm.com/developerworks/linux/library/l-shlibs/index.html#N1006E | ||
57 | # | ||
58 | |||
59 | # the last major version number from the 0.x release cycle | ||
60 | # this must be constant starting from the 1.0 release | ||
61 | LAST_SOMAJOR=1 | ||
62 | |||
63 | if [ $MAJOR -eq 0 ]; then | ||
64 | SOMAJOR=$MINOR | ||
65 | SOMINOR=$PATCH | ||
66 | |||
67 | # update lastmajor above | ||
68 | update 'other/version-sync' 's/^\(LAST_SOMAJOR=\).*/\1'$SOMAJOR'/' | ||
69 | else | ||
70 | SOMAJOR=$(expr $MAJOR + $LAST_SOMAJOR) | ||
71 | SOMINOR=$MINOR | ||
72 | fi | ||
73 | |||
74 | # | ||
75 | # libtool has a quite cryptic implementation of the versioning system, which also | ||
76 | # changes between systems, see https://github.com/lxde/lxqt/issues/488#issuecomment-238084222 | ||
77 | # | ||
78 | # .so library version, following the libtool scheme: | ||
79 | # | ||
80 | # current:revision:age | ||
81 | # | ||
82 | # current: increment if interfaces have been added, removed or changed | ||
83 | # revision: increment if source code has changed, set to zero if current is | ||
84 | # incremented | ||
85 | # age: increment if interfaces have been added, set to zero if | ||
86 | # interfaces have been removed or changed | ||
87 | # | ||
88 | # For a full reference see: | ||
89 | # https://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info | ||
90 | # | ||
91 | # Passing such a version string to libtool will generate the following version number | ||
92 | # on the libary binary file on GNU/Linux: | ||
93 | # | ||
94 | # (current - age).(age).(revision) | ||
95 | # | ||
96 | # We do not want to use a separate version numbering for the library because the package versioning is equally good: | ||
97 | # | ||
98 | # Semver non-breaking: 0.y.(z+1) or x.(y+1).0: | ||
99 | # | ||
100 | # This would mean to increment current and age, which leave the major of SOVERSION the same. | ||
101 | # Revision is incremented. | ||
102 | # | ||
103 | # Semver breaking: 0.(y+1).0 or (x+1).0.0: | ||
104 | # | ||
105 | # This would mean to increment current, set age and revision to zero. | ||
106 | # | ||
107 | # Thus to make libtool use our version, we have to pass (major + minor):patch:minor as current:revision:age to get: | ||
108 | # | ||
109 | # (current - age).(age).(revision) | ||
110 | # <=> (major + minor - minor).minor.patch | ||
111 | # <=> major.minor.patch | ||
112 | # | ||
113 | |||
114 | if [ $MAJOR -eq 0 ]; then | ||
115 | LIBTOOL_CURRENT=$(expr $SOMAJOR + $SOMINOR) | ||
116 | LIBTOOL_AGE=$SOMINOR | ||
117 | LIBTOOL_REVISION=0 | ||
118 | else | ||
119 | LIBTOOL_CURRENT=$(expr $SOMAJOR + $SOMINOR) | ||
120 | LIBTOOL_AGE=$SOMINOR | ||
121 | LIBTOOL_REVISION=$PATCH | ||
122 | fi | ||
123 | |||
124 | update 'so.version' 's/^\(CURRENT=\).*/\1'$LIBTOOL_CURRENT'/' | ||
125 | update 'so.version' 's/^\(AGE=\).*/\1'$LIBTOOL_AGE'/' | ||
126 | update 'so.version' 's/^\(REVISION=\).*/\1'$LIBTOOL_REVISION'/' | ||