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:
Brad King 2015-08-21 09:29:06 -04:00 committed by CMake Topic Stage
commit badde9c2a1
11 changed files with 93 additions and 36 deletions

View File

@ -1,11 +1,11 @@
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
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
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

View File

@ -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.

View File

@ -784,8 +784,7 @@ 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() == cmTarget::SHARED_LIBRARY ||
this->GetType() == cmTarget::MODULE_LIBRARY) &&
return ((this->GetType() == cmTarget::SHARED_LIBRARY) &&
!this->GetPropertyAsBool("NO_SONAME") &&
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
}

View File

@ -127,6 +127,9 @@ target_link_libraries(testLibCycleA testLibCycleB)
target_link_libraries(testLibCycleB testLibCycleA)
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
add_library(testLibRequired testLibRequired.c)
add_library(testLibDepends testLibDepends.c)
@ -467,6 +470,7 @@ install(
testExe2lib testLib4lib testLib4libdbg testLib4libopt
testLib6 testLib7
testLibCycleA testLibCycleB
testLibNoSONAME
cmp0022NEW cmp0022OLD
systemlib
EXPORT exp
@ -527,6 +531,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
testLib4lib testLib4libdbg testLib4libopt
testLibCycleA testLibCycleB
testLibNoSONAME
testLibPerConfigDest
NAMESPACE bld_
APPEND FILE ExportBuildTree.cmake

View File

@ -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; }

View File

@ -90,6 +90,50 @@ add_custom_target(check_testLib1_genex ALL
-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)
target_link_libraries(cmp0022OLD_test bld_cmp0022OLD)
add_executable(cmp0022NEW_test cmp0022NEW_test_vs6_1.cpp)

View File

@ -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()

View File

@ -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()

View File

@ -52,13 +52,8 @@ target_link_libraries(example_mod_1 example_exe)
if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
"${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.
export(TARGETS example_mod_1 example_mod_2 NAMESPACE exp_
export(TARGETS example_mod_1 NAMESPACE exp_
FILE ${CMAKE_CURRENT_BINARY_DIR}/mods.cmake)
include(ExternalProject)
@ -68,7 +63,7 @@ if(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG AND
DOWNLOAD_COMMAND ""
INSTALL_COMMAND ""
)
add_dependencies(PluginTest example_mod_1 example_mod_2)
add_dependencies(PluginTest example_mod_1)
endif()
# TODO:

View File

@ -6,17 +6,11 @@ include(${CMAKE_CURRENT_BINARY_DIR}/../mods.cmake)
get_property(configs TARGET exp_example_mod_1 PROPERTY IMPORTED_CONFIGURATIONS)
foreach(c ${configs})
string(TOUPPER "${c}" CONFIG)
get_property(soname1 TARGET exp_example_mod_1 PROPERTY IMPORTED_SONAME_${CONFIG})
get_property(soname2 TARGET exp_example_mod_2 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
if(soname1)
message(STATUS "exp_example_mod_1 has IMPORTED_SONAME_${CONFIG} as expected: ${soname1}")
get_property(soname TARGET exp_example_mod_1 PROPERTY IMPORTED_NO_SONAME_${CONFIG})
if(soname)
message(STATUS "exp_example_mod_1 has IMPORTED_NO_SONAME_${CONFIG} as expected: ${soname}")
else()
message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_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")
message(SEND_ERROR "exp_example_mod_1 does not have IMPORTED_NO_SONAME_${CONFIG} but should")
endif()
endforeach()
@ -26,8 +20,7 @@ if("${CMAKE_EXECUTABLE_FORMAT}" MATCHES "ELF")
if(READELF_EXE)
add_custom_target(check_mod_soname ALL COMMAND
${CMAKE_COMMAND} -Dreadelf=${READELF_EXE}
-Dmod1=$<TARGET_FILE:exp_example_mod_1>
-Dmod2=$<TARGET_FILE:exp_example_mod_2>
-Dmod=$<TARGET_FILE:exp_example_mod_1>
-P ${CMAKE_CURRENT_SOURCE_DIR}/../check_mod_soname.cmake
)
endif()

View File

@ -1,14 +1,7 @@
execute_process(COMMAND ${readelf} -d ${mod1} OUTPUT_FILE ${mod1}.readelf.txt)
execute_process(COMMAND ${readelf} -d ${mod2} OUTPUT_FILE ${mod2}.readelf.txt)
file(STRINGS ${mod1}.readelf.txt soname1 REGEX "\\(SONAME\\)")
file(STRINGS ${mod2}.readelf.txt soname2 REGEX "\\(SONAME\\)")
if(soname1)
message(STATUS "${mod1} has soname as expected: ${soname1}")
execute_process(COMMAND ${readelf} -d ${mod} OUTPUT_FILE ${mod}.readelf.txt)
file(STRINGS ${mod}.readelf.txt soname REGEX "\\(SONAME\\)")
if(soname)
message(FATAL_ERROR "${mod} has soname but should not:\n ${soname}")
else()
message(FATAL_ERROR "${mod1} has no soname but should:\n ${soname1}")
endif()
if(soname2)
message(FATAL_ERROR "${mod2} has soname but should not:\n ${soname2}")
else()
message(STATUS "${mod2} has no soname as expected")
message(STATUS "${mod} has no soname as expected")
endif()