1 /*=========================================================================
3 Program: Insight Segmentation & Registration Toolkit
4 Module: $RCSfile: cmTarget.cxx,v $
6 Date: $Date: 2002-10-06 16:12:59 $
7 Version: $Revision: 1.38 $
9 Copyright (c) 2002 Insight Consortium. All rights reserved.
10 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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 =========================================================================*/
18 #include "cmMakefile.h"
19 #include "cmSourceFile.h"
25 void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile
&mf
)
27 // this is only done for non install targets
28 if ((this->m_TargetType
== cmTarget::INSTALL_FILES
)
29 || (this->m_TargetType
== cmTarget::INSTALL_PROGRAMS
))
34 // for each src lists add the classes
35 for (std::vector
<std::string
>::const_iterator s
= m_SourceLists
.begin();
36 s
!= m_SourceLists
.end(); ++s
)
39 // replace any variables
40 std::string temps
= *s
;
41 mf
.ExpandVariablesInString(temps
);
43 // Next if one wasn't found then assume it is a single class
44 if (!done
&& mf
.GetSource(temps
.c_str()))
46 m_SourceFiles
.push_back(mf
.GetSource(temps
.c_str()));
50 // if it wasn't a source file listed with the makefile
51 // see if it is a variable. This is for old CMake 1.2 compatability
52 // where a source list would be passed into here, by making it
53 // a vector we need to possibly lookup the variable to maintain
54 // CMake 1.2 compatability.
55 const char* versionValue
56 = mf
.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
59 if (!versionValue
|| atof(versionValue
) <= 1.2)
61 const char* varValue
=
62 mf
.GetDefinition(temps
.c_str());
63 // if the definition exists
66 std::vector
<std::string
> tval
;
67 tval
.push_back(varValue
);
68 std::vector
<std::string
> args
;
69 cmSystemTools::ExpandListArguments(tval
, args
);
71 for (i
= 0; i
< args
.size(); ++i
)
73 if (mf
.GetSource(args
[i
].c_str()))
75 m_SourceFiles
.push_back(mf
.GetSource(args
[i
].c_str()));
80 file
.SetProperty("ABSTRACT","0");
81 file
.SetName(args
[i
].c_str(), mf
.GetCurrentDirectory(),
82 mf
.GetSourceExtensions(),
83 mf
.GetHeaderExtensions());
84 m_SourceFiles
.push_back(mf
.AddSource(file
));
92 // if we still are not done, try to create the SourceFile structure
96 file
.SetProperty("ABSTRACT","0");
97 file
.SetName(temps
.c_str(), mf
.GetCurrentDirectory(),
98 mf
.GetSourceExtensions(),
99 mf
.GetHeaderExtensions());
100 m_SourceFiles
.push_back(mf
.AddSource(file
));
105 // expand any link library variables whle we are at it
106 LinkLibraries::iterator p
= m_LinkLibraries
.begin();
107 for (;p
!= m_LinkLibraries
.end(); ++p
)
109 mf
.ExpandVariablesInString(p
->first
);
114 void cmTarget::MergeLinkLibraries( cmMakefile
& mf
,
115 const char *selfname
,
116 const LinkLibraries
& libs
)
118 // Only add on libraries we haven't added on before.
119 // Assumption: the global link libraries could only grow, never shrink
120 LinkLibraries::const_iterator i
= libs
.begin();
121 i
+= m_PrevLinkedLibraries
.size();
122 for( ; i
!= libs
.end(); ++i
)
124 // We call this so that the dependencies get written to the cache
125 this->AddLinkLibrary( mf
, selfname
, i
->first
.c_str(), i
->second
);
127 m_PrevLinkedLibraries
= libs
;
130 void cmTarget::AddLinkDirectory(const char* d
)
132 // Make sure we don't add unnecessary search directories.
133 if( std::find( m_LinkDirectories
.begin(), m_LinkDirectories
.end(), d
)
134 == m_LinkDirectories
.end() )
135 m_LinkDirectories
.push_back( d
);
140 void cmTarget::AddLinkLibrary(const std::string
& lib
,
143 m_LinkLibraries
.push_back( std::pair
<std::string
, cmTarget::LinkLibraryType
>(lib
,llt
) );
146 void cmTarget::AddLinkLibrary(cmMakefile
& mf
,
147 const char *target
, const char* lib
,
150 // Never add a self dependency, even if the user asks for it.
151 if(strcmp( target
, lib
) == 0)
156 m_LinkLibraries
.push_back( std::pair
<std::string
, cmTarget::LinkLibraryType
>(lib
,llt
) );
158 if(llt
!= cmTarget::GENERAL
)
160 std::string linkTypeName
= lib
;
161 linkTypeName
+= "_LINK_TYPE";
164 case cmTarget::DEBUG
:
165 mf
.AddCacheDefinition(linkTypeName
.c_str(),
166 "debug", "Library is used for debug links only",
167 cmCacheManager::STATIC
);
169 case cmTarget::OPTIMIZED
:
170 mf
.AddCacheDefinition(linkTypeName
.c_str(),
171 "optimized", "Library is used for debug links only",
172 cmCacheManager::STATIC
);
174 case cmTarget::GENERAL
: break;
177 // Add the explicit dependency information for this target. This is
178 // simply a set of libraries separated by ";". There should always
179 // be a trailing ";". These library names are not canonical, in that
180 // they may be "-framework x", "-ly", "/path/libz.a", etc.
181 // only add depend information for library targets
182 if(m_TargetType
>= STATIC_LIBRARY
&& m_TargetType
<= MODULE_LIBRARY
)
184 std::string targetEntry
= target
;
185 targetEntry
+= "_LIB_DEPENDS";
186 std::string dependencies
;
187 const char* old_val
= mf
.GetDefinition( targetEntry
.c_str() );
190 dependencies
+= old_val
;
192 if( dependencies
.find( lib
) == std::string::npos
)
197 mf
.AddCacheDefinition( targetEntry
.c_str(), dependencies
.c_str(),
198 "Dependencies for the target",
199 cmCacheManager::STATIC
);
204 bool cmTarget::HasCxx() const
206 for(std::vector
<cmSourceFile
*>::const_iterator i
= m_SourceFiles
.begin();
207 i
!= m_SourceFiles
.end(); ++i
)
209 if((*i
)->GetSourceExtension() != "c" &&
210 (*i
)->GetSourceExtension() != "h")
223 cmTarget::AnalyzeLibDependencies( const cmMakefile
& mf
)
225 // There are two key parts of the dependency analysis: (1)
226 // determining the libraries in the link line, and (2) constructing
227 // the dependency graph for those libraries.
229 // The latter is done using the cache entries that record the
230 // dependencies of each library.
232 // The former is a more thorny issue, since it is not clear how to
233 // determine if two libraries listed on the link line refer to the a
234 // single library or not. For example, consider the link "libraries"
235 // /usr/lib/libtiff.so -ltiff
236 // Is this one library or two? The solution implemented here is the
237 // simplest (and probably the only practical) one: two libraries are
238 // the same if their "link strings" are identical. Thus, the two
239 // libraries above are considered distinct. This also means that for
240 // dependency analysis to be effective, the CMake user must specify
241 // libraries build by his project without using any linker flags or
242 // file extensions. That is,
243 // LINK_LIBRARIES( One Two )
245 // LINK_LIBRARIES( -lOne ${binarypath}/libTwo.a )
246 // The former is probably what most users would do, but it never
247 // hurts to document the assumptions. :-) Therefore, in the analysis
248 // code, the "canonical name" of a library is simply its name as
249 // given to a LINK_LIBRARIES command.
251 // Also, we will leave the original link line intact; we will just add any
252 // dependencies that were missing.
254 typedef std::vector
< std::string
> LinkLine
;
256 // The dependency map.
257 DependencyMap dep_map
;
259 // Keeps track of which dependencies have already been emitted for a given
260 // target. This could be via this function, or because they were already
261 // satisfied on the original link line.
262 DependencyMap satisfied
;
264 // If LIBRARY_OUTPUT_PATH is not set, then we must add search paths
265 // for all the new libraries added by the dependency analysis.
266 const char* libOutPath
= mf
.GetDefinition("LIBRARY_OUTPUT_PATH");
267 bool addLibDirs
= (libOutPath
==0 || strcmp(libOutPath
,"")==0);
269 // 1. Determine the dependencies already satisfied by the original link
271 for(LinkLibraries::iterator lib
= m_LinkLibraries
.begin();
272 lib
!= m_LinkLibraries
.end(); ++lib
)
274 for( LinkLibraries::iterator lib2
= lib
;
275 lib2
!= m_LinkLibraries
.end(); ++lib2
)
277 satisfied
[ lib
->first
].insert( lib2
->first
);
281 // 2. Build the explicit dependency map
282 for(LinkLibraries::reverse_iterator lib
= m_LinkLibraries
.rbegin();
283 lib
!= m_LinkLibraries
.rend(); ++lib
)
285 this->GatherDependencies( mf
, lib
->first
, dep_map
);
288 // 3. Create the new link line by simply emitting any dependencies that are
289 // missing. Start from the back and keep adding.
291 std::set
<cmStdString
> done
, visited
;
292 std::vector
<std::string
> newLinkLibraries
;
293 for(LinkLibraries::reverse_iterator lib
= m_LinkLibraries
.rbegin();
294 lib
!= m_LinkLibraries
.rend(); ++lib
)
296 // skip zero size library entries, this may happen
297 // if a variable expands to nothing.
298 if (lib
->first
.size() == 0) continue;
300 // Emit all the dependencies that are not already satisfied on the
301 // original link line.
302 if( dep_map
.find(lib
->first
) != dep_map
.end() ) // does it have dependencies?
304 const std::set
<cmStdString
>& dep_on
= dep_map
.find( lib
->first
)->second
;
305 std::set
<cmStdString
>::const_iterator i
;
306 for( i
= dep_on
.begin(); i
!= dep_on
.end(); ++i
)
308 if( satisfied
[lib
->first
].end() == satisfied
[lib
->first
].find( *i
) )
310 Emit( *i
, dep_map
, done
, visited
, newLinkLibraries
);
316 // 4. Add the new libraries to the link line.
318 for( std::vector
<std::string
>::reverse_iterator k
= newLinkLibraries
.rbegin();
319 k
!= newLinkLibraries
.rend(); ++k
)
323 // who the hell knows what this is, I think that K contains the
324 // name of a library but ... Ken
325 std::string libPathStr
= *k
+ "_CMAKE_PATH";
326 const char* libpath
= mf
.GetDefinition( libPathStr
.c_str() );
329 // Don't add a link directory that is already present.
330 if(std::find(m_LinkDirectories
.begin(),
331 m_LinkDirectories
.end(), libpath
) == m_LinkDirectories
.end())
333 m_LinkDirectories
.push_back(libpath
);
337 std::string linkType
= *k
;
338 linkType
+= "_LINK_TYPE";
339 cmTarget::LinkLibraryType llt
= cmTarget::GENERAL
;
340 const char* linkTypeString
= mf
.GetDefinition( linkType
.c_str() );
343 if(strcmp(linkTypeString
, "debug") == 0)
345 llt
= cmTarget::DEBUG
;
347 if(strcmp(linkTypeString
, "optimized") == 0)
349 llt
= cmTarget::OPTIMIZED
;
352 m_LinkLibraries
.push_back( std::make_pair(*k
,llt
) );
359 void cmTarget::Emit( const std::string
& lib
,
360 const DependencyMap
& dep_map
,
361 std::set
<cmStdString
>& emitted
,
362 std::set
<cmStdString
>& visited
,
363 std::vector
<std::string
>& link_line
) const
365 // It's already been emitted
366 if( emitted
.find(lib
) != emitted
.end() )
371 // If this library hasn't been visited before, then emit all its
372 // dependencies before emitting the library itself. If it has been
373 // visited before, then there is a dependency cycle. Just emit the
374 // library itself, and let the recursion that got us here deal with
375 // emitting the dependencies for the library.
377 if( visited
.insert(lib
).second
)
379 if( dep_map
.find(lib
) != dep_map
.end() ) // does it have dependencies?
381 const std::set
<cmStdString
>& dep_on
= dep_map
.find( lib
)->second
;
382 std::set
<cmStdString
>::const_iterator i
;
383 for( i
= dep_on
.begin(); i
!= dep_on
.end(); ++i
)
385 Emit( *i
, dep_map
, emitted
, visited
, link_line
);
389 link_line
.push_back( lib
);
394 void cmTarget::GatherDependencies( const cmMakefile
& mf
,
395 const std::string
& lib
,
396 DependencyMap
& dep_map
)
398 // If the library is already in the dependency map, then it has
399 // already been fully processed.
400 if( dep_map
.find(lib
) != dep_map
.end() )
403 const char* deps
= mf
.GetDefinition( (lib
+"_LIB_DEPENDS").c_str() );
404 if( deps
&& strcmp(deps
,"") != 0 )
406 // Make sure this library is in the map, even if it has an empty
407 // set of dependencies. This distinguishes the case of explicitly
408 // no dependencies with that of unspecified dependencies.
411 // Parse the dependency information, which is simply a set of
412 // libraries separated by ";". There is always a trailing ";".
413 std::string depline
= deps
;
414 std::string::size_type start
= 0;
415 std::string::size_type end
;
416 end
= depline
.find( ";", start
);
417 while( end
!= std::string::npos
)
419 std::string l
= depline
.substr( start
, end
-start
);
422 dep_map
[ lib
].insert( l
);
423 GatherDependencies( mf
, l
, dep_map
);
425 start
= end
+1; // skip the ;
426 end
= depline
.find( ";", start
);
428 dep_map
[lib
].erase(lib
); // cannot depend on itself
433 // return true if lib1 depends on lib2
435 bool cmTarget::DependsOn( const std::string
& lib1
, const std::string
& lib2
,
436 const DependencyMap
& dep_map
,
437 std::set
<cmStdString
>& visited
) const
439 if( !visited
.insert( lib1
).second
)
441 return false; // already visited here
450 if( dep_map
.find(lib1
) == dep_map
.end() )
452 return false; // lib1 doesn't have any dependencies
455 const std::set
<cmStdString
>& dep_set
= dep_map
.find(lib1
)->second
;
457 if( dep_set
.end() != dep_set
.find( lib2
) )
459 return true; // lib1 doesn't directly depend on lib2.
462 // Do a recursive check: does lib1 depend on x which depends on lib2?
463 for( std::set
<cmStdString
>::const_iterator itr
= dep_set
.begin();
464 itr
!= dep_set
.end(); ++itr
)
466 if( this->DependsOn( *itr
, lib2
, dep_map
, visited
) )