1#[==[ 2@brief Detect library type of a library 3 4Sometimes it needs to be known whether a library is shared or static on a 5system in order to change the usage requirements of an imported target 6representing that library. This commonly occurs between static and shared 7builds that share a set of installed headers. This function returns one of 8`SHARED`, `STATIC`, or `UNKNOWN` into the variable passed as the first 9argument. 10 11~~~ 12vtk_detect_library_type(<variable> 13 PATH <path>) 14~~~ 15#]==] 16function (vtk_detect_library_type output) 17 cmake_parse_arguments(PARSE_ARGV 1 vdlt 18 "" 19 "PATH" 20 "") 21 22 if (NOT DEFINED vdlt_PATH) 23 message(FATAL_ERROR 24 "The `PATH` argument is required.") 25 endif () 26 27 if (DEFINED vdlt_UNPARSED_ARGUMENTS) 28 message(FATAL_ERROR 29 "Unparsed arguments for vtk_detect_library_type: " 30 "${vdlt_UNPARSED_ARGUMENTS}") 31 endif () 32 33 if (NOT vdlt_PATH) 34 message(FATAL_ERROR 35 "The `PATH` argument is empty.") 36 endif () 37 38 set(vdlt_type UNKNOWN) 39 # Windows libraries all end with `.lib`. We need to detect the type based on 40 # the contents of the library. However, MinGW does use different extensions. 41 if (WIN32 AND NOT MINGW) 42 find_program(DUMPBIN_EXECUTABLE 43 NAMES dumpbin 44 DOC "Path to the dumpbin executable") 45 mark_as_advanced(DUMPBIN_EXECUTABLE) 46 execute_process( 47 COMMAND "${DUMPBIN_EXECUTABLE}" 48 /HEADERS 49 "${vdlt_PATH}" 50 OUTPUT_VARIABLE vdlt_out 51 ERROR_VARIABLE vdlt_err 52 RESULT_VARIABLE vdlt_res) 53 if (vdlt_res) 54 message(WARNING 55 "Failed to run `dumpbin` on ${vdlt_PATH}. Cannot determine " 56 "shared/static library type: ${vdlt_err}") 57 else () 58 if (vdlt_out MATCHES "DLL name :") 59 set(vdlt_type SHARED) 60 else () 61 set(vdlt_type STATIC) 62 endif () 63 endif () 64 else () 65 string(LENGTH "${vdlt_PATH}" vdlt_path_len) 66 67 string(LENGTH "${CMAKE_SHARED_LIBRARY_SUFFIX}" vdlt_shared_suffix_len) 68 math(EXPR vdlt_shared_idx "${vdlt_path_len} - ${vdlt_shared_suffix_len}") 69 string(SUBSTRING "${vdlt_PATH}" "${vdlt_shared_idx}" -1 vdlt_shared_check) 70 71 string(LENGTH "${CMAKE_STATIC_LIBRARY_SUFFIX}" vdlt_static_suffix_len) 72 math(EXPR vdlt_static_idx "${vdlt_path_len} - ${vdlt_static_suffix_len}") 73 string(SUBSTRING "${vdlt_PATH}" "${vdlt_static_idx}" -1 vdlt_static_check) 74 75 if (vdlt_shared_check STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX) 76 set(vdlt_type SHARED) 77 elseif (vdlt_static_check STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX) 78 set(vdlt_type STATIC) 79 endif () 80 81 # when import suffix != static suffix, we can disambiguate static and import 82 if (WIN32 AND NOT CMAKE_IMPORT_LIBRARY_SUFFIX STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX) 83 string(LENGTH "${CMAKE_IMPORT_LIBRARY_SUFFIX}" vdlt_import_suffix_len) 84 math(EXPR vdlt_import_idx "${vdlt_path_len} - ${vdlt_import_suffix_len}") 85 string(SUBSTRING "${vdlt_PATH}" "${vdlt_import_idx}" -1 vdlt_import_check) 86 if (vdlt_import_check STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX) 87 set(vdlt_type SHARED) 88 endif () 89 endif () 90 endif () 91 92 set("${output}" 93 "${vdlt_type}" 94 PARENT_SCOPE) 95endfunction () 96 97#[==[ 98@brief Detect whether an imported target is shared or not 99 100This is intended for use with modules using 101@ref vtk_module_third_party_external to detect whether that module is shared or 102not. Generally, this should be replaced with the `Find` module providing this 103information and modifying the usage requirements as necessary instead, but it 104is not always possible. 105 106~~~ 107vtk_detect_library_shared(<name> <target>) 108~~~ 109 110Sets `<name>_is_shared` in the caller's scope if `<target>` is a shared 111library. If it is an `UNKNOWN_LIBRARY`, a cache variable is exposed to allow 112the user to provide the information if it ends up breaking something. 113#]==] 114function (vtk_detect_library_shared name target) 115 if (VTK_MODULE_USE_EXTERNAL_${name}) 116 get_property(library_type 117 TARGET "${target}" 118 PROPERTY TYPE) 119 if (library_type STREQUAL "SHARED_LIBRARY") 120 set(is_shared 1) 121 elseif (library_type STREQUAL "UNKNOWN_LIBRARY") 122 option("VTK_MODULE_${name}_IS_SHARED" "Whether the ${name} in use is shared or not" ON) 123 mark_as_advanced("VTK_MODULE_${name}_IS_SHARED") 124 set(is_shared "${VTK_MODULE_${name}_IS_SHARED}") 125 else () 126 set(is_shared 0) 127 endif () 128 else () 129 set(is_shared "${BUILD_SHARED_LIBS}") 130 endif () 131 132 set("${name}_is_shared" 133 "${is_shared}" 134 PARENT_SCOPE) 135endfunction () 136