CMake/Source/cmCommonTargetGenerator.h
Ben Boeckel 837f7c113a cmCommonTargetGenerator: classify linked target directories by language
These directories are used to direct collators for Fortran and C++
modules to consume dependent module information to properly collate.
However, the consumption of these files merely checks for existence of
the file, not whether they are actually needed anymore.

The problem arises when a target has Fortran or C++ modules at point A,
a build occurs populating this file, and then the target is updated to
no longer have potential modules. The `DependInfo.make` (for
`Makefiles`) or `<LANG>DependInfo.json` (for `Ninja`) files still exist
as they are never guaranteed to be cleaned up. This can introduce stale
information to the build which may cause a false-positive compilation if
a module file happens to still exist and gets found this way.

Instead, query the `linked-target-dirs` using the language in question
and only add the directory if it contains potential sources for modules
coming from the language in question.
2023-01-31 22:34:29 -05:00

86 lines
2.7 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
#include <set>
#include <string>
#include <vector>
#include "cmValue.h"
class cmGeneratorTarget;
class cmGlobalCommonGenerator;
class cmLocalCommonGenerator;
class cmMakefile;
class cmSourceFile;
/** \class cmCommonTargetGenerator
* \brief Common infrastructure for Makefile and Ninja per-target generators
*/
class cmCommonTargetGenerator
{
public:
cmCommonTargetGenerator(cmGeneratorTarget* gt);
virtual ~cmCommonTargetGenerator();
std::vector<std::string> const& GetConfigNames() const;
protected:
// Feature query methods.
cmValue GetFeature(const std::string& feature, const std::string& config);
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
cmLocalCommonGenerator* LocalCommonGenerator;
cmGlobalCommonGenerator* GlobalCommonGenerator;
std::vector<std::string> ConfigNames;
bool UseLWYU = false;
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
enum class PreprocessFlagsRequired
{
YES,
NO
};
void AppendFortranPreprocessFlags(
std::string& flags, cmSourceFile const& source,
PreprocessFlagsRequired requires_pp = PreprocessFlagsRequired::YES);
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
const std::string& config) = 0;
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so);
std::string GetFlags(const std::string& l, const std::string& config,
const std::string& arch = std::string());
std::string GetDefines(const std::string& l, const std::string& config);
std::string GetIncludes(std::string const& l, const std::string& config);
std::string GetManifests(const std::string& config);
std::string GetAIXExports(std::string const& config);
std::vector<std::string> GetLinkedTargetDirectories(
const std::string& lang, const std::string& config) const;
std::string ComputeTargetCompilePDB(const std::string& config) const;
std::string GetLinkerLauncher(const std::string& config);
bool HaveRequiredLanguages(const std::vector<cmSourceFile const*>& sources,
std::set<std::string>& languagesNeeded) const;
private:
using ByLanguageMap = std::map<std::string, std::string>;
struct ByConfig
{
ByLanguageMap FlagsByLanguage;
ByLanguageMap DefinesByLanguage;
ByLanguageMap IncludesByLanguage;
};
std::map<std::string, ByConfig> Configs;
};