|  | @@ -109,12 +109,13 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string cmNinjaTargetGenerator::LanguageCompilerRule(
 | 
	
		
			
				|  |  | -  const std::string& lang, const std::string& config) const
 | 
	
		
			
				|  |  | +  const std::string& lang, const std::string& config,
 | 
	
		
			
				|  |  | +  WithScanning withScanning) const
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    return cmStrCat(
 | 
	
		
			
				|  |  |      lang, "_COMPILER__",
 | 
	
		
			
				|  |  |      cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
 | 
	
		
			
				|  |  | -    '_', config);
 | 
	
		
			
				|  |  | +    withScanning == WithScanning::Yes ? "_scanned_" : "_unscanned_", config);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string cmNinjaTargetGenerator::LanguagePreprocessAndScanRule(
 | 
	
	
		
			
				|  | @@ -231,6 +232,32 @@ cmFileSet const* cmNinjaTargetGenerator::GetFileSetForSource(
 | 
	
		
			
				|  |  |    return fsit->second;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +bool cmNinjaTargetGenerator::NeedDyndepForSource(std::string const& lang,
 | 
	
		
			
				|  |  | +                                                 std::string const& config,
 | 
	
		
			
				|  |  | +                                                 cmSourceFile const* sf)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  bool const needDyndep = this->NeedDyndep(lang, config);
 | 
	
		
			
				|  |  | +  if (!needDyndep) {
 | 
	
		
			
				|  |  | +    return false;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  auto const* fs = this->GetFileSetForSource(config, sf);
 | 
	
		
			
				|  |  | +  if (fs &&
 | 
	
		
			
				|  |  | +      (fs->GetType() == "CXX_MODULES"_s ||
 | 
	
		
			
				|  |  | +       fs->GetType() == "CXX_MODULE_HEADER_UNITS"_s)) {
 | 
	
		
			
				|  |  | +    return true;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  auto const sfProp = sf->GetProperty("CXX_SCAN_FOR_MODULES");
 | 
	
		
			
				|  |  | +  if (sfProp.IsSet()) {
 | 
	
		
			
				|  |  | +    return sfProp.IsOn();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  auto const tgtProp =
 | 
	
		
			
				|  |  | +    this->GeneratorTarget->GetProperty("CXX_SCAN_FOR_MODULES");
 | 
	
		
			
				|  |  | +  if (tgtProp.IsSet()) {
 | 
	
		
			
				|  |  | +    return tgtProp.IsOn();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return true;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
 | 
	
		
			
				|  |  |    const std::string& config)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -670,6 +697,19 @@ cmNinjaRule GetScanRule(
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
 | 
	
		
			
				|  |  |                                                const std::string& config)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  // For some cases we scan to dynamically discover dependencies.
 | 
	
		
			
				|  |  | +  bool const needDyndep = this->NeedDyndep(lang, config);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (needDyndep) {
 | 
	
		
			
				|  |  | +    this->WriteCompileRule(lang, config, WithScanning::Yes);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  this->WriteCompileRule(lang, config, WithScanning::No);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
 | 
	
		
			
				|  |  | +                                              const std::string& config,
 | 
	
		
			
				|  |  | +                                              WithScanning withScanning)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    cmRulePlaceholderExpander::RuleVariables vars;
 | 
	
		
			
				|  |  |    vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
 | 
	
	
		
			
				|  | @@ -690,7 +730,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
 | 
	
		
			
				|  |  |    cmMakefile* mf = this->GetMakefile();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // For some cases we scan to dynamically discover dependencies.
 | 
	
		
			
				|  |  | -  bool const needDyndep = this->NeedDyndep(lang, config);
 | 
	
		
			
				|  |  |    bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    std::string flags = "$FLAGS";
 | 
	
	
		
			
				|  | @@ -728,7 +767,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
 | 
	
		
			
				|  |  |      this->GetLocalGenerator()->ConvertToOutputFormat(
 | 
	
		
			
				|  |  |        cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (needDyndep) {
 | 
	
		
			
				|  |  | +  if (withScanning == WithScanning::Yes) {
 | 
	
		
			
				|  |  |      const auto& scanDepType = this->GetMakefile()->GetSafeDefinition(
 | 
	
		
			
				|  |  |        cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_DEPFILE_FORMAT"));
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -834,7 +873,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
 | 
	
		
			
				|  |  |      this->GetGlobalGenerator()->AddRule(rule);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
 | 
	
		
			
				|  |  | +  cmNinjaRule rule(this->LanguageCompilerRule(lang, config, withScanning));
 | 
	
		
			
				|  |  |    // If using a response file, move defines, includes, and flags into it.
 | 
	
		
			
				|  |  |    if (!responseFlag.empty()) {
 | 
	
		
			
				|  |  |      rule.RspFile = "$RSP_FILE";
 | 
	
	
		
			
				|  | @@ -888,7 +927,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (needDyndep && !modmapFormat.empty()) {
 | 
	
		
			
				|  |  | +  if (withScanning == WithScanning::Yes && !modmapFormat.empty()) {
 | 
	
		
			
				|  |  |      std::string modmapFlags = mf->GetRequiredDefinition(
 | 
	
		
			
				|  |  |        cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG"));
 | 
	
		
			
				|  |  |      cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>",
 | 
	
	
		
			
				|  | @@ -1348,8 +1387,10 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 | 
	
		
			
				|  |  |      !(language == "RC" || (language == "CUDA" && !flag));
 | 
	
		
			
				|  |  |    int const commandLineLengthLimit =
 | 
	
		
			
				|  |  |      ((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
 | 
	
		
			
				|  |  | +  bool const needDyndep = this->NeedDyndepForSource(language, config, source);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
 | 
	
		
			
				|  |  | +  cmNinjaBuild objBuild(this->LanguageCompilerRule(
 | 
	
		
			
				|  |  | +    language, config, needDyndep ? WithScanning::Yes : WithScanning::No));
 | 
	
		
			
				|  |  |    cmNinjaVars& vars = objBuild.Variables;
 | 
	
		
			
				|  |  |    vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
 | 
	
		
			
				|  |  |    vars["DEFINES"] = this->ComputeDefines(source, language, config);
 | 
	
	
		
			
				|  | @@ -1458,7 +1499,6 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // For some cases we scan to dynamically discover dependencies.
 | 
	
		
			
				|  |  | -  bool const needDyndep = this->NeedDyndep(language, config);
 | 
	
		
			
				|  |  |    bool const compilationPreprocesses =
 | 
	
		
			
				|  |  |      !this->NeedExplicitPreprocessing(language);
 | 
	
		
			
				|  |  |  
 |