Add a module to help detect shared/static libraries
It would be nice to have imported targets be something other than UNKNOWN
. Some projects require consumers of the library to specify whether the dllimport
defines are required based on whether the library is static or shared. CMake should offer this as part of the imported targets it ships in its standard modules, but first a new module to detect this should be created.
A non-exhaustive list of modules which CMake provides which have imported targets that need static/shared conditionals:
-
FindLibXml2
:LIBXML_STATIC
-
FindFreetype
:FT2_DLLIMPORT
(only on Windows) -
FindEXPAT
:XML_STATIC
Here is a template to start from. It doesn't implement Windows yet.
include(CMakeParseArguments)
function (vtk_detect_library_type output)
cmake_parse_arguments(vdlt
""
"PATH"
""
${ARGN})
if (NOT DEFINED vdlt_PATH)
message(FATAL_ERROR
"The `PATH` argument is required.")
endif ()
if (DEFINED vdlt_UNPARSED_ARGUMENTS)
message(FATAL_ERROR
"Unparsed arguments for vtk_detect_library_type: "
"${vdlt_UNPARSED_ARGUMENTS}")
endif ()
set(vdlt_type UNKNOWN)
# Windows libraries all end with `.lib`. We need to detect the type based on
# the contents of the library. However, MinGW does use different extensions.
if (WIN32 AND NOT MINGW)
# TODO: Implement by looking at the contents to see if it is a static or
# shared library.
else ()
string(LENGTH "${vdlt_PATH}" vdlt_path_len)
# We can't do `get_filename_component(EXT)` because it only gets the
# longest extension, but there may be `.` elsewhere in the filename.
string(LENGTH "${CMAKE_SHARED_LIBRARY_SUFFIX}" vdlt_shared_suffix_len)
math(EXPR vdlt_shared_idx "${vdlt_path_len} - ${vdlt_shared_suffix_len}")
string(SUBSTRING "${vdlt_PATH}" "${vdlt_shared_idx}" -1 vdlt_shared_check)
string(LENGTH "${CMAKE_STATIC_LIBRARY_SUFFIX}" vdlt_static_suffix_len)
math(EXPR vdlt_static_idx "${vdlt_path_len} - ${vdlt_static_suffix_len}")
string(SUBSTRING "${vdlt_PATH}" "${vdlt_static_idx}" -1 vdlt_static_check)
if (vdlt_shared_check STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX)
set(vdlt_type SHARED)
elseif (vdlt_static_check STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX)
set(vdlt_type STATIC)
endif ()
endif ()
set("${output}"
"${vdlt_type}"
PARENT_SCOPE)
endfunction ()
Its use looks like:
vtk_detect_library_type(pkg_library_type PATH "${PKG_LIBRARY}")
add_library(PKG::PKG "${pkg_library_type}" IMPORTED)
unset(pkg_library_type)