ENH: support for --build-config-sample feature #1022
This commit is contained in:
parent
fc7c433463
commit
3abf39eda0
|
@ -658,6 +658,7 @@ IF(BUILD_TESTING)
|
|||
"${CMake_SOURCE_DIR}/Tests/Complex"
|
||||
"${CMake_BINARY_DIR}/Tests/Complex"
|
||||
--build-two-config
|
||||
--build-config-sample "${CMAKE_CTEST_COMMAND}"
|
||||
--build-generator ${CMAKE_TEST_GENERATOR}
|
||||
--build-project Complex
|
||||
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "cmake.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include <cmsys/Process.h>
|
||||
#include "cmCTestTestHandler.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
|
||||
|
@ -161,6 +162,28 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
|
|||
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
|
||||
// and test time
|
||||
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
|
||||
std::vector<std::string> attempted;
|
||||
std::vector<std::string> failed;
|
||||
std::string tempPath;
|
||||
std::string filepath =
|
||||
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);
|
||||
}
|
||||
}
|
||||
// store the final location in fullPath
|
||||
std::string fullPath;
|
||||
std::string resultingConfig;
|
||||
std::vector<std::string> extraPaths;
|
||||
// if this->ExecutableDirectory is set try that as well
|
||||
if (this->ExecutableDirectory.size())
|
||||
{
|
||||
tempPath = this->ExecutableDirectory;
|
||||
std::string tempPath = this->ExecutableDirectory;
|
||||
tempPath += "/";
|
||||
tempPath += this->TestCommand;
|
||||
attempted.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());
|
||||
}
|
||||
}
|
||||
extraPaths.push_back(tempPath);
|
||||
}
|
||||
std::vector<std::string> failed;
|
||||
fullPath =
|
||||
cmCTestTestHandler::FindExecutable(this->CTest,
|
||||
this->TestCommand.c_str(),
|
||||
resultingConfig,
|
||||
extraPaths,
|
||||
failed);
|
||||
|
||||
if(!cmSystemTools::FileExists(fullPath.c_str()))
|
||||
{
|
||||
|
@ -489,6 +439,12 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
|
|||
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)
|
||||
{
|
||||
this->BuildNoClean = true;
|
||||
|
@ -525,4 +481,3 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ protected:
|
|||
std::vector<std::string> BuildOptions;
|
||||
bool BuildTwoConfig;
|
||||
std::string BuildMakeProgram;
|
||||
std::string ConfigSample;
|
||||
std::string SourceDir;
|
||||
std::string BinaryDir;
|
||||
std::string BuildProject;
|
||||
|
|
|
@ -218,8 +218,10 @@ bool cmCTestSetTestsPropertiesCommand::InitialPass(
|
|||
// 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
|
||||
// Release/Debug/etc)
|
||||
bool TryExecutable(const char *dir, const char *file,
|
||||
std::string *fullPath, const char *subdir)
|
||||
bool cmCTestTestHandler::TryExecutable(const char *dir,
|
||||
const char *file,
|
||||
std::string *fullPath,
|
||||
const char *subdir)
|
||||
{
|
||||
// try current directory
|
||||
std::string tryPath;
|
||||
|
@ -1080,88 +1082,171 @@ int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
|
|||
// Find the appropriate executable to run for a test
|
||||
std::string cmCTestTestHandler::FindTheExecutable(const char *exe)
|
||||
{
|
||||
std::string fullPath = "";
|
||||
std::string dir;
|
||||
std::string file;
|
||||
std::string resConfig;
|
||||
std::vector<std::string> extraPaths;
|
||||
std::vector<std::string> failedPaths;
|
||||
return cmCTestTestHandler::FindExecutable(this->CTest,
|
||||
exe, resConfig,
|
||||
extraPaths,
|
||||
failedPaths);
|
||||
}
|
||||
|
||||
cmSystemTools::SplitProgramPath(exe, dir, file);
|
||||
// first try to find the executable given a config type subdir if there is
|
||||
// one
|
||||
if(this->CTest->GetConfigType() != "" &&
|
||||
::TryExecutable(dir.c_str(), file.c_str(), &fullPath,
|
||||
this->CTest->GetConfigType().c_str()))
|
||||
// add additional configuraitons to the search path
|
||||
void cmCTestTestHandler
|
||||
::AddConfigurations(cmCTest *ctest,
|
||||
std::vector<std::string> &attempted,
|
||||
std::vector<std::string> &attemptedConfigs,
|
||||
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
|
||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"."))
|
||||
{
|
||||
return fullPath;
|
||||
}
|
||||
// store the final location in fullPath
|
||||
std::string fullPath;
|
||||
|
||||
// try without the config subdir
|
||||
if (::TryExecutable(dir.c_str(),file.c_str(),&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()))
|
||||
{
|
||||
fullPath = cmSystemTools::CollapseFullPath(attempted[ai].c_str());
|
||||
resultingConfig = attemptedConfigs[ai];
|
||||
}
|
||||
|
||||
if ( this->CTest->GetConfigType() == "" )
|
||||
// then try with the exe extension
|
||||
else
|
||||
{
|
||||
// No config type, so try to guess it
|
||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Deployment"))
|
||||
failed.push_back(attempted[ai].c_str());
|
||||
tempPath = attempted[ai];
|
||||
tempPath += cmSystemTools::GetExecutableExtension();
|
||||
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,"Development"))
|
||||
else
|
||||
{
|
||||
return fullPath;
|
||||
failed.push_back(tempPath.c_str());
|
||||
}
|
||||
|
||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release"))
|
||||
{
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug"))
|
||||
{
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
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
|
||||
// wasn;t specified
|
||||
if (dir.size() == 0)
|
||||
// wasn't specified
|
||||
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 != "")
|
||||
{
|
||||
resultingConfig = "";
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,25 @@ public:
|
|||
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:
|
||||
virtual int PreProcessHandler();
|
||||
virtual int PostProcessHandler();
|
||||
|
|
|
@ -162,6 +162,10 @@ static const cmDocumentationEntry cmDocumentationOptions[] =
|
|||
{"--build-project", "Specify the name of the project to build.", "" },
|
||||
{"--build-makeprogram", "Specify the make program to use.", "" },
|
||||
{"--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.",
|
||||
"This option must be the last option with the exception of --test-command"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue