helpers.cmake 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. if (__cmake_helpers_included)
  2. return ()
  3. endif ()
  4. set ( __cmake_helpers_included YES )
  5. include ( printers )
  6. include ( CheckFunctionExists )
  7. function ( add_lib_for FUNCTION_NAME LIBS_REQUIRED LIB_TRG )
  8. # check if we can use FUNCTION_NAME first.
  9. # if possible without extra libs - ok. If no - try to use LIB_REQUIRED list.
  10. # finally append found (if necessary) library to the link of LIB_TRG
  11. string ( TOUPPER ${FUNCTION_NAME} _fupcase_name )
  12. set ( HAVE_NAME HAVE_${_fupcase_name} )
  13. set ( FUNC_FOR_NAME FUNC_FOR_${_fupcase_name} )
  14. if (NOT DEFINED ${HAVE_NAME})
  15. check_function_exists ( ${FUNCTION_NAME} ${HAVE_NAME} )
  16. if (NOT ${HAVE_NAME})
  17. foreach (LIB ${LIBS_REQUIRED})
  18. set ( LIB_XXX "LIB_${LIB}" )
  19. UNSET ( ${HAVE_NAME} CACHE )
  20. set ( CMAKE_REQUIRED_LIBRARIES ${LIB} )
  21. check_function_exists ( ${FUNCTION_NAME} ${HAVE_NAME} )
  22. if (${${HAVE_NAME}})
  23. find_library ( LIB_${LIB} ${LIB} )
  24. set ( ${FUNC_FOR_NAME} "${LIB}" CACHE INTERNAL "Library for function ${FUNCTION}" )
  25. mark_as_advanced ( ${FUNC_FOR_NAME} LIB_${LIB} )
  26. break ()
  27. endif ()
  28. endforeach (LIB)
  29. endif ()
  30. endif ()
  31. if (DEFINED ${FUNC_FOR_NAME})
  32. target_link_libraries ( ${LIB_TRG} INTERFACE ${${FUNC_FOR_NAME}} )
  33. endif ()
  34. mark_as_advanced ( ${HAVE_NAME} )
  35. endfunction ()
  36. function ( with_menu_comp PACKAGE Component NAME INFO )
  37. string ( TOUPPER "${Component}" COMPONENT )
  38. if (NOT DEFINED WITH_${COMPONENT})
  39. find_package ( ${PACKAGE} COMPONENTS ${Component} )
  40. if (${PACKAGE}_FOUND)
  41. set ( WITH_${COMPONENT} ON CACHE BOOL "link with ${NAME} library" )
  42. endif ()
  43. elseif (WITH_${COMPONENT} AND NOT TARGET ${PACKAGE}::${Component})
  44. find_package ( ${PACKAGE} REQUIRED COMPONENTS ${Component} )
  45. endif ()
  46. add_feature_info ( ${PACKAGE} WITH_${COMPONENT} "${INFO}" )
  47. trace ( ${PACKAGE}::${Component} )
  48. bannervar ( WITH_${Component} )
  49. endfunction ()
  50. function ( with_menu Package NAME INFO )
  51. string ( TOUPPER "${Package}" PACKAGE )
  52. if (NOT DEFINED WITH_${PACKAGE})
  53. find_package ( ${Package} )
  54. if (${Package}_FOUND)
  55. set ( WITH_${PACKAGE} ON CACHE BOOL "link with ${NAME} library" )
  56. endif ()
  57. elseif (WITH_${PACKAGE} AND NOT TARGET ${Package}::${Package})
  58. find_package ( ${Package} REQUIRED )
  59. endif ()
  60. add_feature_info ( ${Package} WITH_${PACKAGE} "${INFO}" )
  61. trace ( ${Package}::${Package} )
  62. bannervar ( WITH_${PACKAGE} )
  63. endfunction ()
  64. function ( with_menu_libname Package Libname NAME INFO )
  65. string ( TOUPPER "${Package}" PACKAGE )
  66. if (NOT DEFINED WITH_${PACKAGE})
  67. find_package ( ${Package} )
  68. if (${Package}_FOUND)
  69. set ( WITH_${PACKAGE} ON CACHE BOOL "link with ${NAME} library" )
  70. endif ()
  71. elseif (WITH_${PACKAGE} AND NOT TARGET ${Package}::${Libname})
  72. find_package ( ${Package} REQUIRED )
  73. endif ()
  74. add_feature_info ( ${Package} WITH_${PACKAGE} "${INFO}" )
  75. trace ( ${Package}::${Libname} )
  76. bannervar ( WITH_${PACKAGE} )
  77. endfunction ()
  78. function ( with_get Package NAME INFO )
  79. string ( TOUPPER "${Package}" PACKAGE )
  80. if (NOT DEFINED WITH_${PACKAGE} OR WITH_${PACKAGE})
  81. include ( Get${PACKAGE} )
  82. set ( WITH_${PACKAGE} ON CACHE BOOL "compile with ${NAME} library" )
  83. endif ()
  84. add_feature_info ( ${Package} WITH_${PACKAGE} "${INFO}" )
  85. trace ( ${Package}::${Package} )
  86. bannervar ( WITH_${PACKAGE} )
  87. if (WITH_${PACKAGE})
  88. bannervar ( WITH_${PACKAGE}_FORCE_STATIC )
  89. endif ()
  90. endfunction ()
  91. function ( get_dep Package Name INFO )
  92. string ( TOUPPER "${Name}" _NAME )
  93. if (NOT DEFINED WITH_${_NAME} OR WITH_${_NAME})
  94. include ( Get${Name} )
  95. set ( WITH_${_NAME} ON CACHE BOOL "compile with ${Package} library" )
  96. endif ()
  97. add_feature_info ( ${Package} WITH_${_NAME} "${INFO}" )
  98. trace ( ${Package}::${Package} )
  99. bannervar ( WITH_${_NAME} )
  100. endfunction ()
  101. function ( __get_imported_soname TRG OUTVAR )
  102. get_target_property ( _lib ${TRG} LOCATION )
  103. if (NOT _lib)
  104. diags ( "${TRG}: location is not determined" )
  105. return ()
  106. endif ()
  107. GET_SONAME ( "${_lib}" _solib )
  108. if (NOT _solib)
  109. diags ( "${TRG}: no soname" )
  110. return ()
  111. endif ()
  112. set ( "${OUTVAR}" "${_solib}" PARENT_SCOPE )
  113. endfunction ()
  114. function ( __copyp SRC DST PROPERTY ) # copy property from SRC to DST, if exists
  115. get_target_property ( _prp ${SRC} ${PROPERTY} )
  116. if (_prp)
  117. set_target_properties ( ${DST} PROPERTIES ${PROPERTY} "${_prp}" )
  118. endif ()
  119. endfunction ()
  120. function ( __make_dl_lib SRC ) # copy lib without location
  121. add_library ( "${SRC}_ld" INTERFACE IMPORTED )
  122. foreach (_prop
  123. INTERFACE_COMPILE_DEFINITIONS
  124. INTERFACE_COMPILE_FEATURES
  125. INTERFACE_COMPILE_OPTIONS
  126. INTERFACE_INCLUDE_DIRECTORIES
  127. INTERFACE_LINK_LIBRARIES
  128. INTERFACE_LINK_DEPENDS
  129. INTERFACE_LINK_DIRECTORIES
  130. INTERFACE_LINK_OPTIONS
  131. INTERFACE_POSITION_INDEPENDENT_CODE
  132. INTERFACE_SOURCES
  133. INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
  134. MAP_IMPORTED_CONFIG_RELEASE
  135. MAP_IMPORTED_CONFIG_RELWITHDEBINFO
  136. MAP_IMPORTED_CONFIG_DEBUG
  137. MAP_IMPORTED_CONFIG_MINSIZEREL)
  138. __copyp ( ${SRC} ${SRC}_ld ${_prop} )
  139. endforeach ()
  140. endfunction ()
  141. # windows installation stuff
  142. function ( __win_install_lib _lib suffix )
  143. if (NOT TARGET ${_lib} OR NOT WIN32)
  144. return ()
  145. endif ()
  146. get_property ( _type TARGET ${_lib} PROPERTY TYPE )
  147. if (_type STREQUAL SHARED_LIBRARY OR _type STREQUAL INTERFACE_LIBRARY)
  148. get_property ( _file TARGET ${_lib} PROPERTY LOCATION )
  149. addruntime ( "${_file}" ${suffix} )
  150. get_property ( _deps TARGET ${_lib} PROPERTY INTERFACE_LINK_LIBRARIES )
  151. foreach (_dep ${_deps})
  152. trace ( ${_dep} )
  153. __win_install_lib ( ${_dep} ${suffix} )
  154. endforeach ()
  155. endif ()
  156. endfunction ()
  157. function ( win_install_c Package Component suffix )
  158. string ( TOUPPER "${Component}" COMPONENT )
  159. if (NOT WITH_${COMPONENT})
  160. return ()
  161. endif ()
  162. __win_install_lib ( "${Package}::${Component}" ${suffix} )
  163. endfunction ()
  164. function ( win_install_lib Namespace Lib suffix )
  165. string ( TOUPPER "${Namespace}" _NAMESPACE )
  166. if (NOT WITH_${_NAMESPACE})
  167. return ()
  168. endif ()
  169. __win_install_lib ( "${Namespace}::${Lib}" ${suffix} )
  170. endfunction ()
  171. function ( win_install Package suffix )
  172. win_install_c ( ${Package} ${Package} ${suffix} )
  173. endfunction ()
  174. function ( dl_package_comp Package Component NAME )
  175. string ( TOUPPER "${Package}" PACKAGE )
  176. if (NOT WITH_${PACKAGE} OR NOT (HAVE_DLOPEN OR WIN32))
  177. diag ( WITH_${PACKAGE} HAVE_DLOPEN WIN32 )
  178. diags ( "can't make dl_${PACKAGE} - package not found, or no dlopen, or not windows" )
  179. return ()
  180. endif ()
  181. if (DEFINED DL_${PACKAGE} AND NOT DL_${PACKAGE})
  182. diags ( "DL_${PACKAGE} is explicitly set to FALSE - will not dynamically-load" )
  183. return ()
  184. endif ()
  185. __get_imported_soname ( "${Package}::${Component}" _lib )
  186. if (NOT _lib)
  187. if (DL_${PACKAGE})
  188. message ( FATAL_ERROR "Cant dynamicaly load ${Package}: library is not present" )
  189. endif ()
  190. diags ( "imported soname of ${Package}::${Component} is empty (no location, or no soname) - will not dynamically-load" )
  191. return () # library is not preset as external essence, can't dlopen it
  192. endif ()
  193. set ( DL_${PACKAGE} ON CACHE BOOL "load ${NAME} dynamically in runtime (usually with dlopen)" )
  194. set ( ${PACKAGE}_LIB "${_lib}" CACHE FILEPATH "Library file of ${NAME}" )
  195. __make_dl_lib ( ${Package}::${Component} )
  196. GET_FILENAME_COMPONENT ( _FNAME ${_lib} NAME )
  197. infomsg ( "${PACKAGE} will be loaded dynamically in runtime as ${_FNAME} (${_lib})" )
  198. trace ( ${Package}::${Component}_ld )
  199. bannervar ( DL_${PACKAGE} )
  200. bannervar ( ${PACKAGE}_LIB )
  201. endfunction ()
  202. function ( dl_package Package NAME )
  203. string ( TOUPPER "${Package}" PACKAGE )
  204. if (NOT WITH_${PACKAGE} OR NOT (HAVE_DLOPEN OR WIN32))
  205. diag ( WITH_${PACKAGE} HAVE_DLOPEN WIN32 )
  206. diags ( "can't make dl_${PACKAGE} - package not found, or no dlopen, or not windows" )
  207. return ()
  208. endif ()
  209. if (DEFINED DL_${PACKAGE} AND NOT DL_${PACKAGE})
  210. diags ( "DL_${PACKAGE} is explicitly set to FALSE - will not dynamically-load" )
  211. return ()
  212. endif ()
  213. __get_imported_soname ( "${Package}::${Package}" _lib )
  214. if (NOT _lib)
  215. if (DL_${PACKAGE})
  216. message ( FATAL_ERROR "Cant dynamicaly load ${Package}: library is not present" )
  217. endif ()
  218. diags ( "imported soname of ${Package}::${Package} is empty (no location, or no soname) - will not dynamically-load" )
  219. return () # library is not preset as external essence, can't dlopen it
  220. endif ()
  221. set ( DL_${PACKAGE} ON CACHE BOOL "load ${NAME} dynamically in runtime (usually with dlopen)" )
  222. set ( ${PACKAGE}_LIB "${_lib}" CACHE FILEPATH "Library file of ${NAME}" )
  223. __make_dl_lib ( ${Package}::${Package} )
  224. GET_FILENAME_COMPONENT ( _FNAME ${${PACKAGE}_LIB} NAME )
  225. infomsg ( "${PACKAGE} will be loaded dynamically in runtime as ${_FNAME} (${${PACKAGE}_LIB})" )
  226. trace ( ${Package}::${Package}_ld )
  227. bannervar ( DL_${PACKAGE} )
  228. bannervar ( ${PACKAGE}_LIB )
  229. endfunction ()
  230. function ( GET_SONAME RAWLIB OUTVAR )
  231. if (NOT WIN32)
  232. if (NOT DEFINED CMAKE_OBJDUMP)
  233. find_package ( BinUtils QUIET )
  234. endif ()
  235. if (NOT DEFINED CMAKE_OBJDUMP)
  236. find_program ( CMAKE_OBJDUMP objdump )
  237. endif ()
  238. mark_as_advanced ( CMAKE_OBJDUMP BinUtils_DIR )
  239. if (APPLE)
  240. GET_FILENAME_COMPONENT ( EXTNAME "${RAWLIB}" EXT )
  241. if (EXTNAME STREQUAL ".tbd")
  242. return () # library is present in system by design, no need to unbind from it via dlopen at all.
  243. endif ()
  244. execute_process ( COMMAND "${CMAKE_OBJDUMP}" --macho --dylib-id "${RAWLIB}"
  245. WORKING_DIRECTORY "${SOURCE_DIR}"
  246. RESULT_VARIABLE res
  247. OUTPUT_VARIABLE _CONTENT
  248. ERROR_QUIET
  249. OUTPUT_STRIP_TRAILING_WHITESPACE )
  250. STRING ( REGEX REPLACE ".*:\n" "" _CONTENT "${_CONTENT}" )
  251. GET_FILENAME_COMPONENT ( EXTNAME "${_CONTENT}" LAST_EXT )
  252. if (EXTNAME STREQUAL ".dylib")
  253. set ( "${OUTVAR}" "${_CONTENT}" PARENT_SCOPE )
  254. return ()
  255. endif ()
  256. else ()
  257. execute_process ( COMMAND "${CMAKE_OBJDUMP}" -p "${RAWLIB}"
  258. WORKING_DIRECTORY "${SOURCE_DIR}"
  259. RESULT_VARIABLE res
  260. OUTPUT_VARIABLE _CONTENT
  261. ERROR_QUIET
  262. OUTPUT_STRIP_TRAILING_WHITESPACE )
  263. STRING ( REGEX REPLACE "\n" ";" _CONTENT "${_CONTENT}" )
  264. FOREACH (LINE ${_CONTENT})
  265. IF ("${LINE}" MATCHES "^[ \t]+SONAME[ \t]+(.*)")
  266. set ( "${OUTVAR}" "${CMAKE_MATCH_1}" PARENT_SCOPE )
  267. break ()
  268. endif ()
  269. endforeach ()
  270. endif (APPLE)
  271. else ()
  272. GET_FILENAME_COMPONENT ( LIBNAME "${RAWLIB}" NAME_WE )
  273. set ( "${OUTVAR}" "${LIBNAME}.dll" PARENT_SCOPE )
  274. endif ()
  275. endfunction ()
  276. function ( configure_config data )
  277. # generate config files
  278. set ( RUNDIR "${CMAKE_INSTALL_FULL_RUNSTATEDIR}/manticore" )
  279. set ( LOGDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/log/manticore" )
  280. set ( CONFDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/${data}" )
  281. configure_file ( "${MANTICORE_SOURCE_DIR}/manticore.conf.in" "${MANTICORE_BINARY_DIR}/manticore.conf" @ONLY )
  282. endfunction ()
  283. macro ( return_if_target_found TRG LEGEND )
  284. if (TARGET ${TRG})
  285. diagst ( ${TRG} "${LEGEND}" )
  286. return ()
  287. endif ()
  288. endmacro ()
  289. macro ( getruntime OUTVAR suffix )
  290. if (TARGET RUNTIME)
  291. get_target_property ( __runtime RUNTIME LIBS${suffix} )
  292. if ( NOT "${__runtime}" STREQUAL "__runtime-NOTFOUND" )
  293. list ( APPEND ${OUTVAR} ${__runtime} )
  294. endif ()
  295. endif ()
  296. endmacro ()
  297. # append any text to build info
  298. function ( addruntime library suffix )
  299. if (NOT TARGET RUNTIME)
  300. add_library ( RUNTIME INTERFACE )
  301. endif ()
  302. set_property ( TARGET RUNTIME APPEND PROPERTY LIBS${suffix} "${library}" )
  303. endfunction ()
  304. function ( implib_config prefix name )
  305. if (${prefix}_FOUND AND NOT TARGET ${name})
  306. add_library ( ${name} UNKNOWN IMPORTED )
  307. if (${prefix}_INCLUDE_DIRS)
  308. set_property ( TARGET ${name} PROPERTY
  309. INTERFACE_INCLUDE_DIRECTORIES "${${prefix}_INCLUDE_DIRS}" )
  310. endif ()
  311. if (${prefix}_LINK_LIBRARIES)
  312. set_property ( TARGET ${name} PROPERTY
  313. IMPORTED_LOCATION "${${prefix}_LINK_LIBRARIES}" )
  314. endif ()
  315. if (${prefix}_LDFLAGS_OTHER)
  316. set_property ( TARGET ${name} PROPERTY
  317. INTERFACE_LINK_OPTIONS "${${prefix}_LDFLAGS_OTHER}" )
  318. endif ()
  319. if (${prefix}_CFLAGS_OTHER)
  320. set_property ( TARGET ${name} PROPERTY
  321. INTERFACE_COMPILE_OPTIONS "${${prefix}_CFLAGS_OTHER}" )
  322. endif ()
  323. endif ()
  324. endfunction ()
  325. function ( implib_includes prefix name )
  326. if (${prefix}_FOUND AND NOT TARGET ${name})
  327. add_library ( ${name} INTERFACE IMPORTED )
  328. if (${prefix}_INCLUDE_DIRS)
  329. set_property ( TARGET ${name} PROPERTY
  330. INTERFACE_INCLUDE_DIRECTORIES "${${prefix}_INCLUDE_DIRS}" )
  331. endif ()
  332. endif ()
  333. endfunction ()
  334. # helpers vars to shorten generate lines
  335. set ( CLANGCXX "$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>" )
  336. set ( GNUCXX "$<COMPILE_LANG_AND_ID:CXX,GNU>" )
  337. set ( GNUCLANGCXX "$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang,GNU>" )
  338. set ( CLANGC "$<COMPILE_LANG_AND_ID:C,Clang,AppleClang>" )
  339. set ( GNUC "$<COMPILE_LANG_AND_ID:C,GNU>" )
  340. set ( GNUCLANGC "$<COMPILE_LANG_AND_ID:C,Clang,AppleClang,GNU>" )
  341. set ( GNUC_CXX "$<OR:${GNUCXX},${GNUC}>" )
  342. set ( CLANGC_CXX "$<OR:${CLANGCXX},${CLANGC}>" )
  343. set ( GNUCLANGC_CXX "$<OR:${GNUCLANGCXX},${GNUCLANGC}>" )
  344. if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
  345. set ( CLANG_CL 1 )
  346. set ( ONLYGNUCLANGCXX 0 )
  347. set ( ONLYCLANGCXX 0 )
  348. set ( ONLYGNUCLANGC 0 )
  349. set ( ONLYGNUCLANGC_CXX 0 )
  350. set ( MSCXX 1 )
  351. else ()
  352. set ( CLANG_CL 0 )
  353. set ( ONLYGNUCLANGCXX "${GNUCLANGCXX}" )
  354. set ( ONLYCLANGCXX "${CLANGCXX}" )
  355. set ( ONLYGNUCLANGC "${GNUCLANGC}" )
  356. set ( ONLYGNUCLANGC_CXX "${GNUCLANGC_CXX}" )
  357. set ( MSCXX "$<COMPILE_LANG_AND_ID:CXX,MSVC>" )
  358. endif ()
  359. if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_PLATFORM_ID STREQUAL Windows)
  360. set ( CLANGWIN 1 )
  361. else ()
  362. set ( CLANGWIN 0 )
  363. endif ()