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_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}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
cmSystemTools::SplitProgramPath(exe, dir, file);
|
exe, resConfig,
|
||||||
// first try to find the executable given a config type subdir if there is
|
extraPaths,
|
||||||
// one
|
failedPaths);
|
||||||
if(this->CTest->GetConfigType() != "" &&
|
|
||||||
::TryExecutable(dir.c_str(), file.c_str(), &fullPath,
|
|
||||||
this->CTest->GetConfigType().c_str()))
|
|
||||||
{
|
|
||||||
return fullPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// next try the current directory as the subdir
|
// add additional configuraitons to the search path
|
||||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"."))
|
void cmCTestTestHandler
|
||||||
|
::AddConfigurations(cmCTest *ctest,
|
||||||
|
std::vector<std::string> &attempted,
|
||||||
|
std::vector<std::string> &attemptedConfigs,
|
||||||
|
std::string filepath,
|
||||||
|
std::string &filename)
|
||||||
{
|
{
|
||||||
return fullPath;
|
std::string tempPath;
|
||||||
|
|
||||||
|
if (filepath.size())
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try without the config subdir
|
|
||||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,""))
|
//----------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
{
|
{
|
||||||
return fullPath;
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this->CTest->GetConfigType() == "" )
|
// store the final location in fullPath
|
||||||
{
|
std::string fullPath;
|
||||||
// No config type, so try to guess it
|
|
||||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Deployment"))
|
|
||||||
{
|
|
||||||
return fullPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Development"))
|
// 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];
|
||||||
}
|
}
|
||||||
|
// then try with the exe extension
|
||||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release"))
|
else
|
||||||
{
|
{
|
||||||
return fullPath;
|
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());
|
||||||
|
resultingConfig = attemptedConfigs[ai];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug"))
|
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue