Merge topic 'emulator-property'

1975d53a Help: Add notes for topic 'emulator-property'
9160d6c2 TestGenerator: Add CROSSCOMPILING_EMULATOR support.
e942526b try_run: Use CMAKE_CROSSCOMPILING_EMULATOR.
579c4bec Properties: Add CROSSCOMPILING_EMULATOR target property.
This commit is contained in:
Brad King 2015-04-08 09:07:03 -04:00 committed by CMake Topic Stage
commit 977796e307
20 changed files with 176 additions and 4 deletions

View File

@ -73,7 +73,8 @@ When cross compiling, the executable compiled in the first step
usually cannot be run on the build host. The ``try_run`` command checks
the :variable:`CMAKE_CROSSCOMPILING` variable to detect whether CMake is in
cross-compiling mode. If that is the case, it will still try to compile
the executable, but it will not try to run the executable. Instead it
the executable, but it will not try to run the executable unless the
:variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable is set. Instead it
will create cache variables which must be filled by the user or by
presetting them in some CMake script file to the values the executable
would have produced if it had been run on its actual target platform.

View File

@ -119,6 +119,7 @@ Properties on Targets
/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
/prop_tgt/CONFIG_OUTPUT_NAME
/prop_tgt/CONFIG_POSTFIX
/prop_tgt/CROSSCOMPILING_EMULATOR
/prop_tgt/CXX_EXTENSIONS
/prop_tgt/CXX_STANDARD
/prop_tgt/CXX_STANDARD_REQUIRED

View File

@ -25,6 +25,7 @@ Variables that Provide Information
/variable/CMAKE_CFG_INTDIR
/variable/CMAKE_COMMAND
/variable/CMAKE_CROSSCOMPILING
/variable/CMAKE_CROSSCOMPILING_EMULATOR
/variable/CMAKE_CTEST_COMMAND
/variable/CMAKE_CURRENT_BINARY_DIR
/variable/CMAKE_CURRENT_LIST_DIR

View File

@ -0,0 +1,6 @@
CROSSCOMPILING_EMULATOR
-----------------------
Use the given emulator to run executables created when crosscompiling. This
command will be added as a prefix to :command:`add_test` test commands for
built target system executables.

View File

@ -0,0 +1,7 @@
emulator-property
-----------------
* A :prop_tgt:`CROSSCOMPILING_EMULATOR` target property and supporting
:variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable were introduced
to allow target platform binaries to run on the host during cross
compiling.

View File

@ -0,0 +1,12 @@
CMAKE_CROSSCOMPILING_EMULATOR
-----------------------------
This variable is only used when :variable:`CMAKE_CROSSCOMPILING` is on. It
should point to a command on the host system that can run executable built
for the target system.
The command will be used to run :command:`try_run` generated executables,
which avoids manual population of the TryRunResults.cmake file.
It is also used as the default value for the
:prop_tgt:`CROSSCOMPILING_EMULATOR` target property of executables.

View File

@ -442,6 +442,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
if(this->TargetTypeValue == cmTarget::EXECUTABLE)
{
this->SetPropertyDefault("ANDROID_GUI", 0);
this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", 0);
}
if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
|| this->TargetTypeValue == cmTarget::MODULE_LIBRARY)

View File

@ -82,11 +82,31 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// be translated.
std::string exe = command[0];
cmMakefile* mf = this->Test->GetMakefile();
cmLocalGenerator* lg = mf->GetLocalGenerator();
cmTarget* target = mf->FindTargetToUse(exe);
if(target && target->GetType() == cmTarget::EXECUTABLE)
{
// Use the target file on disk.
exe = target->GetFullPath(config);
// Prepend with the emulator when cross compiling if required.
const char * emulator =
target->GetProperty("CROSSCOMPILING_EMULATOR");
if (emulator != 0)
{
std::vector<std::string> emulatorWithArgs;
cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << lg->EscapeForCMake(emulatorExe) << " ";
for(std::vector<std::string>::const_iterator ei =
emulatorWithArgs.begin()+1;
ei != emulatorWithArgs.end();
++ei)
{
os << lg->EscapeForCMake(*ei) << " ";
}
}
}
else
{
@ -96,7 +116,6 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
}
// Generate the command line with full escapes.
cmLocalGenerator* lg = mf->GetLocalGenerator();
os << lg->EscapeForCMake(exe);
for(std::vector<std::string>::const_iterator ci = command.begin()+1;
ci != command.end(); ++ci)

View File

@ -149,7 +149,8 @@ bool cmTryRunCommand
{
// "run" it and capture the output
std::string runOutputContents;
if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))
if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING") &&
!this->Makefile->IsDefinitionSet("CMAKE_CROSSCOMPILING_EMULATOR"))
{
this->DoNotRunExecutable(runArgs,
argv[3],
@ -195,7 +196,28 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
std::string* out)
{
int retVal = -1;
std::string finalCommand = cmSystemTools::ConvertToRunCommandPath(
std::string finalCommand;
const std::string emulator =
this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
if (!emulator.empty())
{
std::vector<std::string> emulatorWithArgs;
cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs);
finalCommand += cmSystemTools::ConvertToRunCommandPath(
emulatorWithArgs[0].c_str());
finalCommand += " ";
for (std::vector<std::string>::const_iterator ei =
emulatorWithArgs.begin()+1;
ei != emulatorWithArgs.end(); ++ei)
{
finalCommand += "\"";
finalCommand += *ei;
finalCommand += "\"";
finalCommand += " ";
}
}
finalCommand += cmSystemTools::ConvertToRunCommandPath(
this->OutputFile.c_str());
if (!runArgs.empty())
{

View File

@ -226,3 +226,7 @@ add_RunCMake_test(COMPILE_LANGUAGE-genex)
if(CMake_TEST_FindMatlab)
add_RunCMake_test(FindMatlab)
endif()
add_executable(pseudo_emulator pseudo_emulator.c)
add_RunCMake_test(CrosscompilingEmulator
-DPSEUDO_EMULATOR=$<TARGET_FILE:pseudo_emulator>)

View File

@ -0,0 +1,12 @@
set(testfile "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake")
if(EXISTS "${testfile}")
file(READ "${testfile}" testfile_contents)
else()
message(FATAL_ERROR "Could not find expected CTestTestfile.cmake.")
endif()
if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator ^(pseudo_emulator)+$")
message(SEND_ERROR "Used emulator when it should not be used.")
endif()
if(NOT testfile_contents MATCHES "add_test[(]UsesEmulator .+pseudo_emulator.+$")
message(SEND_ERROR "Did not use emulator when it should be used.")
endif()

View File

@ -0,0 +1,8 @@
set(CMAKE_CROSSCOMPILING 1)
enable_testing()
add_test(NAME DoesNotUseEmulator
COMMAND ${CMAKE_COMMAND} -E echo "Hi")
add_executable(generated_exe simple_src.cxx)
add_test(NAME UsesEmulator
COMMAND generated_exe)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.1)
project(${RunCMake_TEST} CXX)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,28 @@
# This tests setting the CROSSCOMPILING_EMULATOR target property from the
# CMAKE_CROSSCOMPILING_EMULATOR variable.
# -DCMAKE_CROSSCOMPILING_EMULATOR=/path/to/pseudo_emulator is passed to this
# test
add_executable(target_with_emulator simple_src.cxx)
get_property(emulator TARGET target_with_emulator
PROPERTY CROSSCOMPILING_EMULATOR)
if(NOT "${emulator}" MATCHES "pseudo_emulator")
message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set")
endif()
set_property(TARGET target_with_emulator
PROPERTY CROSSCOMPILING_EMULATOR "another_emulator")
get_property(emulator TARGET target_with_emulator
PROPERTY CROSSCOMPILING_EMULATOR)
if(NOT "${emulator}" MATCHES "another_emulator")
message(SEND_ERROR
"set_property/get_property CROSSCOMPILING_EMULATOR is not consistent")
endif()
unset(CMAKE_CROSSCOMPILING_EMULATOR CACHE)
add_executable(target_without_emulator simple_src.cxx)
get_property(emulator TARGET target_without_emulator
PROPERTY CROSSCOMPILING_EMULATOR)
if(NOT "${emulator}" STREQUAL "")
message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set to null")
endif()

View File

@ -0,0 +1 @@
CMAKE_EMULATOR:STRING=@PSEUDO_EMULATOR@

View File

@ -0,0 +1,8 @@
include(RunCMake)
set(RunCMake_TEST_OPTIONS
"-DCMAKE_CROSSCOMPILING_EMULATOR=${PSEUDO_EMULATOR}")
run_cmake(CrosscompilingEmulatorProperty)
run_cmake(TryRun)
run_cmake(AddTest)

View File

@ -0,0 +1 @@
run_result: 42

View File

@ -0,0 +1,18 @@
set(CMAKE_CROSSCOMPILING 1)
try_run(run_result compile_result
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/simple_src.cxx
RUN_OUTPUT_VARIABLE run_output)
message(STATUS "run_output: ${run_output}")
message(STATUS "run_result: ${run_result}")
set(CMAKE_CROSSCOMPILING_EMULATOR ${CMAKE_CROSSCOMPILING_EMULATOR}
--flag
"multi arg")
try_run(run_result compile_result
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/simple_src.cxx
RUN_OUTPUT_VARIABLE run_output)
message(STATUS "Emulator with arguments run_output: ${run_output}")

View File

@ -0,0 +1,4 @@
int main(int, char **)
{
return 13;
}

View File

@ -0,0 +1,15 @@
#include <stdio.h>
int main(int argc, char * argv[] )
{
int ii;
printf("Command:");
for(ii = 1; ii < argc; ++ii)
{
printf(" \"%s\"", argv[ii]);
}
printf("\n");
return 42;
}