Fix issue #2336 - honor the -C arg to ctest. Honor it for all stages of running -D dashboards from the command line and running ctest_configure, ctest_build and ctest_test commands in -S scripts. Also, allow a script to change it by setting the CTEST_CONFIGURATION_TYPE variable: allows for multiple configuration build/test cycles within one script. Add a new signature for the cmake command build_command that accepts CONFIGURATION as one argument. The original build_command signature is still there, but now marked as deprecated in the documentation. Of course... also add CTestConfig tests to verify that -C is honored for -D dashboards and -S scripts.
This commit is contained in:
parent
af14f1f2c3
commit
0b38bb4c53
|
@ -84,10 +84,6 @@ IF(BUILD_TESTING)
|
|||
ENDIF(EXISTS "${PROJECT_SOURCE_DIR}/DartConfig.cmake")
|
||||
SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT")
|
||||
|
||||
# make program just needs to use CMAKE_MAKE_PROGRAM which is required
|
||||
# to be defined by cmake
|
||||
SET(MAKEPROGRAM ${CMAKE_MAKE_PROGRAM})
|
||||
|
||||
FIND_PROGRAM(CVSCOMMAND cvs )
|
||||
SET(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING
|
||||
"Options passed to the cvs update command.")
|
||||
|
@ -202,8 +198,17 @@ IF(BUILD_TESTING)
|
|||
ENDIF(DART_CXX_NAME MATCHES "devenv")
|
||||
SET(BUILDNAME "${BUILD_NAME_SYSTEM_NAME}-${DART_CXX_NAME}")
|
||||
ENDIF(NOT BUILDNAME)
|
||||
# set the build command
|
||||
BUILD_COMMAND(MAKECOMMAND ${MAKEPROGRAM} )
|
||||
|
||||
# the build command
|
||||
BUILD_COMMAND(MAKECOMMAND CONFIGURATION "\${CTEST_CONFIGURATION_TYPE}")
|
||||
SET(MAKECOMMAND ${MAKECOMMAND} CACHE STRING "Command to build the project")
|
||||
|
||||
# the default build configuration the ctest build handler will use
|
||||
# if there is no -C arg given to ctest:
|
||||
SET(DEFAULT_CTEST_CONFIGURATION_TYPE "$ENV{CMAKE_CONFIG_TYPE}")
|
||||
IF(DEFAULT_CTEST_CONFIGURATION_TYPE STREQUAL "")
|
||||
SET(DEFAULT_CTEST_CONFIGURATION_TYPE "Release")
|
||||
ENDIF(DEFAULT_CTEST_CONFIGURATION_TYPE STREQUAL "")
|
||||
|
||||
IF(NOT "${CMAKE_GENERATOR}" MATCHES "Make")
|
||||
SET(CTEST_USE_LAUNCHERS 0)
|
||||
|
|
|
@ -30,6 +30,7 @@ NightlyStartTime: @NIGHTLY_START_TIME@
|
|||
# Commands for the build/test/submit cycle
|
||||
ConfigureCommand: "@CMAKE_COMMAND@" "@PROJECT_SOURCE_DIR@"
|
||||
MakeCommand: @MAKECOMMAND@
|
||||
DefaultCTestConfigurationType: @DEFAULT_CTEST_CONFIGURATION_TYPE@
|
||||
|
||||
# CVS options
|
||||
# Default is "-d -P -A"
|
||||
|
|
|
@ -53,6 +53,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
|
|||
return 0;
|
||||
}
|
||||
this->Handler = (cmCTestBuildHandler*)handler;
|
||||
|
||||
const char* ctestBuildCommand
|
||||
= this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
|
||||
if ( ctestBuildCommand && *ctestBuildCommand )
|
||||
|
@ -67,10 +68,21 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
|
|||
= (this->Values[ctb_PROJECT_NAME] && *this->Values[ctb_PROJECT_NAME])
|
||||
? this->Values[ctb_PROJECT_NAME]
|
||||
: this->Makefile->GetDefinition("CTEST_PROJECT_NAME");
|
||||
|
||||
// Build configuration is determined by: CONFIGURATION argument,
|
||||
// or CTEST_BUILD_CONFIGURATION script variable, or
|
||||
// CTEST_CONFIGURATION_TYPE script variable, or ctest -C command
|
||||
// line argument... in that order.
|
||||
//
|
||||
const char* ctestBuildConfiguration
|
||||
= this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
|
||||
const char* cmakeBuildConfiguration
|
||||
= (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION])
|
||||
? this->Values[ctb_CONFIGURATION]
|
||||
: this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
|
||||
: ((ctestBuildConfiguration && *ctestBuildConfiguration)
|
||||
? ctestBuildConfiguration
|
||||
: this->CTest->GetConfigType().c_str());
|
||||
|
||||
const char* cmakeBuildAdditionalFlags
|
||||
= (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
|
||||
? this->Values[ctb_FLAGS]
|
||||
|
@ -117,7 +129,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
|
|||
}
|
||||
cmakeBuildConfiguration = config;
|
||||
}
|
||||
|
||||
|
||||
std::string buildCommand
|
||||
= this->GlobalGenerator->
|
||||
GenerateBuildCommand(cmakeMakeProgram,
|
||||
|
|
|
@ -264,6 +264,32 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile *mf)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
std::string cmCTestBuildHandler::GetMakeCommand()
|
||||
{
|
||||
std::string makeCommand
|
||||
= this->CTest->GetCTestConfiguration("MakeCommand");
|
||||
cmCTestLog(this->CTest,
|
||||
HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand <<
|
||||
"\n");
|
||||
|
||||
std::string configType = this->CTest->GetConfigType();
|
||||
if (configType == "")
|
||||
{
|
||||
configType
|
||||
= this->CTest->GetCTestConfiguration("DefaultCTestConfigurationType");
|
||||
}
|
||||
if (configType == "")
|
||||
{
|
||||
configType = "Release";
|
||||
}
|
||||
|
||||
cmSystemTools::ReplaceString(makeCommand,
|
||||
"${CTEST_CONFIGURATION_TYPE}", configType.c_str());
|
||||
|
||||
return makeCommand;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//clearly it would be nice if this were broken up into a few smaller
|
||||
//functions and commented...
|
||||
|
@ -300,11 +326,7 @@ int cmCTestBuildHandler::ProcessHandler()
|
|||
}
|
||||
|
||||
// Determine build command and build directory
|
||||
const std::string &makeCommand
|
||||
= this->CTest->GetCTestConfiguration("MakeCommand");
|
||||
cmCTestLog(this->CTest,
|
||||
HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand <<
|
||||
"\n");
|
||||
std::string makeCommand = this->GetMakeCommand();
|
||||
if ( makeCommand.size() == 0 )
|
||||
{
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE,
|
||||
|
@ -312,6 +334,7 @@ int cmCTestBuildHandler::ProcessHandler()
|
|||
<< std::endl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const std::string &buildDirectory
|
||||
= this->CTest->GetCTestConfiguration("BuildDirectory");
|
||||
if ( buildDirectory.size() == 0 )
|
||||
|
@ -519,8 +542,7 @@ void cmCTestBuildHandler::GenerateXMLHeader(std::ostream& os)
|
|||
static_cast<unsigned int>(this->StartBuildTime)
|
||||
<< "</StartBuildTime>\n"
|
||||
<< "<BuildCommand>"
|
||||
<< cmXMLSafe(
|
||||
this->CTest->GetCTestConfiguration("MakeCommand"))
|
||||
<< cmXMLSafe(this->GetMakeCommand())
|
||||
<< "</BuildCommand>" << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,10 @@ public:
|
|||
|
||||
int GetTotalErrors() { return this->TotalErrors;}
|
||||
int GetTotalWarnings() { return this->TotalWarnings;}
|
||||
|
||||
private:
|
||||
std::string GetMakeCommand();
|
||||
|
||||
//! Run command specialized for make and configure. Returns process status
|
||||
// and retVal is return value or exception.
|
||||
int RunMakeCommand(const char* command,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
============================================================================*/
|
||||
#include "cmCTestConfigureCommand.h"
|
||||
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmCTest.h"
|
||||
#include "cmCTestGenericHandler.h"
|
||||
|
||||
|
@ -66,6 +67,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
|
|||
|
||||
const char* ctestConfigureCommand
|
||||
= this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
|
||||
|
||||
if ( ctestConfigureCommand && *ctestConfigureCommand )
|
||||
{
|
||||
this->CTest->SetCTestConfiguration("ConfigureCommand",
|
||||
|
@ -86,6 +88,19 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
|
|||
"variable");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool multiConfig = false;
|
||||
bool cmakeBuildTypeInOptions = false;
|
||||
|
||||
cmGlobalGenerator *gg =
|
||||
this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
|
||||
cmakeGeneratorName);
|
||||
if(gg)
|
||||
{
|
||||
multiConfig = gg->IsMultiConfig();
|
||||
delete gg;
|
||||
}
|
||||
|
||||
std::string cmakeConfigureCommand = "\"";
|
||||
cmakeConfigureCommand += this->CTest->GetCMakeExecutable();
|
||||
cmakeConfigureCommand += "\"";
|
||||
|
@ -95,9 +110,23 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
|
|||
for (it= options.begin(); it!=options.end(); ++it)
|
||||
{
|
||||
option = *it;
|
||||
|
||||
cmakeConfigureCommand += " \"";
|
||||
cmakeConfigureCommand += option;
|
||||
cmakeConfigureCommand += "\"";
|
||||
|
||||
if ((0 != strstr(option.c_str(), "CMAKE_BUILD_TYPE=")) ||
|
||||
(0 != strstr(option.c_str(), "CMAKE_BUILD_TYPE:STRING=")))
|
||||
{
|
||||
cmakeBuildTypeInOptions = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!multiConfig && !cmakeBuildTypeInOptions)
|
||||
{
|
||||
cmakeConfigureCommand += " \"-DCMAKE_BUILD_TYPE:STRING=";
|
||||
cmakeConfigureCommand += this->CTest->GetConfigType();
|
||||
cmakeConfigureCommand += "\"";
|
||||
}
|
||||
|
||||
cmakeConfigureCommand += " \"-G";
|
||||
|
@ -113,9 +142,9 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
|
|||
}
|
||||
else
|
||||
{
|
||||
this->SetError("Configure command is not specified. If this is a CMake "
|
||||
"project, specify CTEST_CMAKE_GENERATOR, or if this is not CMake "
|
||||
"project, specify CTEST_CONFIGURE_COMMAND.");
|
||||
this->SetError("Configure command is not specified. If this is a "
|
||||
"\"built with CMake\" project, set CTEST_CMAKE_GENERATOR. If not, "
|
||||
"set CTEST_CONFIGURE_COMMAND.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,17 @@ bool cmCTestHandlerCommand
|
|||
}
|
||||
}
|
||||
|
||||
// Set the config type of this ctest to the current value of the
|
||||
// CTEST_CONFIGURATION_TYPE script variable if it is defined.
|
||||
// The current script value trumps the -C argument on the command
|
||||
// line.
|
||||
const char* ctestConfigType =
|
||||
this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
|
||||
if (ctestConfigType)
|
||||
{
|
||||
this->CTest->SetConfigType(ctestConfigType);
|
||||
}
|
||||
|
||||
cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
|
||||
cmCTestGenericHandler* handler = this->InitializeHandler();
|
||||
if ( !handler )
|
||||
|
|
|
@ -33,6 +33,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
|
|||
{
|
||||
const char* ctestTimeout =
|
||||
this->Makefile->GetDefinition("CTEST_TEST_TIMEOUT");
|
||||
|
||||
double timeout = this->CTest->GetTimeOut();
|
||||
if ( ctestTimeout )
|
||||
{
|
||||
|
@ -104,4 +105,3 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeActualHandler()
|
|||
{
|
||||
return this->CTest->GetInitializedHandler("test");
|
||||
}
|
||||
|
||||
|
|
|
@ -14,25 +14,135 @@
|
|||
#include "cmLocalGenerator.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
|
||||
// cmBuildCommand
|
||||
//----------------------------------------------------------------------
|
||||
bool cmBuildCommand
|
||||
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||||
{
|
||||
if(args.size() < 2 )
|
||||
// Support the legacy signature of the command:
|
||||
//
|
||||
if(2 == args.size())
|
||||
{
|
||||
this->SetError("called with incorrect number of arguments");
|
||||
return this->TwoArgsSignature(args);
|
||||
}
|
||||
|
||||
return this->MainSignature(args);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool cmBuildCommand
|
||||
::MainSignature(std::vector<std::string> const& args)
|
||||
{
|
||||
if(args.size() < 1)
|
||||
{
|
||||
this->SetError("requires at least one argument naming a CMake variable");
|
||||
return false;
|
||||
}
|
||||
|
||||
// The cmake variable in which to store the result.
|
||||
const char* variable = args[0].c_str();
|
||||
|
||||
// Parse remaining arguments.
|
||||
const char* configuration = 0;
|
||||
const char* project_name = 0;
|
||||
const char* target = 0;
|
||||
enum Doing { DoingNone, DoingConfiguration, DoingProjectName, DoingTarget };
|
||||
Doing doing = DoingNone;
|
||||
for(unsigned int i=1; i < args.size(); ++i)
|
||||
{
|
||||
if(args[i] == "CONFIGURATION")
|
||||
{
|
||||
doing = DoingConfiguration;
|
||||
}
|
||||
else if(args[i] == "PROJECT_NAME")
|
||||
{
|
||||
doing = DoingProjectName;
|
||||
}
|
||||
else if(args[i] == "TARGET")
|
||||
{
|
||||
doing = DoingTarget;
|
||||
}
|
||||
else if(doing == DoingConfiguration)
|
||||
{
|
||||
doing = DoingNone;
|
||||
configuration = args[i].c_str();
|
||||
}
|
||||
else if(doing == DoingProjectName)
|
||||
{
|
||||
doing = DoingNone;
|
||||
project_name = args[i].c_str();
|
||||
}
|
||||
else if(doing == DoingTarget)
|
||||
{
|
||||
doing = DoingNone;
|
||||
target = args[i].c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "unknown argument \"" << args[i] << "\"";
|
||||
this->SetError(e.str().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* makeprogram
|
||||
= this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
|
||||
|
||||
// If null/empty CONFIGURATION argument, GenerateBuildCommand uses 'Debug'
|
||||
// in the currently implemented multi-configuration global generators...
|
||||
// so we put this code here to end up with the same default configuration
|
||||
// as the original 2-arg build_command signature:
|
||||
//
|
||||
if(!configuration || !*configuration)
|
||||
{
|
||||
configuration = getenv("CMAKE_CONFIG_TYPE");
|
||||
}
|
||||
if(!configuration || !*configuration)
|
||||
{
|
||||
configuration = "Release";
|
||||
}
|
||||
|
||||
// If null/empty PROJECT_NAME argument, use the Makefile's project name:
|
||||
//
|
||||
if(!project_name || !*project_name)
|
||||
{
|
||||
project_name = this->Makefile->GetProjectName();
|
||||
}
|
||||
|
||||
// If null/empty TARGET argument, GenerateBuildCommand omits any mention
|
||||
// of a target name on the build command line...
|
||||
//
|
||||
std::string makecommand = this->Makefile->GetLocalGenerator()
|
||||
->GetGlobalGenerator()->GenerateBuildCommand
|
||||
(makeprogram, project_name, 0, target, configuration, true, false);
|
||||
|
||||
this->Makefile->AddDefinition(variable, makecommand.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool cmBuildCommand
|
||||
::TwoArgsSignature(std::vector<std::string> const& args)
|
||||
{
|
||||
if(args.size() < 2 )
|
||||
{
|
||||
this->SetError("called with less than two arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* define = args[0].c_str();
|
||||
const char* cacheValue
|
||||
= this->Makefile->GetDefinition(define);
|
||||
std::string makeprogram = args[1];
|
||||
|
||||
std::string configType = "Release";
|
||||
const char* cfg = getenv("CMAKE_CONFIG_TYPE");
|
||||
if ( cfg )
|
||||
{
|
||||
configType = cfg;
|
||||
}
|
||||
|
||||
std::string makecommand = this->Makefile->GetLocalGenerator()
|
||||
->GetGlobalGenerator()->GenerateBuildCommand
|
||||
(makeprogram.c_str(), this->Makefile->GetProjectName(), 0,
|
||||
|
@ -49,4 +159,3 @@ bool cmBuildCommand
|
|||
cmCacheManager::STRING);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,36 +37,61 @@ public:
|
|||
virtual bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus &status);
|
||||
|
||||
/**
|
||||
* The primary command signature with optional, KEYWORD-based args.
|
||||
*/
|
||||
virtual bool MainSignature(std::vector<std::string> const& args);
|
||||
|
||||
/**
|
||||
* Legacy "exactly 2 args required" signature.
|
||||
*/
|
||||
virtual bool TwoArgsSignature(std::vector<std::string> const& args);
|
||||
|
||||
/**
|
||||
* The name of the command as specified in CMakeList.txt.
|
||||
*/
|
||||
virtual const char* GetName() {return "build_command";}
|
||||
|
||||
|
||||
/**
|
||||
* Succinct documentation.
|
||||
*/
|
||||
virtual const char* GetTerseDocumentation()
|
||||
{
|
||||
return "Get the command line that will build this project.";
|
||||
return "Get the command line to build this project.";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* More documentation.
|
||||
*/
|
||||
virtual const char* GetFullDocumentation()
|
||||
{
|
||||
return
|
||||
" build_command(<variable> <makecommand>)\n"
|
||||
"Sets the given <variable> to a string containing the command that "
|
||||
"will build this project from the root of the build tree using the "
|
||||
"build tool given by <makecommand>. <makecommand> should be msdev, "
|
||||
"nmake, make or one of the end user build tools. "
|
||||
"This is useful for configuring testing systems.";
|
||||
" build_command(<variable>\n"
|
||||
" [CONFIGURATION <config>]\n"
|
||||
" [PROJECT_NAME <projname>]\n"
|
||||
" [TARGET <target>])\n"
|
||||
"Sets the given <variable> to a string containing the command line "
|
||||
"for building one configuration of a target in a project using the "
|
||||
"build tool appropriate for the current CMAKE_GENERATOR.\n"
|
||||
"If CONFIGURATION is omitted, CMake chooses a reasonable default "
|
||||
"value for multi-configuration generators. CONFIGURATION is "
|
||||
"ignored for single-configuration generators.\n"
|
||||
"If PROJECT_NAME is omitted, the resulting command line will build "
|
||||
"the top level PROJECT in the current build tree.\n"
|
||||
"If TARGET is omitted, the resulting command line will build "
|
||||
"everything, effectively using build target 'all' or 'ALL_BUILD'.\n"
|
||||
" build_command(<cachevariable> <makecommand>)\n"
|
||||
"This second signature is deprecated, but still available for "
|
||||
"backwards compatibility. Use the first signature instead.\n"
|
||||
"Sets the given <cachevariable> to a string containing the command "
|
||||
"to build this project from the root of the build tree using "
|
||||
"the build tool given by <makecommand>. <makecommand> should be "
|
||||
"the full path to msdev, devenv, nmake, make or one of the end "
|
||||
"user build tools."
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
cmTypeMacro(cmBuildCommand, cmCommand);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -258,6 +258,10 @@ public:
|
|||
/** Supported systems creates a GUID for the given name */
|
||||
virtual void CreateGUID(const char*) {}
|
||||
|
||||
/** Return true if the generated build tree may contain multiple builds.
|
||||
i.e. "Can I build Debug and Release in the same tree?" */
|
||||
virtual bool IsMultiConfig() { return false; }
|
||||
|
||||
protected:
|
||||
typedef std::vector<cmLocalGenerator*> GeneratorVector;
|
||||
// for a project collect all its targets by following depend
|
||||
|
|
|
@ -65,6 +65,11 @@ public:
|
|||
|
||||
/** Get the top-level registry key for this VS version. */
|
||||
std::string GetRegistryBase();
|
||||
|
||||
/** Return true if the generated build tree may contain multiple builds.
|
||||
i.e. "Can I build Debug and Release in the same tree?" */
|
||||
virtual bool IsMultiConfig() { return true; }
|
||||
|
||||
protected:
|
||||
void FixUtilityDepends();
|
||||
|
||||
|
|
|
@ -3302,3 +3302,18 @@ cmGlobalXCodeGenerator::ComputeInfoPListLocation(cmTarget& target)
|
|||
plist += ".dir/Info.plist";
|
||||
return plist;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Return true if the generated build tree may contain multiple builds.
|
||||
// i.e. "Can I build Debug and Release in the same tree?"
|
||||
bool cmGlobalXCodeGenerator::IsMultiConfig()
|
||||
{
|
||||
// Old Xcode 1.5 is single config:
|
||||
if(this->XcodeVersion == 15)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Newer Xcode versions are multi config:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,11 @@ public:
|
|||
std::vector<std::string>&
|
||||
dirs);
|
||||
void SetCurrentLocalGenerator(cmLocalGenerator*);
|
||||
|
||||
/** Return true if the generated build tree may contain multiple builds.
|
||||
i.e. "Can I build Debug and Release in the same tree?" */
|
||||
virtual bool IsMultiConfig();
|
||||
|
||||
private:
|
||||
cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
|
||||
cmSourceGroup* sg);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# This CMakeLists file is *sometimes expected* to result in a configure error.
|
||||
#
|
||||
# expect this to succeed:
|
||||
# ../bin/Release/cmake -G Xcode
|
||||
# ../../CMake/Tests/CMakeCommands/build_command
|
||||
#
|
||||
# expect this to fail:
|
||||
# ../bin/Release/cmake -DTEST_ERROR_CONDITIONS:BOOL=ON -G Xcode
|
||||
# ../../CMake/Tests/CMakeCommands/build_command
|
||||
#
|
||||
# This project exists merely to test the CMake command 'build_command'...
|
||||
# ...even purposefully calling it with known-bad argument lists to cover
|
||||
# error handling code.
|
||||
#
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(test_build_command)
|
||||
|
||||
set(cmd "initial")
|
||||
|
||||
message("CTEST_FULL_OUTPUT")
|
||||
message("0. begin")
|
||||
|
||||
if(TEST_ERROR_CONDITIONS)
|
||||
# Test with no arguments (an error):
|
||||
build_command()
|
||||
message("1. cmd='${cmd}'")
|
||||
|
||||
# Test with unknown arguments (also an error):
|
||||
build_command(cmd BOGUS STUFF)
|
||||
message("2. cmd='${cmd}'")
|
||||
|
||||
build_command(cmd STUFF BOGUS)
|
||||
message("3. cmd='${cmd}'")
|
||||
else()
|
||||
message("(skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF)")
|
||||
endif()
|
||||
|
||||
# Test the one arg signature with none of the optional KEYWORD arguments:
|
||||
build_command(cmd)
|
||||
message("4. cmd='${cmd}'")
|
||||
|
||||
# Test the two-arg legacy signature:
|
||||
build_command(legacy_cmd ${CMAKE_BUILD_TOOL})
|
||||
message("5. legacy_cmd='${legacy_cmd}'")
|
||||
message(" CMAKE_BUILD_TOOL='${CMAKE_BUILD_TOOL}'")
|
||||
|
||||
# Test the optional KEYWORDs:
|
||||
build_command(cmd CONFIGURATION hoohaaConfig)
|
||||
message("6. cmd='${cmd}'")
|
||||
|
||||
build_command(cmd PROJECT_NAME hoohaaProject)
|
||||
message("7. cmd='${cmd}'")
|
||||
|
||||
build_command(cmd TARGET hoohaaTarget)
|
||||
message("8. cmd='${cmd}'")
|
||||
|
||||
set(cmd "final")
|
||||
message("9. cmd='${cmd}'")
|
|
@ -0,0 +1,86 @@
|
|||
if(NOT DEFINED CMake_SOURCE_DIR)
|
||||
message(FATAL_ERROR "CMake_SOURCE_DIR not defined")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED dir)
|
||||
message(FATAL_ERROR "dir not defined")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED gen)
|
||||
message(FATAL_ERROR "gen not defined")
|
||||
endif()
|
||||
|
||||
message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
|
||||
|
||||
# Run cmake:
|
||||
#
|
||||
function(run_cmake build_dir extra_args expected_result expected_output expected_error)
|
||||
message(STATUS "run_cmake build_dir='${build_dir}' extra_args='${extra_args}'")
|
||||
|
||||
# Ensure build_dir exists:
|
||||
#
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${build_dir})
|
||||
|
||||
# Run cmake:
|
||||
#
|
||||
execute_process(COMMAND ${CMAKE_COMMAND}
|
||||
${extra_args}
|
||||
-G ${gen} ${CMake_SOURCE_DIR}/Tests/CMakeCommands/build_command
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE stdout
|
||||
ERROR_VARIABLE stderr
|
||||
WORKING_DIRECTORY ${build_dir}
|
||||
)
|
||||
|
||||
message(STATUS "result='${result}'")
|
||||
message(STATUS "stdout='${stdout}'")
|
||||
message(STATUS "stderr='${stderr}'")
|
||||
message(STATUS "")
|
||||
|
||||
# Verify result and output match expectations:
|
||||
#
|
||||
if("0" STREQUAL "${expected_result}")
|
||||
if(NOT "${result}" STREQUAL "0")
|
||||
message(FATAL_ERROR
|
||||
"error: result='${result}' is non-zero and different than expected_result='${expected_result}'")
|
||||
endif()
|
||||
else()
|
||||
if("${result}" STREQUAL "0")
|
||||
message(FATAL_ERROR
|
||||
"error: result='${result}' is zero and different than expected_result='${expected_result}'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(e ${expected_output})
|
||||
if(NOT stdout MATCHES "${e}")
|
||||
message(FATAL_ERROR
|
||||
"error: stdout does not match expected_output item e='${e}'")
|
||||
else()
|
||||
message(STATUS "info: stdout matches '${e}'")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(e ${expected_error})
|
||||
if(NOT stderr MATCHES "${e}")
|
||||
message(FATAL_ERROR
|
||||
"error: stderr does not match expected_error item e='${e}'")
|
||||
else()
|
||||
message(STATUS "info: stderr matches '${e}'")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
message(STATUS "result, stdout and stderr match all expectations: test passes")
|
||||
message(STATUS "")
|
||||
endfunction()
|
||||
|
||||
|
||||
# Expect this case to succeed:
|
||||
run_cmake("${dir}/b1" "" 0
|
||||
"Build files have been written to:"
|
||||
"skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF")
|
||||
|
||||
|
||||
# Expect this one to fail:
|
||||
run_cmake("${dir}/b2" "-DTEST_ERROR_CONDITIONS:BOOL=ON" 1
|
||||
"Configuring incomplete, errors occurred!"
|
||||
"build_command requires at least one argument naming a CMake variable;build_command unknown argument ")
|
|
@ -1181,7 +1181,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=CVS -P ${CMake_SOURCE_DIR}/Utilities/Rel
|
|||
)
|
||||
SET_TESTS_PROPERTIES(CTestTestNoBuild PROPERTIES
|
||||
FAIL_REGULAR_EXPRESSION "Error" WILL_FAIL true)
|
||||
|
||||
|
||||
CONFIGURE_FILE(
|
||||
"${CMake_SOURCE_DIR}/Tests/CTestTestFailure/testNoExe.cmake.in"
|
||||
"${CMake_BINARY_DIR}/Tests/CTestTestFailure/testNoExe.cmake"
|
||||
|
@ -1194,6 +1194,50 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=CVS -P ${CMake_SOURCE_DIR}/Utilities/Rel
|
|||
PASS_REGULAR_EXPRESSION "Could not find executable"
|
||||
FAIL_REGULAR_EXPRESSION "SegFault")
|
||||
|
||||
|
||||
# Use macro, not function so that build can still be driven by CMake 2.4.
|
||||
# After 2.6 is required, this could be a function without the extra 'set'
|
||||
# calls.
|
||||
#
|
||||
macro(add_config_tests cfg)
|
||||
set(cfg "${cfg}")
|
||||
set(base "${CMake_BINARY_DIR}/Tests/CTestConfig")
|
||||
|
||||
# Test -S script with a -C config arg to ctest:
|
||||
configure_file(
|
||||
"${CMake_SOURCE_DIR}/Tests/CTestConfig/script.cmake.in"
|
||||
"${base}/${cfg}-script.cmake"
|
||||
@ONLY ESCAPE_QUOTES)
|
||||
add_test(CTestConfig.Script.${cfg} ${CMAKE_CTEST_COMMAND}
|
||||
-C ${cfg}
|
||||
-S "${base}/${cfg}-script.cmake" -VV
|
||||
--output-log "${base}/${cfg}-script.log"
|
||||
)
|
||||
|
||||
# Test -D dashboard with a -C config arg to ctest.
|
||||
# (Actual commands inside a cmake -P script because we need to be able to set
|
||||
# the working directory reliably...)
|
||||
configure_file(
|
||||
"${CMake_SOURCE_DIR}/Tests/CTestConfig/dashboard.cmake.in"
|
||||
"${base}/${cfg}-dashboard.cmake"
|
||||
@ONLY ESCAPE_QUOTES)
|
||||
add_test(CTestConfig.Dashboard.${cfg} ${CMAKE_CMAKE_COMMAND}
|
||||
-P "${base}/${cfg}-dashboard.cmake" -VV
|
||||
)
|
||||
endmacro()
|
||||
|
||||
add_config_tests(Debug)
|
||||
add_config_tests(MinSizeRel)
|
||||
add_config_tests(Release)
|
||||
add_config_tests(RelWithDebInfo)
|
||||
|
||||
add_test(CMakeCommands.build_command ${CMAKE_CMAKE_COMMAND}
|
||||
-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}
|
||||
-Ddir=${CMake_BINARY_DIR}/Tests/CMakeCommands/build_command
|
||||
-Dgen=${CMAKE_TEST_GENERATOR}
|
||||
-P "${CMake_SOURCE_DIR}/Tests/CMakeCommands/build_command/RunCMake.cmake"
|
||||
)
|
||||
|
||||
CONFIGURE_FILE(
|
||||
"${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in"
|
||||
"${CMake_BINARY_DIR}/Tests/CTestTestCrash/test.cmake"
|
||||
|
@ -1256,11 +1300,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=CVS -P ${CMake_SOURCE_DIR}/Utilities/Rel
|
|||
-S "${CMake_BINARY_DIR}/Tests/CTestTestRunScript/test.cmake" -V
|
||||
--output-log "${CMake_BINARY_DIR}/Tests/CTestTestRunScript/testOutput.log"
|
||||
)
|
||||
|
||||
|
||||
ADD_TEST(CTestTestShowOnly ${CMAKE_CTEST_COMMAND} -N)
|
||||
|
||||
|
||||
ADD_TEST(CTestBatchTest ${CMAKE_CTEST_COMMAND} -B)
|
||||
|
||||
|
||||
# Use macro, not function so that build can still be driven by CMake 2.4.
|
||||
# After 2.6 is required, this could be a function without the extra 'set'
|
||||
# calls.
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(CTestConfig)
|
||||
|
||||
include(CTest)
|
||||
|
||||
|
||||
# We expect this configure to occur through a 'ctest -D Experimental' or a
|
||||
# 'ctest -S script.cmake' call.
|
||||
#
|
||||
# In either case, we expect CMAKE_BUILD_TYPE to be defined for single-configuration
|
||||
# build trees and not defined for multi-configuration build trees.
|
||||
#
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
# multi-configuration: expect not defined, error if defined
|
||||
if(DEFINED CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "")
|
||||
message(FATAL_ERROR "CMAKE_CONFIGURATION_TYPES='${CMAKE_CONFIGURATION_TYPES}' CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}' is defined and non-empty (but should not be for a multi-configuration generator)")
|
||||
endif()
|
||||
else()
|
||||
# single-configuration: expect defined, error if not defined
|
||||
if(NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
|
||||
message(FATAL_ERROR "CMAKE_BUILD_TYPE is not defined or is empty (but should be defined and non-empty for a single-configuration generator)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(DEFINED CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL "")
|
||||
add_definitions(-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}")
|
||||
endif()
|
||||
|
||||
add_executable(ctc CTestConfig.cxx)
|
||||
|
||||
|
||||
foreach(cfg ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE})
|
||||
add_test(NAME ctc-${cfg} CONFIGURATIONS ${cfg} COMMAND ctc --config $<CONFIGURATION>)
|
||||
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
set_property(TEST ctc-${cfg}
|
||||
PROPERTY PASS_REGULAR_EXPRESSION "CMAKE_INTDIR is ${cfg}")
|
||||
set_property(TEST ctc-${cfg}
|
||||
PROPERTY FAIL_REGULAR_EXPRESSION "CMAKE_BUILD_TYPE is")
|
||||
else()
|
||||
set_property(TEST ctc-${cfg}
|
||||
PROPERTY PASS_REGULAR_EXPRESSION "CMAKE_BUILD_TYPE is ${cfg}")
|
||||
set_property(TEST ctc-${cfg}
|
||||
PROPERTY FAIL_REGULAR_EXPRESSION "CMAKE_INTDIR is")
|
||||
endif()
|
||||
endforeach()
|
|
@ -0,0 +1,20 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
int i = 0;
|
||||
for (; i<argc; ++i)
|
||||
{
|
||||
fprintf(stdout, "%s\n", argv[i]);
|
||||
}
|
||||
|
||||
#ifdef CMAKE_BUILD_TYPE
|
||||
fprintf(stdout, "CMAKE_BUILD_TYPE is %s\n", CMAKE_BUILD_TYPE);
|
||||
#endif
|
||||
|
||||
#ifdef CMAKE_INTDIR
|
||||
fprintf(stdout, "CMAKE_INTDIR is %s\n", CMAKE_INTDIR);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
set(CMAKE_CONFIGURATION_TYPES "@CMAKE_CONFIGURATION_TYPES@")
|
||||
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestConfig")
|
||||
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg@-dashboard")
|
||||
|
||||
file(MAKE_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
|
||||
|
||||
get_filename_component(dir "${CMAKE_COMMAND}" PATH)
|
||||
set(CMAKE_CTEST_COMMAND "${dir}/ctest")
|
||||
|
||||
message("CMAKE_COMMAND='${CMAKE_COMMAND}'")
|
||||
message("CMAKE_CTEST_COMMAND='${CMAKE_CTEST_COMMAND}'")
|
||||
|
||||
set(arg "")
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(arg "-DCMAKE_BUILD_TYPE:STRING=@cfg@")
|
||||
endif()
|
||||
|
||||
message("cmake initial configure")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND}
|
||||
${arg} -G "@CMAKE_TEST_GENERATOR@" ${CTEST_SOURCE_DIRECTORY}
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
|
||||
RESULT_VARIABLE rv)
|
||||
if(NOT rv STREQUAL 0)
|
||||
message(FATAL_ERROR "error calling cmake: rv='${rv}'")
|
||||
endif()
|
||||
|
||||
|
||||
function(call_ctest arg)
|
||||
message("call_ctest ${arg}")
|
||||
execute_process(COMMAND ${CMAKE_CTEST_COMMAND}
|
||||
-C "@cfg@" -D ${arg} -VV
|
||||
WORKING_DIRECTORY ${CTEST_BINARY_DIRECTORY}
|
||||
RESULT_VARIABLE rv)
|
||||
if(NOT rv STREQUAL 0)
|
||||
message(FATAL_ERROR "error calling ctest: rv='${rv}'")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
call_ctest(ExperimentalStart)
|
||||
call_ctest(ExperimentalConfigure)
|
||||
call_ctest(ExperimentalBuild)
|
||||
call_ctest(ExperimentalTest)
|
|
@ -0,0 +1,21 @@
|
|||
set(CTEST_CMAKE_GENERATOR "@CMAKE_TEST_GENERATOR@")
|
||||
set(CTEST_PROJECT_NAME "CTestConfig")
|
||||
set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestConfig")
|
||||
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg@-script")
|
||||
|
||||
ctest_start(Experimental)
|
||||
|
||||
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
|
||||
if(NOT rv STREQUAL 0)
|
||||
message(FATAL_ERROR "*** error in ctest_configure ***")
|
||||
endif()
|
||||
|
||||
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
|
||||
if(NOT rv STREQUAL 0)
|
||||
message(FATAL_ERROR "*** error in ctest_build ***")
|
||||
endif()
|
||||
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
|
||||
if(NOT rv STREQUAL 0)
|
||||
message(FATAL_ERROR "*** error in ctest_test ***")
|
||||
endif()
|
Loading…
Reference in New Issue