1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmSourceFileLocation.cxx,v $
6 Date: $Date: 2008-08-05 17:27:01 $
7 Version: $Revision: 1.8 $
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 "cmSourceFileLocation.h"
19 #include "cmMakefile.h"
20 #include "cmLocalGenerator.h"
21 #include "cmGlobalGenerator.h"
22 #include "cmSystemTools.h"
24 //----------------------------------------------------------------------------
26 ::cmSourceFileLocation(cmMakefile
* mf
, const char* name
): Makefile(mf
)
28 this->AmbiguousDirectory
= !cmSystemTools::FileIsFullPath(name
);
29 this->AmbiguousExtension
= true;
30 this->Directory
= cmSystemTools::GetFilenamePath(name
);
31 this->Name
= cmSystemTools::GetFilenameName(name
);
32 this->UpdateExtension(name
);
35 //----------------------------------------------------------------------------
36 void cmSourceFileLocation::Update(const char* name
)
38 if(this->AmbiguousDirectory
)
40 this->UpdateDirectory(name
);
42 if(this->AmbiguousExtension
)
44 this->UpdateExtension(name
);
48 //----------------------------------------------------------------------------
49 void cmSourceFileLocation::Update(cmSourceFileLocation
const& loc
)
51 if(this->AmbiguousDirectory
&& !loc
.AmbiguousDirectory
)
53 this->Directory
= loc
.Directory
;
54 this->AmbiguousDirectory
= false;
56 if(this->AmbiguousExtension
&& !loc
.AmbiguousExtension
)
58 this->Name
= loc
.Name
;
59 this->AmbiguousExtension
= false;
63 //----------------------------------------------------------------------------
64 void cmSourceFileLocation::DirectoryUseSource()
66 if(this->AmbiguousDirectory
)
69 cmSystemTools::CollapseFullPath(
70 this->Directory
.c_str(), this->Makefile
->GetCurrentDirectory());
71 this->AmbiguousDirectory
= false;
75 //----------------------------------------------------------------------------
76 void cmSourceFileLocation::DirectoryUseBinary()
78 if(this->AmbiguousDirectory
)
81 cmSystemTools::CollapseFullPath(
82 this->Directory
.c_str(), this->Makefile
->GetCurrentOutputDirectory());
83 this->AmbiguousDirectory
= false;
87 //----------------------------------------------------------------------------
88 void cmSourceFileLocation::UpdateExtension(const char* name
)
90 // Check the extension.
91 std::string ext
= cmSystemTools::GetFilenameLastExtension(name
);
92 if(!ext
.empty()) { ext
= ext
.substr(1); }
94 // The global generator checks extensions of enabled languages.
95 cmGlobalGenerator
* gg
=
96 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator();
97 cmMakefile
* mf
= this->Makefile
;
98 const std::vector
<std::string
>& srcExts
= mf
->GetSourceExtensions();
99 const std::vector
<std::string
>& hdrExts
= mf
->GetHeaderExtensions();
100 if(gg
->GetLanguageFromExtension(ext
.c_str()) ||
101 std::find(srcExts
.begin(), srcExts
.end(), ext
) != srcExts
.end() ||
102 std::find(hdrExts
.begin(), hdrExts
.end(), ext
) != hdrExts
.end())
104 // This is a known extension. Use the given filename with extension.
105 this->Name
= cmSystemTools::GetFilenameName(name
);
106 this->AmbiguousExtension
= false;
110 // This is not a known extension. See if the file exists on disk as
113 if(this->AmbiguousDirectory
)
115 // Check the source tree only because a file in the build tree should
116 // be specified by full path at least once. We do not want this
117 // detection to depend on whether the project has already been built.
118 tryPath
= this->Makefile
->GetCurrentDirectory();
121 if(!this->Directory
.empty())
123 tryPath
+= this->Directory
;
126 tryPath
+= this->Name
;
127 if(cmSystemTools::FileExists(tryPath
.c_str(), true))
129 // We found a source file named by the user on disk. Trust it's
131 this->Name
= cmSystemTools::GetFilenameName(name
);
132 this->AmbiguousExtension
= false;
134 // If the directory was ambiguous, it isn't anymore.
135 if(this->AmbiguousDirectory
)
137 this->DirectoryUseSource();
143 //----------------------------------------------------------------------------
144 void cmSourceFileLocation::UpdateDirectory(const char* name
)
146 // If a full path was given we know the directory.
147 if(cmSystemTools::FileIsFullPath(name
))
149 this->Directory
= cmSystemTools::GetFilenamePath(name
);
150 this->AmbiguousDirectory
= false;
154 //----------------------------------------------------------------------------
157 ::MatchesAmbiguousExtension(cmSourceFileLocation
const& loc
) const
159 // This location's extension is not ambiguous but loc's extension
160 // is. See if the names match as-is.
161 if(this->Name
== loc
.Name
)
166 // Check if loc's name could possibly be extended to our name by
167 // adding an extension.
168 if(!(this->Name
.size() > loc
.Name
.size() &&
169 this->Name
.substr(0, loc
.Name
.size()) == loc
.Name
&&
170 this->Name
[loc
.Name
.size()] == '.'))
175 // Only a fixed set of extensions will be tried to match a file on
176 // disk. One of these must match if loc refers to this source file.
177 std::string ext
= this->Name
.substr(loc
.Name
.size()+1);
178 cmMakefile
* mf
= this->Makefile
;
179 const std::vector
<std::string
>& srcExts
= mf
->GetSourceExtensions();
180 if(std::find(srcExts
.begin(), srcExts
.end(), ext
) != srcExts
.end())
184 const std::vector
<std::string
>& hdrExts
= mf
->GetHeaderExtensions();
185 if(std::find(hdrExts
.begin(), hdrExts
.end(), ext
) != hdrExts
.end())
192 //----------------------------------------------------------------------------
193 bool cmSourceFileLocation::Matches(cmSourceFileLocation
const& loc
)
195 if(this->AmbiguousExtension
&& loc
.AmbiguousExtension
)
197 // Both extensions are ambiguous. Since only the old fixed set of
198 // extensions will be tried, the names must match at this point to
200 if(this->Name
!= loc
.Name
)
205 else if(this->AmbiguousExtension
)
207 // Only "this" extension is ambiguous.
208 if(!loc
.MatchesAmbiguousExtension(*this))
213 else if(loc
.AmbiguousExtension
)
215 // Only "loc" extension is ambiguous.
216 if(!this->MatchesAmbiguousExtension(loc
))
223 // Neither extension is ambiguous.
224 if(this->Name
!= loc
.Name
)
230 if(!this->AmbiguousDirectory
&& !loc
.AmbiguousDirectory
)
232 // Both sides have absolute directories.
233 if(this->Directory
!= loc
.Directory
)
238 else if(this->AmbiguousDirectory
&& loc
.AmbiguousDirectory
&&
239 this->Makefile
== loc
.Makefile
)
241 // Both sides have directories relative to the same location.
242 if(this->Directory
!= loc
.Directory
)
247 else if(this->AmbiguousDirectory
&& loc
.AmbiguousDirectory
)
249 // Each side has a directory relative to a different location.
250 // This can occur when referencing a source file from a different
251 // directory. This is not yet allowed.
252 this->Makefile
->IssueMessage(
253 cmake::INTERNAL_ERROR
,
254 "Matches error: Each side has a directory relative to a different "
255 "location. This can occur when referencing a source file from a "
256 "different directory. This is not yet allowed."
260 else if(this->AmbiguousDirectory
)
262 // Compare possible directory combinations.
264 cmSystemTools::CollapseFullPath(
265 this->Directory
.c_str(), this->Makefile
->GetCurrentDirectory());
267 cmSystemTools::CollapseFullPath(
268 this->Directory
.c_str(), this->Makefile
->GetCurrentOutputDirectory());
269 if(srcDir
!= loc
.Directory
&&
270 binDir
!= loc
.Directory
)
275 else if(loc
.AmbiguousDirectory
)
277 // Compare possible directory combinations.
279 cmSystemTools::CollapseFullPath(
280 loc
.Directory
.c_str(), loc
.Makefile
->GetCurrentDirectory());
282 cmSystemTools::CollapseFullPath(
283 loc
.Directory
.c_str(), loc
.Makefile
->GetCurrentOutputDirectory());
284 if(srcDir
!= this->Directory
&&
285 binDir
!= this->Directory
)
291 // File locations match.