cmGeneratorTarget.cxx 102 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2012 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmGeneratorTarget.h"
  11. #include "cmTarget.h"
  12. #include "cmMakefile.h"
  13. #include "cmLocalGenerator.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmSourceFile.h"
  16. #include "cmGeneratorExpression.h"
  17. #include "cmGeneratorExpressionDAGChecker.h"
  18. #include "cmComputeLinkInformation.h"
  19. #include "cmCustomCommandGenerator.h"
  20. #include "cmAlgorithms.h"
  21. #include <queue>
  22. #include <errno.h>
  23. #include "assert.h"
  24. #if defined(CMAKE_BUILD_WITH_CMAKE)
  25. #include <cmsys/hash_set.hxx>
  26. #define UNORDERED_SET cmsys::hash_set
  27. #else
  28. #define UNORDERED_SET std::set
  29. #endif
  30. //----------------------------------------------------------------------------
  31. void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
  32. cmTarget *target, cmake *cm)
  33. {
  34. if(!badObjLib.empty())
  35. {
  36. std::ostringstream e;
  37. e << "OBJECT library \"" << target->GetName() << "\" contains:\n";
  38. for(std::vector<cmSourceFile*>::const_iterator i = badObjLib.begin();
  39. i != badObjLib.end(); ++i)
  40. {
  41. e << " " << (*i)->GetLocation().GetName() << "\n";
  42. }
  43. e << "but may contain only sources that compile, header files, and "
  44. "other files that would not affect linking of a normal library.";
  45. cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
  46. target->GetBacktrace());
  47. }
  48. }
  49. struct ObjectSourcesTag {};
  50. struct CustomCommandsTag {};
  51. struct ExtraSourcesTag {};
  52. struct HeaderSourcesTag {};
  53. struct ExternalObjectsTag {};
  54. struct IDLSourcesTag {};
  55. struct ResxTag {};
  56. struct ModuleDefinitionFileTag {};
  57. struct AppManifestTag{};
  58. struct CertificatesTag{};
  59. struct XamlTag{};
  60. template<typename Tag, typename OtherTag>
  61. struct IsSameTag
  62. {
  63. enum {
  64. Result = false
  65. };
  66. };
  67. template<typename Tag>
  68. struct IsSameTag<Tag, Tag>
  69. {
  70. enum {
  71. Result = true
  72. };
  73. };
  74. template<bool>
  75. struct DoAccept
  76. {
  77. template <typename T> static void Do(T&, cmSourceFile*) {}
  78. };
  79. template<>
  80. struct DoAccept<true>
  81. {
  82. static void Do(std::vector<cmSourceFile const*>& files, cmSourceFile* f)
  83. {
  84. files.push_back(f);
  85. }
  86. static void Do(cmGeneratorTarget::ResxData& data, cmSourceFile* f)
  87. {
  88. // Build and save the name of the corresponding .h file
  89. // This relationship will be used later when building the project files.
  90. // Both names would have been auto generated from Visual Studio
  91. // where the user supplied the file name and Visual Studio
  92. // appended the suffix.
  93. std::string resx = f->GetFullPath();
  94. std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
  95. data.ExpectedResxHeaders.insert(hFileName);
  96. data.ResxSources.push_back(f);
  97. }
  98. static void Do(cmGeneratorTarget::XamlData& data, cmSourceFile* f)
  99. {
  100. // Build and save the name of the corresponding .h and .cpp file
  101. // This relationship will be used later when building the project files.
  102. // Both names would have been auto generated from Visual Studio
  103. // where the user supplied the file name and Visual Studio
  104. // appended the suffix.
  105. std::string xaml = f->GetFullPath();
  106. std::string hFileName = xaml + ".h";
  107. std::string cppFileName = xaml + ".cpp";
  108. data.ExpectedXamlHeaders.insert(hFileName);
  109. data.ExpectedXamlSources.insert(cppFileName);
  110. data.XamlSources.push_back(f);
  111. }
  112. static void Do(std::string& data, cmSourceFile* f)
  113. {
  114. data = f->GetFullPath();
  115. }
  116. };
  117. //----------------------------------------------------------------------------
  118. template<typename Tag, typename DataType = std::vector<cmSourceFile const*> >
  119. struct TagVisitor
  120. {
  121. DataType& Data;
  122. std::vector<cmSourceFile*> BadObjLibFiles;
  123. cmTarget *Target;
  124. cmGlobalGenerator *GlobalGenerator;
  125. cmsys::RegularExpression Header;
  126. bool IsObjLib;
  127. TagVisitor(cmTarget *target, DataType& data)
  128. : Data(data), Target(target),
  129. GlobalGenerator(target->GetMakefile()->GetGlobalGenerator()),
  130. Header(CM_HEADER_REGEX),
  131. IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY)
  132. {
  133. }
  134. ~TagVisitor()
  135. {
  136. reportBadObjLib(this->BadObjLibFiles, this->Target,
  137. this->GlobalGenerator->GetCMakeInstance());
  138. }
  139. void Accept(cmSourceFile *sf)
  140. {
  141. std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
  142. if(sf->GetCustomCommand())
  143. {
  144. DoAccept<IsSameTag<Tag, CustomCommandsTag>::Result>::Do(this->Data, sf);
  145. }
  146. else if(this->Target->GetType() == cmTarget::UTILITY)
  147. {
  148. DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
  149. }
  150. else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
  151. {
  152. DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
  153. }
  154. else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
  155. {
  156. DoAccept<IsSameTag<Tag, ExternalObjectsTag>::Result>::Do(this->Data, sf);
  157. if(this->IsObjLib)
  158. {
  159. this->BadObjLibFiles.push_back(sf);
  160. }
  161. }
  162. else if(!sf->GetLanguage().empty())
  163. {
  164. DoAccept<IsSameTag<Tag, ObjectSourcesTag>::Result>::Do(this->Data, sf);
  165. }
  166. else if(ext == "def")
  167. {
  168. DoAccept<IsSameTag<Tag, ModuleDefinitionFileTag>::Result>::Do(this->Data,
  169. sf);
  170. if(this->IsObjLib)
  171. {
  172. this->BadObjLibFiles.push_back(sf);
  173. }
  174. }
  175. else if(ext == "idl")
  176. {
  177. DoAccept<IsSameTag<Tag, IDLSourcesTag>::Result>::Do(this->Data, sf);
  178. if(this->IsObjLib)
  179. {
  180. this->BadObjLibFiles.push_back(sf);
  181. }
  182. }
  183. else if(ext == "resx")
  184. {
  185. DoAccept<IsSameTag<Tag, ResxTag>::Result>::Do(this->Data, sf);
  186. }
  187. else if (ext == "appxmanifest")
  188. {
  189. DoAccept<IsSameTag<Tag, AppManifestTag>::Result>::Do(this->Data, sf);
  190. }
  191. else if (ext == "pfx")
  192. {
  193. DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf);
  194. }
  195. else if (ext == "xaml")
  196. {
  197. DoAccept<IsSameTag<Tag, XamlTag>::Result>::Do(this->Data, sf);
  198. }
  199. else if(this->Header.find(sf->GetFullPath().c_str()))
  200. {
  201. DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
  202. }
  203. else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
  204. {
  205. DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
  206. }
  207. else
  208. {
  209. DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
  210. }
  211. }
  212. };
  213. //----------------------------------------------------------------------------
  214. cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
  215. : Target(t),
  216. SourceFileFlagsConstructed(false)
  217. {
  218. this->Makefile = this->Target->GetMakefile();
  219. this->LocalGenerator = lg;
  220. this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
  221. }
  222. cmGeneratorTarget::~cmGeneratorTarget()
  223. {
  224. cmDeleteAll(this->LinkInformation);
  225. this->LinkInformation.clear();
  226. }
  227. cmLocalGenerator* cmGeneratorTarget::GetLocalGenerator() const
  228. {
  229. return this->LocalGenerator;
  230. }
  231. //----------------------------------------------------------------------------
  232. int cmGeneratorTarget::GetType() const
  233. {
  234. return this->Target->GetType();
  235. }
  236. //----------------------------------------------------------------------------
  237. std::string cmGeneratorTarget::GetName() const
  238. {
  239. return this->Target->GetName();
  240. }
  241. //----------------------------------------------------------------------------
  242. const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
  243. {
  244. return this->Target->GetProperty(prop);
  245. }
  246. //----------------------------------------------------------------------------
  247. std::string cmGeneratorTarget::GetOutputName(const std::string& config,
  248. bool implib) const
  249. {
  250. std::vector<std::string> props;
  251. std::string type = this->Target->GetOutputTargetType(implib);
  252. std::string configUpper = cmSystemTools::UpperCase(config);
  253. if(!type.empty() && !configUpper.empty())
  254. {
  255. // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME_<CONFIG>
  256. props.push_back(type + "_OUTPUT_NAME_" + configUpper);
  257. }
  258. if(!type.empty())
  259. {
  260. // <ARCHIVE|LIBRARY|RUNTIME>_OUTPUT_NAME
  261. props.push_back(type + "_OUTPUT_NAME");
  262. }
  263. if(!configUpper.empty())
  264. {
  265. // OUTPUT_NAME_<CONFIG>
  266. props.push_back("OUTPUT_NAME_" + configUpper);
  267. // <CONFIG>_OUTPUT_NAME
  268. props.push_back(configUpper + "_OUTPUT_NAME");
  269. }
  270. // OUTPUT_NAME
  271. props.push_back("OUTPUT_NAME");
  272. std::string outName;
  273. for(std::vector<std::string>::const_iterator i = props.begin();
  274. i != props.end(); ++i)
  275. {
  276. if (const char* outNameProp = this->Target->GetProperty(*i))
  277. {
  278. outName = outNameProp;
  279. break;
  280. }
  281. }
  282. if (outName.empty())
  283. {
  284. outName = this->GetName();
  285. }
  286. cmGeneratorExpression ge;
  287. cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
  288. return cge->Evaluate(this->Makefile, config);
  289. }
  290. //----------------------------------------------------------------------------
  291. std::vector<cmSourceFile*> const*
  292. cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
  293. {
  294. SourceEntriesType::const_iterator i = this->SourceEntries.find(sf);
  295. if(i != this->SourceEntries.end())
  296. {
  297. return &i->second.Depends;
  298. }
  299. return 0;
  300. }
  301. static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
  302. const std::string& config,
  303. cmTarget *headTarget,
  304. cmGeneratorExpressionDAGChecker *dagChecker,
  305. std::vector<std::string>& result,
  306. bool excludeImported)
  307. {
  308. if (const char* dirs =
  309. depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"))
  310. {
  311. cmGeneratorExpression ge;
  312. cmSystemTools::ExpandListArgument(ge.Parse(dirs)
  313. ->Evaluate(mf,
  314. config, false, headTarget,
  315. depTgt, dagChecker), result);
  316. }
  317. if (!depTgt->IsImported() || excludeImported)
  318. {
  319. return;
  320. }
  321. if (const char* dirs =
  322. depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES"))
  323. {
  324. cmGeneratorExpression ge;
  325. cmSystemTools::ExpandListArgument(ge.Parse(dirs)
  326. ->Evaluate(mf,
  327. config, false, headTarget,
  328. depTgt, dagChecker), result);
  329. }
  330. }
  331. #define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
  332. { \
  333. std::vector<cmSourceFile*> sourceFiles; \
  334. this->Target->GetSourceFiles(sourceFiles, config); \
  335. TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
  336. for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
  337. si != sourceFiles.end(); ++si) \
  338. { \
  339. visitor.Accept(*si); \
  340. } \
  341. } \
  342. #define IMPLEMENT_VISIT(DATA) \
  343. IMPLEMENT_VISIT_IMPL(DATA, EMPTY) \
  344. #define EMPTY
  345. #define COMMA ,
  346. //----------------------------------------------------------------------------
  347. void
  348. cmGeneratorTarget
  349. ::GetObjectSources(std::vector<cmSourceFile const*> &data,
  350. const std::string& config) const
  351. {
  352. IMPLEMENT_VISIT(ObjectSources);
  353. if (!this->Objects.empty())
  354. {
  355. return;
  356. }
  357. for(std::vector<cmSourceFile const*>::const_iterator it = data.begin();
  358. it != data.end(); ++it)
  359. {
  360. this->Objects[*it];
  361. }
  362. this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
  363. }
  364. void cmGeneratorTarget::ComputeObjectMapping()
  365. {
  366. if(!this->Objects.empty())
  367. {
  368. return;
  369. }
  370. std::vector<std::string> configs;
  371. this->Makefile->GetConfigurations(configs);
  372. if (configs.empty())
  373. {
  374. configs.push_back("");
  375. }
  376. for(std::vector<std::string>::const_iterator ci = configs.begin();
  377. ci != configs.end(); ++ci)
  378. {
  379. std::vector<cmSourceFile const*> sourceFiles;
  380. this->GetObjectSources(sourceFiles, *ci);
  381. }
  382. }
  383. //----------------------------------------------------------------------------
  384. const char* cmGeneratorTarget::GetFeature(const std::string& feature,
  385. const std::string& config) const
  386. {
  387. if(!config.empty())
  388. {
  389. std::string featureConfig = feature;
  390. featureConfig += "_";
  391. featureConfig += cmSystemTools::UpperCase(config);
  392. if(const char* value = this->Target->GetProperty(featureConfig))
  393. {
  394. return value;
  395. }
  396. }
  397. if(const char* value = this->Target->GetProperty(feature))
  398. {
  399. return value;
  400. }
  401. return this->LocalGenerator->GetFeature(feature, config);
  402. }
  403. //----------------------------------------------------------------------------
  404. bool cmGeneratorTarget::GetFeatureAsBool(const std::string& feature,
  405. const std::string& config) const
  406. {
  407. return cmSystemTools::IsOn(this->GetFeature(feature, config));
  408. }
  409. //----------------------------------------------------------------------------
  410. const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
  411. {
  412. this->ComputeObjectMapping();
  413. return this->Objects[file];
  414. }
  415. //----------------------------------------------------------------------------
  416. void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
  417. {
  418. this->ExplicitObjectName.insert(sf);
  419. }
  420. //----------------------------------------------------------------------------
  421. bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
  422. {
  423. const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
  424. std::set<cmSourceFile const*>::const_iterator it
  425. = this->ExplicitObjectName.find(file);
  426. return it != this->ExplicitObjectName.end();
  427. }
  428. //----------------------------------------------------------------------------
  429. void cmGeneratorTarget
  430. ::GetIDLSources(std::vector<cmSourceFile const*>& data,
  431. const std::string& config) const
  432. {
  433. IMPLEMENT_VISIT(IDLSources);
  434. }
  435. //----------------------------------------------------------------------------
  436. void
  437. cmGeneratorTarget
  438. ::GetHeaderSources(std::vector<cmSourceFile const*>& data,
  439. const std::string& config) const
  440. {
  441. IMPLEMENT_VISIT(HeaderSources);
  442. }
  443. //----------------------------------------------------------------------------
  444. void cmGeneratorTarget
  445. ::GetExtraSources(std::vector<cmSourceFile const*>& data,
  446. const std::string& config) const
  447. {
  448. IMPLEMENT_VISIT(ExtraSources);
  449. }
  450. //----------------------------------------------------------------------------
  451. void
  452. cmGeneratorTarget
  453. ::GetCustomCommands(std::vector<cmSourceFile const*>& data,
  454. const std::string& config) const
  455. {
  456. IMPLEMENT_VISIT(CustomCommands);
  457. }
  458. //----------------------------------------------------------------------------
  459. void
  460. cmGeneratorTarget
  461. ::GetExternalObjects(std::vector<cmSourceFile const*>& data,
  462. const std::string& config) const
  463. {
  464. IMPLEMENT_VISIT(ExternalObjects);
  465. }
  466. //----------------------------------------------------------------------------
  467. void
  468. cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs,
  469. const std::string& config) const
  470. {
  471. ResxData data;
  472. IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
  473. srcs = data.ExpectedResxHeaders;
  474. }
  475. //----------------------------------------------------------------------------
  476. void cmGeneratorTarget
  477. ::GetResxSources(std::vector<cmSourceFile const*>& srcs,
  478. const std::string& config) const
  479. {
  480. ResxData data;
  481. IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
  482. srcs = data.ResxSources;
  483. }
  484. //----------------------------------------------------------------------------
  485. void
  486. cmGeneratorTarget
  487. ::GetAppManifest(std::vector<cmSourceFile const*>& data,
  488. const std::string& config) const
  489. {
  490. IMPLEMENT_VISIT(AppManifest);
  491. }
  492. //----------------------------------------------------------------------------
  493. void
  494. cmGeneratorTarget
  495. ::GetCertificates(std::vector<cmSourceFile const*>& data,
  496. const std::string& config) const
  497. {
  498. IMPLEMENT_VISIT(Certificates);
  499. }
  500. //----------------------------------------------------------------------------
  501. void
  502. cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers,
  503. const std::string& config) const
  504. {
  505. XamlData data;
  506. IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
  507. headers = data.ExpectedXamlHeaders;
  508. }
  509. //----------------------------------------------------------------------------
  510. void
  511. cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
  512. const std::string& config) const
  513. {
  514. XamlData data;
  515. IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
  516. srcs = data.ExpectedXamlSources;
  517. }
  518. //----------------------------------------------------------------------------
  519. void cmGeneratorTarget
  520. ::GetXamlSources(std::vector<cmSourceFile const*>& srcs,
  521. const std::string& config) const
  522. {
  523. XamlData data;
  524. IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
  525. srcs = data.XamlSources;
  526. }
  527. //----------------------------------------------------------------------------
  528. const char* cmGeneratorTarget::GetLocation(const std::string& config) const
  529. {
  530. static std::string location;
  531. if (this->Target->IsImported())
  532. {
  533. location = this->Target->ImportedGetFullPath(config, false);
  534. }
  535. else
  536. {
  537. location = this->GetFullPath(config, false);
  538. }
  539. return location.c_str();
  540. }
  541. bool cmGeneratorTarget::IsImported() const
  542. {
  543. return this->Target->IsImported();
  544. }
  545. //----------------------------------------------------------------------------
  546. const char* cmGeneratorTarget::GetLocationForBuild() const
  547. {
  548. static std::string location;
  549. if(this->IsImported())
  550. {
  551. location = this->Target->ImportedGetFullPath("", false);
  552. return location.c_str();
  553. }
  554. // Now handle the deprecated build-time configuration location.
  555. location = this->Target->GetDirectory();
  556. const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
  557. if(cfgid && strcmp(cfgid, ".") != 0)
  558. {
  559. location += "/";
  560. location += cfgid;
  561. }
  562. if(this->Target->IsAppBundleOnApple())
  563. {
  564. std::string macdir = this->BuildMacContentDirectory("", "",
  565. false);
  566. if(!macdir.empty())
  567. {
  568. location += "/";
  569. location += macdir;
  570. }
  571. }
  572. location += "/";
  573. location += this->GetFullName("", false);
  574. return location.c_str();
  575. }
  576. //----------------------------------------------------------------------------
  577. bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
  578. const std::string& config) const
  579. {
  580. assert(this->GetType() != cmTarget::INTERFACE_LIBRARY);
  581. std::string config_upper;
  582. if(!config.empty())
  583. {
  584. config_upper = cmSystemTools::UpperCase(config);
  585. }
  586. typedef std::map<std::string, std::vector<std::string> > IncludeCacheType;
  587. IncludeCacheType::const_iterator iter =
  588. this->SystemIncludesCache.find(config_upper);
  589. if (iter == this->SystemIncludesCache.end())
  590. {
  591. cmGeneratorExpressionDAGChecker dagChecker(
  592. this->GetName(),
  593. "SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
  594. bool excludeImported
  595. = this->Target->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
  596. std::vector<std::string> result;
  597. for (std::set<std::string>::const_iterator
  598. it = this->Target->GetSystemIncludeDirectories().begin();
  599. it != this->Target->GetSystemIncludeDirectories().end(); ++it)
  600. {
  601. cmGeneratorExpression ge;
  602. cmSystemTools::ExpandListArgument(ge.Parse(*it)
  603. ->Evaluate(this->Makefile,
  604. config, false, this->Target,
  605. &dagChecker), result);
  606. }
  607. std::vector<cmTarget const*> const& deps =
  608. this->GetLinkImplementationClosure(config);
  609. for(std::vector<cmTarget const*>::const_iterator
  610. li = deps.begin(), le = deps.end(); li != le; ++li)
  611. {
  612. handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
  613. &dagChecker, result, excludeImported);
  614. }
  615. std::set<std::string> unique;
  616. for(std::vector<std::string>::iterator li = result.begin();
  617. li != result.end(); ++li)
  618. {
  619. cmSystemTools::ConvertToUnixSlashes(*li);
  620. unique.insert(*li);
  621. }
  622. result.clear();
  623. result.insert(result.end(), unique.begin(), unique.end());
  624. IncludeCacheType::value_type entry(config_upper, result);
  625. iter = this->SystemIncludesCache.insert(entry).first;
  626. }
  627. return std::binary_search(iter->second.begin(), iter->second.end(), dir);
  628. }
  629. //----------------------------------------------------------------------------
  630. bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
  631. {
  632. return this->Target->GetPropertyAsBool(prop);
  633. }
  634. //----------------------------------------------------------------------------
  635. void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
  636. const std::string& config) const
  637. {
  638. this->Target->GetSourceFiles(files, config);
  639. }
  640. //----------------------------------------------------------------------------
  641. std::string
  642. cmGeneratorTarget::GetCompilePDBName(const std::string& config) const
  643. {
  644. std::string prefix;
  645. std::string base;
  646. std::string suffix;
  647. this->GetFullNameInternal(config, false, prefix, base, suffix);
  648. // Check for a per-configuration output directory target property.
  649. std::string configUpper = cmSystemTools::UpperCase(config);
  650. std::string configProp = "COMPILE_PDB_NAME_";
  651. configProp += configUpper;
  652. const char* config_name = this->Target->GetProperty(configProp);
  653. if(config_name && *config_name)
  654. {
  655. return prefix + config_name + ".pdb";
  656. }
  657. const char* name = this->Target->GetProperty("COMPILE_PDB_NAME");
  658. if(name && *name)
  659. {
  660. return prefix + name + ".pdb";
  661. }
  662. return "";
  663. }
  664. //----------------------------------------------------------------------------
  665. std::string
  666. cmGeneratorTarget::GetCompilePDBPath(const std::string& config) const
  667. {
  668. std::string dir = this->GetCompilePDBDirectory(config);
  669. std::string name = this->GetCompilePDBName(config);
  670. if(dir.empty() && !name.empty())
  671. {
  672. dir = this->Target->GetPDBDirectory(config);
  673. }
  674. if(!dir.empty())
  675. {
  676. dir += "/";
  677. }
  678. return dir + name;
  679. }
  680. //----------------------------------------------------------------------------
  681. bool cmGeneratorTarget::HasSOName(const std::string& config) const
  682. {
  683. // soname is supported only for shared libraries and modules,
  684. // and then only when the platform supports an soname flag.
  685. return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
  686. this->GetType() == cmTarget::MODULE_LIBRARY) &&
  687. !this->GetPropertyAsBool("NO_SONAME") &&
  688. this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
  689. }
  690. //----------------------------------------------------------------------------
  691. bool
  692. cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
  693. {
  694. // Only executables and shared libraries can have an rpath and may
  695. // need relinking.
  696. if(this->GetType() != cmTarget::EXECUTABLE &&
  697. this->GetType() != cmTarget::SHARED_LIBRARY &&
  698. this->GetType() != cmTarget::MODULE_LIBRARY)
  699. {
  700. return false;
  701. }
  702. // If there is no install location this target will not be installed
  703. // and therefore does not need relinking.
  704. if(!this->Target->GetHaveInstallRule())
  705. {
  706. return false;
  707. }
  708. // If skipping all rpaths completely then no relinking is needed.
  709. if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
  710. {
  711. return false;
  712. }
  713. // If building with the install-tree rpath no relinking is needed.
  714. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
  715. {
  716. return false;
  717. }
  718. // If chrpath is going to be used no relinking is needed.
  719. if(this->IsChrpathUsed(config))
  720. {
  721. return false;
  722. }
  723. // Check for rpath support on this platform.
  724. std::string ll = this->GetLinkerLanguage(config);
  725. if(!ll.empty())
  726. {
  727. std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
  728. flagVar += ll;
  729. flagVar += "_FLAG";
  730. if(!this->Makefile->IsSet(flagVar))
  731. {
  732. // There is no rpath support on this platform so nothing needs
  733. // relinking.
  734. return false;
  735. }
  736. }
  737. else
  738. {
  739. // No linker language is known. This error will be reported by
  740. // other code.
  741. return false;
  742. }
  743. // If either a build or install tree rpath is set then the rpath
  744. // will likely change between the build tree and install tree and
  745. // this target must be relinked.
  746. return this->Target->HaveBuildTreeRPATH(config)
  747. || this->Target->HaveInstallTreeRPATH();
  748. }
  749. //----------------------------------------------------------------------------
  750. bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
  751. {
  752. // Only certain target types have an rpath.
  753. if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
  754. this->GetType() == cmTarget::MODULE_LIBRARY ||
  755. this->GetType() == cmTarget::EXECUTABLE))
  756. {
  757. return false;
  758. }
  759. // If the target will not be installed we do not need to change its
  760. // rpath.
  761. if(!this->Target->GetHaveInstallRule())
  762. {
  763. return false;
  764. }
  765. // Skip chrpath if skipping rpath altogether.
  766. if(this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
  767. {
  768. return false;
  769. }
  770. // Skip chrpath if it does not need to be changed at install time.
  771. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
  772. {
  773. return false;
  774. }
  775. // Allow the user to disable builtin chrpath explicitly.
  776. if(this->Makefile->IsOn("CMAKE_NO_BUILTIN_CHRPATH"))
  777. {
  778. return false;
  779. }
  780. if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
  781. {
  782. return true;
  783. }
  784. #if defined(CMAKE_USE_ELF_PARSER)
  785. // Enable if the rpath flag uses a separator and the target uses ELF
  786. // binaries.
  787. std::string ll = this->GetLinkerLanguage(config);
  788. if(!ll.empty())
  789. {
  790. std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
  791. sepVar += ll;
  792. sepVar += "_FLAG_SEP";
  793. const char* sep = this->Makefile->GetDefinition(sepVar);
  794. if(sep && *sep)
  795. {
  796. // TODO: Add ELF check to ABI detection and get rid of
  797. // CMAKE_EXECUTABLE_FORMAT.
  798. if(const char* fmt =
  799. this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT"))
  800. {
  801. return strcmp(fmt, "ELF") == 0;
  802. }
  803. }
  804. }
  805. #endif
  806. static_cast<void>(config);
  807. return false;
  808. }
  809. //----------------------------------------------------------------------------
  810. std::string cmGeneratorTarget::GetSOName(const std::string& config) const
  811. {
  812. if(this->Target->IsImported())
  813. {
  814. // Lookup the imported soname.
  815. if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config))
  816. {
  817. if(info->NoSOName)
  818. {
  819. // The imported library has no builtin soname so the name
  820. // searched at runtime will be just the filename.
  821. return cmSystemTools::GetFilenameName(info->Location);
  822. }
  823. else
  824. {
  825. // Use the soname given if any.
  826. if(info->SOName.find("@rpath/") == 0)
  827. {
  828. return info->SOName.substr(6);
  829. }
  830. return info->SOName;
  831. }
  832. }
  833. else
  834. {
  835. return "";
  836. }
  837. }
  838. else
  839. {
  840. // Compute the soname that will be built.
  841. std::string name;
  842. std::string soName;
  843. std::string realName;
  844. std::string impName;
  845. std::string pdbName;
  846. this->GetLibraryNames(name, soName, realName,
  847. impName, pdbName, config);
  848. return soName;
  849. }
  850. }
  851. //----------------------------------------------------------------------------
  852. std::string
  853. cmGeneratorTarget::GetAppBundleDirectory(const std::string& config,
  854. bool contentOnly) const
  855. {
  856. std::string fpath = this->GetFullName(config, false);
  857. fpath += ".app/Contents";
  858. if(!contentOnly)
  859. fpath += "/MacOS";
  860. return fpath;
  861. }
  862. //----------------------------------------------------------------------------
  863. bool cmGeneratorTarget::IsBundleOnApple() const
  864. {
  865. return this->Target->IsFrameworkOnApple()
  866. || this->Target->IsAppBundleOnApple()
  867. || this->Target->IsCFBundleOnApple();
  868. }
  869. //----------------------------------------------------------------------------
  870. std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config,
  871. bool contentOnly) const
  872. {
  873. std::string fpath;
  874. fpath += this->GetOutputName(config, false);
  875. fpath += ".";
  876. const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION");
  877. if (!ext)
  878. {
  879. if (this->Target->IsXCTestOnApple())
  880. {
  881. ext = "xctest";
  882. }
  883. else
  884. {
  885. ext = "bundle";
  886. }
  887. }
  888. fpath += ext;
  889. fpath += "/Contents";
  890. if(!contentOnly)
  891. fpath += "/MacOS";
  892. return fpath;
  893. }
  894. //----------------------------------------------------------------------------
  895. std::string
  896. cmGeneratorTarget::GetFrameworkDirectory(const std::string& config,
  897. bool rootDir) const
  898. {
  899. std::string fpath;
  900. fpath += this->GetOutputName(config, false);
  901. fpath += ".framework";
  902. if(!rootDir)
  903. {
  904. fpath += "/Versions/";
  905. fpath += this->Target->GetFrameworkVersion();
  906. }
  907. return fpath;
  908. }
  909. //----------------------------------------------------------------------------
  910. std::string
  911. cmGeneratorTarget::GetFullName(const std::string& config, bool implib) const
  912. {
  913. if(this->Target->IsImported())
  914. {
  915. return this->Target->GetFullNameImported(config, implib);
  916. }
  917. else
  918. {
  919. return this->GetFullNameInternal(config, implib);
  920. }
  921. }
  922. //----------------------------------------------------------------------------
  923. std::string
  924. cmGeneratorTarget::GetInstallNameDirForBuildTree(
  925. const std::string& config) const
  926. {
  927. // If building directly for installation then the build tree install_name
  928. // is the same as the install tree.
  929. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"))
  930. {
  931. return this->GetInstallNameDirForInstallTree();
  932. }
  933. // Use the build tree directory for the target.
  934. if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME") &&
  935. !this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
  936. !this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
  937. {
  938. std::string dir;
  939. if(this->Target->MacOSXRpathInstallNameDirDefault())
  940. {
  941. dir = "@rpath";
  942. }
  943. else
  944. {
  945. dir = this->Target->GetDirectory(config);
  946. }
  947. dir += "/";
  948. return dir;
  949. }
  950. else
  951. {
  952. return "";
  953. }
  954. }
  955. //----------------------------------------------------------------------------
  956. std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
  957. {
  958. if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
  959. {
  960. std::string dir;
  961. const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
  962. if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") &&
  963. !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"))
  964. {
  965. if(install_name_dir && *install_name_dir)
  966. {
  967. dir = install_name_dir;
  968. dir += "/";
  969. }
  970. }
  971. if(!install_name_dir)
  972. {
  973. if(this->Target->MacOSXRpathInstallNameDirDefault())
  974. {
  975. dir = "@rpath/";
  976. }
  977. }
  978. return dir;
  979. }
  980. else
  981. {
  982. return "";
  983. }
  984. }
  985. //----------------------------------------------------------------------------
  986. class cmTargetCollectLinkLanguages
  987. {
  988. public:
  989. cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
  990. const std::string& config,
  991. UNORDERED_SET<std::string>& languages,
  992. cmTarget const* head):
  993. Config(config), Languages(languages), HeadTarget(head),
  994. Makefile(target->Target->GetMakefile()), Target(target)
  995. { this->Visited.insert(target->Target); }
  996. void Visit(cmLinkItem const& item)
  997. {
  998. if(!item.Target)
  999. {
  1000. if(item.find("::") != std::string::npos)
  1001. {
  1002. bool noMessage = false;
  1003. cmake::MessageType messageType = cmake::FATAL_ERROR;
  1004. std::stringstream e;
  1005. switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
  1006. {
  1007. case cmPolicies::WARN:
  1008. {
  1009. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0028) << "\n";
  1010. messageType = cmake::AUTHOR_WARNING;
  1011. }
  1012. break;
  1013. case cmPolicies::OLD:
  1014. noMessage = true;
  1015. case cmPolicies::REQUIRED_IF_USED:
  1016. case cmPolicies::REQUIRED_ALWAYS:
  1017. case cmPolicies::NEW:
  1018. // Issue the fatal message.
  1019. break;
  1020. }
  1021. if(!noMessage)
  1022. {
  1023. e << "Target \"" << this->Target->GetName()
  1024. << "\" links to target \"" << item
  1025. << "\" but the target was not found. Perhaps a find_package() "
  1026. "call is missing for an IMPORTED target, or an ALIAS target is "
  1027. "missing?";
  1028. this->Makefile->GetCMakeInstance()->IssueMessage(
  1029. messageType, e.str(), this->Target->Target->GetBacktrace());
  1030. }
  1031. }
  1032. return;
  1033. }
  1034. if(!this->Visited.insert(item.Target).second)
  1035. {
  1036. return;
  1037. }
  1038. cmTarget::LinkInterface const* iface =
  1039. item.Target->GetLinkInterface(this->Config, this->HeadTarget);
  1040. if(!iface) { return; }
  1041. for(std::vector<std::string>::const_iterator
  1042. li = iface->Languages.begin(); li != iface->Languages.end(); ++li)
  1043. {
  1044. this->Languages.insert(*li);
  1045. }
  1046. for(std::vector<cmLinkItem>::const_iterator
  1047. li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
  1048. {
  1049. this->Visit(*li);
  1050. }
  1051. }
  1052. private:
  1053. std::string Config;
  1054. UNORDERED_SET<std::string>& Languages;
  1055. cmTarget const* HeadTarget;
  1056. cmMakefile* Makefile;
  1057. const cmGeneratorTarget* Target;
  1058. std::set<cmTarget const*> Visited;
  1059. };
  1060. //----------------------------------------------------------------------------
  1061. cmGeneratorTarget::LinkClosure const*
  1062. cmGeneratorTarget::GetLinkClosure(const std::string& config) const
  1063. {
  1064. std::string key(cmSystemTools::UpperCase(config));
  1065. LinkClosureMapType::iterator
  1066. i = this->LinkClosureMap.find(key);
  1067. if(i == this->LinkClosureMap.end())
  1068. {
  1069. LinkClosure lc;
  1070. this->ComputeLinkClosure(config, lc);
  1071. LinkClosureMapType::value_type entry(key, lc);
  1072. i = this->LinkClosureMap.insert(entry).first;
  1073. }
  1074. return &i->second;
  1075. }
  1076. //----------------------------------------------------------------------------
  1077. class cmTargetSelectLinker
  1078. {
  1079. int Preference;
  1080. cmGeneratorTarget const* Target;
  1081. cmMakefile* Makefile;
  1082. cmGlobalGenerator* GG;
  1083. std::set<std::string> Preferred;
  1084. public:
  1085. cmTargetSelectLinker(cmGeneratorTarget const* target)
  1086. : Preference(0), Target(target)
  1087. {
  1088. this->Makefile = this->Target->Makefile;
  1089. this->GG = this->Makefile->GetGlobalGenerator();
  1090. }
  1091. void Consider(const char* lang)
  1092. {
  1093. int preference = this->GG->GetLinkerPreference(lang);
  1094. if(preference > this->Preference)
  1095. {
  1096. this->Preference = preference;
  1097. this->Preferred.clear();
  1098. }
  1099. if(preference == this->Preference)
  1100. {
  1101. this->Preferred.insert(lang);
  1102. }
  1103. }
  1104. std::string Choose()
  1105. {
  1106. if(this->Preferred.empty())
  1107. {
  1108. return "";
  1109. }
  1110. else if(this->Preferred.size() > 1)
  1111. {
  1112. std::stringstream e;
  1113. e << "Target " << this->Target->GetName()
  1114. << " contains multiple languages with the highest linker preference"
  1115. << " (" << this->Preference << "):\n";
  1116. for(std::set<std::string>::const_iterator
  1117. li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
  1118. {
  1119. e << " " << *li << "\n";
  1120. }
  1121. e << "Set the LINKER_LANGUAGE property for this target.";
  1122. cmake* cm = this->Makefile->GetCMakeInstance();
  1123. cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
  1124. this->Target->Target->GetBacktrace());
  1125. }
  1126. return *this->Preferred.begin();
  1127. }
  1128. };
  1129. //----------------------------------------------------------------------------
  1130. void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
  1131. LinkClosure& lc) const
  1132. {
  1133. // Get languages built in this target.
  1134. UNORDERED_SET<std::string> languages;
  1135. cmTarget::LinkImplementation const* impl =
  1136. this->Target->GetLinkImplementation(config);
  1137. for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
  1138. li != impl->Languages.end(); ++li)
  1139. {
  1140. languages.insert(*li);
  1141. }
  1142. // Add interface languages from linked targets.
  1143. cmTargetCollectLinkLanguages cll(this, config, languages, this->Target);
  1144. for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
  1145. li != impl->Libraries.end(); ++li)
  1146. {
  1147. cll.Visit(*li);
  1148. }
  1149. // Store the transitive closure of languages.
  1150. for(UNORDERED_SET<std::string>::const_iterator li = languages.begin();
  1151. li != languages.end(); ++li)
  1152. {
  1153. lc.Languages.push_back(*li);
  1154. }
  1155. // Choose the language whose linker should be used.
  1156. if(this->GetProperty("HAS_CXX"))
  1157. {
  1158. lc.LinkerLanguage = "CXX";
  1159. }
  1160. else if(const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"))
  1161. {
  1162. lc.LinkerLanguage = linkerLang;
  1163. }
  1164. else
  1165. {
  1166. // Find the language with the highest preference value.
  1167. cmTargetSelectLinker tsl(this);
  1168. // First select from the languages compiled directly in this target.
  1169. for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
  1170. li != impl->Languages.end(); ++li)
  1171. {
  1172. tsl.Consider(li->c_str());
  1173. }
  1174. // Now consider languages that propagate from linked targets.
  1175. for(UNORDERED_SET<std::string>::const_iterator sit = languages.begin();
  1176. sit != languages.end(); ++sit)
  1177. {
  1178. std::string propagates = "CMAKE_"+*sit+"_LINKER_PREFERENCE_PROPAGATES";
  1179. if(this->Makefile->IsOn(propagates))
  1180. {
  1181. tsl.Consider(sit->c_str());
  1182. }
  1183. }
  1184. lc.LinkerLanguage = tsl.Choose();
  1185. }
  1186. }
  1187. //----------------------------------------------------------------------------
  1188. void cmGeneratorTarget::GetFullNameComponents(std::string& prefix,
  1189. std::string& base,
  1190. std::string& suffix,
  1191. const std::string& config,
  1192. bool implib) const
  1193. {
  1194. this->GetFullNameInternal(config, implib, prefix, base, suffix);
  1195. }
  1196. //----------------------------------------------------------------------------
  1197. std::string
  1198. cmGeneratorTarget::BuildMacContentDirectory(const std::string& base,
  1199. const std::string& config,
  1200. bool contentOnly) const
  1201. {
  1202. std::string fpath = base;
  1203. if(this->Target->IsAppBundleOnApple())
  1204. {
  1205. fpath += this->GetAppBundleDirectory(config, contentOnly);
  1206. }
  1207. if(this->Target->IsFrameworkOnApple())
  1208. {
  1209. fpath += this->GetFrameworkDirectory(config, contentOnly);
  1210. }
  1211. if(this->Target->IsCFBundleOnApple())
  1212. {
  1213. fpath += this->GetCFBundleDirectory(config, contentOnly);
  1214. }
  1215. return fpath;
  1216. }
  1217. //----------------------------------------------------------------------------
  1218. std::string
  1219. cmGeneratorTarget::GetMacContentDirectory(const std::string& config,
  1220. bool implib) const
  1221. {
  1222. // Start with the output directory for the target.
  1223. std::string fpath = this->Target->GetDirectory(config, implib);
  1224. fpath += "/";
  1225. bool contentOnly = true;
  1226. if(this->Target->IsFrameworkOnApple())
  1227. {
  1228. // additional files with a framework go into the version specific
  1229. // directory
  1230. contentOnly = false;
  1231. }
  1232. fpath = this->BuildMacContentDirectory(fpath, config, contentOnly);
  1233. return fpath;
  1234. }
  1235. //----------------------------------------------------------------------------
  1236. cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
  1237. const std::string& config) const
  1238. {
  1239. // There is no compile information for imported targets.
  1240. if(this->IsImported())
  1241. {
  1242. return 0;
  1243. }
  1244. if(this->GetType() > cmTarget::OBJECT_LIBRARY)
  1245. {
  1246. std::string msg = "cmTarget::GetCompileInfo called for ";
  1247. msg += this->GetName();
  1248. msg += " which has type ";
  1249. msg += cmTarget::GetTargetTypeName(this->Target->GetType());
  1250. this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, msg);
  1251. return 0;
  1252. }
  1253. // Lookup/compute/cache the compile information for this configuration.
  1254. std::string config_upper;
  1255. if(!config.empty())
  1256. {
  1257. config_upper = cmSystemTools::UpperCase(config);
  1258. }
  1259. CompileInfoMapType::const_iterator i =
  1260. this->CompileInfoMap.find(config_upper);
  1261. if(i == this->CompileInfoMap.end())
  1262. {
  1263. CompileInfo info;
  1264. this->Target
  1265. ->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
  1266. CompileInfoMapType::value_type entry(config_upper, info);
  1267. i = this->CompileInfoMap.insert(entry).first;
  1268. }
  1269. return &i->second;
  1270. }
  1271. //----------------------------------------------------------------------------
  1272. std::string
  1273. cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
  1274. {
  1275. std::string data;
  1276. IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
  1277. return data;
  1278. }
  1279. //----------------------------------------------------------------------------
  1280. void
  1281. cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
  1282. const std::string &config) const
  1283. {
  1284. std::vector<cmSourceFile const*> objectFiles;
  1285. this->GetExternalObjects(objectFiles, config);
  1286. std::vector<cmTarget*> objectLibraries;
  1287. for(std::vector<cmSourceFile const*>::const_iterator
  1288. it = objectFiles.begin(); it != objectFiles.end(); ++it)
  1289. {
  1290. std::string objLib = (*it)->GetObjectLibrary();
  1291. if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
  1292. {
  1293. objectLibraries.push_back(tgt);
  1294. }
  1295. }
  1296. std::vector<cmTarget*>::const_iterator end
  1297. = cmRemoveDuplicates(objectLibraries);
  1298. for(std::vector<cmTarget*>::const_iterator
  1299. ti = objectLibraries.begin();
  1300. ti != end; ++ti)
  1301. {
  1302. cmTarget* objLib = *ti;
  1303. cmGeneratorTarget* ogt =
  1304. this->GlobalGenerator->GetGeneratorTarget(objLib);
  1305. std::vector<cmSourceFile const*> objectSources;
  1306. ogt->GetObjectSources(objectSources, config);
  1307. for(std::vector<cmSourceFile const*>::const_iterator
  1308. si = objectSources.begin();
  1309. si != objectSources.end(); ++si)
  1310. {
  1311. std::string obj = ogt->ObjectDirectory;
  1312. obj += ogt->Objects[*si];
  1313. objs.push_back(obj);
  1314. }
  1315. }
  1316. }
  1317. //----------------------------------------------------------------------------
  1318. void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
  1319. const std::string& config) const
  1320. {
  1321. const char *prop
  1322. = this->GetLinkInterfaceDependentStringProperty("AUTOUIC_OPTIONS",
  1323. config);
  1324. if (!prop)
  1325. {
  1326. return;
  1327. }
  1328. cmGeneratorExpression ge;
  1329. cmGeneratorExpressionDAGChecker dagChecker(
  1330. this->GetName(),
  1331. "AUTOUIC_OPTIONS", 0, 0);
  1332. cmSystemTools::ExpandListArgument(ge.Parse(prop)
  1333. ->Evaluate(this->Makefile,
  1334. config,
  1335. false,
  1336. this->Target,
  1337. &dagChecker),
  1338. result);
  1339. }
  1340. //----------------------------------------------------------------------------
  1341. void processILibs(const std::string& config,
  1342. cmTarget const* headTarget,
  1343. cmLinkItem const& item,
  1344. std::vector<cmTarget const*>& tgts,
  1345. std::set<cmTarget const*>& emitted)
  1346. {
  1347. if (item.Target && emitted.insert(item.Target).second)
  1348. {
  1349. tgts.push_back(item.Target);
  1350. if(cmTarget::LinkInterfaceLibraries const* iface =
  1351. item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
  1352. {
  1353. for(std::vector<cmLinkItem>::const_iterator
  1354. it = iface->Libraries.begin();
  1355. it != iface->Libraries.end(); ++it)
  1356. {
  1357. processILibs(config, headTarget, *it, tgts, emitted);
  1358. }
  1359. }
  1360. }
  1361. }
  1362. //----------------------------------------------------------------------------
  1363. const std::vector<const cmTarget*>&
  1364. cmGeneratorTarget::GetLinkImplementationClosure(
  1365. const std::string& config) const
  1366. {
  1367. LinkImplClosure& tgts =
  1368. this->LinkImplClosureMap[config];
  1369. if(!tgts.Done)
  1370. {
  1371. tgts.Done = true;
  1372. std::set<cmTarget const*> emitted;
  1373. cmLinkImplementationLibraries const* impl
  1374. = this->Target->GetLinkImplementationLibraries(config);
  1375. for(std::vector<cmLinkImplItem>::const_iterator
  1376. it = impl->Libraries.begin();
  1377. it != impl->Libraries.end(); ++it)
  1378. {
  1379. processILibs(config, this->Target, *it, tgts , emitted);
  1380. }
  1381. }
  1382. return tgts;
  1383. }
  1384. //----------------------------------------------------------------------------
  1385. class cmTargetTraceDependencies
  1386. {
  1387. public:
  1388. cmTargetTraceDependencies(cmGeneratorTarget* target);
  1389. void Trace();
  1390. private:
  1391. cmTarget* Target;
  1392. cmGeneratorTarget* GeneratorTarget;
  1393. cmMakefile* Makefile;
  1394. cmGlobalGenerator const* GlobalGenerator;
  1395. typedef cmGeneratorTarget::SourceEntry SourceEntry;
  1396. SourceEntry* CurrentEntry;
  1397. std::queue<cmSourceFile*> SourceQueue;
  1398. std::set<cmSourceFile*> SourcesQueued;
  1399. typedef std::map<std::string, cmSourceFile*> NameMapType;
  1400. NameMapType NameMap;
  1401. std::vector<std::string> NewSources;
  1402. void QueueSource(cmSourceFile* sf);
  1403. void FollowName(std::string const& name);
  1404. void FollowNames(std::vector<std::string> const& names);
  1405. bool IsUtility(std::string const& dep);
  1406. void CheckCustomCommand(cmCustomCommand const& cc);
  1407. void CheckCustomCommands(const std::vector<cmCustomCommand>& commands);
  1408. void FollowCommandDepends(cmCustomCommand const& cc,
  1409. const std::string& config,
  1410. std::set<std::string>& emitted);
  1411. };
  1412. //----------------------------------------------------------------------------
  1413. cmTargetTraceDependencies
  1414. ::cmTargetTraceDependencies(cmGeneratorTarget* target):
  1415. Target(target->Target), GeneratorTarget(target)
  1416. {
  1417. // Convenience.
  1418. this->Makefile = this->Target->GetMakefile();
  1419. this->GlobalGenerator = this->Makefile->GetGlobalGenerator();
  1420. this->CurrentEntry = 0;
  1421. // Queue all the source files already specified for the target.
  1422. if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
  1423. {
  1424. std::vector<std::string> configs;
  1425. this->Makefile->GetConfigurations(configs);
  1426. if (configs.empty())
  1427. {
  1428. configs.push_back("");
  1429. }
  1430. std::set<cmSourceFile*> emitted;
  1431. for(std::vector<std::string>::const_iterator ci = configs.begin();
  1432. ci != configs.end(); ++ci)
  1433. {
  1434. std::vector<cmSourceFile*> sources;
  1435. this->Target->GetSourceFiles(sources, *ci);
  1436. for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
  1437. si != sources.end(); ++si)
  1438. {
  1439. cmSourceFile* sf = *si;
  1440. const std::set<cmTarget const*> tgts =
  1441. this->GlobalGenerator->GetFilenameTargetDepends(sf);
  1442. if (tgts.find(this->Target) != tgts.end())
  1443. {
  1444. std::ostringstream e;
  1445. e << "Evaluation output file\n \"" << sf->GetFullPath()
  1446. << "\"\ndepends on the sources of a target it is used in. This "
  1447. "is a dependency loop and is not allowed.";
  1448. this->GeneratorTarget
  1449. ->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
  1450. return;
  1451. }
  1452. if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second)
  1453. {
  1454. this->SourceQueue.push(sf);
  1455. }
  1456. }
  1457. }
  1458. }
  1459. // Queue pre-build, pre-link, and post-build rule dependencies.
  1460. this->CheckCustomCommands(this->Target->GetPreBuildCommands());
  1461. this->CheckCustomCommands(this->Target->GetPreLinkCommands());
  1462. this->CheckCustomCommands(this->Target->GetPostBuildCommands());
  1463. }
  1464. //----------------------------------------------------------------------------
  1465. void cmTargetTraceDependencies::Trace()
  1466. {
  1467. // Process one dependency at a time until the queue is empty.
  1468. while(!this->SourceQueue.empty())
  1469. {
  1470. // Get the next source from the queue.
  1471. cmSourceFile* sf = this->SourceQueue.front();
  1472. this->SourceQueue.pop();
  1473. this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
  1474. // Queue dependencies added explicitly by the user.
  1475. if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
  1476. {
  1477. std::vector<std::string> objDeps;
  1478. cmSystemTools::ExpandListArgument(additionalDeps, objDeps);
  1479. for(std::vector<std::string>::iterator odi = objDeps.begin();
  1480. odi != objDeps.end(); ++odi)
  1481. {
  1482. if (cmSystemTools::FileIsFullPath(*odi))
  1483. {
  1484. *odi = cmSystemTools::CollapseFullPath(*odi);
  1485. }
  1486. }
  1487. this->FollowNames(objDeps);
  1488. }
  1489. // Queue the source needed to generate this file, if any.
  1490. this->FollowName(sf->GetFullPath());
  1491. // Queue dependencies added programatically by commands.
  1492. this->FollowNames(sf->GetDepends());
  1493. // Queue custom command dependencies.
  1494. if(cmCustomCommand const* cc = sf->GetCustomCommand())
  1495. {
  1496. this->CheckCustomCommand(*cc);
  1497. }
  1498. }
  1499. this->CurrentEntry = 0;
  1500. this->Target->AddTracedSources(this->NewSources);
  1501. }
  1502. //----------------------------------------------------------------------------
  1503. void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
  1504. {
  1505. if(this->SourcesQueued.insert(sf).second)
  1506. {
  1507. this->SourceQueue.push(sf);
  1508. // Make sure this file is in the target at the end.
  1509. this->NewSources.push_back(sf->GetFullPath());
  1510. }
  1511. }
  1512. //----------------------------------------------------------------------------
  1513. void cmTargetTraceDependencies::FollowName(std::string const& name)
  1514. {
  1515. NameMapType::iterator i = this->NameMap.find(name);
  1516. if(i == this->NameMap.end())
  1517. {
  1518. // Check if we know how to generate this file.
  1519. cmSourceFile* sf = this->Makefile->GetSourceFileWithOutput(name);
  1520. NameMapType::value_type entry(name, sf);
  1521. i = this->NameMap.insert(entry).first;
  1522. }
  1523. if(cmSourceFile* sf = i->second)
  1524. {
  1525. // Record the dependency we just followed.
  1526. if(this->CurrentEntry)
  1527. {
  1528. this->CurrentEntry->Depends.push_back(sf);
  1529. }
  1530. this->QueueSource(sf);
  1531. }
  1532. }
  1533. //----------------------------------------------------------------------------
  1534. void
  1535. cmTargetTraceDependencies::FollowNames(std::vector<std::string> const& names)
  1536. {
  1537. for(std::vector<std::string>::const_iterator i = names.begin();
  1538. i != names.end(); ++i)
  1539. {
  1540. this->FollowName(*i);
  1541. }
  1542. }
  1543. //----------------------------------------------------------------------------
  1544. bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
  1545. {
  1546. // Dependencies on targets (utilities) are supposed to be named by
  1547. // just the target name. However for compatibility we support
  1548. // naming the output file generated by the target (assuming there is
  1549. // no output-name property which old code would not have set). In
  1550. // that case the target name will be the file basename of the
  1551. // dependency.
  1552. std::string util = cmSystemTools::GetFilenameName(dep);
  1553. if(cmSystemTools::GetFilenameLastExtension(util) == ".exe")
  1554. {
  1555. util = cmSystemTools::GetFilenameWithoutLastExtension(util);
  1556. }
  1557. // Check for a target with this name.
  1558. if(cmGeneratorTarget* t
  1559. = this->Makefile->FindGeneratorTargetToUse(util))
  1560. {
  1561. // If we find the target and the dep was given as a full path,
  1562. // then make sure it was not a full path to something else, and
  1563. // the fact that the name matched a target was just a coincidence.
  1564. if(cmSystemTools::FileIsFullPath(dep.c_str()))
  1565. {
  1566. if(t->GetType() >= cmTarget::EXECUTABLE &&
  1567. t->GetType() <= cmTarget::MODULE_LIBRARY)
  1568. {
  1569. // This is really only for compatibility so we do not need to
  1570. // worry about configuration names and output names.
  1571. std::string tLocation = t->GetLocationForBuild();
  1572. tLocation = cmSystemTools::GetFilenamePath(tLocation);
  1573. std::string depLocation = cmSystemTools::GetFilenamePath(dep);
  1574. depLocation = cmSystemTools::CollapseFullPath(depLocation);
  1575. tLocation = cmSystemTools::CollapseFullPath(tLocation);
  1576. if(depLocation == tLocation)
  1577. {
  1578. this->Target->AddUtility(util);
  1579. return true;
  1580. }
  1581. }
  1582. }
  1583. else
  1584. {
  1585. // The original name of the dependency was not a full path. It
  1586. // must name a target, so add the target-level dependency.
  1587. this->Target->AddUtility(util);
  1588. return true;
  1589. }
  1590. }
  1591. // The dependency does not name a target built in this project.
  1592. return false;
  1593. }
  1594. //----------------------------------------------------------------------------
  1595. void
  1596. cmTargetTraceDependencies
  1597. ::CheckCustomCommand(cmCustomCommand const& cc)
  1598. {
  1599. // Transform command names that reference targets built in this
  1600. // project to corresponding target-level dependencies.
  1601. cmGeneratorExpression ge(cc.GetBacktrace());
  1602. // Add target-level dependencies referenced by generator expressions.
  1603. std::set<cmTarget*> targets;
  1604. for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
  1605. cit != cc.GetCommandLines().end(); ++cit)
  1606. {
  1607. std::string const& command = *cit->begin();
  1608. // Check for a target with this name.
  1609. if(cmTarget* t = this->Makefile->FindTargetToUse(command))
  1610. {
  1611. if(t->GetType() == cmTarget::EXECUTABLE)
  1612. {
  1613. // The command refers to an executable target built in
  1614. // this project. Add the target-level dependency to make
  1615. // sure the executable is up to date before this custom
  1616. // command possibly runs.
  1617. this->Target->AddUtility(command);
  1618. }
  1619. }
  1620. // Check for target references in generator expressions.
  1621. for(cmCustomCommandLine::const_iterator cli = cit->begin();
  1622. cli != cit->end(); ++cli)
  1623. {
  1624. const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
  1625. = ge.Parse(*cli);
  1626. cge->Evaluate(this->Makefile, "", true);
  1627. std::set<cmTarget*> geTargets = cge->GetTargets();
  1628. targets.insert(geTargets.begin(), geTargets.end());
  1629. }
  1630. }
  1631. for(std::set<cmTarget*>::iterator ti = targets.begin();
  1632. ti != targets.end(); ++ti)
  1633. {
  1634. this->Target->AddUtility((*ti)->GetName());
  1635. }
  1636. // Queue the custom command dependencies.
  1637. std::vector<std::string> configs;
  1638. std::set<std::string> emitted;
  1639. this->Makefile->GetConfigurations(configs);
  1640. if (configs.empty())
  1641. {
  1642. configs.push_back("");
  1643. }
  1644. for(std::vector<std::string>::const_iterator ci = configs.begin();
  1645. ci != configs.end(); ++ci)
  1646. {
  1647. this->FollowCommandDepends(cc, *ci, emitted);
  1648. }
  1649. }
  1650. //----------------------------------------------------------------------------
  1651. void cmTargetTraceDependencies::FollowCommandDepends(cmCustomCommand const& cc,
  1652. const std::string& config,
  1653. std::set<std::string>& emitted)
  1654. {
  1655. cmCustomCommandGenerator ccg(cc, config,
  1656. this->GeneratorTarget->LocalGenerator);
  1657. const std::vector<std::string>& depends = ccg.GetDepends();
  1658. for(std::vector<std::string>::const_iterator di = depends.begin();
  1659. di != depends.end(); ++di)
  1660. {
  1661. std::string const& dep = *di;
  1662. if(emitted.insert(dep).second)
  1663. {
  1664. if(!this->IsUtility(dep))
  1665. {
  1666. // The dependency does not name a target and may be a file we
  1667. // know how to generate. Queue it.
  1668. this->FollowName(dep);
  1669. }
  1670. }
  1671. }
  1672. }
  1673. //----------------------------------------------------------------------------
  1674. void
  1675. cmTargetTraceDependencies
  1676. ::CheckCustomCommands(const std::vector<cmCustomCommand>& commands)
  1677. {
  1678. for(std::vector<cmCustomCommand>::const_iterator cli = commands.begin();
  1679. cli != commands.end(); ++cli)
  1680. {
  1681. this->CheckCustomCommand(*cli);
  1682. }
  1683. }
  1684. //----------------------------------------------------------------------------
  1685. void cmGeneratorTarget::TraceDependencies()
  1686. {
  1687. // CMake-generated targets have no dependencies to trace. Normally tracing
  1688. // would find nothing anyway, but when building CMake itself the "install"
  1689. // target command ends up referencing the "cmake" target but we do not
  1690. // really want the dependency because "install" depend on "all" anyway.
  1691. if(this->GetType() == cmTarget::GLOBAL_TARGET)
  1692. {
  1693. return;
  1694. }
  1695. // Use a helper object to trace the dependencies.
  1696. cmTargetTraceDependencies tracer(this);
  1697. tracer.Trace();
  1698. }
  1699. std::string
  1700. cmGeneratorTarget::GetCompilePDBDirectory(const std::string& config) const
  1701. {
  1702. if(CompileInfo const* info = this->GetCompileInfo(config))
  1703. {
  1704. return info->CompilePdbDir;
  1705. }
  1706. return "";
  1707. }
  1708. //----------------------------------------------------------------------------
  1709. void cmGeneratorTarget::GetAppleArchs(const std::string& config,
  1710. std::vector<std::string>& archVec) const
  1711. {
  1712. const char* archs = 0;
  1713. if(!config.empty())
  1714. {
  1715. std::string defVarName = "OSX_ARCHITECTURES_";
  1716. defVarName += cmSystemTools::UpperCase(config);
  1717. archs = this->Target->GetProperty(defVarName);
  1718. }
  1719. if(!archs)
  1720. {
  1721. archs = this->Target->GetProperty("OSX_ARCHITECTURES");
  1722. }
  1723. if(archs)
  1724. {
  1725. cmSystemTools::ExpandListArgument(std::string(archs), archVec);
  1726. }
  1727. }
  1728. //----------------------------------------------------------------------------
  1729. std::string
  1730. cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
  1731. std::string const& config) const
  1732. {
  1733. switch(this->GetType())
  1734. {
  1735. case cmTarget::STATIC_LIBRARY:
  1736. {
  1737. std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
  1738. if(this->GetFeatureAsBool(
  1739. "INTERPROCEDURAL_OPTIMIZATION", config))
  1740. {
  1741. std::string varIPO = var + "_IPO";
  1742. if(this->Makefile->GetDefinition(varIPO))
  1743. {
  1744. return varIPO;
  1745. }
  1746. }
  1747. return var;
  1748. }
  1749. case cmTarget::SHARED_LIBRARY:
  1750. return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY";
  1751. case cmTarget::MODULE_LIBRARY:
  1752. return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
  1753. case cmTarget::EXECUTABLE:
  1754. return "CMAKE_" + lang + "_LINK_EXECUTABLE";
  1755. default:
  1756. break;
  1757. }
  1758. return "";
  1759. }
  1760. //----------------------------------------------------------------------------
  1761. std::vector<std::string>
  1762. cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
  1763. const std::string& lang) const
  1764. {
  1765. return this->Target->GetIncludeDirectories(config, lang);
  1766. }
  1767. //----------------------------------------------------------------------------
  1768. void cmGeneratorTarget::GenerateTargetManifest(
  1769. const std::string& config) const
  1770. {
  1771. if (this->Target->IsImported())
  1772. {
  1773. return;
  1774. }
  1775. cmMakefile* mf = this->Target->GetMakefile();
  1776. cmGlobalGenerator* gg = mf->GetGlobalGenerator();
  1777. // Get the names.
  1778. std::string name;
  1779. std::string soName;
  1780. std::string realName;
  1781. std::string impName;
  1782. std::string pdbName;
  1783. if(this->GetType() == cmTarget::EXECUTABLE)
  1784. {
  1785. this->GetExecutableNames(name, realName, impName, pdbName, config);
  1786. }
  1787. else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
  1788. this->GetType() == cmTarget::SHARED_LIBRARY ||
  1789. this->GetType() == cmTarget::MODULE_LIBRARY)
  1790. {
  1791. this->GetLibraryNames(name, soName, realName, impName, pdbName,
  1792. config);
  1793. }
  1794. else
  1795. {
  1796. return;
  1797. }
  1798. // Get the directory.
  1799. std::string dir = this->Target->GetDirectory(config, false);
  1800. // Add each name.
  1801. std::string f;
  1802. if(!name.empty())
  1803. {
  1804. f = dir;
  1805. f += "/";
  1806. f += name;
  1807. gg->AddToManifest(f);
  1808. }
  1809. if(!soName.empty())
  1810. {
  1811. f = dir;
  1812. f += "/";
  1813. f += soName;
  1814. gg->AddToManifest(f);
  1815. }
  1816. if(!realName.empty())
  1817. {
  1818. f = dir;
  1819. f += "/";
  1820. f += realName;
  1821. gg->AddToManifest(f);
  1822. }
  1823. if(!pdbName.empty())
  1824. {
  1825. f = dir;
  1826. f += "/";
  1827. f += pdbName;
  1828. gg->AddToManifest(f);
  1829. }
  1830. if(!impName.empty())
  1831. {
  1832. f = this->Target->GetDirectory(config, true);
  1833. f += "/";
  1834. f += impName;
  1835. gg->AddToManifest(f);
  1836. }
  1837. }
  1838. //----------------------------------------------------------------------------
  1839. std::string cmGeneratorTarget::GetFullPath(const std::string& config,
  1840. bool implib, bool realname) const
  1841. {
  1842. if(this->Target->IsImported())
  1843. {
  1844. return this->Target->ImportedGetFullPath(config, implib);
  1845. }
  1846. else
  1847. {
  1848. return this->NormalGetFullPath(config, implib, realname);
  1849. }
  1850. }
  1851. std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config,
  1852. bool implib,
  1853. bool realname) const
  1854. {
  1855. std::string fpath = this->Target->GetDirectory(config, implib);
  1856. fpath += "/";
  1857. if(this->Target->IsAppBundleOnApple())
  1858. {
  1859. fpath = this->BuildMacContentDirectory(fpath, config, false);
  1860. fpath += "/";
  1861. }
  1862. // Add the full name of the target.
  1863. if(implib)
  1864. {
  1865. fpath += this->GetFullName(config, true);
  1866. }
  1867. else if(realname)
  1868. {
  1869. fpath += this->NormalGetRealName(config);
  1870. }
  1871. else
  1872. {
  1873. fpath += this->GetFullName(config, false);
  1874. }
  1875. return fpath;
  1876. }
  1877. //----------------------------------------------------------------------------
  1878. std::string
  1879. cmGeneratorTarget::NormalGetRealName(const std::string& config) const
  1880. {
  1881. // This should not be called for imported targets.
  1882. // TODO: Split cmTarget into a class hierarchy to get compile-time
  1883. // enforcement of the limited imported target API.
  1884. if(this->Target->IsImported())
  1885. {
  1886. std::string msg = "NormalGetRealName called on imported target: ";
  1887. msg += this->GetName();
  1888. this->Makefile->IssueMessage(cmake::INTERNAL_ERROR, msg);
  1889. }
  1890. if(this->GetType() == cmTarget::EXECUTABLE)
  1891. {
  1892. // Compute the real name that will be built.
  1893. std::string name;
  1894. std::string realName;
  1895. std::string impName;
  1896. std::string pdbName;
  1897. this->GetExecutableNames(name, realName, impName, pdbName, config);
  1898. return realName;
  1899. }
  1900. else
  1901. {
  1902. // Compute the real name that will be built.
  1903. std::string name;
  1904. std::string soName;
  1905. std::string realName;
  1906. std::string impName;
  1907. std::string pdbName;
  1908. this->GetLibraryNames(name, soName, realName,
  1909. impName, pdbName, config);
  1910. return realName;
  1911. }
  1912. }
  1913. //----------------------------------------------------------------------------
  1914. void cmGeneratorTarget::GetLibraryNames(std::string& name,
  1915. std::string& soName,
  1916. std::string& realName,
  1917. std::string& impName,
  1918. std::string& pdbName,
  1919. const std::string& config) const
  1920. {
  1921. // This should not be called for imported targets.
  1922. // TODO: Split cmTarget into a class hierarchy to get compile-time
  1923. // enforcement of the limited imported target API.
  1924. if(this->Target->IsImported())
  1925. {
  1926. std::string msg = "GetLibraryNames called on imported target: ";
  1927. msg += this->GetName();
  1928. this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR,
  1929. msg);
  1930. return;
  1931. }
  1932. // Check for library version properties.
  1933. const char* version = this->GetProperty("VERSION");
  1934. const char* soversion = this->GetProperty("SOVERSION");
  1935. if(!this->HasSOName(config) ||
  1936. this->Target->IsFrameworkOnApple())
  1937. {
  1938. // Versioning is supported only for shared libraries and modules,
  1939. // and then only when the platform supports an soname flag.
  1940. version = 0;
  1941. soversion = 0;
  1942. }
  1943. if(version && !soversion)
  1944. {
  1945. // The soversion must be set if the library version is set. Use
  1946. // the library version as the soversion.
  1947. soversion = version;
  1948. }
  1949. if(!version && soversion)
  1950. {
  1951. // Use the soversion as the library version.
  1952. version = soversion;
  1953. }
  1954. // Get the components of the library name.
  1955. std::string prefix;
  1956. std::string base;
  1957. std::string suffix;
  1958. this->GetFullNameInternal(config, false, prefix, base, suffix);
  1959. // The library name.
  1960. name = prefix+base+suffix;
  1961. if(this->Target->IsFrameworkOnApple())
  1962. {
  1963. realName = prefix;
  1964. realName += "Versions/";
  1965. realName += this->Target->GetFrameworkVersion();
  1966. realName += "/";
  1967. realName += base;
  1968. soName = realName;
  1969. }
  1970. else
  1971. {
  1972. // The library's soname.
  1973. this->Target->ComputeVersionedName(soName, prefix, base, suffix,
  1974. name, soversion);
  1975. // The library's real name on disk.
  1976. this->Target->ComputeVersionedName(realName, prefix, base, suffix,
  1977. name, version);
  1978. }
  1979. // The import library name.
  1980. if(this->GetType() == cmTarget::SHARED_LIBRARY ||
  1981. this->GetType() == cmTarget::MODULE_LIBRARY)
  1982. {
  1983. impName = this->GetFullNameInternal(config, true);
  1984. }
  1985. else
  1986. {
  1987. impName = "";
  1988. }
  1989. // The program database file name.
  1990. pdbName = this->GetPDBName(config);
  1991. }
  1992. //----------------------------------------------------------------------------
  1993. void cmGeneratorTarget::GetExecutableNames(std::string& name,
  1994. std::string& realName,
  1995. std::string& impName,
  1996. std::string& pdbName,
  1997. const std::string& config) const
  1998. {
  1999. // This should not be called for imported targets.
  2000. // TODO: Split cmTarget into a class hierarchy to get compile-time
  2001. // enforcement of the limited imported target API.
  2002. if(this->Target->IsImported())
  2003. {
  2004. std::string msg =
  2005. "GetExecutableNames called on imported target: ";
  2006. msg += this->GetName();
  2007. this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
  2008. }
  2009. // This versioning is supported only for executables and then only
  2010. // when the platform supports symbolic links.
  2011. #if defined(_WIN32) && !defined(__CYGWIN__)
  2012. const char* version = 0;
  2013. #else
  2014. // Check for executable version properties.
  2015. const char* version = this->GetProperty("VERSION");
  2016. if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
  2017. {
  2018. version = 0;
  2019. }
  2020. #endif
  2021. // Get the components of the executable name.
  2022. std::string prefix;
  2023. std::string base;
  2024. std::string suffix;
  2025. this->GetFullNameInternal(config, false, prefix, base, suffix);
  2026. // The executable name.
  2027. name = prefix+base+suffix;
  2028. // The executable's real name on disk.
  2029. #if defined(__CYGWIN__)
  2030. realName = prefix+base;
  2031. #else
  2032. realName = name;
  2033. #endif
  2034. if(version)
  2035. {
  2036. realName += "-";
  2037. realName += version;
  2038. }
  2039. #if defined(__CYGWIN__)
  2040. realName += suffix;
  2041. #endif
  2042. // The import library name.
  2043. impName = this->GetFullNameInternal(config, true);
  2044. // The program database file name.
  2045. pdbName = this->GetPDBName(config);
  2046. }
  2047. //----------------------------------------------------------------------------
  2048. std::string cmGeneratorTarget::GetFullNameInternal(const std::string& config,
  2049. bool implib) const
  2050. {
  2051. std::string prefix;
  2052. std::string base;
  2053. std::string suffix;
  2054. this->GetFullNameInternal(config, implib, prefix, base, suffix);
  2055. return prefix+base+suffix;
  2056. }
  2057. //----------------------------------------------------------------------------
  2058. void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
  2059. bool implib,
  2060. std::string& outPrefix,
  2061. std::string& outBase,
  2062. std::string& outSuffix) const
  2063. {
  2064. // Use just the target name for non-main target types.
  2065. if(this->GetType() != cmTarget::STATIC_LIBRARY &&
  2066. this->GetType() != cmTarget::SHARED_LIBRARY &&
  2067. this->GetType() != cmTarget::MODULE_LIBRARY &&
  2068. this->GetType() != cmTarget::EXECUTABLE)
  2069. {
  2070. outPrefix = "";
  2071. outBase = this->GetName();
  2072. outSuffix = "";
  2073. return;
  2074. }
  2075. // Return an empty name for the import library if this platform
  2076. // does not support import libraries.
  2077. if(implib &&
  2078. !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
  2079. {
  2080. outPrefix = "";
  2081. outBase = "";
  2082. outSuffix = "";
  2083. return;
  2084. }
  2085. // The implib option is only allowed for shared libraries, module
  2086. // libraries, and executables.
  2087. if(this->GetType() != cmTarget::SHARED_LIBRARY &&
  2088. this->GetType() != cmTarget::MODULE_LIBRARY &&
  2089. this->GetType() != cmTarget::EXECUTABLE)
  2090. {
  2091. implib = false;
  2092. }
  2093. // Compute the full name for main target types.
  2094. const char* targetPrefix = (implib
  2095. ? this->GetProperty("IMPORT_PREFIX")
  2096. : this->GetProperty("PREFIX"));
  2097. const char* targetSuffix = (implib
  2098. ? this->GetProperty("IMPORT_SUFFIX")
  2099. : this->GetProperty("SUFFIX"));
  2100. const char* configPostfix = 0;
  2101. if(!config.empty())
  2102. {
  2103. std::string configProp = cmSystemTools::UpperCase(config);
  2104. configProp += "_POSTFIX";
  2105. configPostfix = this->GetProperty(configProp);
  2106. // Mac application bundles and frameworks have no postfix.
  2107. if(configPostfix &&
  2108. (this->Target->IsAppBundleOnApple()
  2109. || this->Target->IsFrameworkOnApple()))
  2110. {
  2111. configPostfix = 0;
  2112. }
  2113. }
  2114. const char* prefixVar = this->Target->GetPrefixVariableInternal(implib);
  2115. const char* suffixVar = this->Target->GetSuffixVariableInternal(implib);
  2116. // Check for language-specific default prefix and suffix.
  2117. std::string ll = this->GetLinkerLanguage(config);
  2118. if(!ll.empty())
  2119. {
  2120. if(!targetSuffix && suffixVar && *suffixVar)
  2121. {
  2122. std::string langSuff = suffixVar + std::string("_") + ll;
  2123. targetSuffix = this->Makefile->GetDefinition(langSuff);
  2124. }
  2125. if(!targetPrefix && prefixVar && *prefixVar)
  2126. {
  2127. std::string langPrefix = prefixVar + std::string("_") + ll;
  2128. targetPrefix = this->Makefile->GetDefinition(langPrefix);
  2129. }
  2130. }
  2131. // if there is no prefix on the target use the cmake definition
  2132. if(!targetPrefix && prefixVar)
  2133. {
  2134. targetPrefix = this->Makefile->GetSafeDefinition(prefixVar);
  2135. }
  2136. // if there is no suffix on the target use the cmake definition
  2137. if(!targetSuffix && suffixVar)
  2138. {
  2139. targetSuffix = this->Makefile->GetSafeDefinition(suffixVar);
  2140. }
  2141. // frameworks have directory prefix but no suffix
  2142. std::string fw_prefix;
  2143. if(this->Target->IsFrameworkOnApple())
  2144. {
  2145. fw_prefix = this->GetOutputName(config, false);
  2146. fw_prefix += ".framework/";
  2147. targetPrefix = fw_prefix.c_str();
  2148. targetSuffix = 0;
  2149. }
  2150. if(this->Target->IsCFBundleOnApple())
  2151. {
  2152. fw_prefix = this->GetCFBundleDirectory(config, false);
  2153. fw_prefix += "/";
  2154. targetPrefix = fw_prefix.c_str();
  2155. targetSuffix = 0;
  2156. }
  2157. // Begin the final name with the prefix.
  2158. outPrefix = targetPrefix?targetPrefix:"";
  2159. // Append the target name or property-specified name.
  2160. outBase += this->GetOutputName(config, implib);
  2161. // Append the per-configuration postfix.
  2162. outBase += configPostfix?configPostfix:"";
  2163. // Name shared libraries with their version number on some platforms.
  2164. if(const char* soversion = this->GetProperty("SOVERSION"))
  2165. {
  2166. if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
  2167. this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
  2168. {
  2169. outBase += "-";
  2170. outBase += soversion;
  2171. }
  2172. }
  2173. // Append the suffix.
  2174. outSuffix = targetSuffix?targetSuffix:"";
  2175. }
  2176. //----------------------------------------------------------------------------
  2177. std::string
  2178. cmGeneratorTarget::GetLinkerLanguage(const std::string& config) const
  2179. {
  2180. return this->GetLinkClosure(config)->LinkerLanguage;
  2181. }
  2182. //----------------------------------------------------------------------------
  2183. std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
  2184. {
  2185. std::string prefix;
  2186. std::string base;
  2187. std::string suffix;
  2188. this->GetFullNameInternal(config, false, prefix, base, suffix);
  2189. std::vector<std::string> props;
  2190. std::string configUpper =
  2191. cmSystemTools::UpperCase(config);
  2192. if(!configUpper.empty())
  2193. {
  2194. // PDB_NAME_<CONFIG>
  2195. props.push_back("PDB_NAME_" + configUpper);
  2196. }
  2197. // PDB_NAME
  2198. props.push_back("PDB_NAME");
  2199. for(std::vector<std::string>::const_iterator i = props.begin();
  2200. i != props.end(); ++i)
  2201. {
  2202. if(const char* outName = this->GetProperty(*i))
  2203. {
  2204. base = outName;
  2205. break;
  2206. }
  2207. }
  2208. return prefix+base+".pdb";
  2209. }
  2210. bool cmStrictTargetComparison::operator()(cmTarget const* t1,
  2211. cmTarget const* t2) const
  2212. {
  2213. int nameResult = strcmp(t1->GetName().c_str(), t2->GetName().c_str());
  2214. if (nameResult == 0)
  2215. {
  2216. return strcmp(t1->GetMakefile()->GetCurrentBinaryDirectory(),
  2217. t2->GetMakefile()->GetCurrentBinaryDirectory()) < 0;
  2218. }
  2219. return nameResult < 0;
  2220. }
  2221. //----------------------------------------------------------------------------
  2222. struct cmGeneratorTarget::SourceFileFlags
  2223. cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
  2224. {
  2225. struct SourceFileFlags flags;
  2226. this->ConstructSourceFileFlags();
  2227. std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
  2228. this->SourceFlagsMap.find(sf);
  2229. if(si != this->SourceFlagsMap.end())
  2230. {
  2231. flags = si->second;
  2232. }
  2233. else
  2234. {
  2235. // Handle the MACOSX_PACKAGE_LOCATION property on source files that
  2236. // were not listed in one of the other lists.
  2237. if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
  2238. {
  2239. flags.MacFolder = location;
  2240. if(strcmp(location, "Resources") == 0)
  2241. {
  2242. flags.Type = cmGeneratorTarget::SourceFileTypeResource;
  2243. }
  2244. else
  2245. {
  2246. flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
  2247. }
  2248. }
  2249. }
  2250. return flags;
  2251. }
  2252. //----------------------------------------------------------------------------
  2253. void cmGeneratorTarget::ConstructSourceFileFlags() const
  2254. {
  2255. if(this->SourceFileFlagsConstructed)
  2256. {
  2257. return;
  2258. }
  2259. this->SourceFileFlagsConstructed = true;
  2260. // Process public headers to mark the source files.
  2261. if(const char* files = this->Target->GetProperty("PUBLIC_HEADER"))
  2262. {
  2263. std::vector<std::string> relFiles;
  2264. cmSystemTools::ExpandListArgument(files, relFiles);
  2265. for(std::vector<std::string>::iterator it = relFiles.begin();
  2266. it != relFiles.end(); ++it)
  2267. {
  2268. if(cmSourceFile* sf = this->Makefile->GetSource(*it))
  2269. {
  2270. SourceFileFlags& flags = this->SourceFlagsMap[sf];
  2271. flags.MacFolder = "Headers";
  2272. flags.Type = cmGeneratorTarget::SourceFileTypePublicHeader;
  2273. }
  2274. }
  2275. }
  2276. // Process private headers after public headers so that they take
  2277. // precedence if a file is listed in both.
  2278. if(const char* files = this->Target->GetProperty("PRIVATE_HEADER"))
  2279. {
  2280. std::vector<std::string> relFiles;
  2281. cmSystemTools::ExpandListArgument(files, relFiles);
  2282. for(std::vector<std::string>::iterator it = relFiles.begin();
  2283. it != relFiles.end(); ++it)
  2284. {
  2285. if(cmSourceFile* sf = this->Makefile->GetSource(*it))
  2286. {
  2287. SourceFileFlags& flags = this->SourceFlagsMap[sf];
  2288. flags.MacFolder = "PrivateHeaders";
  2289. flags.Type = cmGeneratorTarget::SourceFileTypePrivateHeader;
  2290. }
  2291. }
  2292. }
  2293. // Mark sources listed as resources.
  2294. if(const char* files = this->Target->GetProperty("RESOURCE"))
  2295. {
  2296. std::vector<std::string> relFiles;
  2297. cmSystemTools::ExpandListArgument(files, relFiles);
  2298. for(std::vector<std::string>::iterator it = relFiles.begin();
  2299. it != relFiles.end(); ++it)
  2300. {
  2301. if(cmSourceFile* sf = this->Makefile->GetSource(*it))
  2302. {
  2303. SourceFileFlags& flags = this->SourceFlagsMap[sf];
  2304. flags.MacFolder = "Resources";
  2305. flags.Type = cmGeneratorTarget::SourceFileTypeResource;
  2306. }
  2307. }
  2308. }
  2309. }
  2310. //----------------------------------------------------------------------------
  2311. const cmGeneratorTarget::CompatibleInterfacesBase&
  2312. cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
  2313. {
  2314. cmGeneratorTarget::CompatibleInterfaces& compat =
  2315. this->CompatibleInterfacesMap[config];
  2316. if(!compat.Done)
  2317. {
  2318. compat.Done = true;
  2319. compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
  2320. compat.PropsString.insert("AUTOUIC_OPTIONS");
  2321. std::vector<cmTarget const*> const& deps =
  2322. this->GetLinkImplementationClosure(config);
  2323. for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
  2324. li != deps.end(); ++li)
  2325. {
  2326. #define CM_READ_COMPATIBLE_INTERFACE(X, x) \
  2327. if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
  2328. { \
  2329. std::vector<std::string> props; \
  2330. cmSystemTools::ExpandListArgument(prop, props); \
  2331. compat.Props##x.insert(props.begin(), props.end()); \
  2332. }
  2333. CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
  2334. CM_READ_COMPATIBLE_INTERFACE(STRING, String)
  2335. CM_READ_COMPATIBLE_INTERFACE(NUMBER_MIN, NumberMin)
  2336. CM_READ_COMPATIBLE_INTERFACE(NUMBER_MAX, NumberMax)
  2337. #undef CM_READ_COMPATIBLE_INTERFACE
  2338. }
  2339. }
  2340. return compat;
  2341. }
  2342. //----------------------------------------------------------------------------
  2343. bool cmGeneratorTarget::IsLinkInterfaceDependentBoolProperty(
  2344. const std::string &p, const std::string& config) const
  2345. {
  2346. if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
  2347. || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
  2348. {
  2349. return false;
  2350. }
  2351. return this->GetCompatibleInterfaces(config).PropsBool.count(p) > 0;
  2352. }
  2353. //----------------------------------------------------------------------------
  2354. bool cmGeneratorTarget::IsLinkInterfaceDependentStringProperty(
  2355. const std::string &p, const std::string& config) const
  2356. {
  2357. if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
  2358. || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
  2359. {
  2360. return false;
  2361. }
  2362. return this->GetCompatibleInterfaces(config).PropsString.count(p) > 0;
  2363. }
  2364. //----------------------------------------------------------------------------
  2365. bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMinProperty(
  2366. const std::string &p, const std::string& config) const
  2367. {
  2368. if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
  2369. || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
  2370. {
  2371. return false;
  2372. }
  2373. return this->GetCompatibleInterfaces(config).PropsNumberMin.count(p) > 0;
  2374. }
  2375. //----------------------------------------------------------------------------
  2376. bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
  2377. const std::string &p, const std::string& config) const
  2378. {
  2379. if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
  2380. || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
  2381. {
  2382. return false;
  2383. }
  2384. return this->GetCompatibleInterfaces(config).PropsNumberMax.count(p) > 0;
  2385. }
  2386. enum CompatibleType
  2387. {
  2388. BoolType,
  2389. StringType,
  2390. NumberMinType,
  2391. NumberMaxType
  2392. };
  2393. template<typename PropertyType>
  2394. PropertyType getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
  2395. const std::string& prop,
  2396. const std::string& config,
  2397. CompatibleType,
  2398. PropertyType *);
  2399. template<>
  2400. bool getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
  2401. const std::string& prop,
  2402. const std::string& config,
  2403. CompatibleType, bool *)
  2404. {
  2405. return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
  2406. }
  2407. template<>
  2408. const char * getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
  2409. const std::string& prop,
  2410. const std::string& config,
  2411. CompatibleType t,
  2412. const char **)
  2413. {
  2414. switch(t)
  2415. {
  2416. case BoolType:
  2417. assert(0 && "String compatibility check function called for boolean");
  2418. return 0;
  2419. case StringType:
  2420. return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
  2421. case NumberMinType:
  2422. return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config);
  2423. case NumberMaxType:
  2424. return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config);
  2425. }
  2426. assert(0 && "Unreachable!");
  2427. return 0;
  2428. }
  2429. //----------------------------------------------------------------------------
  2430. template<typename PropertyType>
  2431. void checkPropertyConsistency(cmGeneratorTarget const* depender,
  2432. cmTarget const* dependee,
  2433. const std::string& propName,
  2434. std::set<std::string> &emitted,
  2435. const std::string& config,
  2436. CompatibleType t,
  2437. PropertyType *)
  2438. {
  2439. const char *prop = dependee->GetProperty(propName);
  2440. if (!prop)
  2441. {
  2442. return;
  2443. }
  2444. std::vector<std::string> props;
  2445. cmSystemTools::ExpandListArgument(prop, props);
  2446. std::string pdir =
  2447. dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
  2448. pdir += "/Help/prop_tgt/";
  2449. for(std::vector<std::string>::iterator pi = props.begin();
  2450. pi != props.end(); ++pi)
  2451. {
  2452. std::string pname = cmSystemTools::HelpFileName(*pi);
  2453. std::string pfile = pdir + pname + ".rst";
  2454. if(cmSystemTools::FileExists(pfile.c_str(), true))
  2455. {
  2456. std::ostringstream e;
  2457. e << "Target \"" << dependee->GetName() << "\" has property \""
  2458. << *pi << "\" listed in its " << propName << " property. "
  2459. "This is not allowed. Only user-defined properties may appear "
  2460. "listed in the " << propName << " property.";
  2461. depender->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
  2462. return;
  2463. }
  2464. if(emitted.insert(*pi).second)
  2465. {
  2466. getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
  2467. t, 0);
  2468. if (cmSystemTools::GetErrorOccuredFlag())
  2469. {
  2470. return;
  2471. }
  2472. }
  2473. }
  2474. }
  2475. static std::string intersect(const std::set<std::string> &s1,
  2476. const std::set<std::string> &s2)
  2477. {
  2478. std::set<std::string> intersect;
  2479. std::set_intersection(s1.begin(),s1.end(),
  2480. s2.begin(),s2.end(),
  2481. std::inserter(intersect,intersect.begin()));
  2482. if (!intersect.empty())
  2483. {
  2484. return *intersect.begin();
  2485. }
  2486. return "";
  2487. }
  2488. static std::string intersect(const std::set<std::string> &s1,
  2489. const std::set<std::string> &s2,
  2490. const std::set<std::string> &s3)
  2491. {
  2492. std::string result;
  2493. result = intersect(s1, s2);
  2494. if (!result.empty())
  2495. return result;
  2496. result = intersect(s1, s3);
  2497. if (!result.empty())
  2498. return result;
  2499. return intersect(s2, s3);
  2500. }
  2501. static std::string intersect(const std::set<std::string> &s1,
  2502. const std::set<std::string> &s2,
  2503. const std::set<std::string> &s3,
  2504. const std::set<std::string> &s4)
  2505. {
  2506. std::string result;
  2507. result = intersect(s1, s2);
  2508. if (!result.empty())
  2509. return result;
  2510. result = intersect(s1, s3);
  2511. if (!result.empty())
  2512. return result;
  2513. result = intersect(s1, s4);
  2514. if (!result.empty())
  2515. return result;
  2516. return intersect(s2, s3, s4);
  2517. }
  2518. //----------------------------------------------------------------------------
  2519. void cmGeneratorTarget::CheckPropertyCompatibility(
  2520. cmComputeLinkInformation *info, const std::string& config) const
  2521. {
  2522. const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
  2523. std::set<std::string> emittedBools;
  2524. static std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
  2525. std::set<std::string> emittedStrings;
  2526. static std::string strString = "COMPATIBLE_INTERFACE_STRING";
  2527. std::set<std::string> emittedMinNumbers;
  2528. static std::string strNumMin = "COMPATIBLE_INTERFACE_NUMBER_MIN";
  2529. std::set<std::string> emittedMaxNumbers;
  2530. static std::string strNumMax = "COMPATIBLE_INTERFACE_NUMBER_MAX";
  2531. for(cmComputeLinkInformation::ItemVector::const_iterator li =
  2532. deps.begin(); li != deps.end(); ++li)
  2533. {
  2534. if (!li->Target)
  2535. {
  2536. continue;
  2537. }
  2538. checkPropertyConsistency<bool>(this, li->Target,
  2539. strBool,
  2540. emittedBools, config, BoolType, 0);
  2541. if (cmSystemTools::GetErrorOccuredFlag())
  2542. {
  2543. return;
  2544. }
  2545. checkPropertyConsistency<const char *>(this, li->Target,
  2546. strString,
  2547. emittedStrings, config,
  2548. StringType, 0);
  2549. if (cmSystemTools::GetErrorOccuredFlag())
  2550. {
  2551. return;
  2552. }
  2553. checkPropertyConsistency<const char *>(this, li->Target,
  2554. strNumMin,
  2555. emittedMinNumbers, config,
  2556. NumberMinType, 0);
  2557. if (cmSystemTools::GetErrorOccuredFlag())
  2558. {
  2559. return;
  2560. }
  2561. checkPropertyConsistency<const char *>(this, li->Target,
  2562. strNumMax,
  2563. emittedMaxNumbers, config,
  2564. NumberMaxType, 0);
  2565. if (cmSystemTools::GetErrorOccuredFlag())
  2566. {
  2567. return;
  2568. }
  2569. }
  2570. std::string prop = intersect(emittedBools,
  2571. emittedStrings,
  2572. emittedMinNumbers,
  2573. emittedMaxNumbers);
  2574. if (!prop.empty())
  2575. {
  2576. // Use a sorted std::vector to keep the error message sorted.
  2577. std::vector<std::string> props;
  2578. std::set<std::string>::const_iterator i = emittedBools.find(prop);
  2579. if (i != emittedBools.end())
  2580. {
  2581. props.push_back(strBool);
  2582. }
  2583. i = emittedStrings.find(prop);
  2584. if (i != emittedStrings.end())
  2585. {
  2586. props.push_back(strString);
  2587. }
  2588. i = emittedMinNumbers.find(prop);
  2589. if (i != emittedMinNumbers.end())
  2590. {
  2591. props.push_back(strNumMin);
  2592. }
  2593. i = emittedMaxNumbers.find(prop);
  2594. if (i != emittedMaxNumbers.end())
  2595. {
  2596. props.push_back(strNumMax);
  2597. }
  2598. std::sort(props.begin(), props.end());
  2599. std::string propsString = cmJoin(cmMakeRange(props).retreat(1), ", ");
  2600. propsString += " and the " + props.back();
  2601. std::ostringstream e;
  2602. e << "Property \"" << prop << "\" appears in both the "
  2603. << propsString <<
  2604. " property in the dependencies of target \"" << this->GetName() <<
  2605. "\". This is not allowed. A property may only require compatibility "
  2606. "in a boolean interpretation, a numeric minimum, a numeric maximum or a "
  2607. "string interpretation, but not a mixture.";
  2608. this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
  2609. }
  2610. }
  2611. //----------------------------------------------------------------------------
  2612. std::string compatibilityType(CompatibleType t)
  2613. {
  2614. switch(t)
  2615. {
  2616. case BoolType:
  2617. return "Boolean compatibility";
  2618. case StringType:
  2619. return "String compatibility";
  2620. case NumberMaxType:
  2621. return "Numeric maximum compatibility";
  2622. case NumberMinType:
  2623. return "Numeric minimum compatibility";
  2624. }
  2625. assert(0 && "Unreachable!");
  2626. return "";
  2627. }
  2628. //----------------------------------------------------------------------------
  2629. std::string compatibilityAgree(CompatibleType t, bool dominant)
  2630. {
  2631. switch(t)
  2632. {
  2633. case BoolType:
  2634. case StringType:
  2635. return dominant ? "(Disagree)\n" : "(Agree)\n";
  2636. case NumberMaxType:
  2637. case NumberMinType:
  2638. return dominant ? "(Dominant)\n" : "(Ignored)\n";
  2639. }
  2640. assert(0 && "Unreachable!");
  2641. return "";
  2642. }
  2643. //----------------------------------------------------------------------------
  2644. template<typename PropertyType>
  2645. PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop);
  2646. //----------------------------------------------------------------------------
  2647. template<>
  2648. bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop)
  2649. {
  2650. return tgt->GetPropertyAsBool(prop);
  2651. }
  2652. //----------------------------------------------------------------------------
  2653. template<>
  2654. const char *getTypedProperty<const char *>(cmTarget const* tgt,
  2655. const std::string& prop)
  2656. {
  2657. return tgt->GetProperty(prop);
  2658. }
  2659. template<typename PropertyType>
  2660. std::string valueAsString(PropertyType);
  2661. template<>
  2662. std::string valueAsString<bool>(bool value)
  2663. {
  2664. return value ? "TRUE" : "FALSE";
  2665. }
  2666. template<>
  2667. std::string valueAsString<const char*>(const char* value)
  2668. {
  2669. return value ? value : "(unset)";
  2670. }
  2671. template<typename PropertyType>
  2672. PropertyType impliedValue(PropertyType);
  2673. template<>
  2674. bool impliedValue<bool>(bool)
  2675. {
  2676. return false;
  2677. }
  2678. template<>
  2679. const char* impliedValue<const char*>(const char*)
  2680. {
  2681. return "";
  2682. }
  2683. //----------------------------------------------------------------------------
  2684. template<typename PropertyType>
  2685. std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
  2686. PropertyType rhs,
  2687. CompatibleType t);
  2688. //----------------------------------------------------------------------------
  2689. template<>
  2690. std::pair<bool, bool> consistentProperty(bool lhs, bool rhs,
  2691. CompatibleType)
  2692. {
  2693. return std::make_pair(lhs == rhs, lhs);
  2694. }
  2695. //----------------------------------------------------------------------------
  2696. std::pair<bool, const char*> consistentStringProperty(const char *lhs,
  2697. const char *rhs)
  2698. {
  2699. const bool b = strcmp(lhs, rhs) == 0;
  2700. return std::make_pair(b, b ? lhs : 0);
  2701. }
  2702. //----------------------------------------------------------------------------
  2703. std::pair<bool, const char*> consistentNumberProperty(const char *lhs,
  2704. const char *rhs,
  2705. CompatibleType t)
  2706. {
  2707. char *pEnd;
  2708. const char* const null_ptr = 0;
  2709. long lnum = strtol(lhs, &pEnd, 0);
  2710. if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE)
  2711. {
  2712. return std::pair<bool, const char*>(false, null_ptr);
  2713. }
  2714. long rnum = strtol(rhs, &pEnd, 0);
  2715. if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE)
  2716. {
  2717. return std::pair<bool, const char*>(false, null_ptr);
  2718. }
  2719. if (t == NumberMaxType)
  2720. {
  2721. return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs);
  2722. }
  2723. else
  2724. {
  2725. return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs);
  2726. }
  2727. }
  2728. //----------------------------------------------------------------------------
  2729. template<>
  2730. std::pair<bool, const char*> consistentProperty(const char *lhs,
  2731. const char *rhs,
  2732. CompatibleType t)
  2733. {
  2734. if (!lhs && !rhs)
  2735. {
  2736. return std::make_pair(true, lhs);
  2737. }
  2738. if (!lhs)
  2739. {
  2740. return std::make_pair(true, rhs);
  2741. }
  2742. if (!rhs)
  2743. {
  2744. return std::make_pair(true, lhs);
  2745. }
  2746. const char* const null_ptr = 0;
  2747. switch(t)
  2748. {
  2749. case BoolType:
  2750. assert(0 && "consistentProperty for strings called with BoolType");
  2751. return std::pair<bool, const char*>(false, null_ptr);
  2752. case StringType:
  2753. return consistentStringProperty(lhs, rhs);
  2754. case NumberMinType:
  2755. case NumberMaxType:
  2756. return consistentNumberProperty(lhs, rhs, t);
  2757. }
  2758. assert(0 && "Unreachable!");
  2759. return std::pair<bool, const char*>(false, null_ptr);
  2760. }
  2761. //----------------------------------------------------------------------------
  2762. template<typename PropertyType>
  2763. PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
  2764. const std::string &p,
  2765. const std::string& config,
  2766. const char *defaultValue,
  2767. CompatibleType t,
  2768. PropertyType *)
  2769. {
  2770. PropertyType propContent = getTypedProperty<PropertyType>(tgt->Target, p);
  2771. const bool explicitlySet = tgt->Target->GetProperties()
  2772. .find(p)
  2773. != tgt->Target->GetProperties().end();
  2774. const bool impliedByUse =
  2775. tgt->Target->IsNullImpliedByLinkLibraries(p);
  2776. assert((impliedByUse ^ explicitlySet)
  2777. || (!impliedByUse && !explicitlySet));
  2778. std::vector<cmTarget const*> const& deps =
  2779. tgt->GetLinkImplementationClosure(config);
  2780. if(deps.empty())
  2781. {
  2782. return propContent;
  2783. }
  2784. bool propInitialized = explicitlySet;
  2785. std::string report = " * Target \"";
  2786. report += tgt->GetName();
  2787. if (explicitlySet)
  2788. {
  2789. report += "\" has property content \"";
  2790. report += valueAsString<PropertyType>(propContent);
  2791. report += "\"\n";
  2792. }
  2793. else if (impliedByUse)
  2794. {
  2795. report += "\" property is implied by use.\n";
  2796. }
  2797. else
  2798. {
  2799. report += "\" property not set.\n";
  2800. }
  2801. std::string interfaceProperty = "INTERFACE_" + p;
  2802. for(std::vector<cmTarget const*>::const_iterator li =
  2803. deps.begin();
  2804. li != deps.end(); ++li)
  2805. {
  2806. // An error should be reported if one dependency
  2807. // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
  2808. // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
  2809. // target itself has a POSITION_INDEPENDENT_CODE which disagrees
  2810. // with a dependency.
  2811. cmTarget const* theTarget = *li;
  2812. const bool ifaceIsSet = theTarget->GetProperties()
  2813. .find(interfaceProperty)
  2814. != theTarget->GetProperties().end();
  2815. PropertyType ifacePropContent =
  2816. getTypedProperty<PropertyType>(theTarget,
  2817. interfaceProperty);
  2818. std::string reportEntry;
  2819. if (ifaceIsSet)
  2820. {
  2821. reportEntry += " * Target \"";
  2822. reportEntry += theTarget->GetName();
  2823. reportEntry += "\" property value \"";
  2824. reportEntry += valueAsString<PropertyType>(ifacePropContent);
  2825. reportEntry += "\" ";
  2826. }
  2827. if (explicitlySet)
  2828. {
  2829. if (ifaceIsSet)
  2830. {
  2831. std::pair<bool, PropertyType> consistent =
  2832. consistentProperty(propContent,
  2833. ifacePropContent, t);
  2834. report += reportEntry;
  2835. report += compatibilityAgree(t, propContent != consistent.second);
  2836. if (!consistent.first)
  2837. {
  2838. std::ostringstream e;
  2839. e << "Property " << p << " on target \""
  2840. << tgt->GetName() << "\" does\nnot match the "
  2841. "INTERFACE_" << p << " property requirement\nof "
  2842. "dependency \"" << theTarget->GetName() << "\".\n";
  2843. cmSystemTools::Error(e.str().c_str());
  2844. break;
  2845. }
  2846. else
  2847. {
  2848. propContent = consistent.second;
  2849. continue;
  2850. }
  2851. }
  2852. else
  2853. {
  2854. // Explicitly set on target and not set in iface. Can't disagree.
  2855. continue;
  2856. }
  2857. }
  2858. else if (impliedByUse)
  2859. {
  2860. propContent = impliedValue<PropertyType>(propContent);
  2861. if (ifaceIsSet)
  2862. {
  2863. std::pair<bool, PropertyType> consistent =
  2864. consistentProperty(propContent,
  2865. ifacePropContent, t);
  2866. report += reportEntry;
  2867. report += compatibilityAgree(t, propContent != consistent.second);
  2868. if (!consistent.first)
  2869. {
  2870. std::ostringstream e;
  2871. e << "Property " << p << " on target \""
  2872. << tgt->GetName() << "\" is\nimplied to be " << defaultValue
  2873. << " because it was used to determine the link libraries\n"
  2874. "already. The INTERFACE_" << p << " property on\ndependency \""
  2875. << theTarget->GetName() << "\" is in conflict.\n";
  2876. cmSystemTools::Error(e.str().c_str());
  2877. break;
  2878. }
  2879. else
  2880. {
  2881. propContent = consistent.second;
  2882. continue;
  2883. }
  2884. }
  2885. else
  2886. {
  2887. // Implicitly set on target and not set in iface. Can't disagree.
  2888. continue;
  2889. }
  2890. }
  2891. else
  2892. {
  2893. if (ifaceIsSet)
  2894. {
  2895. if (propInitialized)
  2896. {
  2897. std::pair<bool, PropertyType> consistent =
  2898. consistentProperty(propContent,
  2899. ifacePropContent, t);
  2900. report += reportEntry;
  2901. report += compatibilityAgree(t, propContent != consistent.second);
  2902. if (!consistent.first)
  2903. {
  2904. std::ostringstream e;
  2905. e << "The INTERFACE_" << p << " property of \""
  2906. << theTarget->GetName() << "\" does\nnot agree with the value "
  2907. "of " << p << " already determined\nfor \""
  2908. << tgt->GetName() << "\".\n";
  2909. cmSystemTools::Error(e.str().c_str());
  2910. break;
  2911. }
  2912. else
  2913. {
  2914. propContent = consistent.second;
  2915. continue;
  2916. }
  2917. }
  2918. else
  2919. {
  2920. report += reportEntry + "(Interface set)\n";
  2921. propContent = ifacePropContent;
  2922. propInitialized = true;
  2923. }
  2924. }
  2925. else
  2926. {
  2927. // Not set. Nothing to agree on.
  2928. continue;
  2929. }
  2930. }
  2931. }
  2932. tgt->ReportPropertyOrigin(p, valueAsString<PropertyType>(propContent),
  2933. report, compatibilityType(t));
  2934. return propContent;
  2935. }
  2936. //----------------------------------------------------------------------------
  2937. bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
  2938. const std::string &p, const std::string& config) const
  2939. {
  2940. return checkInterfacePropertyCompatibility<bool>(this, p, config,
  2941. "FALSE",
  2942. BoolType, 0);
  2943. }
  2944. //----------------------------------------------------------------------------
  2945. const char* cmGeneratorTarget::GetLinkInterfaceDependentStringProperty(
  2946. const std::string &p,
  2947. const std::string& config) const
  2948. {
  2949. return checkInterfacePropertyCompatibility<const char *>(this,
  2950. p,
  2951. config,
  2952. "empty",
  2953. StringType, 0);
  2954. }
  2955. //----------------------------------------------------------------------------
  2956. const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMinProperty(
  2957. const std::string &p,
  2958. const std::string& config) const
  2959. {
  2960. return checkInterfacePropertyCompatibility<const char *>(this,
  2961. p,
  2962. config,
  2963. "empty",
  2964. NumberMinType, 0);
  2965. }
  2966. //----------------------------------------------------------------------------
  2967. const char * cmGeneratorTarget::GetLinkInterfaceDependentNumberMaxProperty(
  2968. const std::string &p,
  2969. const std::string& config) const
  2970. {
  2971. return checkInterfacePropertyCompatibility<const char *>(this,
  2972. p,
  2973. config,
  2974. "empty",
  2975. NumberMaxType, 0);
  2976. }
  2977. //----------------------------------------------------------------------------
  2978. cmComputeLinkInformation*
  2979. cmGeneratorTarget::GetLinkInformation(const std::string& config) const
  2980. {
  2981. // Lookup any existing information for this configuration.
  2982. std::string key(cmSystemTools::UpperCase(config));
  2983. cmTargetLinkInformationMap::iterator
  2984. i = this->LinkInformation.find(key);
  2985. if(i == this->LinkInformation.end())
  2986. {
  2987. // Compute information for this configuration.
  2988. cmComputeLinkInformation* info =
  2989. new cmComputeLinkInformation(this, config);
  2990. if(!info || !info->Compute())
  2991. {
  2992. delete info;
  2993. info = 0;
  2994. }
  2995. // Store the information for this configuration.
  2996. cmTargetLinkInformationMap::value_type entry(key, info);
  2997. i = this->LinkInformation.insert(entry).first;
  2998. if (info)
  2999. {
  3000. this->CheckPropertyCompatibility(info, config);
  3001. }
  3002. }
  3003. return i->second;
  3004. }
  3005. //----------------------------------------------------------------------------
  3006. void
  3007. cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
  3008. const std::string &result,
  3009. const std::string &report,
  3010. const std::string &compatibilityType) const
  3011. {
  3012. std::vector<std::string> debugProperties;
  3013. const char *debugProp = this->Target->GetMakefile()
  3014. ->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
  3015. if (debugProp)
  3016. {
  3017. cmSystemTools::ExpandListArgument(debugProp, debugProperties);
  3018. }
  3019. bool debugOrigin = !this->DebugCompatiblePropertiesDone[p]
  3020. && std::find(debugProperties.begin(),
  3021. debugProperties.end(),
  3022. p)
  3023. != debugProperties.end();
  3024. if (this->Target->GetMakefile()->IsConfigured())
  3025. {
  3026. this->DebugCompatiblePropertiesDone[p] = true;
  3027. }
  3028. if (!debugOrigin)
  3029. {
  3030. return;
  3031. }
  3032. std::string areport = compatibilityType;
  3033. areport += std::string(" of property \"") + p + "\" for target \"";
  3034. areport += std::string(this->GetName());
  3035. areport += "\" (result: \"";
  3036. areport += result;
  3037. areport += "\"):\n" + report;
  3038. this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
  3039. }