Fix Xcode project references to the source tree
[cmake.git] / Source / cmTargetLinkLibrariesCommand.cxx
blob6396a2bce36de224a59a29e1f07dc3d35c31f21d
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmTargetLinkLibrariesCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2008-09-04 21:34:24 $
7 Version: $Revision: 1.29 $
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 "cmTargetLinkLibrariesCommand.h"
19 const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] =
21 "general",
22 "debug",
23 "optimized"
26 // cmTargetLinkLibrariesCommand
27 bool cmTargetLinkLibrariesCommand
28 ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
30 // must have one argument
31 if(args.size() < 1)
33 this->SetError("called with incorrect number of arguments");
34 return false;
37 // but we might not have any libs after variable expansion
38 if(args.size() < 2)
40 return true;
43 // Lookup the target for which libraries are specified.
44 this->Target =
45 this->Makefile->GetCMakeInstance()
46 ->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
47 if(!this->Target)
49 cmOStringStream e;
50 e << "Cannot specify link libraries for target \"" << args[0] << "\" "
51 << "which is not built by this project.";
52 this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
53 cmSystemTools::SetFatalErrorOccured();
54 return true;
57 // Keep track of link configuration specifiers.
58 cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
59 bool haveLLT = false;
61 // Start with primary linking and switch to link interface
62 // specification when the keyword is encountered.
63 this->DoingInterface = false;
65 // add libraries, nothe that there is an optional prefix
66 // of debug and optimized than can be used
67 for(unsigned int i=1; i < args.size(); ++i)
69 if(args[i] == "LINK_INTERFACE_LIBRARIES")
71 this->DoingInterface = true;
72 if(i != 1)
74 this->Makefile->IssueMessage(
75 cmake::FATAL_ERROR,
76 "The LINK_INTERFACE_LIBRARIES option must appear as the second "
77 "argument, just after the target name."
79 return true;
82 else if(args[i] == "debug")
84 if(haveLLT)
86 this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::DEBUG);
88 llt = cmTarget::DEBUG;
89 haveLLT = true;
91 else if(args[i] == "optimized")
93 if(haveLLT)
95 this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::OPTIMIZED);
97 llt = cmTarget::OPTIMIZED;
98 haveLLT = true;
100 else if(args[i] == "general")
102 if(haveLLT)
104 this->LinkLibraryTypeSpecifierWarning(llt, cmTarget::GENERAL);
106 llt = cmTarget::GENERAL;
107 haveLLT = true;
109 else if(haveLLT)
111 // The link type was specified by the previous argument.
112 haveLLT = false;
113 this->HandleLibrary(args[i].c_str(), llt);
115 else
117 // Lookup old-style cache entry if type is unspecified. So if you
118 // do a target_link_libraries(foo optimized bar) it will stay optimized
119 // and not use the lookup. As there maybe the case where someone has
120 // specifed that a library is both debug and optimized. (this check is
121 // only there for backwards compatibility when mixing projects built
122 // with old versions of CMake and new)
123 llt = cmTarget::GENERAL;
124 std::string linkType = args[0];
125 linkType += "_LINK_TYPE";
126 const char* linkTypeString =
127 this->Makefile->GetDefinition( linkType.c_str() );
128 if(linkTypeString)
130 if(strcmp(linkTypeString, "debug") == 0)
132 llt = cmTarget::DEBUG;
134 if(strcmp(linkTypeString, "optimized") == 0)
136 llt = cmTarget::OPTIMIZED;
139 this->HandleLibrary(args[i].c_str(), llt);
143 // Make sure the last argument was not a library type specifier.
144 if(haveLLT)
146 cmOStringStream e;
147 e << "The \"" << this->LinkLibraryTypeNames[llt]
148 << "\" argument must be followed by a library.";
149 this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
150 cmSystemTools::SetFatalErrorOccured();
153 // If the INTERFACE option was given, make sure the
154 // LINK_INTERFACE_LIBRARIES property exists. This allows the
155 // command to be used to specify an empty link interface.
156 if(this->DoingInterface &&
157 !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES"))
159 this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
162 return true;
165 //----------------------------------------------------------------------------
166 void
167 cmTargetLinkLibrariesCommand
168 ::LinkLibraryTypeSpecifierWarning(int left, int right)
170 cmOStringStream w;
171 w << "Link library type specifier \""
172 << this->LinkLibraryTypeNames[left] << "\" is followed by specifier \""
173 << this->LinkLibraryTypeNames[right] << "\" instead of a library name. "
174 << "The first specifier will be ignored.";
175 this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
178 //----------------------------------------------------------------------------
179 void
180 cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
181 cmTarget::LinkLibraryType llt)
183 // Handle normal case first.
184 if(!this->DoingInterface)
186 this->Makefile
187 ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
188 return;
191 // Get the list of configurations considered to be DEBUG.
192 std::vector<std::string> const& debugConfigs =
193 this->Makefile->GetCMakeInstance()->GetDebugConfigs();
194 std::string prop;
196 // Include this library in the link interface for the target.
197 if(llt == cmTarget::DEBUG || llt == cmTarget::GENERAL)
199 // Put in the DEBUG configuration interfaces.
200 for(std::vector<std::string>::const_iterator i = debugConfigs.begin();
201 i != debugConfigs.end(); ++i)
203 prop = "LINK_INTERFACE_LIBRARIES_";
204 prop += *i;
205 this->Target->AppendProperty(prop.c_str(), lib);
208 if(llt == cmTarget::OPTIMIZED || llt == cmTarget::GENERAL)
210 // Put in the non-DEBUG configuration interfaces.
211 this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
213 // Make sure the DEBUG configuration interfaces exist so that the
214 // general one will not be used as a fall-back.
215 for(std::vector<std::string>::const_iterator i = debugConfigs.begin();
216 i != debugConfigs.end(); ++i)
218 prop = "LINK_INTERFACE_LIBRARIES_";
219 prop += *i;
220 if(!this->Target->GetProperty(prop.c_str()))
222 this->Target->SetProperty(prop.c_str(), "");