FindXCTest.cmake 6.2 KB

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