From eeb4aece1cf564c10d1c4e7409907ca6c92462ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Fri, 18 Oct 2013 12:59:47 +0200 Subject: Ninja: use deps = gcc/msvc feature cmcldeps is now only used for .rc file processing --- Modules/CMakeCCompiler.cmake.in | 2 +- Modules/CMakeCXXCompiler.cmake.in | 2 +- Modules/CMakeClDeps.cmake | 4 +- Modules/CMakeDetermineCCompiler.cmake | 3 +- Modules/CMakeDetermineCXXCompiler.cmake | 3 +- Source/cmGlobalNinjaGenerator.cxx | 36 +++++++-- Source/cmGlobalNinjaGenerator.h | 15 ++-- Source/cmLocalNinjaGenerator.cxx | 20 +++-- Source/cmNinjaNormalTargetGenerator.cxx | 23 +++++- Source/cmNinjaTargetGenerator.cxx | 125 +++++++++++++++++++------------- Source/cmNinjaTargetGenerator.h | 2 + 11 files changed, 158 insertions(+), 77 deletions(-) diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index 3e8d4ff..804cce2 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -55,4 +55,4 @@ set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@") set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") @SET_CMAKE_CMCLDEPS_EXECUTABLE@ -@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@ +@SET_CMAKE_CL_SHOWINCLUDES_PREFIX@ diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 777f007..35aa6c4 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -56,4 +56,4 @@ set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@") set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") @SET_CMAKE_CMCLDEPS_EXECUTABLE@ -@SET_CMAKE_CL_SHOWINCLUDE_PREFIX@ +@SET_CMAKE_CL_SHOWINCLUDES_PREFIX@ diff --git a/Modules/CMakeClDeps.cmake b/Modules/CMakeClDeps.cmake index 0214ead..b46e7c2 100644 --- a/Modules/CMakeClDeps.cmake +++ b/Modules/CMakeClDeps.cmake @@ -20,7 +20,7 @@ # in front of each include path, so it can remove it. # -if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND) +if(CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPILER AND CMAKE_COMMAND) string(REPLACE "cmake.exe" "cmcldeps.exe" CMAKE_CMCLDEPS_EXECUTABLE ${CMAKE_COMMAND}) set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes) file(WRITE ${showdir}/foo.h "\n") @@ -30,5 +30,5 @@ if(MSVC_C_ARCHITECTURE_ID AND CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_C_COMPIL string(REGEX MATCH "\n([^:]*:[^:]*:[ \t]*)" tmp "${outLine}") set(localizedPrefix "${CMAKE_MATCH_1}") set(SET_CMAKE_CMCLDEPS_EXECUTABLE "set(CMAKE_CMCLDEPS_EXECUTABLE \"${CMAKE_CMCLDEPS_EXECUTABLE}\")") - set(SET_CMAKE_CL_SHOWINCLUDE_PREFIX "set(CMAKE_CL_SHOWINCLUDE_PREFIX \"${localizedPrefix}\")") + set(SET_CMAKE_CL_SHOWINCLUDES_PREFIX "set(CMAKE_CL_SHOWINCLUDES_PREFIX \"${localizedPrefix}\")") endif() diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index 8769c66..ce0978c 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -176,12 +176,13 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) endif () -include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) include(CMakeFindBinUtils) if(MSVC_C_ARCHITECTURE_ID) + include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) set(SET_MSVC_C_ARCHITECTURE_ID "set(MSVC_C_ARCHITECTURE_ID ${MSVC_C_ARCHITECTURE_ID})") endif() + # configure variables set in this file for fast reload later on configure_file(${CMAKE_ROOT}/Modules/CMakeCCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeCCompiler.cmake diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index c79ba89..d821dcc 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -175,12 +175,13 @@ if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX) endif () -include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) include(CMakeFindBinUtils) if(MSVC_CXX_ARCHITECTURE_ID) + include(${CMAKE_ROOT}/Modules/CMakeClDeps.cmake) set(SET_MSVC_CXX_ARCHITECTURE_ID "set(MSVC_CXX_ARCHITECTURE_ID ${MSVC_CXX_ARCHITECTURE_ID})") endif() + # configure all variables set in this file configure_file(${CMAKE_ROOT}/Modules/CMakeCXXCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeCXXCompiler.cmake diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index e45d024..6472949 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -102,6 +102,13 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) return EncodeLiteral(result); } +std::string cmGlobalNinjaGenerator::EncodeDepfileSpace(const std::string &path) +{ + std::string result = path; + cmSystemTools::ReplaceString(result, " ", "\\ "); + return result; +} + void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, const std::string& comment, const std::string& rule, @@ -236,9 +243,11 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() "$DESC", "Rule for running custom commands.", /*depfile*/ "", + /*deptype*/ "", /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ true); + /*restat*/ true, + /*generator*/ false); } void @@ -247,7 +256,7 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, const std::string& comment, const cmNinjaDeps& outputs, const cmNinjaDeps& deps, - const cmNinjaDeps& orderOnlyDeps) + const cmNinjaDeps& orderOnly) { std::string cmd = command; #ifdef _WIN32 @@ -268,7 +277,7 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, outputs, deps, cmNinjaDeps(), - orderOnlyDeps, + orderOnly, vars); } @@ -287,9 +296,13 @@ cmGlobalNinjaGenerator::AddMacOSXContentRule() this->AddRule("COPY_OSX_CONTENT", cmd.str(), "Copying OS X Content $out", - "Rule for copying OS X bundle content file." + "Rule for copying OS X bundle content file.", /*depfile*/ "", - /*rspfile*/ ""); + /*deptype*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); } void @@ -320,6 +333,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, bool restat, @@ -355,6 +369,13 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, os << "depfile = " << depfile << "\n"; } + // Write the deptype if any. + if (!deptype.empty()) + { + cmGlobalNinjaGenerator::Indent(os, 1); + os << "deps = " << deptype << "\n"; + } + // Write the command. cmGlobalNinjaGenerator::Indent(os, 1); os << "command = " << command << "\n"; @@ -583,6 +604,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, bool restat, @@ -601,6 +623,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, description, comment, depfile, + deptype, rspfile, rspcontent, restat, @@ -1089,6 +1112,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) "Re-running CMake...", "Rule for re-running cmake.", /*depfile=*/ "", + /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", /*restat=*/ false, @@ -1142,6 +1166,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) "Cleaning all built files...", "Rule for cleaning all built files.", /*depfile=*/ "", + /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", /*restat=*/ false, @@ -1164,6 +1189,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) "All primary targets available:", "Rule for printing all primary targets available.", /*depfile=*/ "", + /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", /*restat=*/ false, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index e046c7c..be58df1 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -64,6 +64,7 @@ public: static std::string EncodeIdent(const std::string &ident, std::ostream &vars); static std::string EncodeLiteral(const std::string &lit); static std::string EncodePath(const std::string &path); + static std::string EncodeDepfileSpace(const std::string &path); /** * Write the given @a comment to the output stream @a os. It @@ -104,7 +105,7 @@ public: const std::string& comment, const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), - const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + const cmNinjaDeps& orderOnly = cmNinjaDeps()); void WriteMacOSXContentBuild(const std::string& input, const std::string& output); @@ -120,6 +121,7 @@ public: const std::string& description, const std::string& comment, const std::string& depfile, + const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, bool restat, @@ -239,11 +241,12 @@ public: const std::string& command, const std::string& description, const std::string& comment, - const std::string& depfile = "", - const std::string& rspfile = "", - const std::string& rspcontent = "", - bool restat = false, - bool generator = false); + const std::string& depfile, + const std::string& deptype, + const std::string& rspfile, + const std::string& rspcontent, + bool restat, + bool generator); bool HasRule(const std::string& name); diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 89b05d7..d95a213 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -48,7 +48,21 @@ void cmLocalNinjaGenerator::Generate() this->WriteProcessedMakefile(this->GetRulesFileStream()); #endif - this->WriteBuildFileTop(); + // We do that only once for the top CMakeLists.txt file. + if(this->isRootMakefile()) + { + this->WriteBuildFileTop(); + + const std::string showIncludesPrefix = this->GetMakefile() + ->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"); + if (!showIncludesPrefix.empty()) + { + cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(), + "localized /showIncludes string"); + this->GetRulesFileStream() + << "msvc_deps_prefix = " << showIncludesPrefix << "\n\n"; + } + } cmTargets& targets = this->GetMakefile()->GetTargets(); for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) @@ -163,10 +177,6 @@ bool cmLocalNinjaGenerator::isRootMakefile() const void cmLocalNinjaGenerator::WriteBuildFileTop() { - // We do that only once for the top CMakeLists.txt file. - if(!this->isRootMakefile()) - return; - // For the build file. this->WriteProjectHeader(this->GetBuildFileStream()); this->WriteNinjaFilesInclusion(this->GetBuildFileStream()); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 57adeba..015654b 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -261,8 +261,11 @@ cmNinjaNormalTargetGenerator description.str(), comment.str(), /*depfile*/ "", + /*deptype*/ "", rspfile, - rspcontent); + rspcontent, + /*restat*/ false, + /*generator*/ false); } if (this->TargetNameOut != this->TargetNameReal && @@ -277,14 +280,28 @@ cmNinjaNormalTargetGenerator " -E cmake_symlink_executable" " $in $out && $POST_BUILD", "Creating executable symlink $out", - "Rule for creating executable symlink."); + "Rule for creating " + "executable symlink.", + /*depfile*/ "", + /*deptype*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); else this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY", cmakeCommand + " -E cmake_symlink_library" " $in $SONAME $out && $POST_BUILD", "Creating library symlink $out", - "Rule for creating library symlink."); + "Rule for creating " + "library symlink.", + /*depfile*/ "", + /*deptype*/ "", + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); } } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 898aa0e..a6f8159 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -187,6 +187,21 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, return flags; } + +bool cmNinjaTargetGenerator::needsDepFile(const std::string& lang) +{ + cmMakefile* mf = this->GetMakefile(); + + const bool usingMSVC = std::string("MSVC") == + (mf->GetDefinition("CMAKE_C_COMPILER_ID") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID")); + + return !usingMSVC || lang == "RC"; +} + + + // TODO: Refactor with // void cmMakefileTargetGenerator::WriteTargetLanguageFlags(). std::string @@ -331,77 +346,75 @@ cmNinjaTargetGenerator void cmNinjaTargetGenerator -::WriteCompileRule(const std::string& language) +::WriteCompileRule(const std::string& lang) { cmLocalGenerator::RuleVariables vars; vars.RuleLauncher = "RULE_LAUNCH_COMPILE"; vars.CMTarget = this->GetTarget(); - std::string lang = language; vars.Language = lang.c_str(); vars.Source = "$in"; vars.Object = "$out"; - std::string flags = "$FLAGS"; vars.Defines = "$DEFINES"; vars.TargetPDB = "$TARGET_PDB"; vars.ObjectDir = "$OBJECT_DIR"; cmMakefile* mf = this->GetMakefile(); - bool useClDeps = false; - std::string clBinary; - std::string clDepsBinary; - std::string clShowPrefix; - if (lang == "C" || lang == "CXX" || lang == "RC") + const bool usingMSVC = std::string("MSVC") == + (mf->GetDefinition("CMAKE_C_COMPILER_ID") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID")); + + // Tell ninja dependency format so all deps can be loaded into a database + std::string deptype; + std::string depfile; + std::string cldeps; + std::string flags = "$FLAGS"; + if (usingMSVC) { - clDepsBinary = mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); - if (!clDepsBinary.empty() && !mf->GetIsSourceFileTryCompile()) + if (!mf->GetIsSourceFileTryCompile() && lang == "RC") { - clShowPrefix = mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDE_PREFIX"); - clBinary = mf->GetDefinition("CMAKE_C_COMPILER") ? - mf->GetSafeDefinition("CMAKE_C_COMPILER") : - mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); - if (!clBinary.empty() && !clShowPrefix.empty()) - { - useClDeps = true; - const std::string quote = " \""; - clBinary = quote + clBinary + "\" "; - clDepsBinary = quote + clDepsBinary + "\" "; - clShowPrefix = quote + clShowPrefix + "\" "; - vars.DependencyFile = "$DEP_FILE"; - } + deptype = "gcc"; + depfile = "$DEP_FILE"; + const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER") ? + mf->GetSafeDefinition("CMAKE_C_COMPILER") : + mf->GetSafeDefinition("CMAKE_CXX_COMPILER"); + cldeps = "\""; + cldeps += mf->GetSafeDefinition("CMAKE_CMCLDEPS_EXECUTABLE"); + cldeps += "\" " + lang + " $in \"$DEP_FILE\" $out \""; + cldeps += mf->GetSafeDefinition("CMAKE_CL_SHOWINCLUDES_PREFIX"); + cldeps += "\" \"" + cl + "\" "; + } + else + { + deptype = "msvc"; + depfile = ""; + flags += " /showIncludes"; } } - - - std::string depfile; - std::string depfileFlagsName = "CMAKE_DEPFILE_FLAGS_" + language; - const char *depfileFlags = mf->GetDefinition(depfileFlagsName.c_str()); - if (depfileFlags || useClDeps) { - std::string depFlagsStr = depfileFlags ? depfileFlags : ""; + else + { + deptype = "gcc"; depfile = "$DEP_FILE"; - cmSystemTools::ReplaceString(depFlagsStr, "", "\"$DEP_FILE\""); - cmSystemTools::ReplaceString(depFlagsStr, "", "$out"); - cmSystemTools::ReplaceString(depFlagsStr, "", - mf->GetDefinition("CMAKE_C_COMPILER")); - flags += " " + depFlagsStr; - } - vars.Flags = flags.c_str(); + const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang; + std::string depfileFlags = mf->GetSafeDefinition(flagsName.c_str()); + cmSystemTools::ReplaceString(depfileFlags, "", "$DEP_FILE"); + cmSystemTools::ReplaceString(depfileFlags, "", "$out"); + cmSystemTools::ReplaceString(depfileFlags, "", + mf->GetDefinition("CMAKE_C_COMPILER")); + flags += " " + depfileFlags; + } + vars.Flags = flags.c_str(); + vars.DependencyFile = depfile.c_str(); // Rule for compiling object file. - std::string compileCmdVar = "CMAKE_"; - compileCmdVar += language; - compileCmdVar += "_COMPILE_OBJECT"; - std::string compileCmd = mf->GetRequiredDefinition(compileCmdVar.c_str()); + const std::string cmdVar = std::string("CMAKE_") + lang + "_COMPILE_OBJECT"; + std::string compileCmd = mf->GetRequiredDefinition(cmdVar.c_str()); std::vector compileCmds; cmSystemTools::ExpandListArgument(compileCmd, compileCmds); - if(useClDeps) - { - std::string cmdPrefix = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " + - clShowPrefix + clBinary; - compileCmds.front().insert(0, cmdPrefix); - } + compileCmds.front().insert(0, cldeps); for (std::vector::iterator i = compileCmds.begin(); i != compileCmds.end(); ++i) @@ -413,14 +426,19 @@ cmNinjaTargetGenerator // Write the rule for compiling file of the given language. cmOStringStream comment; - comment << "Rule for compiling " << language << " files."; + comment << "Rule for compiling " << lang << " files."; cmOStringStream description; - description << "Building " << language << " object $out"; - this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(language), + description << "Building " << lang << " object $out"; + this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang), cmdLine, description.str(), comment.str(), - depfile); + depfile, + deptype, + /*rspfile*/ "", + /*rspcontent*/ "", + /*restat*/ false, + /*generator*/ false); } void @@ -540,7 +558,10 @@ cmNinjaTargetGenerator cmNinjaVars vars; vars["FLAGS"] = this->ComputeFlagsForObject(source, language); vars["DEFINES"] = this->ComputeDefines(source, language); - vars["DEP_FILE"] = objectFileName + ".d";; + if (needsDepFile(language)) { + vars["DEP_FILE"] = + cmGlobalNinjaGenerator::EncodeDepfileSpace(objectFileName + ".d"); + } EnsureParentDirectoryExists(objectFileName); std::string objectDir = cmSystemTools::GetFilenamePath(objectFileName); diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index cf06bfd..1cf811a 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -42,6 +42,8 @@ public: std::string GetTargetName() const; + bool needsDepFile(const std::string& lang); + protected: bool SetMsvcTargetPdbVariable(cmNinjaVars&) const; -- cgit v0.12