1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4# This function handles pushing all of the test files needed to the device. 5# It places the data files in the object store and makes links to them from 6# the appropriate directories. 7# 8# This function accepts the following named parameters: 9# DIRS : one or more directories needed for testing. 10# FILES : one or more files needed for testing. 11# LIBS : one or more libraries needed for testing. 12# DIRS_DEST : specify where the directories should be installed. 13# FILES_DEST : specify where the files should be installed. 14# LIBS_DEST : specify where the libraries should be installed. 15# DEV_OBJ_STORE : specify where the actual data files should be placed. 16# DEV_TEST_DIR : specify the root file for the module test directory. 17# The DEV_OBJ_STORE and DEV_TEST_DIR variables are required. 18 19# The parameters to this function should be set to the list of directories, 20# files, and libraries that need to be installed prior to testing. 21function(android_push_test_files_to_device) 22 23 # The functions in the module need the adb executable. 24 find_program(adb_executable adb) 25 if(NOT adb_executable) 26 message(FATAL_ERROR "could not find adb") 27 endif() 28 29 function(execute_adb_command) 30 execute_process(COMMAND ${adb_executable} ${ARGN} RESULT_VARIABLE res_var OUTPUT_VARIABLE out_var ERROR_VARIABLE err_var) 31 set(out_var ${out_var} PARENT_SCOPE) 32 if(res_var) 33 string(REGEX REPLACE ";" " " com "${ARGN}") 34 message(FATAL_ERROR "Error occurred during adb command: adb ${com}\nError: ${err_var}.") 35 endif() 36 endfunction() 37 38 # Checks to make sure that a given file exists on the device. If it does, 39 # if(file_exists) will return true. 40 macro(check_device_file_exists device_file file_exists) 41 set(${file_exists} "") 42 execute_process( 43 COMMAND ${adb_executable} shell ls ${device_file} 44 OUTPUT_VARIABLE out_var ERROR_VARIABLE out_var) 45 if(NOT out_var) # when a directory exists but is empty the output is empty 46 set(${file_exists} "YES") 47 else() 48 string(FIND ${out_var} "No such file or directory" no_file_exists) 49 if(${no_file_exists} STREQUAL "-1") # -1 means the file exists 50 set(${file_exists} "YES") 51 endif() 52 endif() 53 endmacro() 54 55 # Checks to see if a filename matches a regex. 56 function(filename_regex filename reg_ex) 57 string(REGEX MATCH ${reg_ex} filename_match ${filename}) 58 set(filename_match ${filename_match} PARENT_SCOPE) 59 endfunction() 60 61 # If a file with given name exists in the CMAKE_BINARY_DIR then use that file. 62 # Otherwise use the file with root in CMAKE_CURRENT_SOURCE_DIR. 63 macro(set_absolute_path relative_path absolute_path) 64 set(${absolute_path} ${arg_src_dir}/${relative_path}) 65 if(EXISTS ${CMAKE_BINARY_DIR}/${relative_path}) 66 set(${absolute_path} ${CMAKE_BINARY_DIR}/${relative_path}) 67 endif() 68 if(NOT EXISTS ${${absolute_path}}) 69 if(EXISTS ${relative_path}) 70 set(${absolute_path} ${relative_path}) 71 else() 72 message(FATAL_ERROR "Cannot find file for specified path: ${relative_path}") 73 endif() 74 endif() 75 endmacro() 76 77 # This function pushes the data into the device object store and 78 # creates a link to that data file in a specified location. 79 # 80 # This function requires the following un-named parameters: 81 # data_path : absolute path to data to load into dev obj store. 82 # dev_object_store : absolute path to the device object store directory. 83 # link_origin : absolute path to the origin of the link to the dev obj store data file. 84 function(push_and_link data_path dev_object_store link_origin) 85 FILE(SHA1 ${data_path} hash_val) 86 set(obj_store_dst ${dev_object_store}/${hash_val}) 87 check_device_file_exists(${obj_store_dst} obj_store_file_exists) 88 # TODO: Verify that the object store file is indeed hashed correctly. Could use md5. 89 if(NOT obj_store_file_exists) 90 execute_adb_command(push ${data_path} ${obj_store_dst}) 91 endif() 92 check_device_file_exists(${link_origin} link_exists) 93 if(link_exists) 94 execute_adb_command(shell rm -f ${link_origin}) 95 endif() 96 foreach(ex ${arg_no_link_regex}) 97 filename_regex(${data_path} ${ex}) 98 LIST(APPEND match_ex ${filename_match}) 99 endforeach() 100 if(match_ex) 101 execute_adb_command(shell cp ${obj_store_dst} ${link_origin}) 102 else() 103 execute_adb_command(shell ln -s ${obj_store_dst} ${link_origin}) 104 endif() 105 endfunction() 106 107 #---------------------------------------------------------------------------- 108 #--------------------Beginning of actual function---------------------------- 109 #---------------------------------------------------------------------------- 110 set(oneValueArgs FILES_DEST LIBS_DEST DEV_TEST_DIR DEV_OBJ_STORE) 111 set(multiValueArgs FILES LIBS) 112 cmake_parse_arguments(_ptd "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 113 114 # Setup of object store and test dir. 115 check_device_file_exists(${_ptd_DEV_OBJ_STORE} dev_obj_store_exists) 116 if(NOT dev_obj_store_exists) 117 execute_adb_command(shell mkdir -p ${_ptd_DEV_OBJ_STORE}) 118 endif() 119 check_device_file_exists(${_ptd_DEV_TEST_DIR} test_dir_exists) 120 if(test_dir_exists) 121 # This is protected in the SetupProjectTests module. 122 execute_adb_command(shell rm -r ${_ptd_DEV_TEST_DIR}) 123 endif() 124 execute_adb_command(shell mkdir -p ${_ptd_DEV_TEST_DIR}) 125 126 # Looping over the various types of test data possible. 127 foreach(TYPE ${multiValueArgs}) 128 if(_ptd_${TYPE}) 129 130 # determine if the data type destination has been explicitly specified. 131 if(_ptd_${TYPE}_DEST) 132 set(dest ${_ptd_${TYPE}_DEST}) 133 else() 134 if(${TYPE} STREQUAL LIBS) 135 set(dest ${_ptd_DEV_TEST_DIR}/lib) 136 else() 137 set(dest ${_ptd_DEV_TEST_DIR}) 138 endif() 139 endif() 140 execute_adb_command(shell mkdir -p ${dest}) 141 142 # Loop over the files passed in 143 foreach(relative_path ${_ptd_${TYPE}}) 144 # The absolute path can be through the source directory or the build directory. 145 # If the file/dir exists in the build directory that version is chosen. 146 set_absolute_path(${relative_path} absolute_path) 147 # Need to transfer all data files in the data directories to the device 148 # except those explicitly ignored. 149 if(${TYPE} STREQUAL FILES) 150 get_filename_component(file_dir ${relative_path} DIRECTORY) 151 # dest was determined earlier, relative_path is a dir, file is path from relative path to a data 152 set(cur_dest ${dest}/${relative_path}) 153 set(on_dev_dir ${dest}/${file_dir}) 154 execute_adb_command(shell mkdir -p ${on_dev_dir}) 155 if(IS_SYMLINK ${absolute_path}) 156 get_filename_component(real_data_origin ${absolute_path} REALPATH) 157 push_and_link(${real_data_origin} ${_ptd_DEV_OBJ_STORE} ${cur_dest}) 158 else() 159 push_and_link(${absolute_path} ${_ptd_DEV_OBJ_STORE} ${cur_dest}) 160 endif() 161 else() # LIBS 162 execute_adb_command(push ${absolute_path} ${dest}) 163 endif() 164 endforeach() 165 endif() 166 endforeach() 167endfunction() 168 169android_push_test_files_to_device( 170 FILES_DEST ${arg_files_dest} 171 LIBS_DEST ${arg_libs_dest} 172 DEV_TEST_DIR ${arg_dev_test_dir} 173 DEV_OBJ_STORE ${arg_dev_obj_store} 174 FILES ${arg_files} 175 LIBS ${arg_libs} 176 ) 177