Shared libraries - move versioning and export list into functions.

Also for Windows add looking for a template .RC of the target name and adding that to the build too.
This commit is contained in:
Jim Hague 2019-10-28 17:11:00 +00:00
parent 7cf119fb6b
commit 4ab7f8f757
4 changed files with 80 additions and 37 deletions

View File

@ -49,6 +49,9 @@ include(CTest)
include(GNUInstallDirs)
include(TestBigEndian)
include(TargetSharedLibraryExports)
include(TargetSharedLibraryVersion)
# Target Platform
if (WIN32 OR MINGW OR MSYS OR CYGWIN)
set(HOSTOS "windows")
@ -582,50 +585,19 @@ if (ENABLE_SHARED)
target_link_libraries(getdns_shared PUBLIC Libidn2::Libidn2)
endif ()
set_target_properties(getdns_shared PROPERTIES OUTPUT_NAME getdns)
if (NOT ENABLE_STATIC)
add_library(getdns ALIAS getdns_shared)
endif ()
target_shared_library_version(getdns_shared ${GETDNS_VERSION_CURRENT} ${GETDNS_VERSION_REVISION} ${GETDNS_VERSION_AGE})
# Generate platform-specific link file with the export symbols.
file(STRINGS src/libgetdns.symbols symbols)
if (WIN32)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/getdns.def" "LIBRARY GETDNS\n VERSION ${GETDNS_VERSION_CURRENT}.${GETDNS_VERSION_REVISION}\n EXPORTS\n")
foreach (symbol IN LISTS symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/getdns.def" " ${symbol}\n")
endforeach ()
target_sources(getdns_shared PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/getdns.def")
elseif (APPLE)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/getdns.syms" "")
foreach (symbol IN LISTS symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/getdns.syms" "_${symbol}\n")
endforeach ()
target_sources(getdns_shared PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/getdns.syms")
target_link_libraries(getdns_shared PRIVATE "-exported_symbols_list getdns.syms")
target_shared_library_exports(getdns_shared getdns "${symbols}")
# Follow libtool. Add one to major version, as version 0 doesn't work.
# But tag dynlib name with current-age.
math(EXPR major_version "${GETDNS_VERSION_CURRENT}+1")
math(EXPR dynlib_version "${GETDNS_VERSION_CURRENT}-${GETDNS_VERSION_AGE}")
set_target_properties(getdns_shared PROPERTIES VERSION "${dynlib_version}")
target_link_libraries(getdns_shared PRIVATE "-compatibility_version ${major_version}")
target_link_libraries(getdns_shared PRIVATE "-current_version ${major_version}.${GETDNS_VERSION_REVISION}")
else ()
# Assume GNU ld.
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/getdns.ver" "{ global:\n")
foreach (symbol IN LISTS symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/getdns.ver" " ${symbol};\n")
endforeach ()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/getdns.ver" "local:\n *;\n};\n")
target_link_libraries(getdns_shared PRIVATE "-Wl,--version-script=getdns.ver")
# Again, follow libtool. Major version is current-age.
math(EXPR compat_version "${GETDNS_VERSION_CURRENT}-${GETDNS_VERSION_AGE}")
set_target_properties(getdns_shared PROPERTIES VERSION "${compat_version}.${GETDNS_VERSION_AGE}.${GETDNS_VERSION_REVISION}" SOVERSION "${compat_version}")
# If we're not building a static library, use this wherever we use
# the static library in tool and test builds.
if (NOT ENABLE_STATIC)
add_library(getdns ALIAS getdns_shared)
endif ()
endif ()
# The tools.
if (BUILD_GETDNS_QUERY)
add_executable(getdns_query src/tools/getdns_query.c)

View File

@ -0,0 +1,19 @@
1 VERSIONINFO
FILEVERSION @version_current@,@version_revision@,@version_age@,0
PRODUCTVERSION @version_current@,@version_revision@,0,0
FILEOS 4
FILETYPE 2
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "getdns project\0"
VALUE "ProductName", "getdns\0"
VALUE "FileVersion", "@version_current@.@version_revision@\0"
VALUE "ProductVersion", "@version_current@.@version_revision@\0"
VALUE "LegalCopyright", "NLnet Labs, Sinodun, No Mountain Software. New BSD licence.\0"
END
END
END

View File

@ -0,0 +1,27 @@
# Export only named entry points from shared library.
function(target_shared_library_exports lib libname symbols)
if (WIN32)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${libname}.def" "LIBRARY ${libname}\n EXPORTS\n")
foreach (symbol IN LISTS symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.def" " ${symbol}\n")
endforeach ()
target_sources(${lib} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${libname}.def")
elseif (APPLE)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${libname}.syms" "")
foreach (symbol IN LISTS symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.syms" "_${symbol}\n")
endforeach ()
target_sources(${lib} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${libname}.syms")
target_link_libraries(${lib} PRIVATE "-exported_symbols_list ${libname}.syms")
elseif (UNIX)
# Assume GNU ld.
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" "{ global:\n")
foreach (symbol IN LISTS symbols)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" " ${symbol};\n")
endforeach ()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${libname}.ver" "local:\n *;\n};\n")
target_link_libraries(${lib} PRIVATE "-Wl,--version-script=getdns.ver")
else ()
message(WARNING "Unknown platform, ${lib} exports not set.")
endif ()
endfunction ()

View File

@ -0,0 +1,25 @@
# Add version to given shared library linkage.
function(target_shared_library_version lib version_current version_revision version_age)
if (WIN32)
set(rc_template "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include/${lib}_version.rc.in")
if (EXISTS ${rc_template})
configure_file(${rc_template} ${lib}.rc @ONLY)
target_sources(${lib} PRIVATE ${lib}.rc)
endif ()
target_link_libraries(${lib} PRIVATE "-VERSION:${version_current}.${version_revision}")
elseif (APPLE)
# Follow libtool. Add one to major version, as version 0 doesn't work.
# But tag dynlib name with current-age.
math(EXPR major_version "${version_current}+1")
math(EXPR dynlib_version "${version_current}-${version_age}")
set_target_properties(${lib} PROPERTIES VERSION "${dynlib_version}")
target_link_libraries(${lib} PRIVATE "-compatibility_version ${major_version}")
target_link_libraries(${lib} PRIVATE "-current_version ${major_version}.${version_revision}")
elseif (UNIX)
# Assume GNU ld, and again follow libtool. Major version is current-age.
math(EXPR compat_version "${version_current}-${version_age}")
set_target_properties(${lib} PROPERTIES VERSION "${compat_version}.${version_age}.${version_revision}" SOVERSION "${compat_version}")
else ()
message(WARNING "Unknown platform, ${lib} will not be versioned.")
endif ()
endfunction ()