1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportLibraryDependencies.cxx,v $
6 Date: $Date: 2008/02/12 14:18:50 $
7 Version: $Revision: 1.21 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmExportLibraryDependencies.h"
18 #include "cmGlobalGenerator.h"
19 #include "cmLocalGenerator.h"
20 #include "cmGeneratedFileStream.h"
23 #include <cmsys/auto_ptr.hxx>
25 bool cmExportLibraryDependenciesCommand
26 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
30 this->SetError("called with incorrect number of arguments");
34 // store the arguments for the final pass
35 this->Filename
= args
[0];
39 if(args
[1] == "APPEND")
48 void cmExportLibraryDependenciesCommand::FinalPass()
50 // export_library_dependencies() shouldn't modify anything
51 // ensure this by calling a const method
52 this->ConstFinalPass();
55 void cmExportLibraryDependenciesCommand::ConstFinalPass() const
57 // Use copy-if-different if not appending.
58 cmsys::auto_ptr
<std::ofstream
> foutPtr
;
61 cmsys::auto_ptr
<std::ofstream
> ap(
62 new std::ofstream(this->Filename
.c_str(), std::ios::app
));
67 cmsys::auto_ptr
<cmGeneratedFileStream
> ap(
68 new cmGeneratedFileStream(this->Filename
.c_str(), true));
69 ap
->SetCopyIfDifferent(true);
72 std::ostream
& fout
= *foutPtr
.get();
76 cmSystemTools::Error("Error Writing ", this->Filename
.c_str());
77 cmSystemTools::ReportLastSystemError("");
81 // Collect dependency information about all library targets built in
83 const cmake
* cm
= this->Makefile
->GetCMakeInstance();
84 const cmGlobalGenerator
* global
= cm
->GetGlobalGenerator();
85 const std::vector
<cmLocalGenerator
*>& locals
= global
->GetLocalGenerators();
86 std::map
<cmStdString
, cmStdString
> libDepsOld
;
87 std::map
<cmStdString
, cmStdString
> libDepsNew
;
88 std::map
<cmStdString
, cmStdString
> libTypes
;
89 for(std::vector
<cmLocalGenerator
*>::const_iterator i
= locals
.begin();
90 i
!= locals
.end(); ++i
)
92 const cmLocalGenerator
* gen
= *i
;
93 const cmTargets
&tgts
= gen
->GetMakefile()->GetTargets();
94 for(cmTargets::const_iterator l
= tgts
.begin();
97 // Get the current target.
98 cmTarget
const& target
= l
->second
;
100 // Skip non-library targets.
101 if(target
.GetType() < cmTarget::STATIC_LIBRARY
102 || target
.GetType() > cmTarget::MODULE_LIBRARY
)
107 // Construct the dependency variable name.
108 std::string targetEntry
= target
.GetName();
109 targetEntry
+= "_LIB_DEPENDS";
111 // Construct the dependency variable value. It is safe to use
112 // the target GetLinkLibraries method here because this code is
113 // called at the end of configure but before generate so library
114 // dependencies have yet to be analyzed. Therefore the value
115 // will be the direct link dependencies.
116 std::string valueOld
;
117 std::string valueNew
;
118 cmTarget::LinkLibraryVectorType
const& libs
= target
.GetLinkLibraries();
119 for(cmTarget::LinkLibraryVectorType::const_iterator li
= libs
.begin();
120 li
!= libs
.end(); ++li
)
122 std::string ltVar
= li
->first
;
123 ltVar
+= "_LINK_TYPE";
127 case cmTarget::GENERAL
:
128 valueNew
+= "general;";
131 case cmTarget::DEBUG
:
132 valueNew
+= "debug;";
135 case cmTarget::OPTIMIZED
:
136 valueNew
+= "optimized;";
137 ltValue
= "optimized";
140 valueOld
+= li
->first
;
142 valueNew
+= li
->first
;
145 std::string
& ltEntry
= libTypes
[ltVar
];
150 else if(ltEntry
!= ltValue
)
155 libDepsNew
[targetEntry
] = valueNew
;
156 libDepsOld
[targetEntry
] = valueOld
;
160 // Generate dependency information for both old and new style CMake
162 const char* vertest
=
163 "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
164 fout
<< "IF(" << vertest
<< ")\n";
165 fout
<< " # Information for CMake 2.6 and above.\n";
166 for(std::map
<cmStdString
, cmStdString
>::const_iterator
167 i
= libDepsNew
.begin();
168 i
!= libDepsNew
.end(); ++i
)
170 if(!i
->second
.empty())
172 fout
<< " SET(\"" << i
->first
<< "\" \"" << i
->second
<< "\")\n";
175 fout
<< "ELSE(" << vertest
<< ")\n";
176 fout
<< " # Information for CMake 2.4 and lower.\n";
177 for(std::map
<cmStdString
, cmStdString
>::const_iterator
178 i
= libDepsOld
.begin();
179 i
!= libDepsOld
.end(); ++i
)
181 if(!i
->second
.empty())
183 fout
<< " SET(\"" << i
->first
<< "\" \"" << i
->second
<< "\")\n";
186 for(std::map
<cmStdString
, cmStdString
>::const_iterator i
= libTypes
.begin();
187 i
!= libTypes
.end(); ++i
)
189 if(i
->second
!= "general")
191 fout
<< " SET(\"" << i
->first
<< "\" \"" << i
->second
<< "\")\n";
194 fout
<< "ENDIF(" << vertest
<< ")\n";