Require CMAKE_<LANG>_COMPILER to be found as a full path
All generators now support detection of the full path to the compiler, so require it to be so. This will allow CMake<LANG>Information.cmake and other logic to assume the full path to the compiler tool is available. The Makefile generators already rejected CMAKE_<LANG>_COMPILER values that did not name an existing compiler. Extend this error message to all generators, make it occur as early as possible, and improve the message with advice about how to set the compiler. If the full path to the compiler is not known, finish enabling languages with a fatal error so configuration does not continue. For now, allow the RC language compiler to not be a full path. Later we will need to detect the full path to "rc" under the VS IDE. Add a RunCMake.CompilerNotFound test to cover failure cases. Fix the RunCMake.CompilerChange test EmptyCompiler case to work when configuration does not continue past enable_language.
This commit is contained in:
parent
6007f7ca01
commit
3e04946f7b
|
@ -228,6 +228,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
|
@CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
|
||||||
|
@CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
|
@CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
|
||||||
|
@CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -138,15 +138,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
|
||||||
if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str()))
|
if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str()))
|
||||||
&& (optional==false))
|
&& (optional==false))
|
||||||
{
|
{
|
||||||
std::string message = "your ";
|
return;
|
||||||
message += lang;
|
|
||||||
message += " compiler: \"";
|
|
||||||
message += name;
|
|
||||||
message += "\" was not found. Please set ";
|
|
||||||
message += langComp;
|
|
||||||
message += " to a valid compiler path or name.";
|
|
||||||
cmSystemTools::Error(message.c_str());
|
|
||||||
path = name;
|
|
||||||
}
|
}
|
||||||
std::string doc = lang;
|
std::string doc = lang;
|
||||||
doc += " compiler.";
|
doc += " compiler.";
|
||||||
|
@ -334,7 +326,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
|
||||||
|
|
||||||
void
|
void
|
||||||
cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
cmMakefile *mf, bool)
|
cmMakefile *mf, bool optional)
|
||||||
{
|
{
|
||||||
if(languages.size() == 0)
|
if(languages.size() == 0)
|
||||||
{
|
{
|
||||||
|
@ -370,6 +362,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fatalError = false;
|
||||||
|
|
||||||
mf->AddDefinition("RUN_CONFIGURE", true);
|
mf->AddDefinition("RUN_CONFIGURE", true);
|
||||||
std::string rootBin = mf->GetHomeOutputDirectory();
|
std::string rootBin = mf->GetHomeOutputDirectory();
|
||||||
rootBin += cmake::GetCMakeFilesDirectory();
|
rootBin += cmake::GetCMakeFilesDirectory();
|
||||||
|
@ -556,6 +550,65 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
this->SetLanguageEnabled("NONE", mf);
|
this->SetLanguageEnabled("NONE", mf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that the compiler was found.
|
||||||
|
std::string compilerName = "CMAKE_";
|
||||||
|
compilerName += lang;
|
||||||
|
compilerName += "_COMPILER";
|
||||||
|
std::string compilerEnv = "CMAKE_";
|
||||||
|
compilerEnv += lang;
|
||||||
|
compilerEnv += "_COMPILER_ENV_VAR";
|
||||||
|
cmOStringStream noCompiler;
|
||||||
|
const char* compilerFile = mf->GetDefinition(compilerName.c_str());
|
||||||
|
if(!compilerFile || !*compilerFile ||
|
||||||
|
cmSystemTools::IsNOTFOUND(compilerFile))
|
||||||
|
{
|
||||||
|
noCompiler <<
|
||||||
|
"No " << compilerName << " could be found.\n"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(strcmp(lang, "RC") != 0)
|
||||||
|
{
|
||||||
|
if(!cmSystemTools::FileIsFullPath(compilerFile))
|
||||||
|
{
|
||||||
|
noCompiler <<
|
||||||
|
"The " << compilerName << ":\n"
|
||||||
|
" " << compilerFile << "\n"
|
||||||
|
"is not a full path and was not found in the PATH.\n"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(!cmSystemTools::FileExists(compilerFile))
|
||||||
|
{
|
||||||
|
noCompiler <<
|
||||||
|
"The " << compilerName << ":\n"
|
||||||
|
" " << compilerFile << "\n"
|
||||||
|
"is not a full path to an existing compiler tool.\n"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!noCompiler.str().empty())
|
||||||
|
{
|
||||||
|
// Skip testing this language since the compiler is not found.
|
||||||
|
needTestLanguage[lang] = false;
|
||||||
|
if(!optional)
|
||||||
|
{
|
||||||
|
// The compiler was not found and it is not optional. Remove
|
||||||
|
// CMake(LANG)Compiler.cmake so we try again next time CMake runs.
|
||||||
|
std::string compilerLangFile = rootBin;
|
||||||
|
compilerLangFile += "/CMake";
|
||||||
|
compilerLangFile += lang;
|
||||||
|
compilerLangFile += "Compiler.cmake";
|
||||||
|
cmSystemTools::RemoveFile(compilerLangFile.c_str());
|
||||||
|
if(!this->CMakeInstance->GetIsInTryCompile())
|
||||||
|
{
|
||||||
|
this->PrintCompilerAdvice(noCompiler, lang,
|
||||||
|
mf->GetDefinition(compilerEnv.c_str()));
|
||||||
|
mf->IssueMessage(cmake::FATAL_ERROR, noCompiler.str());
|
||||||
|
fatalError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string langLoadedVar = "CMAKE_";
|
std::string langLoadedVar = "CMAKE_";
|
||||||
langLoadedVar += lang;
|
langLoadedVar += lang;
|
||||||
langLoadedVar += "_INFORMATION_LOADED";
|
langLoadedVar += "_INFORMATION_LOADED";
|
||||||
|
@ -582,26 +635,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
}
|
}
|
||||||
this->LanguagesReady.insert(lang);
|
this->LanguagesReady.insert(lang);
|
||||||
|
|
||||||
std::string compilerName = "CMAKE_";
|
|
||||||
compilerName += lang;
|
|
||||||
compilerName += "_COMPILER";
|
|
||||||
std::string compilerLangFile = rootBin;
|
|
||||||
compilerLangFile += "/CMake";
|
|
||||||
compilerLangFile += lang;
|
|
||||||
compilerLangFile += "Compiler.cmake";
|
|
||||||
// Test the compiler for the language just setup
|
// Test the compiler for the language just setup
|
||||||
// (but only if a compiler has been actually found)
|
// (but only if a compiler has been actually found)
|
||||||
// At this point we should have enough info for a try compile
|
// At this point we should have enough info for a try compile
|
||||||
// which is used in the backward stuff
|
// which is used in the backward stuff
|
||||||
// If the language is untested then test it now with a try compile.
|
// If the language is untested then test it now with a try compile.
|
||||||
if (!mf->IsSet(compilerName.c_str()))
|
if(needTestLanguage[lang])
|
||||||
{
|
|
||||||
// if the compiler did not work, then remove the
|
|
||||||
// CMake(LANG)Compiler.cmake file so that it will get tested the
|
|
||||||
// next time cmake is run
|
|
||||||
cmSystemTools::RemoveFile(compilerLangFile.c_str());
|
|
||||||
}
|
|
||||||
else if(needTestLanguage[lang])
|
|
||||||
{
|
{
|
||||||
if (!this->CMakeInstance->GetIsInTryCompile())
|
if (!this->CMakeInstance->GetIsInTryCompile())
|
||||||
{
|
{
|
||||||
|
@ -622,6 +661,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
// next time cmake is run
|
// next time cmake is run
|
||||||
if(!mf->IsOn(compilerWorks.c_str()))
|
if(!mf->IsOn(compilerWorks.c_str()))
|
||||||
{
|
{
|
||||||
|
std::string compilerLangFile = rootBin;
|
||||||
|
compilerLangFile += "/CMake";
|
||||||
|
compilerLangFile += lang;
|
||||||
|
compilerLangFile += "Compiler.cmake";
|
||||||
cmSystemTools::RemoveFile(compilerLangFile.c_str());
|
cmSystemTools::RemoveFile(compilerLangFile.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -675,6 +718,33 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
|
||||||
{
|
{
|
||||||
mf->ReadListFile(0,projectCompatibility.c_str());
|
mf->ReadListFile(0,projectCompatibility.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(fatalError)
|
||||||
|
{
|
||||||
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os,
|
||||||
|
std::string lang,
|
||||||
|
const char* envVar)
|
||||||
|
{
|
||||||
|
// Subclasses override this method if they do not support this advice.
|
||||||
|
os <<
|
||||||
|
"Tell CMake where to find the compiler by setting "
|
||||||
|
;
|
||||||
|
if(envVar)
|
||||||
|
{
|
||||||
|
os <<
|
||||||
|
"either the environment variable \"" << envVar << "\" or "
|
||||||
|
;
|
||||||
|
}
|
||||||
|
os <<
|
||||||
|
"the CMake cache entry CMAKE_" << lang << "_COMPILER "
|
||||||
|
"to the full path to the compiler, or to the compiler name "
|
||||||
|
"if it is in the PATH."
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -392,6 +392,8 @@ private:
|
||||||
void WriteSummary();
|
void WriteSummary();
|
||||||
void WriteSummary(cmTarget* target);
|
void WriteSummary(cmTarget* target);
|
||||||
|
|
||||||
|
virtual void PrintCompilerAdvice(std::ostream& os, std::string lang,
|
||||||
|
const char* envVar);
|
||||||
void CheckCompilerIdCompatibility(cmMakefile* mf, std::string lang);
|
void CheckCompilerIdCompatibility(cmMakefile* mf, std::string lang);
|
||||||
|
|
||||||
cmExternalMakefileProjectGenerator* ExtraGenerator;
|
cmExternalMakefileProjectGenerator* ExtraGenerator;
|
||||||
|
|
|
@ -107,6 +107,7 @@ protected:
|
||||||
const char* AdditionalPlatformDefinition;
|
const char* AdditionalPlatformDefinition;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void PrintCompilerAdvice(std::ostream&, std::string, const char*) {}
|
||||||
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||||
|
|
||||||
void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
|
void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
|
||||||
|
|
|
@ -210,6 +210,7 @@ protected:
|
||||||
std::vector<cmXCodeObject*> XCodeObjects;
|
std::vector<cmXCodeObject*> XCodeObjects;
|
||||||
cmXCodeObject* RootObject;
|
cmXCodeObject* RootObject;
|
||||||
private:
|
private:
|
||||||
|
void PrintCompilerAdvice(std::ostream&, std::string, const char*) {}
|
||||||
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||||
|
|
||||||
std::string GetObjectsNormalDirectory(
|
std::string GetObjectsNormalDirectory(
|
||||||
|
|
|
@ -60,6 +60,7 @@ add_RunCMake_test(CTest)
|
||||||
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
||||||
add_RunCMake_test(CompilerChange)
|
add_RunCMake_test(CompilerChange)
|
||||||
endif()
|
endif()
|
||||||
|
add_RunCMake_test(CompilerNotFound)
|
||||||
add_RunCMake_test(Configure)
|
add_RunCMake_test(Configure)
|
||||||
add_RunCMake_test(DisallowedCommands)
|
add_RunCMake_test(DisallowedCommands)
|
||||||
add_RunCMake_test(ExternalData)
|
add_RunCMake_test(ExternalData)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
|
|
@ -1,5 +1,13 @@
|
||||||
You have changed variables that require your cache to be deleted.
|
You have changed variables that require your cache to be deleted.
|
||||||
Configure will be re-run and you may have to reset some variables.
|
Configure will be re-run and you may have to reset some variables.
|
||||||
The following variables have changed:
|
The following variables have changed:
|
||||||
CMAKE_C_COMPILER= *(
|
CMAKE_C_COMPILER= *
|
||||||
|$)
|
+
|
||||||
|
CMake Error at EmptyCompiler.cmake:2 \(enable_language\):
|
||||||
|
No CMAKE_C_COMPILER could be found.
|
||||||
|
|
||||||
|
Tell CMake where to find the compiler by setting either the environment
|
||||||
|
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
|
||||||
|
the compiler, or to the compiler name if it is in the PATH.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:6 \(include\)$
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
|
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_LIST_DIR}/EmptyCompiler-override.cmake)
|
||||||
enable_language(C)
|
enable_language(C)
|
||||||
message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"")
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n")
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,12 @@
|
||||||
|
CMake Error at BadCompilerC.cmake:2 \(enable_language\):
|
||||||
|
The CMAKE_C_COMPILER:
|
||||||
|
|
||||||
|
no-C-compiler
|
||||||
|
|
||||||
|
is not a full path and was not found in the PATH.
|
||||||
|
|
||||||
|
Tell CMake where to find the compiler by setting either the environment
|
||||||
|
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
|
||||||
|
the compiler, or to the compiler name if it is in the PATH.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,3 @@
|
||||||
|
set(CMAKE_C_COMPILER "no-C-compiler")
|
||||||
|
enable_language(C)
|
||||||
|
message(FATAL_ERROR "This error should not be reached.")
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,12 @@
|
||||||
|
CMake Error at BadCompilerCXX.cmake:2 \(enable_language\):
|
||||||
|
The CMAKE_CXX_COMPILER:
|
||||||
|
|
||||||
|
no-CXX-compiler
|
||||||
|
|
||||||
|
is not a full path and was not found in the PATH.
|
||||||
|
|
||||||
|
Tell CMake where to find the compiler by setting either the environment
|
||||||
|
variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
|
||||||
|
to the compiler, or to the compiler name if it is in the PATH.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,3 @@
|
||||||
|
set(CMAKE_CXX_COMPILER "no-CXX-compiler")
|
||||||
|
enable_language(CXX)
|
||||||
|
message(FATAL_ERROR "This error should not be reached.")
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,25 @@
|
||||||
|
CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
|
||||||
|
The CMAKE_C_COMPILER:
|
||||||
|
|
||||||
|
no-C-compiler
|
||||||
|
|
||||||
|
is not a full path and was not found in the PATH.
|
||||||
|
|
||||||
|
Tell CMake where to find the compiler by setting either the environment
|
||||||
|
variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
|
||||||
|
the compiler, or to the compiler name if it is in the PATH.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
||||||
|
+
|
||||||
|
CMake Error at BadCompilerCandCXX.cmake:3 \(project\):
|
||||||
|
The CMAKE_CXX_COMPILER:
|
||||||
|
|
||||||
|
no-CXX-compiler
|
||||||
|
|
||||||
|
is not a full path and was not found in the PATH.
|
||||||
|
|
||||||
|
Tell CMake where to find the compiler by setting either the environment
|
||||||
|
variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
|
||||||
|
to the compiler, or to the compiler name if it is in the PATH.
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,4 @@
|
||||||
|
set(CMAKE_C_COMPILER "no-C-compiler")
|
||||||
|
set(CMAKE_CXX_COMPILER "no-CXX-compiler")
|
||||||
|
project(BadCompilerCandCXXInner C CXX)
|
||||||
|
message(FATAL_ERROR "This error should not be reached.")
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8.4)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at NoCompilerC-IDE.cmake:2 \(enable_language\):
|
||||||
|
No CMAKE_C_COMPILER could be found.
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,3 @@
|
||||||
|
set(CMAKE_C_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerC-IDE")
|
||||||
|
enable_language(C)
|
||||||
|
message(FATAL_ERROR "This error should not be reached.")
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error at NoCompilerCXX-IDE.cmake:2 \(enable_language\):
|
||||||
|
No CMAKE_CXX_COMPILER could be found.
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,3 @@
|
||||||
|
set(CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCXX-IDE")
|
||||||
|
enable_language(CXX)
|
||||||
|
message(FATAL_ERROR "This error should not be reached.")
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,11 @@
|
||||||
|
CMake Error at NoCompilerCandCXX-IDE.cmake:3 \(project\):
|
||||||
|
No CMAKE_C_COMPILER could be found.
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
||||||
|
+
|
||||||
|
CMake Error at NoCompilerCandCXX-IDE.cmake:3 \(project\):
|
||||||
|
No CMAKE_CXX_COMPILER could be found.
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,4 @@
|
||||||
|
set(CMAKE_C_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCandCXX-IDE")
|
||||||
|
set(CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST "#error NoCompilerCandCXX-IDE")
|
||||||
|
project(NoCompilerCandCXXInner C CXX)
|
||||||
|
message(FATAL_ERROR "This error should not be reached.")
|
|
@ -0,0 +1,11 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
|
||||||
|
run_cmake(NoCompilerC-IDE)
|
||||||
|
run_cmake(NoCompilerCXX-IDE)
|
||||||
|
run_cmake(NoCompilerCandCXX-IDE)
|
||||||
|
else()
|
||||||
|
run_cmake(BadCompilerC)
|
||||||
|
run_cmake(BadCompilerCXX)
|
||||||
|
run_cmake(BadCompilerCandCXX)
|
||||||
|
endif()
|
Loading…
Reference in New Issue