1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportLibraryDependencies.cxx,v $
6 <<<<<<< cmExportLibraryDependencies.cxx
7 Date: $Date: 2008/02/20 18:36:38 $
8 Version: $Revision: 1.22 $
10 Date: $Date: 2008-04-27 11:01:05 $
11 Version: $Revision: 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"
27 #include "cmVersion.h"
29 #include <cmsys/auto_ptr.hxx>
31 bool cmExportLibraryDependenciesCommand
32 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
36 this->SetError("called with incorrect number of arguments");
40 // store the arguments for the final pass
41 this->Filename
= args
[0];
45 if(args
[1] == "APPEND")
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
;
67 cmsys::auto_ptr
<std::ofstream
> ap(
68 new std::ofstream(this->Filename
.c_str(), std::ios::app
));
73 cmsys::auto_ptr
<cmGeneratedFileStream
> ap(
74 new cmGeneratedFileStream(this->Filename
.c_str(), true));
75 ap
->SetCopyIfDifferent(true);
78 std::ostream
& fout
= *foutPtr
.get();
82 cmSystemTools::Error("Error Writing ", this->Filename
.c_str());
83 cmSystemTools::ReportLastSystemError("");
87 // Collect dependency information about all library targets built in
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
)
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";
133 case cmTarget::GENERAL
:
134 valueNew
+= "general;";
137 case cmTarget::DEBUG
:
138 valueNew
+= "debug;";
141 case cmTarget::OPTIMIZED
:
142 valueNew
+= "optimized;";
143 ltValue
= "optimized";
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"))
162 std::string
& ltEntry
= libTypes
[ltVar
];
167 else if(ltEntry
!= ltValue
)
172 libDepsNew
[targetEntry
] = valueNew
;
173 libDepsOld
[targetEntry
] = valueOld
;
177 // Generate dependency information for both old and new style CMake
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";