CheckPrototypeDefinition.cmake 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. CheckPrototypeDefinition
  5. ------------------------
  6. Check if the prototype we expect is correct.
  7. .. command:: check_prototype_definition
  8. .. code-block:: cmake
  9. check_prototype_definition(FUNCTION PROTOTYPE RETURN HEADER VARIABLE)
  10. ::
  11. FUNCTION - The name of the function (used to check if prototype exists)
  12. PROTOTYPE- The prototype to check.
  13. RETURN - The return value of the function.
  14. HEADER - The header files required.
  15. VARIABLE - The variable to store the result.
  16. Will be created as an internal cache variable.
  17. Example:
  18. .. code-block:: cmake
  19. check_prototype_definition(getpwent_r
  20. "struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)"
  21. "NULL"
  22. "unistd.h;pwd.h"
  23. SOLARIS_GETPWENT_R)
  24. The following variables may be set before calling this function to modify
  25. the way the check is run:
  26. ``CMAKE_REQUIRED_FLAGS``
  27. string of compile command line flags.
  28. ``CMAKE_REQUIRED_DEFINITIONS``
  29. list of macros to define (-DFOO=bar).
  30. ``CMAKE_REQUIRED_INCLUDES``
  31. list of include directories.
  32. ``CMAKE_REQUIRED_LINK_OPTIONS``
  33. .. versionadded:: 3.14
  34. list of options to pass to link command.
  35. ``CMAKE_REQUIRED_LIBRARIES``
  36. list of libraries to link.
  37. ``CMAKE_REQUIRED_QUIET``
  38. .. versionadded:: 3.1
  39. execute quietly without messages.
  40. #]=======================================================================]
  41. #
  42. get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
  43. include_guard(GLOBAL)
  44. function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
  45. if (NOT DEFINED ${_VARIABLE})
  46. if(NOT CMAKE_REQUIRED_QUIET)
  47. message(CHECK_START "Checking prototype ${_FUNCTION} for ${_VARIABLE}")
  48. endif()
  49. set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
  50. set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
  51. if (CMAKE_REQUIRED_LINK_OPTIONS)
  52. set(CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS
  53. LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
  54. else()
  55. set(CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS)
  56. endif()
  57. if (CMAKE_REQUIRED_LIBRARIES)
  58. set(CHECK_PROTOTYPE_DEFINITION_LIBS
  59. LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
  60. else()
  61. set(CHECK_PROTOTYPE_DEFINITION_LIBS)
  62. endif()
  63. if (CMAKE_REQUIRED_INCLUDES)
  64. set(CMAKE_SYMBOL_EXISTS_INCLUDES
  65. "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
  66. else()
  67. set(CMAKE_SYMBOL_EXISTS_INCLUDES)
  68. endif()
  69. foreach(_FILE ${_HEADER})
  70. string(APPEND CHECK_PROTOTYPE_DEFINITION_HEADER
  71. "#include <${_FILE}>\n")
  72. endforeach()
  73. set(CHECK_PROTOTYPE_DEFINITION_SYMBOL ${_FUNCTION})
  74. set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
  75. set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
  76. configure_file("${__check_proto_def_dir}/CheckPrototypeDefinition.c.in"
  77. "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c" @ONLY)
  78. file(READ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c _SOURCE)
  79. try_compile(${_VARIABLE}
  80. SOURCES ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckPrototypeDefinition.c
  81. COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
  82. ${CHECK_PROTOTYPE_DEFINITION_LINK_OPTIONS}
  83. ${CHECK_PROTOTYPE_DEFINITION_LIBS}
  84. CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CHECK_PROTOTYPE_DEFINITION_FLAGS}
  85. "${CMAKE_SYMBOL_EXISTS_INCLUDES}"
  86. OUTPUT_VARIABLE OUTPUT)
  87. if (${_VARIABLE})
  88. set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
  89. if(NOT CMAKE_REQUIRED_QUIET)
  90. message(CHECK_PASS "True")
  91. endif()
  92. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  93. "Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
  94. "${OUTPUT}\n\n")
  95. else ()
  96. if(NOT CMAKE_REQUIRED_QUIET)
  97. message(CHECK_FAIL "False")
  98. endif()
  99. set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
  100. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
  101. "Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} failed with the following output:\n"
  102. "${OUTPUT}\n\n${_SOURCE}\n\n")
  103. endif ()
  104. endif()
  105. endfunction()