FindXCTest.cmake 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. FindXCTest
  5. ----------
  6. Functions to help creating and executing XCTest bundles.
  7. An XCTest bundle is a CFBundle with a special product-type
  8. and bundle extension. The Mac Developer Library provides more
  9. information in the `Testing with Xcode`_ document.
  10. .. _Testing with Xcode: http://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/
  11. Module Functions
  12. ^^^^^^^^^^^^^^^^
  13. .. command:: xctest_add_bundle
  14. The ``xctest_add_bundle`` function creates a XCTest bundle named
  15. <target> which will test the target <testee>. Supported target types
  16. for testee are Frameworks and App Bundles::
  17. xctest_add_bundle(
  18. <target> # Name of the XCTest bundle
  19. <testee> # Target name of the testee
  20. )
  21. .. command:: xctest_add_test
  22. The ``xctest_add_test`` function adds an XCTest bundle to the
  23. project to be run by :manual:`ctest(1)`. The test will be named
  24. <name> and tests <bundle>::
  25. xctest_add_test(
  26. <name> # Test name
  27. <bundle> # Target name of XCTest bundle
  28. )
  29. Module Variables
  30. ^^^^^^^^^^^^^^^^
  31. The following variables are set by including this module:
  32. .. variable:: XCTest_FOUND
  33. True if the XCTest Framework and executable were found.
  34. .. variable:: XCTest_EXECUTABLE
  35. The path to the xctest command line tool used to execute XCTest bundles.
  36. .. variable:: XCTest_INCLUDE_DIRS
  37. The directory containing the XCTest Framework headers.
  38. .. variable:: XCTest_LIBRARIES
  39. The location of the XCTest Framework.
  40. #]=======================================================================]
  41. find_path(XCTest_INCLUDE_DIR
  42. NAMES "XCTest/XCTest.h"
  43. DOC "XCTest include directory")
  44. mark_as_advanced(XCTest_INCLUDE_DIR)
  45. find_library(XCTest_LIBRARY
  46. NAMES XCTest
  47. DOC "XCTest Framework library")
  48. mark_as_advanced(XCTest_LIBRARY)
  49. execute_process(
  50. COMMAND xcrun --find xctest
  51. OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE
  52. ERROR_VARIABLE _xcrun_err)
  53. if(_xcrun_out)
  54. set(XCTest_EXECUTABLE "${_xcrun_out}" CACHE FILEPATH "XCTest executable")
  55. mark_as_advanced(XCTest_EXECUTABLE)
  56. endif()
  57. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  58. find_package_handle_standard_args(XCTest
  59. FOUND_VAR XCTest_FOUND
  60. REQUIRED_VARS XCTest_LIBRARY XCTest_INCLUDE_DIR XCTest_EXECUTABLE)
  61. if(XCTest_FOUND)
  62. set(XCTest_INCLUDE_DIRS "${XCTest_INCLUDE_DIR}")
  63. set(XCTest_LIBRARIES "${XCTest_LIBRARY}")
  64. endif(XCTest_FOUND)
  65. function(xctest_add_bundle target testee)
  66. if(NOT XCTest_FOUND)
  67. message(FATAL_ERROR "XCTest is required to create a XCTest Bundle.")
  68. endif(NOT XCTest_FOUND)
  69. if(NOT CMAKE_OSX_SYSROOT)
  70. message(FATAL_ERROR "Adding XCTest bundles requires CMAKE_OSX_SYSROOT to be set.")
  71. endif()
  72. add_library(${target} MODULE ${ARGN})
  73. set_target_properties(${target} PROPERTIES
  74. BUNDLE TRUE
  75. XCTEST TRUE
  76. XCTEST_TESTEE ${testee})
  77. target_link_libraries(${target} PRIVATE "-framework Foundation")
  78. target_link_libraries(${target} PRIVATE ${XCTest_LIBRARIES})
  79. target_include_directories(${target} PRIVATE ${XCTest_INCLUDE_DIRS})
  80. # retrieve testee target type
  81. if(NOT TARGET ${testee})
  82. message(FATAL_ERROR "${testee} is not a target.")
  83. endif()
  84. get_property(_testee_type TARGET ${testee} PROPERTY TYPE)
  85. get_property(_testee_framework TARGET ${testee} PROPERTY FRAMEWORK)
  86. get_property(_testee_macosx_bundle TARGET ${testee} PROPERTY MACOSX_BUNDLE)
  87. if(_testee_type STREQUAL "SHARED_LIBRARY" AND _testee_framework)
  88. # testee is a Framework
  89. target_link_libraries(${target} PRIVATE ${testee})
  90. elseif(_testee_type STREQUAL "STATIC_LIBRARY")
  91. # testee is a static library
  92. target_link_libraries(${target} PRIVATE ${testee})
  93. elseif(_testee_type STREQUAL "EXECUTABLE" AND _testee_macosx_bundle)
  94. # testee is an App Bundle
  95. add_dependencies(${target} ${testee})
  96. if(XCODE)
  97. set_target_properties(${target} PROPERTIES
  98. XCODE_ATTRIBUTE_BUNDLE_LOADER "$(TEST_HOST)"
  99. XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:${testee}>")
  100. if(NOT XCODE_VERSION VERSION_LESS 7.3)
  101. set_target_properties(${target} PROPERTIES
  102. LIBRARY_OUTPUT_DIRECTORY "$<TARGET_BUNDLE_CONTENT_DIR:${testee}>/PlugIns")
  103. endif()
  104. else(XCODE)
  105. target_link_libraries(${target}
  106. PRIVATE -bundle_loader $<TARGET_FILE:${testee}>)
  107. endif(XCODE)
  108. else()
  109. message(FATAL_ERROR "Testee ${testee} is of unsupported type.")
  110. endif()
  111. endfunction(xctest_add_bundle)
  112. function(xctest_add_test name bundle)
  113. if(NOT XCTest_EXECUTABLE)
  114. message(FATAL_ERROR "XCTest executable is required to register a test.")
  115. endif()
  116. # check that bundle is a XCTest Bundle
  117. if(NOT TARGET ${bundle})
  118. message(FATAL_ERROR "${bundle} is not a target.")
  119. endif(NOT TARGET ${bundle})
  120. get_property(_test_type TARGET ${bundle} PROPERTY TYPE)
  121. get_property(_test_bundle TARGET ${bundle} PROPERTY BUNDLE)
  122. get_property(_test_xctest TARGET ${bundle} PROPERTY XCTEST)
  123. if(NOT _test_type STREQUAL "MODULE_LIBRARY"
  124. OR NOT _test_xctest OR NOT _test_bundle)
  125. message(FATAL_ERROR "Test ${bundle} is not an XCTest Bundle")
  126. endif()
  127. # get and check testee properties
  128. get_property(_testee TARGET ${bundle} PROPERTY XCTEST_TESTEE)
  129. if(NOT TARGET ${_testee})
  130. message(FATAL_ERROR "${_testee} is not a target.")
  131. endif()
  132. get_property(_testee_type TARGET ${_testee} PROPERTY TYPE)
  133. get_property(_testee_framework TARGET ${_testee} PROPERTY FRAMEWORK)
  134. # register test
  135. add_test(
  136. NAME ${name}
  137. COMMAND ${XCTest_EXECUTABLE} $<TARGET_BUNDLE_DIR:${bundle}>)
  138. # point loader to testee in case rpath is disabled
  139. if(_testee_type STREQUAL "SHARED_LIBRARY" AND _testee_framework)
  140. set_property(TEST ${name} APPEND PROPERTY
  141. ENVIRONMENT DYLD_FRAMEWORK_PATH=$<TARGET_LINKER_FILE_DIR:${_testee}>/..)
  142. endif()
  143. endfunction(xctest_add_test)