CMake/Source/CTest/cmCTestBuildCommand.cxx
David Cole b0d5fa0bc7 Fix for issue #5041 - improve error messages that may occur during ctest_build and ctest_configure.
The improved text gives very clear information when either the CMakeLists.txt or CTestConfig.cmake file is missing. Hopefully, it makes it easier for those poor future souls who encounter these messages to solve their problems quickly.
2009-12-29 18:03:45 -05:00

194 lines
6.6 KiB
C++

/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmCTestBuildCommand.h"
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestBuildHandler.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
//----------------------------------------------------------------------------
cmCTestBuildCommand::cmCTestBuildCommand()
{
this->GlobalGenerator = 0;
this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS";
this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS";
this->Arguments[ctb_TARGET] = "TARGET";
this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION";
this->Arguments[ctb_FLAGS] = "FLAGS";
this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME";
this->Arguments[ctb_LAST] = 0;
this->Last = ctb_LAST;
}
//----------------------------------------------------------------------------
cmCTestBuildCommand::~cmCTestBuildCommand()
{
if ( this->GlobalGenerator )
{
delete this->GlobalGenerator;
this->GlobalGenerator = 0;
}
}
//----------------------------------------------------------------------------
cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
{
cmCTestGenericHandler* handler
= this->CTest->GetInitializedHandler("build");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate build handler");
return 0;
}
this->Handler = (cmCTestBuildHandler*)handler;
const char* ctestBuildCommand
= this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
if ( ctestBuildCommand && *ctestBuildCommand )
{
this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand);
}
else
{
const char* cmakeGeneratorName
= this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
const char* cmakeProjectName
= (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]
: ((ctestBuildConfiguration && *ctestBuildConfiguration)
? ctestBuildConfiguration
: this->CTest->GetConfigType().c_str());
const char* cmakeBuildAdditionalFlags
= (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
? this->Values[ctb_FLAGS]
: this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
const char* cmakeBuildTarget
= (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET])
? this->Values[ctb_TARGET]
: this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
if ( cmakeGeneratorName && *cmakeGeneratorName &&
cmakeProjectName && *cmakeProjectName )
{
if ( !cmakeBuildConfiguration )
{
cmakeBuildConfiguration = "Release";
}
if ( this->GlobalGenerator )
{
if ( strcmp(this->GlobalGenerator->GetName(),
cmakeGeneratorName) != 0 )
{
delete this->GlobalGenerator;
this->GlobalGenerator = 0;
}
}
if ( !this->GlobalGenerator )
{
this->GlobalGenerator =
this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
cmakeGeneratorName);
}
this->GlobalGenerator->FindMakeProgram(this->Makefile);
const char* cmakeMakeProgram
= this->Makefile->GetDefinition("CMAKE_MAKE_PROGRAM");
if(strlen(cmakeBuildConfiguration) == 0)
{
const char* config = 0;
#ifdef CMAKE_INTDIR
config = CMAKE_INTDIR;
#endif
if(!config)
{
config = "Debug";
}
cmakeBuildConfiguration = config;
}
std::string buildCommand
= this->GlobalGenerator->
GenerateBuildCommand(cmakeMakeProgram,
cmakeProjectName,
cmakeBuildAdditionalFlags, cmakeBuildTarget,
cmakeBuildConfiguration, true, false);
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"SetMakeCommand:"
<< buildCommand.c_str() << "\n");
this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str());
}
else
{
cmOStringStream ostr;
ostr << "has no project to build. If this is a "
"\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR "
"and CTEST_PROJECT_NAME are set."
"\n"
"CTEST_PROJECT_NAME is usually set in CTestConfig.cmake. Verify "
"that CTestConfig.cmake exists, or CTEST_PROJECT_NAME "
"is set in the script, or PROJECT_NAME is passed as an argument "
"to ctest_build."
"\n"
"Alternatively, set CTEST_BUILD_COMMAND to build the project "
"with a custom command line.";
this->SetError(ostr.str().c_str());
return 0;
}
}
if(const char* useLaunchers =
this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS"))
{
this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers);
}
return handler;
}
bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status)
{
bool ret = cmCTestHandlerCommand::InitialPass(args, status);
if ( this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS])
{
cmOStringStream str;
str << this->Handler->GetTotalErrors();
this->Makefile->AddDefinition(
this->Values[ctb_NUMBER_ERRORS], str.str().c_str());
}
if ( this->Values[ctb_NUMBER_WARNINGS]
&& *this->Values[ctb_NUMBER_WARNINGS])
{
cmOStringStream str;
str << this->Handler->GetTotalWarnings();
this->Makefile->AddDefinition(
this->Values[ctb_NUMBER_WARNINGS], str.str().c_str());
}
return ret;
}