Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmGeneratorTarget.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmGeneratorTarget.h"
13
14 #include "cmTarget.h"
15 #include "cmMakefile.h"
16 #include "cmLocalGenerator.h"
17 #include "cmGlobalGenerator.h"
18 #include "cmSourceFile.h"
19
20 //----------------------------------------------------------------------------
21 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
22 {
23   this->Makefile = this->Target->GetMakefile();
24   this->LocalGenerator = this->Makefile->GetLocalGenerator();
25   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
26   this->ClassifySources();
27   this->LookupObjectLibraries();
28 }
29
30 //----------------------------------------------------------------------------
31 void cmGeneratorTarget::ClassifySources()
32 {
33   cmsys::RegularExpression header(CM_HEADER_REGEX);
34   bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY;
35   std::vector<cmSourceFile*> badObjLib;
36   std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
37   for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
38       si != sources.end(); ++si)
39     {
40     cmSourceFile* sf = *si;
41     std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
42     if(sf->GetCustomCommand())
43       {
44       this->CustomCommands.push_back(sf);
45       }
46     else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
47       {
48       this->HeaderSources.push_back(sf);
49       }
50     else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
51       {
52       this->ExternalObjects.push_back(sf);
53       if(isObjLib) { badObjLib.push_back(sf); }
54       }
55     else if(sf->GetLanguage())
56       {
57       this->ObjectSources.push_back(sf);
58       }
59     else if(ext == "def")
60       {
61       this->ModuleDefinitionFile = sf->GetFullPath();
62       if(isObjLib) { badObjLib.push_back(sf); }
63       }
64     else if(ext == "idl")
65       {
66       this->IDLSources.push_back(sf);
67       if(isObjLib) { badObjLib.push_back(sf); }
68       }
69     else if(header.find(sf->GetFullPath().c_str()))
70       {
71       this->HeaderSources.push_back(sf);
72       }
73     else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
74       {
75       // We only get here if a source file is not an external object
76       // and has an extension that is listed as an ignored file type.
77       // No message or diagnosis should be given.
78       this->ExtraSources.push_back(sf);
79       }
80     else
81       {
82       this->ExtraSources.push_back(sf);
83       if(isObjLib && ext != "txt")
84         {
85         badObjLib.push_back(sf);
86         }
87       }
88     }
89
90   if(!badObjLib.empty())
91     {
92     cmOStringStream e;
93     e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
94     for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
95         i != badObjLib.end(); ++i)
96       {
97       e << "  " << (*i)->GetLocation().GetName() << "\n";
98       }
99     e << "but may contain only headers and sources that compile.";
100     this->GlobalGenerator->GetCMakeInstance()
101       ->IssueMessage(cmake::FATAL_ERROR, e.str(),
102                      this->Target->GetBacktrace());
103     }
104 }
105
106 //----------------------------------------------------------------------------
107 void cmGeneratorTarget::LookupObjectLibraries()
108 {
109   std::vector<std::string> const& objLibs =
110     this->Target->GetObjectLibraries();
111   for(std::vector<std::string>::const_iterator oli = objLibs.begin();
112       oli != objLibs.end(); ++oli)
113     {
114     std::string const& objLibName = *oli;
115     if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
116       {
117       if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
118         {
119         if(this->Target->GetType() != cmTarget::EXECUTABLE &&
120            this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
121            this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
122            this->Target->GetType() != cmTarget::MODULE_LIBRARY)
123           {
124           this->GlobalGenerator->GetCMakeInstance()
125             ->IssueMessage(cmake::FATAL_ERROR,
126                            "Only executables and non-OBJECT libraries may "
127                            "reference target objects.",
128                            this->Target->GetBacktrace());
129           return;
130           }
131         this->Target->AddUtility(objLib->GetName());
132         this->ObjectLibraries.push_back(objLib);
133         }
134       else
135         {
136         cmOStringStream e;
137         e << "Objects of target \"" << objLibName
138           << "\" referenced but is not an OBJECT library.";
139         this->GlobalGenerator->GetCMakeInstance()
140           ->IssueMessage(cmake::FATAL_ERROR, e.str(),
141                          this->Target->GetBacktrace());
142         return;
143         }
144       }
145     else
146       {
147       cmOStringStream e;
148       e << "Objects of target \"" << objLibName
149         << "\" referenced but no such target exists.";
150       this->GlobalGenerator->GetCMakeInstance()
151         ->IssueMessage(cmake::FATAL_ERROR, e.str(),
152                        this->Target->GetBacktrace());
153       return;
154       }
155     }
156 }
157
158 //----------------------------------------------------------------------------
159 void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
160 {
161   for(std::vector<cmTarget*>::const_iterator
162         ti = this->ObjectLibraries.begin();
163       ti != this->ObjectLibraries.end(); ++ti)
164     {
165     cmTarget* objLib = *ti;
166     cmGeneratorTarget* ogt =
167       this->GlobalGenerator->GetGeneratorTarget(objLib);
168     for(std::vector<cmSourceFile*>::const_iterator
169           si = ogt->ObjectSources.begin();
170         si != ogt->ObjectSources.end(); ++si)
171       {
172       std::string obj = ogt->ObjectDirectory;
173       obj += ogt->Objects[*si];
174       objs.push_back(obj);
175       }
176     }
177 }