1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportLibraryDependencies.cxx,v $
6 Date: $Date: 2008-04-27 11:01:05 $
7 Version: $Revision: 1.23 $
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"
22 #include "cmVersion.h"
24 #include <cmsys/auto_ptr.hxx>
26 bool cmExportLibraryDependenciesCommand
27 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
31 this->SetError("called with incorrect number of arguments");
35 // store the arguments for the final pass
36 this->Filename
= args
[0];
40 if(args
[1] == "APPEND")
49 void cmExportLibraryDependenciesCommand::FinalPass()
51 // export_library_dependencies() shouldn't modify anything
52 // ensure this by calling a const method
53 this->ConstFinalPass();
56 void cmExportLibraryDependenciesCommand::ConstFinalPass() const
58 // Use copy-if-different if not appending.
59 cmsys::auto_ptr
<std::ofstream
> foutPtr
;
62 cmsys::auto_ptr
<std::ofstream
> ap(
63 new std::ofstream(this->Filename
.c_str(), std::ios::app
));
68 cmsys::auto_ptr
<cmGeneratedFileStream
> ap(
69 new cmGeneratedFileStream(this->Filename
.c_str(), true));
70 ap
->SetCopyIfDifferent(true);
73 std::ostream
& fout
= *foutPtr
.get();
77 cmSystemTools::Error("Error Writing ", this->Filename
.c_str());
78 cmSystemTools::ReportLastSystemError("");
82 // Collect dependency information about all library targets built in
84 cmake
* cm
= this->Makefile
->GetCMakeInstance();
85 cmGlobalGenerator
* global
= cm
->GetGlobalGenerator();
86 const std::vector
<cmLocalGenerator
*>& locals
= global
->GetLocalGenerators();
87 std::map
<cmStdString
, cmStdString
> libDepsOld
;
88 std::map
<cmStdString
, cmStdString
> libDepsNew
;
89 std::map
<cmStdString
, cmStdString
> libTypes
;
90 for(std::vector
<cmLocalGenerator
*>::const_iterator i
= locals
.begin();
91 i
!= locals
.end(); ++i
)
93 const cmLocalGenerator
* gen
= *i
;
94 const cmTargets
&tgts
= gen
->GetMakefile()->GetTargets();
95 for(cmTargets::const_iterator l
= tgts
.begin();
98 // Get the current target.
99 cmTarget
const& target
= l
->second
;
101 // Skip non-library targets.
102 if(target
.GetType() < cmTarget::STATIC_LIBRARY
103 || target
.GetType() > cmTarget::MODULE_LIBRARY
)
108 // Construct the dependency variable name.
109 std::string targetEntry
= target
.GetName();
110 targetEntry
+= "_LIB_DEPENDS";
112 // Construct the dependency variable value. It is safe to use
113 // the target GetLinkLibraries method here because this code is
114 // called at the end of configure but before generate so library
115 // dependencies have yet to be analyzed. Therefore the value
116 // will be the direct link dependencies.
117 std::string valueOld
;
118 std::string valueNew
;
119 cmTarget::LinkLibraryVectorType
const& libs
= target
.GetLinkLibraries();
120 for(cmTarget::LinkLibraryVectorType::const_iterator li
= libs
.begin();
121 li
!= libs
.end(); ++li
)
123 std::string ltVar
= li
->first
;
124 ltVar
+= "_LINK_TYPE";
128 case cmTarget::GENERAL
:
129 valueNew
+= "general;";
132 case cmTarget::DEBUG
:
133 valueNew
+= "debug;";
136 case cmTarget::OPTIMIZED
:
137 valueNew
+= "optimized;";
138 ltValue
= "optimized";
141 std::string lib
= li
->first
;
142 if(cmTarget
* libtgt
= global
->FindTarget(0, lib
.c_str()))
144 // Handle simple output name changes. This command is
145 // deprecated so we do not support full target name
146 // translation (which requires per-configuration info).
147 if(const char* outname
= libtgt
->GetProperty("OUTPUT_NAME"))
157 std::string
& ltEntry
= libTypes
[ltVar
];
162 else if(ltEntry
!= ltValue
)
167 libDepsNew
[targetEntry
] = valueNew
;
168 libDepsOld
[targetEntry
] = valueOld
;
172 // Generate dependency information for both old and new style CMake
174 const char* vertest
=
175 "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
176 fout
<< "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
177 fout
<< "IF(" << vertest
<< ")\n";
178 fout
<< " # Information for CMake 2.6 and above.\n";
179 for(std::map
<cmStdString
, cmStdString
>::const_iterator
180 i
= libDepsNew
.begin();
181 i
!= libDepsNew
.end(); ++i
)
183 if(!i
->second
.empty())
185 fout
<< " SET(\"" << i
->first
<< "\" \"" << i
->second
<< "\")\n";
188 fout
<< "ELSE(" << vertest
<< ")\n";
189 fout
<< " # Information for CMake 2.4 and lower.\n";
190 for(std::map
<cmStdString
, cmStdString
>::const_iterator
191 i
= libDepsOld
.begin();
192 i
!= libDepsOld
.end(); ++i
)
194 if(!i
->second
.empty())
196 fout
<< " SET(\"" << i
->first
<< "\" \"" << i
->second
<< "\")\n";
199 for(std::map
<cmStdString
, cmStdString
>::const_iterator i
= libTypes
.begin();
200 i
!= libTypes
.end(); ++i
)
202 if(i
->second
!= "general")
204 fout
<< " SET(\"" << i
->first
<< "\" \"" << i
->second
<< "\")\n";
207 fout
<< "ENDIF(" << vertest
<< ")\n";