diff options
30 files changed, 225 insertions, 29 deletions
diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 871cccd..d53247a 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -228,6 +228,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; #endif @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@ +@CMAKE_C_COMPILER_ID_ERROR_FOR_TEST@ /*--------------------------------------------------------------------------*/ diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index f32fee0..b5d498d 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -221,6 +221,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; #endif @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@ +@CMAKE_CXX_COMPILER_ID_ERROR_FOR_TEST@ /*--------------------------------------------------------------------------*/ diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index fb205be..0461001 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -138,15 +138,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str())) && (optional==false)) { - std::string message = "your "; - 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; + return; } std::string doc = lang; doc += " compiler."; @@ -334,7 +326,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) void cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, - cmMakefile *mf, bool) + cmMakefile *mf, bool optional) { if(languages.size() == 0) { @@ -370,6 +362,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } } + bool fatalError = false; + mf->AddDefinition("RUN_CONFIGURE", true); std::string rootBin = mf->GetHomeOutputDirectory(); rootBin += cmake::GetCMakeFilesDirectory(); @@ -556,6 +550,65 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, this->SetLanguageEnabled("NONE", mf); 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_"; langLoadedVar += lang; langLoadedVar += "_INFORMATION_LOADED"; @@ -582,26 +635,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } 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 // (but only if a compiler has been actually found) // At this point we should have enough info for a try compile // which is used in the backward stuff // If the language is untested then test it now with a try compile. - if (!mf->IsSet(compilerName.c_str())) - { - // 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(needTestLanguage[lang]) { if (!this->CMakeInstance->GetIsInTryCompile()) { @@ -622,6 +661,10 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, // next time cmake is run if(!mf->IsOn(compilerWorks.c_str())) { + std::string compilerLangFile = rootBin; + compilerLangFile += "/CMake"; + compilerLangFile += lang; + compilerLangFile += "Compiler.cmake"; cmSystemTools::RemoveFile(compilerLangFile.c_str()); } else @@ -675,6 +718,33 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { 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." + ; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index c930b2b..3c4ddb2 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -392,6 +392,8 @@ private: void WriteSummary(); void WriteSummary(cmTarget* target); + virtual void PrintCompilerAdvice(std::ostream& os, std::string lang, + const char* envVar); void CheckCompilerIdCompatibility(cmMakefile* mf, std::string lang); cmExternalMakefileProjectGenerator* ExtraGenerator; diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index b665158..ce03a0e 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -107,6 +107,7 @@ protected: const char* AdditionalPlatformDefinition; private: + void PrintCompilerAdvice(std::ostream&, std::string, const char*) {} void ComputeTargetObjects(cmGeneratorTarget* gt) const; void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index c053943..97072b2 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -210,6 +210,7 @@ protected: std::vector<cmXCodeObject*> XCodeObjects; cmXCodeObject* RootObject; private: + void PrintCompilerAdvice(std::ostream&, std::string, const char*) {} void ComputeTargetObjects(cmGeneratorTarget* gt) const; std::string GetObjectsNormalDirectory( diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 8148cb6..4752798 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -60,6 +60,7 @@ add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange) endif() +add_RunCMake_test(CompilerNotFound) add_RunCMake_test(Configure) add_RunCMake_test(DisallowedCommands) add_RunCMake_test(ExternalData) diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake new file mode 100644 index 0000000..28d29e0 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-override.cmake @@ -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") diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt index 4745b25..cf3b1b3 100644 --- a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt @@ -1,5 +1,13 @@ You have changed variables that require your cache to be deleted. Configure will be re-run and you may have to reset some variables. 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\)$ diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake index c87ec49..06e9e03 100644 --- a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake @@ -1,3 +1,2 @@ +set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_LIST_DIR}/EmptyCompiler-override.cmake) 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") diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt new file mode 100644 index 0000000..c98842d --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake new file mode 100644 index 0000000..10fe59a --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerC.cmake @@ -0,0 +1,3 @@ +set(CMAKE_C_COMPILER "no-C-compiler") +enable_language(C) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt new file mode 100644 index 0000000..7ef4f5e --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake new file mode 100644 index 0000000..3b1e890 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCXX.cmake @@ -0,0 +1,3 @@ +set(CMAKE_CXX_COMPILER "no-CXX-compiler") +enable_language(CXX) +message(FATAL_ERROR "This error should not be reached.") diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt new file mode 100644 index 0000000..eecff54 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake new file mode 100644 index 0000000..2b6fa61 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/BadCompilerCandCXX.cmake @@ -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.") diff --git a/Tests/RunCMake/CompilerNotFound/CMakeLists.txt b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt new file mode 100644 index 0000000..12cd3c7 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.4) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt new file mode 100644 index 0000000..88bb95e --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake new file mode 100644 index 0000000..45e1a68 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerC-IDE.cmake @@ -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.") diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt new file mode 100644 index 0000000..4c92323 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake new file mode 100644 index 0000000..85025a0 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCXX-IDE.cmake @@ -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.") diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt new file mode 100644 index 0000000..21c69f5 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE-stderr.txt @@ -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\)$ diff --git a/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake new file mode 100644 index 0000000..78256a9 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/NoCompilerCandCXX-IDE.cmake @@ -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.") diff --git a/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake new file mode 100644 index 0000000..8b84f39 --- /dev/null +++ b/Tests/RunCMake/CompilerNotFound/RunCMakeTest.cmake @@ -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() |