SOVERSION does nothing on MODULE target
Related to #20782.
When creating a MODULE target and setting the VERSION / SOVERSION properties, nothing happens on Linux (at least). The versions are not written to the files (discovered via lintian complaining) and links/namelinks are not created.
Minimal reproducer:
cmake_minimum_required(VERSION 3.19)
project(test VERSION 4.2.1)
file(WRITE "test.cpp" [[ int api() { return 0; } ]])
add_library(test ${test_TYPE} test.cpp)
set_target_properties(
test
PROPERTIES
VERSION ${test_VERSION}
SOVERSION ${test_VERSION_MAJOR}
)
First build as a MODULE:
$ cmake -G Ninja -S . -B build -Dtest_TYPE=MODULE
$ cmake --build build -- -v | tee log
[1/2] ccache /usr/bin/c++ -Dtest_EXPORTS -fPIC -MD -MT CMakeFiles/test.dir/test.cpp.o -MF CMakeFiles/test.dir/test.cpp.o.d -o CMakeFiles/test.dir/test.cpp.o -c ../test.cpp
[2/2] : && /usr/bin/c++ -fPIC -shared -o libtest.so CMakeFiles/test.dir/test.cpp.o && :
$ readelf -d build/libtest.so
Dynamic section at offset 0x2e90 contains 17 entries:
Tag Type Name/Value
0x000000000000000c (INIT) 0x1000
0x000000000000000d (FINI) 0x1108
0x0000000000000019 (INIT_ARRAY) 0x3e80
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x3e88
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x2f0
0x0000000000000005 (STRTAB) 0x3a8
0x0000000000000006 (SYMTAB) 0x318
0x000000000000000a (STRSZ) 93 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x4000
0x0000000000000007 (RELA) 0x408
0x0000000000000008 (RELASZ) 168 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffff9 (RELACOUNT) 3
0x0000000000000000 (NULL) 0x0
Build as SHARED for comparison:
alex@alex-ubuntu:~/test$ cmake -G Ninja -S . -B build -Dtest_TYPE=SHARED
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
alex@alex-ubuntu:~/test$ cmake --build build/ -- -v | tee log
[1/3] ccache /usr/bin/c++ -Dtest_EXPORTS -fPIC -MD -MT CMakeFiles/test.dir/test.cpp.o -MF CMakeFiles/test.dir/test.cpp.o.d -o CMakeFiles/test.dir/test.cpp.o -c ../test.cpp
[2/3] : && /usr/bin/c++ -fPIC -shared -Wl,-soname,libtest.so.4 -o libtest.so.4.2.1 CMakeFiles/test.dir/test.cpp.o && :
[3/3] /snap/cmake/793/bin/cmake -E cmake_symlink_library libtest.so.4.2.1 libtest.so.4 libtest.so && :
alex@alex-ubuntu:~/test$ ls build/libtest.so*
build/libtest.so build/libtest.so.4 build/libtest.so.4.2.1
alex@alex-ubuntu:~/test$ readelf -d build/libtest.so
Dynamic section at offset 0x2e80 contains 18 entries:
Tag Type Name/Value
0x000000000000000e (SONAME) Library soname: [libtest.so.4]
0x000000000000000c (INIT) 0x1000
0x000000000000000d (FINI) 0x1108
0x0000000000000019 (INIT_ARRAY) 0x3e70
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x3e78
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x2f0
0x0000000000000005 (STRTAB) 0x3a8
0x0000000000000006 (SYMTAB) 0x318
0x000000000000000a (STRSZ) 106 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x4000
0x0000000000000007 (RELA) 0x418
0x0000000000000008 (RELASZ) 168 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffff9 (RELACOUNT) 3
0x0000000000000000 (NULL) 0x0
User friendlyanon on the CppLang #cmake
Slack channel points to the following code being a (perhaps not the only) culprit:
https://gitlab.kitware.com/cmake/cmake/-/blob/master/Source/cmGeneratorTarget.cxx#L1944-1951
bool cmGeneratorTarget::HasSOName(const std::string& config) const
{
// soname is supported only for shared libraries and modules,
// and then only when the platform supports an soname flag.
return ((this->GetType() == cmStateEnums::SHARED_LIBRARY) &&
!this->GetPropertyAsBool("NO_SONAME") &&
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
}
The comment reads "shared libraries and modules" but only cmStateEnums::SHARED_LIBRARY
is actually checked.