# Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
# file Copyright.txt or https://cmake.org/licensing for details. | |
# This function handles pushing all of the test files needed to the device. | |
# It places the data files in the object store and makes links to them from | |
# the appropriate directories. | |
# | |
# This function accepts the following named parameters: | |
# DIRS : one or more directories needed for testing. | |
# FILES : one or more files needed for testing. | |
# LIBS : one or more libraries needed for testing. | |
# DIRS_DEST : specify where the directories should be installed. | |
# FILES_DEST : specify where the files should be installed. | |
# LIBS_DEST : specify where the libraries should be installed. | |
# DEV_OBJ_STORE : specify where the actual data files should be placed. | |
# DEV_TEST_DIR : specify the root file for the module test directory. | |
# The DEV_OBJ_STORE and DEV_TEST_DIR variables are required. | |
# The parameters to this function should be set to the list of directories, | |
# files, and libraries that need to be installed prior to testing. | |
function(android_push_test_files_to_device) | |
# The functions in the module need the adb executable. | |
find_program(adb_executable adb) | |
if(NOT adb_executable) | |
message(FATAL_ERROR "could not find adb") | |
endif() | |
function(execute_adb_command) | |
execute_process(COMMAND ${adb_executable} ${ARGN} RESULT_VARIABLE res_var OUTPUT_VARIABLE out_var ERROR_VARIABLE err_var) | |
set(out_var ${out_var} PARENT_SCOPE) | |
if(res_var) | |
string(REGEX REPLACE ";" " " com "${ARGN}") | |
message(FATAL_ERROR "Error occured during adb command: adb ${com}\nError: ${err_var}.") | |
endif() | |
endfunction() | |
# Checks to make sure that a given file exists on the device. If it does, | |
# if(file_exists) will return true. | |
macro(check_device_file_exists device_file file_exists) | |
set(${file_exists} "") | |
execute_process( | |
COMMAND ${adb_executable} shell ls ${device_file} | |
OUTPUT_VARIABLE out_var ERROR_VARIABLE out_var) | |
if(NOT out_var) # when a directory exists but is empty the output is empty | |
set(${file_exists} "YES") | |
else() | |
string(FIND ${out_var} "No such file or directory" no_file_exists) | |
if(${no_file_exists} STREQUAL "-1") # -1 means the file exists | |
set(${file_exists} "YES") | |
endif() | |
endif() | |
endmacro() | |
# Checks to see if a filename matches a regex. | |
function(filename_regex filename reg_ex) | |
string(REGEX MATCH ${reg_ex} filename_match ${filename}) | |
set(filename_match ${filename_match} PARENT_SCOPE) | |
endfunction() | |
# If a file with given name exists in the CMAKE_BINARY_DIR then use that file. | |
# Otherwise use the file with root in CMAKE_CURRENT_SOURCE_DIR. | |
macro(set_absolute_path relative_path absolute_path) | |
set(${absolute_path} ${arg_src_dir}/${relative_path}) | |
if(EXISTS ${CMAKE_BINARY_DIR}/${relative_path}) | |
set(${absolute_path} ${CMAKE_BINARY_DIR}/${relative_path}) | |
endif() | |
if(NOT EXISTS ${${absolute_path}}) | |
if(EXISTS ${relative_path}) | |
set(${absolute_path} ${relative_path}) | |
else() | |
message(FATAL_ERROR "Cannot find file for specified path: ${relative_path}") | |
endif() | |
endif() | |
endmacro() | |
# This function pushes the data into the device object store and | |
# creates a link to that data file in a specified location. | |
# | |
# This function requires the following un-named parameters: | |
# data_path : absolute path to data to load into dev obj store. | |
# dev_object_store : absolute path to the device object store directory. | |
# link_origin : absolute path to the origin of the link to the dev obj store data file. | |
function(push_and_link data_path dev_object_store link_origin) | |
FILE(SHA1 ${data_path} hash_val) | |
set(obj_store_dst ${dev_object_store}/${hash_val}) | |
check_device_file_exists(${obj_store_dst} obj_store_file_exists) | |
# TODO: Verify that the object store file is indeed hashed correctly. Could use md5. | |
if(NOT obj_store_file_exists) | |
execute_adb_command(push ${data_path} ${obj_store_dst}) | |
endif() | |
check_device_file_exists(${link_origin} link_exists) | |
if(link_exists) | |
execute_adb_command(shell rm -f ${link_origin}) | |
endif() | |
foreach(ex ${arg_no_link_regex}) | |
filename_regex(${data_path} ${ex}) | |
LIST(APPEND match_ex ${filename_match}) | |
endforeach() | |
if(match_ex) | |
execute_adb_command(shell cp ${obj_store_dst} ${link_origin}) | |
else() | |
execute_adb_command(shell ln -s ${obj_store_dst} ${link_origin}) | |
endif() | |
endfunction() | |
#---------------------------------------------------------------------------- | |
#--------------------Beginning of actual function---------------------------- | |
#---------------------------------------------------------------------------- | |
set(oneValueArgs FILES_DEST LIBS_DEST DEV_TEST_DIR DEV_OBJ_STORE) | |
set(multiValueArgs FILES LIBS) | |
cmake_parse_arguments(_ptd "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | |
# Setup of object store and test dir. | |
check_device_file_exists(${_ptd_DEV_OBJ_STORE} dev_obj_store_exists) | |
if(NOT dev_obj_store_exists) | |
execute_adb_command(shell mkdir -p ${_ptd_DEV_OBJ_STORE}) | |
endif() | |
check_device_file_exists(${_ptd_DEV_TEST_DIR} test_dir_exists) | |
if(test_dir_exists) | |
# This is protected in the SetupProjectTests module. | |
execute_adb_command(shell rm -r ${_ptd_DEV_TEST_DIR}) | |
endif() | |
execute_adb_command(shell mkdir -p ${_ptd_DEV_TEST_DIR}) | |
# Looping over the various types of test data possible. | |
foreach(TYPE ${multiValueArgs}) | |
if(_ptd_${TYPE}) | |
# determine if the data type destination has been explicitly specified. | |
if(_ptd_${TYPE}_DEST) | |
set(dest ${_ptd_${TYPE}_DEST}) | |
else() | |
if(${TYPE} STREQUAL LIBS) | |
set(dest ${_ptd_DEV_TEST_DIR}/lib) | |
else() | |
set(dest ${_ptd_DEV_TEST_DIR}) | |
endif() | |
endif() | |
execute_adb_command(shell mkdir -p ${dest}) | |
# Loop over the files passed in | |
foreach(relative_path ${_ptd_${TYPE}}) | |
# The absolute path can be through the source directory or the build directory. | |
# If the file/dir exists in the build directory that version is chosen. | |
set_absolute_path(${relative_path} absolute_path) | |
# Need to transfer all data files in the data directories to the device | |
# except those explicitly ignored. | |
if(${TYPE} STREQUAL FILES) | |
get_filename_component(file_dir ${relative_path} DIRECTORY) | |
# dest was determined earlier, relative_path is a dir, file is path from relative path to a data | |
set(cur_dest ${dest}/${relative_path}) | |
set(on_dev_dir ${dest}/${file_dir}) | |
execute_adb_command(shell mkdir -p ${on_dev_dir}) | |
if(IS_SYMLINK ${absolute_path}) | |
get_filename_component(real_data_origin ${absolute_path} REALPATH) | |
push_and_link(${real_data_origin} ${_ptd_DEV_OBJ_STORE} ${cur_dest}) | |
else() | |
push_and_link(${absolute_path} ${_ptd_DEV_OBJ_STORE} ${cur_dest}) | |
endif() | |
else() # LIBS | |
execute_adb_command(push ${absolute_path} ${dest}) | |
endif() | |
endforeach() | |
endif() | |
endforeach() | |
endfunction() | |
android_push_test_files_to_device( | |
FILES_DEST ${arg_files_dest} | |
LIBS_DEST ${arg_libs_dest} | |
DEV_TEST_DIR ${arg_dev_test_dir} | |
DEV_OBJ_STORE ${arg_dev_obj_store} | |
FILES ${arg_files} | |
LIBS ${arg_libs} | |
) |