summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-modules.7.rst1
-rw-r--r--Help/module/AndroidTestUtilities.rst1
-rw-r--r--Help/release/dev/add-android-test-utilities-module.rst5
-rw-r--r--Modules/AndroidTestUtilities.cmake157
-rw-r--r--Modules/AndroidTestUtilities/PushToAndroidDevice.cmake174
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx12
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx71
-rw-r--r--Tests/QtAutogen/CMakeLists.txt6
-rw-r--r--Tests/QtAutogen/rcc_empty.cpp9
-rw-r--r--Tests/QtAutogen/rcc_empty_resource.qrc4
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/RunCMakeTest.cmake20
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/SetupTest1.cmake17
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/SetupTest1Build-check.cmake5
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/SetupTest2.cmake30
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/SetupTest2Build-check.cmake7
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/SetupTest3.cmake33
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/SetupTest3Build-check.cmake6
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/check.cmake20
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/data/a.txt1
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/data/proto.proto1
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/data/subfolder/b.txt1
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/data/subfolder/protobuffer.p1
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.so1
-rw-r--r--Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.txt1
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/Server/server-test.py14
28 files changed, 563 insertions, 41 deletions
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index e905ef479c..015e36e47f 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -14,6 +14,7 @@ All Modules
:maxdepth: 1
/module/AddFileDependencies
+ /module/AndroidTestUtilities
/module/BundleUtilities
/module/CheckCCompilerFlag
/module/CheckCSourceCompiles
diff --git a/Help/module/AndroidTestUtilities.rst b/Help/module/AndroidTestUtilities.rst
new file mode 100644
index 0000000000..e7ec864c73
--- /dev/null
+++ b/Help/module/AndroidTestUtilities.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/AndroidTestUtilities.cmake
diff --git a/Help/release/dev/add-android-test-utilities-module.rst b/Help/release/dev/add-android-test-utilities-module.rst
new file mode 100644
index 0000000000..998b3cd40c
--- /dev/null
+++ b/Help/release/dev/add-android-test-utilities-module.rst
@@ -0,0 +1,5 @@
+add-android-test-utilities-module
+---------------------------------
+
+* A :module:`AndroidTestUtilities` module was added to manage transfer of
+ test data to an Android device.
diff --git a/Modules/AndroidTestUtilities.cmake b/Modules/AndroidTestUtilities.cmake
new file mode 100644
index 0000000000..a0a74fa647
--- /dev/null
+++ b/Modules/AndroidTestUtilities.cmake
@@ -0,0 +1,157 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[======================================================================[.rst:
+AndroidTestUtilities
+------------------------
+
+Create a test that automatically loads specified data onto an Android device.
+
+Introduction
+^^^^^^^^^^^^
+
+Use this module to push data needed for testing an Android device behavior
+onto a connected Android device. The module will accept files and libraries as
+well as separate destinations for each. It will create a test that loads the
+files into a device object store and link to them from the specified
+destination. The files are only uploaded if they are not already in the object
+store.
+
+For example:
+
+.. code-block:: cmake
+
+ include(AndroidTestUtilities)
+ android_add_test_data(
+ example_setup_test
+ FILES <files>...
+ LIBS <libs>...
+ DEVICE_TEST_DIR "/data/local/tests/example"
+ DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA"
+ )
+
+
+At build time a test named "example_setup_test" will be created. Run this test
+on the command line with :manual:`ctest(1)` to load the data onto the Android
+device.
+
+Module Functions
+^^^^^^^^^^^^^^^^
+
+.. command:: android_add_test_data
+
+ ::
+
+ android_add_test_data(<test-name>
+ [FILES <files>...] [FILES_DEST <device-dir>]
+ [LIBS <libs>...] [LIBS_DEST <device-dir>]
+ [DEVICE_OBJECT_STORE <device-dir>]
+ [DEVICE_TEST_DIR <device-dir>]
+ [NO_LINK_REGEX <strings>...]
+ )
+
+ The ``android_add_test_data`` function is used to copy files and libraries
+ needed to run project-specific tests. On the host operating system, this is
+ done at build time. For on-device testing, the files are loaded onto the
+ device by the manufactured test at run time.
+
+ This function accepts the following named parameters:
+
+ ``FILES <files>...``
+ zero or more files needed for testing
+ ``LIBS <libs>...``
+ zero or more libraries needed for testing
+ ``FILES_DEST <device-dir>``
+ absolute path where the data files are expected to be
+ ``LIBS_DEST <device-dir>``
+ absolute path where the libraries are expected to be
+ ``DEVICE_OBJECT_STORE <device-dir>``
+ absolute path to the location where the data is stored on-device
+ ``DEVICE_TEST_DIR <device-dir>``
+ absolute path to the root directory of the on-device test location
+ ``NO_LINK_REGEX <strings>...``
+ list of regex strings matching the names of files that should be
+ copied from the object store to the testing directory
+#]======================================================================]
+
+include(${CMAKE_CURRENT_LIST_DIR}/ExternalData.cmake)
+
+set(_AndroidTestUtilities_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}")
+
+# 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_add_test_data test_name)
+ # As the names suggest, oneValueArgs lists the arguments that specify a
+ # single value, while multiValueArgs can contain one or more values.
+ set(keywordArgs)
+ set(oneValueArgs FILES_DEST LIBS_DEST DEVICE_OBJECT_STORE DEVICE_TEST_DIR)
+ set(multiValueArgs FILES LIBS NO_LINK_REGEX)
+
+ # For example, if you called this function with FILES </path/to/file>
+ # then this path would be stored in the variable AST_FILES.
+ # The AST prefix stands for the name of this function (android_add_test_data).
+ cmake_parse_arguments(AST "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ if(NOT AST_DEVICE_TEST_DIR)
+ message(FATAL_ERROR "-- You must specify the location of the on device test directory.")
+ endif()
+ if(NOT AST_DEVICE_OBJECT_STORE)
+ message(FATAL_ERROR "-- You must specify the location of the on device object store.")
+ endif()
+ if(${AST_DEVICE_TEST_DIR} STREQUAL "/")
+ message(FATAL_ERROR "-- The device test directory cannot be '/'")
+ endif()
+
+ # Copy all test data files into the binary directory, where tests are run.
+ # ExternalData will handle fetching DATA{...} references.
+ string(REPLACE "|" ";" hash_algs "${_ExternalData_REGEX_EXT}")
+ # Convert ExternalData placeholder file names to DATA{} syntax.
+ foreach(alg ${hash_algs})
+ string(REGEX REPLACE "([^ ;]+)\\.${alg}" "DATA{\\1}" AST_FILES "${AST_FILES}")
+ endforeach()
+
+ set(DATA_TARGET_NAME "${test_name}")
+ ExternalData_Expand_Arguments(
+ ${DATA_TARGET_NAME}
+ extern_data_output
+ ${AST_FILES})
+ ExternalData_Add_Target(${DATA_TARGET_NAME})
+
+ # For regular files on Linux, just copy them directly.
+ foreach(path ${AST_FILES})
+ foreach(output ${extern_data_output})
+ if(${output} STREQUAL ${path})
+ # Check if a destination was specified. If not, we copy by default
+ # into this project's binary directory, preserving its relative path.
+ if(AST_${VAR}_DEST)
+ set(DEST ${CMAKE_BINARY_DIR}/${parent_dir}/${AST_${VAR}_DEST})
+ else()
+ get_filename_component(parent_dir ${path} DIRECTORY)
+ set(DEST "${CMAKE_BINARY_DIR}/${parent_dir}")
+ endif()
+ get_filename_component(extern_data_source ${output} REALPATH)
+ get_filename_component(extern_data_basename ${output} NAME)
+ add_custom_command(
+ TARGET ${DATA_TARGET_NAME} POST_BUILD
+ DEPENDS ${extern_data_source}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${extern_data_source} ${DEST}/${extern_data_basename}
+ )
+ endif()
+ endforeach()
+ endforeach()
+
+ if(ANDROID)
+ string(REGEX REPLACE "DATA{([^ ;]+)}" "\\1" processed_FILES "${AST_FILES}")
+ add_test(
+ NAME ${test_name}
+ COMMAND ${CMAKE_COMMAND}
+ "-Darg_files_dest=${AST_FILES_DEST}"
+ "-Darg_libs_dest=${AST_LIBS_DEST}"
+ "-Darg_dev_test_dir=${AST_DEVICE_TEST_DIR}"
+ "-Darg_dev_obj_store=${AST_DEVICE_OBJECT_STORE}"
+ "-Darg_no_link_regex=${AST_NO_LINK_REGEX}"
+ "-Darg_files=${processed_FILES}"
+ "-Darg_libs=${AST_LIBS}"
+ "-Darg_src_dir=${CMAKE_CURRENT_SOURCE_DIR}"
+ -P ${_AndroidTestUtilities_SELF_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake)
+ endif()
+endfunction()
diff --git a/Modules/AndroidTestUtilities/PushToAndroidDevice.cmake b/Modules/AndroidTestUtilities/PushToAndroidDevice.cmake
new file mode 100644
index 0000000000..f5f2564cf3
--- /dev/null
+++ b/Modules/AndroidTestUtilities/PushToAndroidDevice.cmake
@@ -0,0 +1,174 @@
+# 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_adb_command(shell ls ${device_file})
+ 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 echo rm -r ${_ptd_DEV_TEST_DIR} | su)
+ 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}
+ )
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3c36419e5b..3e27338336 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 6)
-set(CMake_VERSION_PATCH 20160930)
+set(CMake_VERSION_PATCH 20161001)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index fed4d5b735..665591185b 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -32,6 +32,8 @@ bool cmAuxSourceDirectoryCommand::InitialPass(
sourceListValue = def;
}
+ std::vector<std::string> files;
+
// Load all the files in the directory
cmsys::Directory dir;
if (dir.Load(tdir.c_str())) {
@@ -55,14 +57,16 @@ bool cmAuxSourceDirectoryCommand::InitialPass(
// depends can be done
cmSourceFile* sf = this->Makefile->GetOrCreateSource(fullname);
sf->SetProperty("ABSTRACT", "0");
- if (!sourceListValue.empty()) {
- sourceListValue += ";";
- }
- sourceListValue += fullname;
+ files.push_back(fullname);
}
}
}
}
+ std::sort(files.begin(), files.end());
+ if (!sourceListValue.empty()) {
+ sourceListValue += ";";
+ }
+ sourceListValue += cmJoin(files, ";");
this->Makefile->AddDefinition(args[1], sourceListValue.c_str());
return true;
}
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 71687ac04c..5246a676b9 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -434,13 +434,15 @@ static std::string ReadAll(const std::string& filename)
return stream.str();
}
-static std::string ListQt5RccInputs(cmSourceFile* sf,
- cmGeneratorTarget const* target,
- std::vector<std::string>& depends)
+/// @brief Reads the resource files list from from a .qrc file - Qt5 version
+/// @return True if the .qrc file was successfully parsed
+static bool ListQt5RccInputs(cmSourceFile* sf, cmGeneratorTarget const* target,
+ std::vector<std::string>& depends)
{
std::string rccCommand = GetRccExecutable(target);
bool hasDashDashList = false;
+ // Read rcc features
{
std::vector<std::string> command;
command.push_back(rccCommand);
@@ -456,15 +458,12 @@ static std::string ListQt5RccInputs(cmSourceFile* sf,
hasDashDashList = true;
}
}
-
- std::vector<std::string> qrcEntries;
-
+ // Run rcc list command
std::vector<std::string> command;
command.push_back(rccCommand);
command.push_back(hasDashDashList ? "--list" : "-list");
std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath());
-
command.push_back(absFile);
std::string rccStdOut;
@@ -479,17 +478,18 @@ static std::string ListQt5RccInputs(cmSourceFile* sf,
<< " failed:\n"
<< rccStdOut << "\n"
<< rccStdErr << std::endl;
- std::cerr << err.str();
- return std::string();
+ cmSystemTools::Error(err.str().c_str());
+ return false;
}
+ // Parse rcc list output
{
std::istringstream ostr(rccStdOut);
std::string oline;
while (std::getline(ostr, oline)) {
oline = cmQtAutoGeneratorsStripCR(oline);
if (!oline.empty()) {
- qrcEntries.push_back(oline);
+ depends.push_back(oline);
}
}
}
@@ -507,30 +507,28 @@ static std::string ListQt5RccInputs(cmSourceFile* sf,
std::ostringstream err;
err << "AUTOGEN: error: Rcc lists unparsable output " << eline
<< std::endl;
- std::cerr << err.str();
- return std::string();
+ cmSystemTools::Error(err.str().c_str());
+ return false;
}
pos += searchString.length();
std::string::size_type sz = eline.size() - pos - 1;
- qrcEntries.push_back(eline.substr(pos, sz));
+ depends.push_back(eline.substr(pos, sz));
}
}
}
- depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end());
- return cmJoin(qrcEntries, "@list_sep@");
+ return true;
}
-static std::string ListQt4RccInputs(cmSourceFile* sf,
- std::vector<std::string>& depends)
+/// @brief Reads the resource files list from from a .qrc file - Qt4 version
+/// @return True if the .qrc file was successfully parsed
+static bool ListQt4RccInputs(cmSourceFile* sf,
+ std::vector<std::string>& depends)
{
const std::string qrcContents = ReadAll(sf->GetFullPath());
cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
- std::string entriesList;
- const char* sep = "";
-
size_t offset = 0;
while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
std::string qrcEntry = fileMatchRegex.match(1);
@@ -547,12 +545,21 @@ static std::string ListQt4RccInputs(cmSourceFile* sf,
qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
}
- entriesList += sep;
- entriesList += qrcEntry;
- sep = "@list_sep@";
depends.push_back(qrcEntry);
}
- return entriesList;
+ return true;
+}
+
+/// @brief Reads the resource files list from from a .qrc file
+/// @return True if the rcc file was successfully parsed
+static bool ListQtRccInputs(const std::string& qtMajorVersion,
+ cmSourceFile* sf, cmGeneratorTarget const* target,
+ std::vector<std::string>& depends)
+{
+ if (qtMajorVersion == "5") {
+ return ListQt5RccInputs(sf, target, depends);
+ }
+ return ListQt4RccInputs(sf, depends);
}
static void SetupAutoRccTarget(cmGeneratorTarget const* target)
@@ -615,16 +622,12 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
}
optionSep = ";";
- std::vector<std::string> depends;
-
std::string entriesList;
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- if (qtMajorVersion == "5") {
- entriesList = ListQt5RccInputs(sf, target, depends);
+ std::vector<std::string> depends;
+ if (ListQtRccInputs(qtMajorVersion, sf, target, depends)) {
+ entriesList = cmJoin(depends, "@list_sep@");
} else {
- entriesList = ListQt4RccInputs(sf, depends);
- }
- if (entriesList.empty()) {
return;
}
}
@@ -778,11 +781,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
rcc_output.push_back(rcc_output_file);
}
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- if (qtMajorVersion == "5") {
- ListQt5RccInputs(sf, target, depends);
- } else {
- ListQt4RccInputs(sf, depends);
- }
+ ListQtRccInputs(qtMajorVersion, sf, target, depends);
#if defined(_WIN32) && !defined(__CYGWIN__)
// Cannot use PRE_BUILD because the resource files themselves
// may not be sources within the target so VS may not know the
diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt
index e35e1d1ff1..c713d1c964 100644
--- a/Tests/QtAutogen/CMakeLists.txt
+++ b/Tests/QtAutogen/CMakeLists.txt
@@ -44,10 +44,16 @@ else()
endif()
+# -- RCC only
add_executable(rcconly rcconly.cpp second_resource.qrc)
set_property(TARGET rcconly PROPERTY AUTORCC ON)
target_link_libraries(rcconly ${QT_QTCORE_TARGET})
+# -- RCC empty
+add_executable(rcc_empty rcc_empty.cpp rcc_empty_resource.qrc)
+set_property(TARGET rcc_empty PROPERTY AUTORCC ON)
+target_link_libraries(rcc_empty ${QT_QTCORE_TARGET})
+
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(-DFOO -DSomeDefine="Barx")
diff --git a/Tests/QtAutogen/rcc_empty.cpp b/Tests/QtAutogen/rcc_empty.cpp
new file mode 100644
index 0000000000..3f9f9a28d7
--- /dev/null
+++ b/Tests/QtAutogen/rcc_empty.cpp
@@ -0,0 +1,9 @@
+
+extern int qInitResources_rcc_empty_resource();
+
+int main(int, char**)
+{
+ // Fails to link if the symbol is not present.
+ qInitResources_rcc_empty_resource();
+ return 0;
+}
diff --git a/Tests/QtAutogen/rcc_empty_resource.qrc b/Tests/QtAutogen/rcc_empty_resource.qrc
new file mode 100644
index 0000000000..4ca9cd5837
--- /dev/null
+++ b/Tests/QtAutogen/rcc_empty_resource.qrc
@@ -0,0 +1,4 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+</qresource>
+</RCC>
diff --git a/Tests/RunCMake/AndroidTestUtilities/CMakeLists.txt b/Tests/RunCMake/AndroidTestUtilities/CMakeLists.txt
new file mode 100644
index 0000000000..dc92486973
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.6)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AndroidTestUtilities/RunCMakeTest.cmake b/Tests/RunCMake/AndroidTestUtilities/RunCMakeTest.cmake
new file mode 100644
index 0000000000..f0ae24b2fe
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/RunCMakeTest.cmake
@@ -0,0 +1,20 @@
+include(RunCMake)
+
+function(run_ATU case target)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ if(target)
+ set(build_args --target ${target})
+ else()
+ set(build_args)
+ endif()
+ run_cmake(${case})
+ run_cmake_command(${case}Build ${CMAKE_COMMAND} --build . --config Debug ${build_args})
+endfunction()
+
+run_ATU(SetupTest1 "")
+run_ATU(SetupTest2 "tests")
+run_ATU(SetupTest3 "tests")
diff --git a/Tests/RunCMake/AndroidTestUtilities/SetupTest1.cmake b/Tests/RunCMake/AndroidTestUtilities/SetupTest1.cmake
new file mode 100644
index 0000000000..1c9098b3af
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/SetupTest1.cmake
@@ -0,0 +1,17 @@
+enable_testing()
+include(AndroidTestUtilities)
+
+find_program(adb_executable adb)
+
+set(ExternalData_URL_TEMPLATES
+ "https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
+ )
+
+set(test_files "data/a.txt")
+
+set(ANDROID 1)
+
+android_add_test_data(setup_test
+ FILES ${test_files}
+ DEVICE_TEST_DIR "/data/local/tests/example1"
+ DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA")
diff --git a/Tests/RunCMake/AndroidTestUtilities/SetupTest1Build-check.cmake b/Tests/RunCMake/AndroidTestUtilities/SetupTest1Build-check.cmake
new file mode 100644
index 0000000000..ef7569d65a
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/SetupTest1Build-check.cmake
@@ -0,0 +1,5 @@
+include(${CMAKE_CURRENT_LIST_DIR}/check.cmake)
+compare_build_to_expected(FILES
+ "data/a.txt"
+ )
+check_for_setup_test()
diff --git a/Tests/RunCMake/AndroidTestUtilities/SetupTest2.cmake b/Tests/RunCMake/AndroidTestUtilities/SetupTest2.cmake
new file mode 100644
index 0000000000..cf4c764a1d
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/SetupTest2.cmake
@@ -0,0 +1,30 @@
+enable_testing()
+include(AndroidTestUtilities)
+
+add_custom_target(tests)
+find_program(adb_executable adb)
+
+set(ExternalData_URL_TEMPLATES
+ "https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
+ )
+set(test_files
+ "data/a.txt"
+ "data/subfolder/b.txt"
+ "data/subfolder/protobuffer.p"
+ )
+
+set(test_libs "data/subfolder/exampleLib.txt")
+
+set(ANDROID 1)
+
+android_add_test_data(setup_test
+ FILES ${test_files}
+ LIBS ${test_libs}
+ DEVICE_TEST_DIR "/data/local/tests/example2"
+ DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA"
+ NO_LINK_REGEX "\\.p$")
+
+set_property(
+ TARGET setup_test
+ PROPERTY EXCLUDE_FROM_ALL 1)
+add_dependencies(tests setup_test)
diff --git a/Tests/RunCMake/AndroidTestUtilities/SetupTest2Build-check.cmake b/Tests/RunCMake/AndroidTestUtilities/SetupTest2Build-check.cmake
new file mode 100644
index 0000000000..6adbd59d77
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/SetupTest2Build-check.cmake
@@ -0,0 +1,7 @@
+include(${CMAKE_CURRENT_LIST_DIR}/check.cmake)
+compare_build_to_expected(FILES
+ "data/a.txt"
+ "data/subfolder/b.txt"
+ "data/subfolder/protobuffer.p"
+ )
+check_for_setup_test()
diff --git a/Tests/RunCMake/AndroidTestUtilities/SetupTest3.cmake b/Tests/RunCMake/AndroidTestUtilities/SetupTest3.cmake
new file mode 100644
index 0000000000..b32b6b1a8a
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/SetupTest3.cmake
@@ -0,0 +1,33 @@
+enable_testing()
+include(AndroidTestUtilities)
+
+add_custom_target(tests)
+find_program(adb_executable adb)
+
+set(ExternalData_URL_TEMPLATES
+ "https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
+ )
+set(test_dir "/data/local/tests/example3")
+set(test_files
+ "data/a.txt"
+ "data/subfolder/b.txt"
+ )
+set(test_libs "libs/exampleLib.txt")
+set(files_dest "${test_dir}/storage_folder")
+set(libs_dest "${test_dir}/lib/lib/lib")
+
+set(ANDROID 1)
+
+android_add_test_data(setup_test
+ FILES ${test_files}
+ LIBS ${test_libs}
+ FILES_DEST ${files_dest}
+ LIBS_DEST ${libs_dest}
+ DEVICE_TEST_DIR "/data/local/tests/example3"
+ DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA"
+ NO_LINK_REGEX "\\.p$")
+
+set_property(
+ TARGET setup_test
+ PROPERTY EXCLUDE_FROM_ALL 1)
+add_dependencies(tests setup_test)
diff --git a/Tests/RunCMake/AndroidTestUtilities/SetupTest3Build-check.cmake b/Tests/RunCMake/AndroidTestUtilities/SetupTest3Build-check.cmake
new file mode 100644
index 0000000000..3062cdc32e
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/SetupTest3Build-check.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_LIST_DIR}/check.cmake)
+compare_build_to_expected(FILES
+ "data/a.txt"
+ "data/subfolder/b.txt"
+ )
+check_for_setup_test()
diff --git a/Tests/RunCMake/AndroidTestUtilities/check.cmake b/Tests/RunCMake/AndroidTestUtilities/check.cmake
new file mode 100644
index 0000000000..ccd4d74dd9
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/check.cmake
@@ -0,0 +1,20 @@
+function(compare_build_to_expected)
+ cmake_parse_arguments(_comp "" "" "FILES" ${ARGN})
+ set(missing)
+ foreach(file ${_comp_FILES})
+ if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${file}")
+ list(APPEND missing "${file}")
+ endif()
+ endforeach()
+ if(missing)
+ string(APPEND RunCMake_TEST_FAILED "Missing files:\n ${missing}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(check_for_setup_test)
+ file(STRINGS "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" output_var REGEX "add_test\\(setup_test.*")
+ if(NOT output_var)
+ set(RunCMake_TEST_FAILED "Could not find the test: setup_test" PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/AndroidTestUtilities/data/a.txt b/Tests/RunCMake/AndroidTestUtilities/data/a.txt
new file mode 100644
index 0000000000..9d454fb87e
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/data/a.txt
@@ -0,0 +1 @@
+Here is a file to test.
diff --git a/Tests/RunCMake/AndroidTestUtilities/data/proto.proto b/Tests/RunCMake/AndroidTestUtilities/data/proto.proto
new file mode 100644
index 0000000000..7402a3a360
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/data/proto.proto
@@ -0,0 +1 @@
+proto.proto
diff --git a/Tests/RunCMake/AndroidTestUtilities/data/subfolder/b.txt b/Tests/RunCMake/AndroidTestUtilities/data/subfolder/b.txt
new file mode 100644
index 0000000000..c8c6a898bb
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/data/subfolder/b.txt
@@ -0,0 +1 @@
+SetupTest2.cmake
diff --git a/Tests/RunCMake/AndroidTestUtilities/data/subfolder/protobuffer.p b/Tests/RunCMake/AndroidTestUtilities/data/subfolder/protobuffer.p
new file mode 100644
index 0000000000..a5dc7d2315
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/data/subfolder/protobuffer.p
@@ -0,0 +1 @@
+protobuffer.p
diff --git a/Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.so b/Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.so
new file mode 100644
index 0000000000..f4cdf826e1
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.so
@@ -0,0 +1 @@
+here is a fake lib.
diff --git a/Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.txt b/Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.txt
new file mode 100644
index 0000000000..308921a52f
--- /dev/null
+++ b/Tests/RunCMake/AndroidTestUtilities/libs/exampleLib.txt
@@ -0,0 +1 @@
+here is an example lib!
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 0eafbeff56..9dc540f785 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -131,6 +131,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
)
endif()
+add_RunCMake_test(AndroidTestUtilities)
add_RunCMake_test(BuildDepends)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(CompilerChange)
diff --git a/Tests/Server/server-test.py b/Tests/Server/server-test.py
index 72f82ba4c4..14767f4cc1 100644
--- a/Tests/Server/server-test.py
+++ b/Tests/Server/server-test.py
@@ -102,4 +102,18 @@ for obj in testData:
print("Completed")
+# Tell the server to exit.
+proc.stdin.close()
+proc.stdout.close()
+
+# Wait for the server to exit.
+# If this version of python supports it, terminate the server after a timeout.
+try:
+ proc.wait(timeout=5)
+except TypeError:
+ proc.wait()
+except:
+ proc.terminate()
+ raise
+
sys.exit(0)