Merge topic 'modules-no-soname'
f799ffb5
Do not set SONAME for MODULE library targets (#15705)899458ab
Tests: Cover NO_SONAME property for SHARED libraries
This commit is contained in:
commit
badde9c2a1
|
@ -1,11 +1,11 @@
|
||||||
NO_SONAME
|
NO_SONAME
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Whether to set "soname" when linking a shared library or module.
|
Whether to set "soname" when linking a shared library.
|
||||||
|
|
||||||
Enable this boolean property if a generated shared library or module
|
Enable this boolean property if a generated shared library
|
||||||
should not have "soname" set. Default is to set "soname" on all
|
should not have "soname" set. Default is to set "soname" on all
|
||||||
shared libraries and modules as long as the platform supports it.
|
shared libraries as long as the platform supports it.
|
||||||
Generally, use this property only for leaf private libraries or
|
Generally, use this property only for leaf private libraries or
|
||||||
plugins. If you use it on normal shared libraries which other targets
|
plugins. If you use it on normal shared libraries which other targets
|
||||||
link against, on some platforms a linker will insert a full path to
|
link against, on some platforms a linker will insert a full path to
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
modules-no-soname
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
* The ``SONAME`` field is no longer set for ``MODULE`` libraries
|
||||||
|
created with the :command:`add_library` command. ``MODULE``
|
||||||
|
libraries are meant for explicit dynamic loading at runtime.
|
||||||
|
They cannot be linked so ``SONAME`` is not useful.
|
|
@ -784,8 +784,7 @@ bool cmGeneratorTarget::HasSOName(const std::string& config) const
|
||||||
{
|
{
|
||||||
// soname is supported only for shared libraries and modules,
|
// soname is supported only for shared libraries and modules,
|
||||||
// and then only when the platform supports an soname flag.
|
// and then only when the platform supports an soname flag.
|
||||||
return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
|
return ((this->GetType() == cmTarget::SHARED_LIBRARY) &&
|
||||||
this->GetType() == cmTarget::MODULE_LIBRARY) &&
|
|
||||||
!this->GetPropertyAsBool("NO_SONAME") &&
|
!this->GetPropertyAsBool("NO_SONAME") &&
|
||||||
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
|
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,9 @@ target_link_libraries(testLibCycleA testLibCycleB)
|
||||||
target_link_libraries(testLibCycleB testLibCycleA)
|
target_link_libraries(testLibCycleB testLibCycleA)
|
||||||
set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
|
||||||
|
|
||||||
|
add_library(testLibNoSONAME SHARED testLibNoSONAME.c)
|
||||||
|
set_property(TARGET testLibNoSONAME PROPERTY NO_SONAME 1)
|
||||||
|
|
||||||
# Test exporting dependent libraries into different exports
|
# Test exporting dependent libraries into different exports
|
||||||
add_library(testLibRequired testLibRequired.c)
|
add_library(testLibRequired testLibRequired.c)
|
||||||
add_library(testLibDepends testLibDepends.c)
|
add_library(testLibDepends testLibDepends.c)
|
||||||
|
@ -467,6 +470,7 @@ install(
|
||||||
testExe2lib testLib4lib testLib4libdbg testLib4libopt
|
testExe2lib testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLib6 testLib7
|
testLib6 testLib7
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
|
testLibNoSONAME
|
||||||
cmp0022NEW cmp0022OLD
|
cmp0022NEW cmp0022OLD
|
||||||
systemlib
|
systemlib
|
||||||
EXPORT exp
|
EXPORT exp
|
||||||
|
@ -527,6 +531,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
|
||||||
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
|
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
|
||||||
testLib4lib testLib4libdbg testLib4libopt
|
testLib4lib testLib4libdbg testLib4libopt
|
||||||
testLibCycleA testLibCycleB
|
testLibCycleA testLibCycleB
|
||||||
|
testLibNoSONAME
|
||||||
testLibPerConfigDest
|
testLibPerConfigDest
|
||||||
NAMESPACE bld_
|
NAMESPACE bld_
|
||||||
APPEND FILE ExportBuildTree.cmake
|
APPEND FILE ExportBuildTree.cmake
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
# define testLibNoSONAME_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
# define testLibNoSONAME_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
testLibNoSONAME_EXPORT int testLibNoSONAME(void) { return 0; }
|
|
@ -90,6 +90,50 @@ add_custom_target(check_testLib1_genex ALL
|
||||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/check_testLib1_genex.cmake
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/check_testLib1_genex.cmake
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
|
||||||
|
"${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
|
||||||
|
foreach(ns exp bld)
|
||||||
|
get_property(configs TARGET ${ns}_testLib5 PROPERTY IMPORTED_CONFIGURATIONS)
|
||||||
|
foreach(c ${configs})
|
||||||
|
string(TOUPPER "${c}" CONFIG)
|
||||||
|
get_property(soname TARGET ${ns}_testLib5 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
|
||||||
|
if(soname)
|
||||||
|
message(SEND_ERROR "${ns}_testLib5 has IMPORTED_NO_SONAME_${CONFIG} but should:\n ${soname}")
|
||||||
|
else()
|
||||||
|
message(STATUS "${ns}_testLib5 does not have IMPORTED_NO_SONAME_${CONFIG} as expected")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
get_property(configs TARGET ${ns}_testLibNoSONAME PROPERTY IMPORTED_CONFIGURATIONS)
|
||||||
|
foreach(c ${configs})
|
||||||
|
string(TOUPPER "${c}" CONFIG)
|
||||||
|
get_property(soname TARGET ${ns}_testLibNoSONAME PROPERTY IMPORTED_NO_SONAME_${CONFIG})
|
||||||
|
if(soname)
|
||||||
|
message(STATUS "${ns}_testLibNoSONAME has IMPORTED_NO_SONAME_${CONFIG} as expected")
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "${ns}_testLibNoSONAME does not have IMPORTED_NO_SONAME_${CONFIG} but should")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Parse the binary to check for SONAME if possible.
|
||||||
|
if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
|
||||||
|
find_program(READELF_EXE readelf)
|
||||||
|
if(READELF_EXE)
|
||||||
|
add_custom_target(check_${ns}_testLib5_soname ALL COMMAND
|
||||||
|
${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
|
||||||
|
-Dlib=$<TARGET_FILE:${ns}_testLib5>
|
||||||
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/check_lib_soname.cmake
|
||||||
|
)
|
||||||
|
add_custom_target(check_${ns}_testLibNoSONAME_soname ALL COMMAND
|
||||||
|
${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
|
||||||
|
-Dlib=$<TARGET_FILE:${ns}_testLibNoSONAME>
|
||||||
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/check_lib_nosoname.cmake
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(cmp0022OLD_test cmp0022OLD_test_vs6_1.cpp)
|
add_executable(cmp0022OLD_test cmp0022OLD_test_vs6_1.cpp)
|
||||||
target_link_libraries(cmp0022OLD_test bld_cmp0022OLD)
|
target_link_libraries(cmp0022OLD_test bld_cmp0022OLD)
|
||||||
add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp)
|
add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
execute_process(COMMAND ${readelf} -d ${lib} OUTPUT_FILE ${lib}.readelf.txt)
|
||||||
|
file(STRINGS ${lib}.readelf.txt soname REGEX "\\(SONAME\\)")
|
||||||
|
if(soname)
|
||||||
|
message(FATAL_ERROR "${lib} has soname but should not:\n ${soname}")
|
||||||
|
else()
|
||||||
|
message(STATUS "${lib} has no soname as expected:\n ${soname}")
|
||||||
|
endif()
|
|
@ -0,0 +1,7 @@
|
||||||
|
execute_process(COMMAND ${readelf} -d ${lib} OUTPUT_FILE ${lib}.readelf.txt)
|
||||||
|
file(STRINGS ${lib}.readelf.txt soname REGEX "\\(SONAME\\)")
|
||||||
|
if(soname)
|
||||||
|
message(STATUS "${lib} has soname as expected:\n ${soname}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "${lib} has no soname but should:\n ${soname}")
|
||||||
|
endif()
|
|
@ -52,13 +52,8 @@ target_link_libraries(example_mod_1 example_exe)
|
||||||
|
|
||||||
if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
|
if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
|
||||||
"${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
|
"${CMAKE_C_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
|
||||||
# Add a second plugin that should not have any soname.
|
|
||||||
add_library(example_mod_2 MODULE src/example_mod_1.c)
|
|
||||||
target_link_libraries(example_mod_2 example_exe)
|
|
||||||
set_property(TARGET example_mod_2 PROPERTY NO_SONAME 1)
|
|
||||||
|
|
||||||
# Verify that targets export with proper IMPORTED SONAME properties.
|
# Verify that targets export with proper IMPORTED SONAME properties.
|
||||||
export(TARGETS example_mod_1 example_mod_2 NAMESPACE exp_
|
export(TARGETS example_mod_1 NAMESPACE exp_
|
||||||
FILE ${CMAKE_CURRENT_BINARY_DIR}/mods.cmake)
|
FILE ${CMAKE_CURRENT_BINARY_DIR}/mods.cmake)
|
||||||
|
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
@ -68,7 +63,7 @@ if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
|
||||||
DOWNLOAD_COMMAND ""
|
DOWNLOAD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
)
|
)
|
||||||
add_dependencies(PluginTest example_mod_1 example_mod_2)
|
add_dependencies(PluginTest example_mod_1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
|
|
|
@ -6,17 +6,11 @@ include(${CMAKE_CURRENT_BINARY_DIR}/../mods.cmake)
|
||||||
get_property(configs TARGET exp_example_mod_1 PROPERTY IMPORTED_CONFIGURATIONS)
|
get_property(configs TARGET exp_example_mod_1 PROPERTY IMPORTED_CONFIGURATIONS)
|
||||||
foreach(c ${configs})
|
foreach(c ${configs})
|
||||||
string(TOUPPER "${c}" CONFIG)
|
string(TOUPPER "${c}" CONFIG)
|
||||||
get_property(soname1 TARGET exp_example_mod_1 PROPERTY IMPORTED_SONAME_${CONFIG})
|
get_property(soname TARGET exp_example_mod_1 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
|
||||||
get_property(soname2 TARGET exp_example_mod_2 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
|
if(soname)
|
||||||
if(soname1)
|
message(STATUS "exp_example_mod_1 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname}")
|
||||||
message(STATUS "exp_example_mod_1 has IMPORTED_SONAME_${CONFIG} as expected: ${soname1}")
|
|
||||||
else()
|
else()
|
||||||
message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_SONAME_${CONFIG} but should")
|
message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
|
||||||
endif()
|
|
||||||
if(soname2)
|
|
||||||
message(STATUS "exp_example_mod_2 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname2}")
|
|
||||||
else()
|
|
||||||
message(SEND_ERROR "exp_example_mod_2 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
|
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
@ -26,8 +20,7 @@ if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
|
||||||
if(READELF_EXE)
|
if(READELF_EXE)
|
||||||
add_custom_target(check_mod_soname ALL COMMAND
|
add_custom_target(check_mod_soname ALL COMMAND
|
||||||
${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
|
${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
|
||||||
-Dmod1=$<TARGET_FILE:exp_example_mod_1>
|
-Dmod=$<TARGET_FILE:exp_example_mod_1>
|
||||||
-Dmod2=$<TARGET_FILE:exp_example_mod_2>
|
|
||||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/../check_mod_soname.cmake
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/../check_mod_soname.cmake
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
execute_process(COMMAND ${readelf} -d ${mod1} OUTPUT_FILE ${mod1}.readelf.txt)
|
execute_process(COMMAND ${readelf} -d ${mod} OUTPUT_FILE ${mod}.readelf.txt)
|
||||||
execute_process(COMMAND ${readelf} -d ${mod2} OUTPUT_FILE ${mod2}.readelf.txt)
|
file(STRINGS ${mod}.readelf.txt soname REGEX "\\(SONAME\\)")
|
||||||
file(STRINGS ${mod1}.readelf.txt soname1 REGEX "\\(SONAME\\)")
|
if(soname)
|
||||||
file(STRINGS ${mod2}.readelf.txt soname2 REGEX "\\(SONAME\\)")
|
message(FATAL_ERROR "${mod} has soname but should not:\n ${soname}")
|
||||||
if(soname1)
|
|
||||||
message(STATUS "${mod1} has soname as expected: ${soname1}")
|
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "${mod1} has no soname but should:\n ${soname1}")
|
message(STATUS "${mod} has no soname as expected")
|
||||||
endif()
|
|
||||||
if(soname2)
|
|
||||||
message(FATAL_ERROR "${mod2} has soname but should not:\n ${soname2}")
|
|
||||||
else()
|
|
||||||
message(STATUS "${mod2} has no soname as expected")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
Loading…
Reference in New Issue