|
@@ -1,514 +0,0 @@
|
|
|
-/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
|
|
|
- file Copyright.txt or https://cmake.org/licensing for details. */
|
|
|
|
|
-#include "cmOutputRequiredFilesCommand.h"
|
|
|
|
|
-
|
|
|
|
|
-#include <cstdio>
|
|
|
|
|
-#include <map>
|
|
|
|
|
-#include <set>
|
|
|
|
|
-#include <unordered_map>
|
|
|
|
|
-#include <utility>
|
|
|
|
|
-
|
|
|
|
|
-#include <cm/memory>
|
|
|
|
|
-
|
|
|
|
|
-#include "cmsys/FStream.hxx"
|
|
|
|
|
-#include "cmsys/RegularExpression.hxx"
|
|
|
|
|
-
|
|
|
|
|
-#include "cmExecutionStatus.h"
|
|
|
|
|
-#include "cmGeneratorExpression.h"
|
|
|
|
|
-#include "cmList.h"
|
|
|
|
|
-#include "cmMakefile.h"
|
|
|
|
|
-#include "cmSourceFile.h"
|
|
|
|
|
-#include "cmStringAlgorithms.h"
|
|
|
|
|
-#include "cmSystemTools.h"
|
|
|
|
|
-#include "cmTarget.h"
|
|
|
|
|
-#include "cmValue.h"
|
|
|
|
|
-
|
|
|
|
|
-namespace {
|
|
|
|
|
-/** \class cmDependInformation
|
|
|
|
|
- * \brief Store dependency information for a single source file.
|
|
|
|
|
- *
|
|
|
|
|
- * This structure stores the depend information for a single source file.
|
|
|
|
|
- */
|
|
|
|
|
-class cmDependInformation
|
|
|
|
|
-{
|
|
|
|
|
-public:
|
|
|
|
|
- /**
|
|
|
|
|
- * Construct with dependency generation marked not done; instance
|
|
|
|
|
- * not placed in cmMakefile's list.
|
|
|
|
|
- */
|
|
|
|
|
- cmDependInformation() = default;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * The set of files on which this one depends.
|
|
|
|
|
- */
|
|
|
|
|
- using DependencySetType = std::set<cmDependInformation*>;
|
|
|
|
|
- DependencySetType DependencySet;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * This flag indicates whether dependency checking has been
|
|
|
|
|
- * performed for this file.
|
|
|
|
|
- */
|
|
|
|
|
- bool DependDone = false;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * If this object corresponds to a cmSourceFile instance, this points
|
|
|
|
|
- * to it.
|
|
|
|
|
- */
|
|
|
|
|
- const cmSourceFile* SourceFile = nullptr;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Full path to this file.
|
|
|
|
|
- */
|
|
|
|
|
- std::string FullPath;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Full path not including file name.
|
|
|
|
|
- */
|
|
|
|
|
- std::string PathOnly;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Name used to #include this file.
|
|
|
|
|
- */
|
|
|
|
|
- std::string IncludeName;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * This method adds the dependencies of another file to this one.
|
|
|
|
|
- */
|
|
|
|
|
- void AddDependencies(cmDependInformation* info)
|
|
|
|
|
- {
|
|
|
|
|
- if (this != info) {
|
|
|
|
|
- this->DependencySet.insert(info);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-class cmLBDepend
|
|
|
|
|
-{
|
|
|
|
|
-public:
|
|
|
|
|
- /**
|
|
|
|
|
- * Construct the object with verbose turned off.
|
|
|
|
|
- */
|
|
|
|
|
- cmLBDepend()
|
|
|
|
|
- {
|
|
|
|
|
- this->Verbose = false;
|
|
|
|
|
- this->IncludeFileRegularExpression.compile("^.*$");
|
|
|
|
|
- this->ComplainFileRegularExpression.compile("^$");
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Destructor.
|
|
|
|
|
- */
|
|
|
|
|
- ~cmLBDepend() = default;
|
|
|
|
|
-
|
|
|
|
|
- cmLBDepend(const cmLBDepend&) = delete;
|
|
|
|
|
- cmLBDepend& operator=(const cmLBDepend&) = delete;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Set the makefile that is used as a source of classes.
|
|
|
|
|
- */
|
|
|
|
|
- void SetMakefile(cmMakefile* makefile)
|
|
|
|
|
- {
|
|
|
|
|
- this->Makefile = makefile;
|
|
|
|
|
-
|
|
|
|
|
- // Now extract the include file regular expression from the makefile.
|
|
|
|
|
- this->IncludeFileRegularExpression.compile(
|
|
|
|
|
- this->Makefile->GetIncludeRegularExpression());
|
|
|
|
|
- this->ComplainFileRegularExpression.compile(
|
|
|
|
|
- this->Makefile->GetComplainRegularExpression());
|
|
|
|
|
-
|
|
|
|
|
- // Now extract any include paths from the targets
|
|
|
|
|
- std::set<std::string> uniqueIncludes;
|
|
|
|
|
- std::vector<std::string> orderedAndUniqueIncludes;
|
|
|
|
|
- for (auto const& target : this->Makefile->GetTargets()) {
|
|
|
|
|
- cmValue incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
|
|
|
|
|
- if (!incDirProp) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::string incDirs = cmGeneratorExpression::Preprocess(
|
|
|
|
|
- *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
|
|
|
|
|
-
|
|
|
|
|
- cmList includes{ incDirs };
|
|
|
|
|
-
|
|
|
|
|
- for (auto& path : includes) {
|
|
|
|
|
- this->Makefile->ExpandVariablesInString(path);
|
|
|
|
|
- if (uniqueIncludes.insert(path).second) {
|
|
|
|
|
- orderedAndUniqueIncludes.push_back(path);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- for (std::string const& inc : orderedAndUniqueIncludes) {
|
|
|
|
|
- this->AddSearchPath(inc);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Add a directory to the search path for include files.
|
|
|
|
|
- */
|
|
|
|
|
- void AddSearchPath(const std::string& path)
|
|
|
|
|
- {
|
|
|
|
|
- this->IncludeDirectories.push_back(path);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Generate dependencies for the file given. Returns a pointer to
|
|
|
|
|
- * the cmDependInformation object for the file.
|
|
|
|
|
- */
|
|
|
|
|
- const cmDependInformation* FindDependencies(const std::string& file)
|
|
|
|
|
- {
|
|
|
|
|
- cmDependInformation* info = this->GetDependInformation(file, "");
|
|
|
|
|
- this->GenerateDependInformation(info);
|
|
|
|
|
- return info;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-protected:
|
|
|
|
|
- /**
|
|
|
|
|
- * Compute the depend information for this class.
|
|
|
|
|
- */
|
|
|
|
|
-
|
|
|
|
|
- void DependWalk(cmDependInformation* info)
|
|
|
|
|
- {
|
|
|
|
|
- cmsys::ifstream fin(info->FullPath.c_str());
|
|
|
|
|
- if (!fin) {
|
|
|
|
|
- cmSystemTools::Error("error can not open " + info->FullPath);
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- std::string line;
|
|
|
|
|
- while (cmSystemTools::GetLineFromStream(fin, line)) {
|
|
|
|
|
- if (cmHasLiteralPrefix(line, "#include")) {
|
|
|
|
|
- // if it is an include line then create a string class
|
|
|
|
|
- size_t qstart = line.find('\"', 8);
|
|
|
|
|
- size_t qend;
|
|
|
|
|
- // if a quote is not found look for a <
|
|
|
|
|
- if (qstart == std::string::npos) {
|
|
|
|
|
- qstart = line.find('<', 8);
|
|
|
|
|
- // if a < is not found then move on
|
|
|
|
|
- if (qstart == std::string::npos) {
|
|
|
|
|
- cmSystemTools::Error("unknown include directive " + line);
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- qend = line.find('>', qstart + 1);
|
|
|
|
|
- } else {
|
|
|
|
|
- qend = line.find('\"', qstart + 1);
|
|
|
|
|
- }
|
|
|
|
|
- // extract the file being included
|
|
|
|
|
- std::string includeFile = line.substr(qstart + 1, qend - qstart - 1);
|
|
|
|
|
- // see if the include matches the regular expression
|
|
|
|
|
- if (!this->IncludeFileRegularExpression.find(includeFile)) {
|
|
|
|
|
- if (this->Verbose) {
|
|
|
|
|
- std::string message =
|
|
|
|
|
- cmStrCat("Skipping ", includeFile, " for file ", info->FullPath);
|
|
|
|
|
- cmSystemTools::Error(message);
|
|
|
|
|
- }
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Add this file and all its dependencies.
|
|
|
|
|
- this->AddDependency(info, includeFile);
|
|
|
|
|
- /// add the cxx file if it exists
|
|
|
|
|
- std::string cxxFile = includeFile;
|
|
|
|
|
- std::string::size_type pos = cxxFile.rfind('.');
|
|
|
|
|
- if (pos != std::string::npos) {
|
|
|
|
|
- std::string root = cxxFile.substr(0, pos);
|
|
|
|
|
- cxxFile = root + ".cxx";
|
|
|
|
|
- bool found = false;
|
|
|
|
|
- // try jumping to .cxx .cpp and .c in order
|
|
|
|
|
- if (cmSystemTools::FileExists(cxxFile)) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- for (std::string const& path : this->IncludeDirectories) {
|
|
|
|
|
- if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!found) {
|
|
|
|
|
- cxxFile = root + ".cpp";
|
|
|
|
|
- if (cmSystemTools::FileExists(cxxFile)) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- for (std::string const& path : this->IncludeDirectories) {
|
|
|
|
|
- if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!found) {
|
|
|
|
|
- cxxFile = root + ".c";
|
|
|
|
|
- if (cmSystemTools::FileExists(cxxFile)) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- for (std::string const& path : this->IncludeDirectories) {
|
|
|
|
|
- if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!found) {
|
|
|
|
|
- cxxFile = root + ".txx";
|
|
|
|
|
- if (cmSystemTools::FileExists(cxxFile)) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- for (std::string const& path : this->IncludeDirectories) {
|
|
|
|
|
- if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (found) {
|
|
|
|
|
- this->AddDependency(info, cxxFile);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Add a dependency. Possibly walk it for more dependencies.
|
|
|
|
|
- */
|
|
|
|
|
- void AddDependency(cmDependInformation* info, const std::string& file)
|
|
|
|
|
- {
|
|
|
|
|
- cmDependInformation* dependInfo =
|
|
|
|
|
- this->GetDependInformation(file, info->PathOnly);
|
|
|
|
|
- this->GenerateDependInformation(dependInfo);
|
|
|
|
|
- info->AddDependencies(dependInfo);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Fill in the given object with dependency information. If the
|
|
|
|
|
- * information is already complete, nothing is done.
|
|
|
|
|
- */
|
|
|
|
|
- void GenerateDependInformation(cmDependInformation* info)
|
|
|
|
|
- {
|
|
|
|
|
- // If dependencies are already done, stop now.
|
|
|
|
|
- if (info->DependDone) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
- // Make sure we don't visit the same file more than once.
|
|
|
|
|
- info->DependDone = true;
|
|
|
|
|
-
|
|
|
|
|
- const std::string& path = info->FullPath;
|
|
|
|
|
- if (path.empty()) {
|
|
|
|
|
- cmSystemTools::Error(
|
|
|
|
|
- "Attempt to find dependencies for file without path!");
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- bool found = false;
|
|
|
|
|
-
|
|
|
|
|
- // If the file exists, use it to find dependency information.
|
|
|
|
|
- if (cmSystemTools::FileExists(path, true)) {
|
|
|
|
|
- // Use the real file to find its dependencies.
|
|
|
|
|
- this->DependWalk(info);
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // See if the cmSourceFile for it has any files specified as
|
|
|
|
|
- // dependency hints.
|
|
|
|
|
- if (info->SourceFile) {
|
|
|
|
|
-
|
|
|
|
|
- // Get the cmSourceFile corresponding to this.
|
|
|
|
|
- const cmSourceFile& cFile = *(info->SourceFile);
|
|
|
|
|
- // See if there are any hints for finding dependencies for the missing
|
|
|
|
|
- // file.
|
|
|
|
|
- if (!cFile.GetDepends().empty()) {
|
|
|
|
|
- // Dependency hints have been given. Use them to begin the
|
|
|
|
|
- // recursion.
|
|
|
|
|
- for (std::string const& file : cFile.GetDepends()) {
|
|
|
|
|
- this->AddDependency(info, file);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Found dependency information. We are done.
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!found) {
|
|
|
|
|
- // Try to find the file amongst the sources
|
|
|
|
|
- cmSourceFile* srcFile = this->Makefile->GetSource(
|
|
|
|
|
- cmSystemTools::GetFilenameWithoutExtension(path));
|
|
|
|
|
- if (srcFile) {
|
|
|
|
|
- if (srcFile->ResolveFullPath() == path) {
|
|
|
|
|
- found = true;
|
|
|
|
|
- } else {
|
|
|
|
|
- // try to guess which include path to use
|
|
|
|
|
- for (std::string incpath : this->IncludeDirectories) {
|
|
|
|
|
- if (!incpath.empty() && incpath.back() != '/') {
|
|
|
|
|
- incpath += "/";
|
|
|
|
|
- }
|
|
|
|
|
- incpath += path;
|
|
|
|
|
- if (srcFile->ResolveFullPath() == incpath) {
|
|
|
|
|
- // set the path to the guessed path
|
|
|
|
|
- info->FullPath = incpath;
|
|
|
|
|
- found = true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!found) {
|
|
|
|
|
- // Couldn't find any dependency information.
|
|
|
|
|
- if (this->ComplainFileRegularExpression.find(info->IncludeName)) {
|
|
|
|
|
- cmSystemTools::Error("error cannot find dependencies for " + path);
|
|
|
|
|
- } else {
|
|
|
|
|
- // Destroy the name of the file so that it won't be output as a
|
|
|
|
|
- // dependency.
|
|
|
|
|
- info->FullPath.clear();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Get an instance of cmDependInformation corresponding to the given file
|
|
|
|
|
- * name.
|
|
|
|
|
- */
|
|
|
|
|
- cmDependInformation* GetDependInformation(const std::string& file,
|
|
|
|
|
- const std::string& extraPath)
|
|
|
|
|
- {
|
|
|
|
|
- // Get the full path for the file so that lookup is unambiguous.
|
|
|
|
|
- std::string fullPath = this->FullPath(file, extraPath);
|
|
|
|
|
-
|
|
|
|
|
- // Try to find the file's instance of cmDependInformation.
|
|
|
|
|
- auto result = this->DependInformationMap.find(fullPath);
|
|
|
|
|
- if (result != this->DependInformationMap.end()) {
|
|
|
|
|
- // Found an instance, return it.
|
|
|
|
|
- return result->second.get();
|
|
|
|
|
- }
|
|
|
|
|
- // Didn't find an instance. Create a new one and save it.
|
|
|
|
|
- auto info = cm::make_unique<cmDependInformation>();
|
|
|
|
|
- auto* ptr = info.get();
|
|
|
|
|
- info->FullPath = fullPath;
|
|
|
|
|
- info->PathOnly = cmSystemTools::GetFilenamePath(fullPath);
|
|
|
|
|
- info->IncludeName = file;
|
|
|
|
|
- this->DependInformationMap[fullPath] = std::move(info);
|
|
|
|
|
- return ptr;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Find the full path name for the given file name.
|
|
|
|
|
- * This uses the include directories.
|
|
|
|
|
- * TODO: Cache path conversions to reduce FileExists calls.
|
|
|
|
|
- */
|
|
|
|
|
- std::string FullPath(const std::string& fname, const std::string& extraPath)
|
|
|
|
|
- {
|
|
|
|
|
- auto m = this->DirectoryToFileToPathMap.find(extraPath);
|
|
|
|
|
-
|
|
|
|
|
- if (m != this->DirectoryToFileToPathMap.end()) {
|
|
|
|
|
- FileToPathMapType& map = m->second;
|
|
|
|
|
- auto p = map.find(fname);
|
|
|
|
|
- if (p != map.end()) {
|
|
|
|
|
- return p->second;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (cmSystemTools::FileExists(fname, true)) {
|
|
|
|
|
- std::string fp = cmSystemTools::CollapseFullPath(fname);
|
|
|
|
|
- this->DirectoryToFileToPathMap[extraPath][fname] = fp;
|
|
|
|
|
- return fp;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- for (std::string path : this->IncludeDirectories) {
|
|
|
|
|
- if (!path.empty() && path.back() != '/') {
|
|
|
|
|
- path += "/";
|
|
|
|
|
- }
|
|
|
|
|
- path += fname;
|
|
|
|
|
- if (cmSystemTools::FileExists(path, true)) {
|
|
|
|
|
- std::string fp = cmSystemTools::CollapseFullPath(path);
|
|
|
|
|
- this->DirectoryToFileToPathMap[extraPath][fname] = fp;
|
|
|
|
|
- return fp;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!extraPath.empty()) {
|
|
|
|
|
- std::string path = extraPath;
|
|
|
|
|
- if (!path.empty() && path.back() != '/') {
|
|
|
|
|
- path = path + "/";
|
|
|
|
|
- }
|
|
|
|
|
- path = path + fname;
|
|
|
|
|
- if (cmSystemTools::FileExists(path, true)) {
|
|
|
|
|
- std::string fp = cmSystemTools::CollapseFullPath(path);
|
|
|
|
|
- this->DirectoryToFileToPathMap[extraPath][fname] = fp;
|
|
|
|
|
- return fp;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Couldn't find the file.
|
|
|
|
|
- return fname;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- cmMakefile* Makefile;
|
|
|
|
|
- bool Verbose;
|
|
|
|
|
- cmsys::RegularExpression IncludeFileRegularExpression;
|
|
|
|
|
- cmsys::RegularExpression ComplainFileRegularExpression;
|
|
|
|
|
- std::vector<std::string> IncludeDirectories;
|
|
|
|
|
- using FileToPathMapType = std::map<std::string, std::string>;
|
|
|
|
|
- using DirectoryToFileToPathMapType =
|
|
|
|
|
- std::map<std::string, FileToPathMapType>;
|
|
|
|
|
- using DependInformationMapType =
|
|
|
|
|
- std::map<std::string, std::unique_ptr<cmDependInformation>>;
|
|
|
|
|
- DependInformationMapType DependInformationMap;
|
|
|
|
|
- DirectoryToFileToPathMapType DirectoryToFileToPathMap;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-void ListDependencies(cmDependInformation const* info, FILE* fout,
|
|
|
|
|
- std::set<cmDependInformation const*>* visited);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// cmOutputRequiredFilesCommand
|
|
|
|
|
-bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
|
|
|
|
|
- cmExecutionStatus& status)
|
|
|
|
|
-{
|
|
|
|
|
- if (args.size() != 2) {
|
|
|
|
|
- status.SetError("called with incorrect number of arguments");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // store the arg for final pass
|
|
|
|
|
- const std::string& file = args[0];
|
|
|
|
|
- const std::string& outputFile = args[1];
|
|
|
|
|
-
|
|
|
|
|
- // compute the list of files
|
|
|
|
|
- cmLBDepend md;
|
|
|
|
|
- md.SetMakefile(&status.GetMakefile());
|
|
|
|
|
- md.AddSearchPath(status.GetMakefile().GetCurrentSourceDirectory());
|
|
|
|
|
- // find the depends for a file
|
|
|
|
|
- const cmDependInformation* info = md.FindDependencies(file);
|
|
|
|
|
- if (info) {
|
|
|
|
|
- // write them out
|
|
|
|
|
- FILE* fout = cmsys::SystemTools::Fopen(outputFile, "w");
|
|
|
|
|
- if (!fout) {
|
|
|
|
|
- status.SetError(cmStrCat("Can not open output file: ", outputFile));
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- std::set<cmDependInformation const*> visited;
|
|
|
|
|
- ListDependencies(info, fout, &visited);
|
|
|
|
|
- fclose(fout);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return true;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-namespace {
|
|
|
|
|
-void ListDependencies(cmDependInformation const* info, FILE* fout,
|
|
|
|
|
- std::set<cmDependInformation const*>* visited)
|
|
|
|
|
-{
|
|
|
|
|
- // add info to the visited set
|
|
|
|
|
- visited->insert(info);
|
|
|
|
|
- // now recurse with info's dependencies
|
|
|
|
|
- for (cmDependInformation* d : info->DependencySet) {
|
|
|
|
|
- if (visited->find(d) == visited->end()) {
|
|
|
|
|
- if (!info->FullPath.empty()) {
|
|
|
|
|
- std::string tmp = d->FullPath;
|
|
|
|
|
- std::string::size_type pos = tmp.rfind('.');
|
|
|
|
|
- if (pos != std::string::npos && (tmp.substr(pos) != ".h")) {
|
|
|
|
|
- tmp = tmp.substr(0, pos);
|
|
|
|
|
- fprintf(fout, "%s\n", d->FullPath.c_str());
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ListDependencies(d, fout, visited);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-}
|
|
|