Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmAddLibraryCommand.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 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 "cmAddLibraryCommand.h"
13
14 #include "cmake.h"
15
16 // cmLibraryCommand
17 bool cmAddLibraryCommand
18 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
19 {
20   if(args.size() < 1 )
21     {
22     this->SetError("called with incorrect number of arguments");
23     return false;
24     }
25   // Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
26   // otherwise it defaults to static library.
27   cmTarget::TargetType type = cmTarget::SHARED_LIBRARY;
28   if (cmSystemTools::IsOff(this->Makefile->GetDefinition("BUILD_SHARED_LIBS")))
29     {
30     type = cmTarget::STATIC_LIBRARY;
31     }
32   bool excludeFromAll = false;
33   bool importTarget = false;
34   bool importGlobal = false;
35
36   std::vector<std::string>::const_iterator s = args.begin();
37
38   std::string libName = *s;
39
40   ++s;
41
42   // If the second argument is "SHARED" or "STATIC", then it controls
43   // the type of library.  Otherwise, it is treated as a source or
44   // source list name. There may be two keyword arguments, check for them
45   bool haveSpecifiedType = false;
46   while ( s != args.end() )
47     {
48     std::string libType = *s;
49     if(libType == "STATIC")
50       {
51       ++s;
52       type = cmTarget::STATIC_LIBRARY;
53       haveSpecifiedType = true;
54       }
55     else if(libType == "SHARED")
56       {
57       ++s;
58       type = cmTarget::SHARED_LIBRARY;
59       haveSpecifiedType = true;
60       }
61     else if(libType == "MODULE")
62       {
63       ++s;
64       type = cmTarget::MODULE_LIBRARY;
65       haveSpecifiedType = true;
66       }
67     else if(libType == "OBJECT")
68       {
69       ++s;
70       type = cmTarget::OBJECT_LIBRARY;
71       haveSpecifiedType = true;
72       }
73     else if(libType == "UNKNOWN")
74       {
75       ++s;
76       type = cmTarget::UNKNOWN_LIBRARY;
77       haveSpecifiedType = true;
78       }
79     else if(*s == "EXCLUDE_FROM_ALL")
80       {
81       ++s;
82       excludeFromAll = true;
83       }
84     else if(*s == "IMPORTED")
85       {
86       ++s;
87       importTarget = true;
88       }
89     else if(importTarget && *s == "GLOBAL")
90       {
91       ++s;
92       importGlobal = true;
93       }
94     else
95       {
96       break;
97       }
98     }
99
100   /* ideally we should check whether for the linker language of the target
101     CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
102     STATIC. But at this point we know only the name of the target, but not
103     yet its linker language. */
104   if ((type != cmTarget::STATIC_LIBRARY) &&
105       (type != cmTarget::OBJECT_LIBRARY) &&
106        (this->Makefile->GetCMakeInstance()->GetPropertyAsBool(
107                                       "TARGET_SUPPORTS_SHARED_LIBS") == false))
108     {
109     cmOStringStream w;
110     w <<
111       "ADD_LIBRARY called with " <<
112       (type==cmTarget::SHARED_LIBRARY ? "SHARED" : "MODULE") <<
113       " option but the target platform does not support dynamic linking. "
114       "Building a STATIC library instead. This may lead to problems.";
115     this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
116     type = cmTarget::STATIC_LIBRARY;
117     }
118
119   // Handle imported target creation.
120   if(importTarget)
121     {
122     // The IMPORTED signature requires a type to be specified explicitly.
123     if (!haveSpecifiedType)
124       {
125       this->SetError("called with IMPORTED argument but no library type.");
126       return false;
127       }
128     if(type == cmTarget::OBJECT_LIBRARY)
129       {
130       this->Makefile->IssueMessage(
131         cmake::FATAL_ERROR,
132         "The OBJECT library type may not be used for IMPORTED libraries."
133         );
134       return true;
135       }
136
137     // Make sure the target does not already exist.
138     if(this->Makefile->FindTargetToUse(libName.c_str()))
139       {
140       cmOStringStream e;
141       e << "cannot create imported target \"" << libName
142         << "\" because another target with the same name already exists.";
143       this->SetError(e.str().c_str());
144       return false;
145       }
146
147     // Create the imported target.
148     this->Makefile->AddImportedTarget(libName.c_str(), type, importGlobal);
149     return true;
150     }
151
152   // A non-imported target may not have UNKNOWN type.
153   if(type == cmTarget::UNKNOWN_LIBRARY)
154     {
155     this->Makefile->IssueMessage(
156       cmake::FATAL_ERROR,
157       "The UNKNOWN library type may be used only for IMPORTED libraries."
158       );
159     return true;
160     }
161
162   // Enforce name uniqueness.
163   {
164   std::string msg;
165   if(!this->Makefile->EnforceUniqueName(libName, msg))
166     {
167     this->SetError(msg.c_str());
168     return false;
169     }
170   }
171
172   if (s == args.end())
173     {
174     std::string msg = "You have called ADD_LIBRARY for library ";
175     msg += args[0];
176     msg += " without any source files. This typically indicates a problem ";
177     msg += "with your CMakeLists.txt file";
178     cmSystemTools::Message(msg.c_str() ,"Warning");
179     }
180
181   std::vector<std::string> srclists;
182   while (s != args.end())
183     {
184     srclists.push_back(*s);
185     ++s;
186     }
187
188   this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll);
189
190   return true;
191 }
192
193