Add SONAME/SOVERSION to generated library
Fixes #229
Might be more robust to pull from https://github.com/evaleev/libint/blob/master/configure.ac#L3 akin to https://gitlab.com/libxc/libxc/-/blob/master/CMakeLists.txt#L125-135 and https://gitlab.com/libxc/libxc/-/blob/master/CMakeLists.txt#L473-474 .
I don't think the VERSION here should be the current:revision:age https://cmake.org/pipermail/cmake-developers/2016-December/029695.html . Would just the SOVERSION be ok?
Well current:revision:age is terribly convoluted and maps to some x.y.z number scheme (see the libxc Gitlab link; the [2:3:0] in libint's configure.ac maps to 2.0.3). It is my understanding that VERSION is supposed to be that x.y.z (see e.g. https://mail.kde.org/pipermail/kde-buildsystem/2008-April/004543.html) and SOVERSION the SONAME number encoded in the library (accessible via objdump -x | grep SONAME), and also the single-number API-level .x ending which gets symlinked.
I didn't realize the top-level configure.ac still has the libint_so_version; as this one did not get bumped for 2.7.1, I guess VERSION should be 2.0.3 then, not 2.0.4 as in this PR.
Also note that libxc does not seem to use ${PROJECT_NAME}_SOVERSION at all in its build system (other than to output it during configuring) and it is setting SOVERSION to ${PROJECT_NAME}_SOMAJOR in https://gitlab.com/libxc/libxc/-/blob/master/CMakeLists.txt#L474 consistent with what this PR is doing.
One more comment: As configure.ac is (to the best of my knowledge) not being pulled into the exported generated library tarball, it cannot be used by CMake similar to what LibXC does, that information just isn;t available I think.
Also, I guess the future is all-CMake, so this is a stop-gap measure. I would agree that it is pretty brittle if we would have to use it for a long time and always remember to bump the library version in both places, but this sounds like a one-off (or two-off) think, famous last words...
@mbanck thanks ... I tried to understand what VERSION and SOVERSION are supposed to be (CMake's dox are no bueno) but I am still not sure about the best-practices:
- It seems to me that since
VERSIONis for human consumption it is easiest to set it to the project version or to whatever the package maintainers (i.e. you) need it to be. I don't understand why it is set to2.0.4then ... - I gave up on API/ABI version tracking in this and other projects because it is far too easy to change the ABI (plus it is unrealistic to test ABI, etc.). Libint library's API/ABI is very stable but I cannot guarantee that it has only changed twice (is that what
SOVERSION 2means?) ... also: theSOVERSIONimplies library configuration (max AM, etc.) so if those change in the futureSOVERSIONwould have to change?
* I gave up on API/ABI version tracking in this and other projects because it is far too easy to change the ABI (plus it is unrealistic to test ABI, etc.). Libint library's API/ABI is very stable but I cannot guarantee that it has only changed twice (is that what `SOVERSION 2` means?) ... also: the `SOVERSION` implies library configuration (max AM, etc.) so if those change in the future `SOVERSION` would have to change?
SOVERSION is part of the SONAME. It should be bumped at least every time the ABI changes in a not-backwards compatible way. In case symbols are not versioned (e.g. using a linker version script, as is the case here), the SOVERSION should also be bumped every time the ABI is changed in a backwards compatible way (e.g. when adding new functions).
The library configuration is an orhogonal aspect. IMHO each configuration should have a different SONAME, and multiple libraries could be installed in parallel. According to https://github.com/evaleev/libint/issues/190, there are 20 different configurations, though only 5 seem to be actually used. E.g. psi4 could link to libint2_gss.
@loriab bumping this to revisit in the light of planned use of Libint2_CONFIG_COMPONENTS (see https://github.com/evaleev/libint/pull/259/files#diff-4a7c86a49b4b056d4c5e5adf66bb420b3e9adc79862abebde6f6c4fe358ed9b0R52)
- presumably
SONAMEwill need to include library configuration ...SONAMEdoes not seem to be controlled directly, need to useVERSION? Should be introduce this mechanism now? (setLibint2_CONFIG_COMPONENTSto its current default, etc.)
good starter-level explanation of SONAME and SOVERSION: https://crascit.com/wp-content/uploads/2019/09/Deep-CMake-For-Library-Authors-Craig-Scott-CppCon-2019.pdf
I don't think this PR thoroughly added SOVERSION (see below for mac/linux with BUILD_SHARED_LIBS=ON). I haven't fully investigated, but the PR may have just caught the build-both-static-and-shared target.
2023-12-19T20:24:34.6214061Z -rwxr-xr-x 2 conda conda 4790576 Dec 19 20:23 libint2.so
2023-12-19T20:24:34.6214631Z lrwxrwxrwx 1 conda conda 15 Dec 19 20:24 libitm.so -> libitm.so.1.0.0
2023-12-19T20:24:34.6215059Z lrwxrwxrwx 1 conda conda 15 Dec 19 20:24 libitm.so.1 -> libitm.so.1.0.0
2023-12-19T20:24:34.6215442Z -rwxrwxr-x 1 conda conda 773744 Nov 12 01:46 libitm.so.1.0.0
2023-12-19T20:33:15.3850370Z -rwxr-xr-x 2 runner staff 4923120 Dec 19 20:30 libint2.dylib
2023-12-19T20:33:15.3851270Z -rwxrwxr-x 4 runner staff 75584 Aug 15 11:12 libk5crypto.3.1.dylib
2023-12-19T20:33:15.3902810Z lrwxr-xr-x 1 runner staff 21 Dec 19 20:33 libk5crypto.3.dylib -> libk5crypto.3.1.dylib
2023-12-19T20:33:15.3952710Z lrwxr-xr-x 1 runner staff 21 Dec 19 20:33 libk5crypto.dylib -> libk5crypto.3.1.dylib