ENH: support for --build-config-sample feature #1022

This commit is contained in:
Ken Martin 2007-03-19 13:04:10 -04:00
parent fc7c433463
commit 3abf39eda0
6 changed files with 218 additions and 153 deletions

View File

@ -653,11 +653,12 @@ IF(BUILD_TESTING)
SET(COMPILER_IS_COMO 1) SET(COMPILER_IS_COMO 1)
ENDIF(CMAKE_BASE_NAME MATCHES "^como$") ENDIF(CMAKE_BASE_NAME MATCHES "^como$")
IF(NOT COMPILER_IS_COMO) IF(NOT COMPILER_IS_COMO)
ADD_TEST(complex ${CMAKE_CTEST_COMMAND} ADD_TEST(complex ${CMAKE_CTEST_COMMAND}
--build-and-test --build-and-test
"${CMake_SOURCE_DIR}/Tests/Complex" "${CMake_SOURCE_DIR}/Tests/Complex"
"${CMake_BINARY_DIR}/Tests/Complex" "${CMake_BINARY_DIR}/Tests/Complex"
--build-two-config --build-two-config
--build-config-sample "${CMAKE_CTEST_COMMAND}"
--build-generator ${CMAKE_TEST_GENERATOR} --build-generator ${CMAKE_TEST_GENERATOR}
--build-project Complex --build-project Complex
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}

View File

@ -22,6 +22,7 @@
#include "cmake.h" #include "cmake.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include <cmsys/Process.h> #include <cmsys/Process.h>
#include "cmCTestTestHandler.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
@ -161,6 +162,28 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1; return 1;
} }
if ( this->CTest->GetConfigType().size() == 0 &&
this->ConfigSample.size())
{
// use the config sample to set the ConfigType
std::string fullPath;
std::string resultingConfig;
std::vector<std::string> extraPaths;
std::vector<std::string> failed;
fullPath =
cmCTestTestHandler::FindExecutable(this->CTest,
this->ConfigSample.c_str(),
resultingConfig,
extraPaths,
failed);
if (fullPath.size() && resultingConfig.size())
{
this->CTest->SetConfigType(resultingConfig.c_str());
}
out << "Using config sample with results: "
<< fullPath << " and " << resultingConfig << std::endl;
}
// we need to honor the timeout specified, the timeout include cmake, build // we need to honor the timeout specified, the timeout include cmake, build
// and test time // and test time
double clock_start = cmSystemTools::GetTime(); double clock_start = cmSystemTools::GetTime();
@ -243,98 +266,25 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
} }
// now run the compiled test if we can find it // now run the compiled test if we can find it
std::vector<std::string> attempted; // store the final location in fullPath
std::vector<std::string> failed; std::string fullPath;
std::string tempPath; std::string resultingConfig;
std::string filepath = std::vector<std::string> extraPaths;
cmSystemTools::GetFilenamePath(this->TestCommand);
std::string filename =
cmSystemTools::GetFilenameName(this->TestCommand);
// if full path specified then search that first
if (filepath.size())
{
tempPath = filepath;
tempPath += "/";
tempPath += filename;
attempted.push_back(tempPath);
if(this->CTest->GetConfigType().size())
{
tempPath = filepath;
tempPath += "/";
tempPath += this->CTest->GetConfigType();
tempPath += "/";
tempPath += filename;
attempted.push_back(tempPath);
// If the file is an OSX bundle then the configtyp
// will be at the start of the path
tempPath = this->CTest->GetConfigType();
tempPath += "/";
tempPath += filepath;
tempPath += "/";
tempPath += filename;
attempted.push_back(tempPath);
}
}
// otherwise search local dirs
else
{
attempted.push_back(filename);
if(this->CTest->GetConfigType().size())
{
tempPath = this->CTest->GetConfigType();
tempPath += "/";
tempPath += filename;
attempted.push_back(tempPath);
}
}
// if this->ExecutableDirectory is set try that as well // if this->ExecutableDirectory is set try that as well
if (this->ExecutableDirectory.size()) if (this->ExecutableDirectory.size())
{ {
tempPath = this->ExecutableDirectory; std::string tempPath = this->ExecutableDirectory;
tempPath += "/"; tempPath += "/";
tempPath += this->TestCommand; tempPath += this->TestCommand;
attempted.push_back(tempPath); extraPaths.push_back(tempPath);
if(this->CTest->GetConfigType().size())
{
tempPath = this->ExecutableDirectory;
tempPath += "/";
tempPath += this->CTest->GetConfigType();
tempPath += "/";
tempPath += filename;
attempted.push_back(tempPath);
}
}
// store the final location in fullPath
std::string fullPath;
// now look in the paths we specified above
for(unsigned int ai=0;
ai < attempted.size() && fullPath.size() == 0; ++ai)
{
// first check without exe extension
if(cmSystemTools::FileExists(attempted[ai].c_str())
&& !cmSystemTools::FileIsDirectory(attempted[ai].c_str()))
{
fullPath = cmSystemTools::CollapseFullPath(attempted[ai].c_str());
}
// then try with the exe extension
else
{
failed.push_back(attempted[ai].c_str());
tempPath = attempted[ai];
tempPath += cmSystemTools::GetExecutableExtension();
if(cmSystemTools::FileExists(tempPath.c_str())
&& !cmSystemTools::FileIsDirectory(tempPath.c_str()))
{
fullPath = cmSystemTools::CollapseFullPath(tempPath.c_str());
}
else
{
failed.push_back(tempPath.c_str());
}
}
} }
std::vector<std::string> failed;
fullPath =
cmCTestTestHandler::FindExecutable(this->CTest,
this->TestCommand.c_str(),
resultingConfig,
extraPaths,
failed);
if(!cmSystemTools::FileExists(fullPath.c_str())) if(!cmSystemTools::FileExists(fullPath.c_str()))
{ {
@ -489,6 +439,12 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
idx++; idx++;
this->BuildMakeProgram = allArgs[idx]; this->BuildMakeProgram = allArgs[idx];
} }
if(currentArg.find("--build-config-sample",0) == 0 &&
idx < allArgs.size() - 1)
{
idx++;
this->ConfigSample = allArgs[idx];
}
if(currentArg.find("--build-noclean",0) == 0) if(currentArg.find("--build-noclean",0) == 0)
{ {
this->BuildNoClean = true; this->BuildNoClean = true;
@ -525,4 +481,3 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
return 1; return 1;
} }

View File

@ -65,6 +65,7 @@ protected:
std::vector<std::string> BuildOptions; std::vector<std::string> BuildOptions;
bool BuildTwoConfig; bool BuildTwoConfig;
std::string BuildMakeProgram; std::string BuildMakeProgram;
std::string ConfigSample;
std::string SourceDir; std::string SourceDir;
std::string BinaryDir; std::string BinaryDir;
std::string BuildProject; std::string BuildProject;

View File

@ -218,8 +218,10 @@ bool cmCTestSetTestsPropertiesCommand::InitialPass(
// of where it was found. The directory and filename to search for are passed // of where it was found. The directory and filename to search for are passed
// in as well an a subdir (typically used for configuraitons such as // in as well an a subdir (typically used for configuraitons such as
// Release/Debug/etc) // Release/Debug/etc)
bool TryExecutable(const char *dir, const char *file, bool cmCTestTestHandler::TryExecutable(const char *dir,
std::string *fullPath, const char *subdir) const char *file,
std::string *fullPath,
const char *subdir)
{ {
// try current directory // try current directory
std::string tryPath; std::string tryPath;
@ -1080,88 +1082,171 @@ int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
// Find the appropriate executable to run for a test // Find the appropriate executable to run for a test
std::string cmCTestTestHandler::FindTheExecutable(const char *exe) std::string cmCTestTestHandler::FindTheExecutable(const char *exe)
{ {
std::string fullPath = ""; std::string resConfig;
std::string dir; std::vector<std::string> extraPaths;
std::string file; std::vector<std::string> failedPaths;
return cmCTestTestHandler::FindExecutable(this->CTest,
exe, resConfig,
extraPaths,
failedPaths);
}
cmSystemTools::SplitProgramPath(exe, dir, file); // add additional configuraitons to the search path
// first try to find the executable given a config type subdir if there is void cmCTestTestHandler
// one ::AddConfigurations(cmCTest *ctest,
if(this->CTest->GetConfigType() != "" && std::vector<std::string> &attempted,
::TryExecutable(dir.c_str(), file.c_str(), &fullPath, std::vector<std::string> &attemptedConfigs,
this->CTest->GetConfigType().c_str())) std::string filepath,
std::string &filename)
{
std::string tempPath;
if (filepath.size())
{ {
return fullPath; filepath += "/";
}
tempPath = filepath + filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("");
if(ctest->GetConfigType().size())
{
tempPath = filepath;
tempPath += ctest->GetConfigType();
tempPath += "/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back(ctest->GetConfigType());
// If the file is an OSX bundle then the configtyp
// will be at the start of the path
tempPath = ctest->GetConfigType();
tempPath += "/";
tempPath += filepath;
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back(ctest->GetConfigType());
}
else
{
// no config specified to try some options
tempPath = filepath;
tempPath += "Deployment/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("Deployment");
tempPath = filepath;
tempPath += "Development/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("Deployment");
tempPath = filepath;
tempPath += "Release/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("Release");
tempPath = filepath;
tempPath += "Debug/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("Debug");
tempPath = filepath;
tempPath += "MinSizeRel/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("MinSizeRel");
tempPath = filepath;
tempPath += "RelWithDebInfo/";
tempPath += filename;
attempted.push_back(tempPath);
attemptedConfigs.push_back("RelWithDebInfo");
}
}
//----------------------------------------------------------------------
// Find the appropriate executable to run for a test
std::string cmCTestTestHandler
::FindExecutable(cmCTest *ctest,
const char *testCommand,
std::string &resultingConfig,
std::vector<std::string> &extraPaths,
std::vector<std::string> &failed)
{
// now run the compiled test if we can find it
std::vector<std::string> attempted;
std::vector<std::string> attemptedConfigs;
std::string tempPath;
std::string filepath =
cmSystemTools::GetFilenamePath(testCommand);
std::string filename =
cmSystemTools::GetFilenameName(testCommand);
cmCTestTestHandler::AddConfigurations(ctest, attempted,
attemptedConfigs,
filepath,filename);
// if extraPaths are provided and we were not passed a full path, try them,
// try any extra paths
if (filepath.size() == 0)
{
for (unsigned int i = 0; i < extraPaths.size(); ++i)
{
std::string filepathExtra =
cmSystemTools::GetFilenamePath(extraPaths[i]);
std::string filenameExtra =
cmSystemTools::GetFilenameName(extraPaths[i]);
cmCTestTestHandler::AddConfigurations(ctest,attempted,
attemptedConfigs,
filepathExtra,
filenameExtra);
}
} }
// next try the current directory as the subdir // store the final location in fullPath
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,".")) std::string fullPath;
// now look in the paths we specified above
for(unsigned int ai=0;
ai < attempted.size() && fullPath.size() == 0; ++ai)
{ {
return fullPath; // first check without exe extension
} if(cmSystemTools::FileExists(attempted[ai].c_str())
&& !cmSystemTools::FileIsDirectory(attempted[ai].c_str()))
// try without the config subdir
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,""))
{
return fullPath;
}
if ( this->CTest->GetConfigType() == "" )
{
// No config type, so try to guess it
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Deployment"))
{ {
return fullPath; fullPath = cmSystemTools::CollapseFullPath(attempted[ai].c_str());
resultingConfig = attemptedConfigs[ai];
} }
// then try with the exe extension
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Development")) else
{ {
return fullPath; failed.push_back(attempted[ai].c_str());
} tempPath = attempted[ai];
tempPath += cmSystemTools::GetExecutableExtension();
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release")) if(cmSystemTools::FileExists(tempPath.c_str())
{ && !cmSystemTools::FileIsDirectory(tempPath.c_str()))
return fullPath; {
} fullPath = cmSystemTools::CollapseFullPath(tempPath.c_str());
resultingConfig = attemptedConfigs[ai];
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug")) }
{ else
return fullPath; {
} failed.push_back(tempPath.c_str());
}
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"MinSizeRel"))
{
return fullPath;
}
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"RelWithDebInfo"))
{
return fullPath;
} }
} }
// if everything else failed, check the users path, but only if a full path // if everything else failed, check the users path, but only if a full path
// wasn;t specified // wasn't specified
if (dir.size() == 0) if (fullPath.size() == 0 && filepath.size() == 0)
{ {
std::string path = cmSystemTools::FindProgram(file.c_str()); std::string path = cmSystemTools::FindProgram(filename.c_str());
if (path != "") if (path != "")
{ {
resultingConfig = "";
return path; return path;
} }
} }
if ( this->CTest->GetConfigType() != "" )
{
dir += "/";
dir += this->CTest->GetConfigType();
dir += "/";
dir += file;
cmSystemTools::Error("config type specified on the command line, but "
"test executable not found.",
dir.c_str());
return "";
}
return fullPath; return fullPath;
} }

View File

@ -103,6 +103,25 @@ public:
cmCTestTestProperties* Properties; cmCTestTestProperties* Properties;
}; };
// useful function for looking for a test
static bool TryExecutable(const char *dir, const char *file,
std::string *fullPath,
const char *subdir);
// add configuraitons to a search path for an executable
static void AddConfigurations(cmCTest *ctest,
std::vector<std::string> &attempted,
std::vector<std::string> &attemptedConfigs,
std::string filepath,
std::string &filename);
// full signature static method to find an executable
static std::string FindExecutable(cmCTest *ctest,
const char *testCommand,
std::string &resultingConfig,
std::vector<std::string> &extraPaths,
std::vector<std::string> &failed);
protected: protected:
virtual int PreProcessHandler(); virtual int PreProcessHandler();
virtual int PostProcessHandler(); virtual int PostProcessHandler();

View File

@ -162,6 +162,10 @@ static const cmDocumentationEntry cmDocumentationOptions[] =
{"--build-project", "Specify the name of the project to build.", "" }, {"--build-project", "Specify the name of the project to build.", "" },
{"--build-makeprogram", "Specify the make program to use.", "" }, {"--build-makeprogram", "Specify the make program to use.", "" },
{"--build-noclean", "Skip the make clean step.", "" }, {"--build-noclean", "Skip the make clean step.", "" },
{"--build-config-sample",
"A sample executable to use to determine the configuraiton",
"A sample executable to use to determine the configuraiton that "
"should be used. e.g. Debug/Release/etc" },
{"--build-options", "Add extra options to the build step.", {"--build-options", "Add extra options to the build step.",
"This option must be the last option with the exception of --test-command" "This option must be the last option with the exception of --test-command"
}, },