AndroidTestUtilities.cmake 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file LICENSE.rst or https://cmake.org/licensing for details.
  3. #[======================================================================[.rst:
  4. AndroidTestUtilities
  5. ------------------------
  6. .. versionadded:: 3.7
  7. Create a test that automatically loads specified data onto an Android device.
  8. Introduction
  9. ^^^^^^^^^^^^
  10. Use this module to push data needed for testing an Android device behavior
  11. onto a connected Android device. The module will accept files and libraries as
  12. well as separate destinations for each. It will create a test that loads the
  13. files into a device object store and link to them from the specified
  14. destination. The files are only uploaded if they are not already in the object
  15. store.
  16. For example:
  17. .. code-block:: cmake
  18. include(AndroidTestUtilities)
  19. android_add_test_data(
  20. example_setup_test
  21. FILES <files>...
  22. LIBS <libs>...
  23. DEVICE_TEST_DIR "/data/local/tests/example"
  24. DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA"
  25. )
  26. At build time a test named "example_setup_test" will be created. Run this test
  27. on the command line with :manual:`ctest(1)` to load the data onto the Android
  28. device.
  29. Module Functions
  30. ^^^^^^^^^^^^^^^^
  31. .. command:: android_add_test_data
  32. .. code-block:: cmake
  33. android_add_test_data(<test-name>
  34. [FILES <files>...] [FILES_DEST <device-dir>]
  35. [LIBS <libs>...] [LIBS_DEST <device-dir>]
  36. [DEVICE_OBJECT_STORE <device-dir>]
  37. [DEVICE_TEST_DIR <device-dir>]
  38. [NO_LINK_REGEX <strings>...]
  39. )
  40. The ``android_add_test_data`` function is used to copy files and libraries
  41. needed to run project-specific tests. On the host operating system, this is
  42. done at build time. For on-device testing, the files are loaded onto the
  43. device by the manufactured test at run time.
  44. This function accepts the following named parameters:
  45. ``FILES <files>...``
  46. zero or more files needed for testing
  47. ``LIBS <libs>...``
  48. zero or more libraries needed for testing
  49. ``FILES_DEST <device-dir>``
  50. absolute path where the data files are expected to be
  51. ``LIBS_DEST <device-dir>``
  52. absolute path where the libraries are expected to be
  53. ``DEVICE_OBJECT_STORE <device-dir>``
  54. absolute path to the location where the data is stored on-device
  55. ``DEVICE_TEST_DIR <device-dir>``
  56. absolute path to the root directory of the on-device test location
  57. ``NO_LINK_REGEX <strings>...``
  58. list of regex strings matching the names of files that should be
  59. copied from the object store to the testing directory
  60. #]======================================================================]
  61. include(${CMAKE_CURRENT_LIST_DIR}/ExternalData.cmake)
  62. # The parameters to this function should be set to the list of directories,
  63. # files, and libraries that need to be installed prior to testing.
  64. function(android_add_test_data test_name)
  65. # As the names suggest, oneValueArgs lists the arguments that specify a
  66. # single value, while multiValueArgs can contain one or more values.
  67. set(keywordArgs)
  68. set(oneValueArgs FILES_DEST LIBS_DEST DEVICE_OBJECT_STORE DEVICE_TEST_DIR)
  69. set(multiValueArgs FILES LIBS NO_LINK_REGEX)
  70. # For example, if you called this function with FILES </path/to/file>
  71. # then this path would be stored in the variable AST_FILES.
  72. # The AST prefix stands for the name of this function (android_add_test_data).
  73. cmake_parse_arguments(AST "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  74. if(NOT AST_DEVICE_TEST_DIR)
  75. message(FATAL_ERROR "-- You must specify the location of the on device test directory.")
  76. endif()
  77. if(NOT AST_DEVICE_OBJECT_STORE)
  78. message(FATAL_ERROR "-- You must specify the location of the on device object store.")
  79. endif()
  80. if(${AST_DEVICE_TEST_DIR} STREQUAL "/")
  81. message(FATAL_ERROR "-- The device test directory cannot be '/'")
  82. endif()
  83. # Copy all test data files into the binary directory, where tests are run.
  84. # ExternalData will handle fetching DATA{...} references.
  85. string(REPLACE "|" ";" hash_algs "${_ExternalData_REGEX_EXT}")
  86. # Convert ExternalData placeholder file names to DATA{} syntax.
  87. foreach(alg ${hash_algs})
  88. string(REGEX REPLACE "([^ ;]+)\\.${alg}" "DATA{\\1}" AST_FILES "${AST_FILES}")
  89. endforeach()
  90. set(DATA_TARGET_NAME "${test_name}")
  91. string(FIND "${AST_FILES}" "DATA{" data_files_found)
  92. if(${data_files_found} GREATER "-1")
  93. # Use ExternalData if any DATA{} files were found.
  94. ExternalData_Expand_Arguments(
  95. ${DATA_TARGET_NAME}
  96. extern_data_output
  97. ${AST_FILES})
  98. ExternalData_Add_Target(${DATA_TARGET_NAME})
  99. else()
  100. add_custom_target(${DATA_TARGET_NAME} ALL)
  101. set(extern_data_output ${AST_FILES})
  102. endif()
  103. # For regular files on Linux, just copy them directly.
  104. foreach(path ${AST_FILES})
  105. foreach(output ${extern_data_output})
  106. if(${output} STREQUAL ${path})
  107. # Check if a destination was specified. If not, we copy by default
  108. # into this project's binary directory, preserving its relative path.
  109. if(AST_${VAR}_DEST)
  110. set(DEST ${CMAKE_BINARY_DIR}/${parent_dir}/${AST_${VAR}_DEST})
  111. else()
  112. get_filename_component(parent_dir ${path} DIRECTORY)
  113. set(DEST "${CMAKE_BINARY_DIR}/${parent_dir}")
  114. endif()
  115. get_filename_component(extern_data_source ${output} REALPATH)
  116. get_filename_component(extern_data_basename ${output} NAME)
  117. add_custom_command(
  118. TARGET ${DATA_TARGET_NAME} POST_BUILD
  119. COMMAND ${CMAKE_COMMAND} -E copy_if_different ${extern_data_source} ${DEST}/${extern_data_basename}
  120. )
  121. endif()
  122. endforeach()
  123. endforeach()
  124. if(ANDROID)
  125. string(REGEX REPLACE "DATA{([^ ;]+)}" "\\1" processed_FILES "${AST_FILES}")
  126. # There's no target used for this command, so we don't need to do anything
  127. # here for CMP0178.
  128. add_test(
  129. NAME ${test_name}
  130. COMMAND ${CMAKE_COMMAND}
  131. "-Darg_files_dest=${AST_FILES_DEST}"
  132. "-Darg_libs_dest=${AST_LIBS_DEST}"
  133. "-Darg_dev_test_dir=${AST_DEVICE_TEST_DIR}"
  134. "-Darg_dev_obj_store=${AST_DEVICE_OBJECT_STORE}"
  135. "-Darg_no_link_regex=${AST_NO_LINK_REGEX}"
  136. "-Darg_files=${processed_FILES}"
  137. "-Darg_libs=${AST_LIBS}"
  138. "-Darg_src_dir=${CMAKE_CURRENT_SOURCE_DIR}"
  139. -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake)
  140. endif()
  141. endfunction()