1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
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"
15 #include "cmMakefile.h"
16 #include "cmLocalGenerator.h"
17 #include "cmGlobalGenerator.h"
18 #include "cmSourceFile.h"
20 //----------------------------------------------------------------------------
21 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
23 this->Makefile = this->Target->GetMakefile();
24 this->LocalGenerator = this->Makefile->GetLocalGenerator();
25 this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
26 this->ClassifySources();
27 this->LookupObjectLibraries();
30 //----------------------------------------------------------------------------
31 void cmGeneratorTarget::ClassifySources()
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)
40 cmSourceFile* sf = *si;
41 std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
42 if(sf->GetCustomCommand())
44 this->CustomCommands.push_back(sf);
46 else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
48 this->HeaderSources.push_back(sf);
50 else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
52 this->ExternalObjects.push_back(sf);
53 if(isObjLib) { badObjLib.push_back(sf); }
55 else if(sf->GetLanguage())
57 this->ObjectSources.push_back(sf);
61 this->ModuleDefinitionFile = sf->GetFullPath();
62 if(isObjLib) { badObjLib.push_back(sf); }
66 this->IDLSources.push_back(sf);
67 if(isObjLib) { badObjLib.push_back(sf); }
69 else if(header.find(sf->GetFullPath().c_str()))
71 this->HeaderSources.push_back(sf);
73 else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
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);
82 this->ExtraSources.push_back(sf);
83 if(isObjLib && ext != "txt")
85 badObjLib.push_back(sf);
90 if(!badObjLib.empty())
93 e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
94 for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
95 i != badObjLib.end(); ++i)
97 e << " " << (*i)->GetLocation().GetName() << "\n";
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());
106 //----------------------------------------------------------------------------
107 void cmGeneratorTarget::LookupObjectLibraries()
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)
114 std::string const& objLibName = *oli;
115 if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
117 if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
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)
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());
131 this->Target->AddUtility(objLib->GetName());
132 this->ObjectLibraries.push_back(objLib);
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());
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());
158 //----------------------------------------------------------------------------
159 void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
161 for(std::vector<cmTarget*>::const_iterator
162 ti = this->ObjectLibraries.begin();
163 ti != this->ObjectLibraries.end(); ++ti)
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)
172 std::string obj = ogt->ObjectDirectory;
173 obj += ogt->Objects[*si];