Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmExportLibraryDependencies.cxx
blobe2e23d42a1098af4b70f01cb510e9d2de380c026
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportLibraryDependencies.cxx,v $
5 Language: C++
6 <<<<<<< cmExportLibraryDependencies.cxx
7 Date: $Date: 2008/02/20 18:36:38 $
8 Version: $Revision: 1.22 $
9 =======
10 Date: $Date: 2008-04-27 11:01:05 $
11 Version: $Revision: 1.23 $
12 >>>>>>> 1.23
14 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
15 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
17 This software is distributed WITHOUT ANY WARRANTY; without even
18 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 PURPOSE. See the above copyright notices for more information.
21 =========================================================================*/
22 #include "cmExportLibraryDependencies.h"
23 #include "cmGlobalGenerator.h"
24 #include "cmLocalGenerator.h"
25 #include "cmGeneratedFileStream.h"
26 #include "cmake.h"
27 #include "cmVersion.h"
29 #include <cmsys/auto_ptr.hxx>
31 bool cmExportLibraryDependenciesCommand
32 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
34 if(args.size() < 1 )
36 this->SetError("called with incorrect number of arguments");
37 return false;
40 // store the arguments for the final pass
41 this->Filename = args[0];
42 this->Append = false;
43 if(args.size() > 1)
45 if(args[1] == "APPEND")
47 this->Append = true;
50 return true;
54 void cmExportLibraryDependenciesCommand::FinalPass()
56 // export_library_dependencies() shouldn't modify anything
57 // ensure this by calling a const method
58 this->ConstFinalPass();
61 void cmExportLibraryDependenciesCommand::ConstFinalPass() const
63 // Use copy-if-different if not appending.
64 cmsys::auto_ptr<std::ofstream> foutPtr;
65 if(this->Append)
67 cmsys::auto_ptr<std::ofstream> ap(
68 new std::ofstream(this->Filename.c_str(), std::ios::app));
69 foutPtr = ap;
71 else
73 cmsys::auto_ptr<cmGeneratedFileStream> ap(
74 new cmGeneratedFileStream(this->Filename.c_str(), true));
75 ap->SetCopyIfDifferent(true);
76 foutPtr = ap;
78 std::ostream& fout = *foutPtr.get();
80 if (!fout)
82 cmSystemTools::Error("Error Writing ", this->Filename.c_str());
83 cmSystemTools::ReportLastSystemError("");
84 return;
87 // Collect dependency information about all library targets built in
88 // the project.
89 cmake* cm = this->Makefile->GetCMakeInstance();
90 cmGlobalGenerator* global = cm->GetGlobalGenerator();
91 const std::vector<cmLocalGenerator *>& locals = global->GetLocalGenerators();
92 std::map<cmStdString, cmStdString> libDepsOld;
93 std::map<cmStdString, cmStdString> libDepsNew;
94 std::map<cmStdString, cmStdString> libTypes;
95 for(std::vector<cmLocalGenerator *>::const_iterator i = locals.begin();
96 i != locals.end(); ++i)
98 const cmLocalGenerator* gen = *i;
99 const cmTargets &tgts = gen->GetMakefile()->GetTargets();
100 for(cmTargets::const_iterator l = tgts.begin();
101 l != tgts.end(); ++l)
103 // Get the current target.
104 cmTarget const& target = l->second;
106 // Skip non-library targets.
107 if(target.GetType() < cmTarget::STATIC_LIBRARY
108 || target.GetType() > cmTarget::MODULE_LIBRARY)
110 continue;
113 // Construct the dependency variable name.
114 std::string targetEntry = target.GetName();
115 targetEntry += "_LIB_DEPENDS";
117 // Construct the dependency variable value. It is safe to use
118 // the target GetLinkLibraries method here because this code is
119 // called at the end of configure but before generate so library
120 // dependencies have yet to be analyzed. Therefore the value
121 // will be the direct link dependencies.
122 std::string valueOld;
123 std::string valueNew;
124 cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
125 for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
126 li != libs.end(); ++li)
128 std::string ltVar = li->first;
129 ltVar += "_LINK_TYPE";
130 std::string ltValue;
131 switch(li->second)
133 case cmTarget::GENERAL:
134 valueNew += "general;";
135 ltValue = "general";
136 break;
137 case cmTarget::DEBUG:
138 valueNew += "debug;";
139 ltValue = "debug";
140 break;
141 case cmTarget::OPTIMIZED:
142 valueNew += "optimized;";
143 ltValue = "optimized";
144 break;
146 std::string lib = li->first;
147 if(cmTarget* libtgt = global->FindTarget(0, lib.c_str()))
149 // Handle simple output name changes. This command is
150 // deprecated so we do not support full target name
151 // translation (which requires per-configuration info).
152 if(const char* outname = libtgt->GetProperty("OUTPUT_NAME"))
154 lib = outname;
157 valueOld += lib;
158 valueOld += ";";
159 valueNew += lib;
160 valueNew += ";";
162 std::string& ltEntry = libTypes[ltVar];
163 if(ltEntry.empty())
165 ltEntry = ltValue;
167 else if(ltEntry != ltValue)
169 ltEntry = "general";
172 libDepsNew[targetEntry] = valueNew;
173 libDepsOld[targetEntry] = valueOld;
177 // Generate dependency information for both old and new style CMake
178 // versions.
179 const char* vertest =
180 "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
181 fout << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
182 fout << "IF(" << vertest << ")\n";
183 fout << " # Information for CMake 2.6 and above.\n";
184 for(std::map<cmStdString, cmStdString>::const_iterator
185 i = libDepsNew.begin();
186 i != libDepsNew.end(); ++i)
188 if(!i->second.empty())
190 fout << " SET(\"" << i->first << "\" \"" << i->second << "\")\n";
193 fout << "ELSE(" << vertest << ")\n";
194 fout << " # Information for CMake 2.4 and lower.\n";
195 for(std::map<cmStdString, cmStdString>::const_iterator
196 i = libDepsOld.begin();
197 i != libDepsOld.end(); ++i)
199 if(!i->second.empty())
201 fout << " SET(\"" << i->first << "\" \"" << i->second << "\")\n";
204 for(std::map<cmStdString, cmStdString>::const_iterator i = libTypes.begin();
205 i != libTypes.end(); ++i)
207 if(i->second != "general")
209 fout << " SET(\"" << i->first << "\" \"" << i->second << "\")\n";
212 fout << "ENDIF(" << vertest << ")\n";
213 return;