cmTarget.cxx 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 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 "cmTarget.h"
  11. #include "cmake.h"
  12. #include "cmMakefile.h"
  13. #include "cmSourceFile.h"
  14. #include "cmOutputConverter.h"
  15. #include "cmGlobalGenerator.h"
  16. #include "cmComputeLinkInformation.h"
  17. #include "cmListFileCache.h"
  18. #include "cmGeneratorExpression.h"
  19. #include "cmGeneratorExpressionDAGChecker.h"
  20. #include "cmAlgorithms.h"
  21. #include <cmsys/RegularExpression.hxx>
  22. #include <map>
  23. #include <set>
  24. #include <stdlib.h> // required for atof
  25. #include <assert.h>
  26. #include <errno.h>
  27. #if defined(CMAKE_BUILD_WITH_CMAKE)
  28. #include <cmsys/hash_set.hxx>
  29. #define UNORDERED_SET cmsys::hash_set
  30. #else
  31. #define UNORDERED_SET std::set
  32. #endif
  33. const char* cmTarget::GetTargetTypeName(cmState::TargetType targetType)
  34. {
  35. switch( targetType )
  36. {
  37. case cmState::STATIC_LIBRARY:
  38. return "STATIC_LIBRARY";
  39. case cmState::MODULE_LIBRARY:
  40. return "MODULE_LIBRARY";
  41. case cmState::SHARED_LIBRARY:
  42. return "SHARED_LIBRARY";
  43. case cmState::OBJECT_LIBRARY:
  44. return "OBJECT_LIBRARY";
  45. case cmState::EXECUTABLE:
  46. return "EXECUTABLE";
  47. case cmState::UTILITY:
  48. return "UTILITY";
  49. case cmState::GLOBAL_TARGET:
  50. return "GLOBAL_TARGET";
  51. case cmState::INTERFACE_LIBRARY:
  52. return "INTERFACE_LIBRARY";
  53. case cmState::UNKNOWN_LIBRARY:
  54. return "UNKNOWN_LIBRARY";
  55. }
  56. assert(0 && "Unexpected target type");
  57. return 0;
  58. }
  59. //----------------------------------------------------------------------------
  60. class cmTargetInternals
  61. {
  62. public:
  63. std::vector<std::string> IncludeDirectoriesEntries;
  64. std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
  65. std::vector<std::string> CompileOptionsEntries;
  66. std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
  67. std::vector<std::string> CompileFeaturesEntries;
  68. std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
  69. std::vector<std::string> CompileDefinitionsEntries;
  70. std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
  71. std::vector<std::string> SourceEntries;
  72. std::vector<cmListFileBacktrace> SourceBacktraces;
  73. std::vector<std::string> LinkImplementationPropertyEntries;
  74. std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
  75. };
  76. //----------------------------------------------------------------------------
  77. cmTarget::cmTarget()
  78. {
  79. this->Makefile = 0;
  80. #if defined(_WIN32) && !defined(__CYGWIN__)
  81. this->LinkLibrariesForVS6Analyzed = false;
  82. #endif
  83. this->HaveInstallRule = false;
  84. this->DLLPlatform = false;
  85. this->IsAndroid = false;
  86. this->IsApple = false;
  87. this->IsImportedTarget = false;
  88. this->BuildInterfaceIncludesAppended = false;
  89. }
  90. void cmTarget::SetType(cmState::TargetType type, const std::string& name)
  91. {
  92. this->Name = name;
  93. // only add dependency information for library targets
  94. this->TargetTypeValue = type;
  95. if(this->TargetTypeValue >= cmState::STATIC_LIBRARY
  96. && this->TargetTypeValue <= cmState::MODULE_LIBRARY)
  97. {
  98. this->RecordDependencies = true;
  99. }
  100. else
  101. {
  102. this->RecordDependencies = false;
  103. }
  104. }
  105. //----------------------------------------------------------------------------
  106. void cmTarget::SetMakefile(cmMakefile* mf)
  107. {
  108. // Set our makefile.
  109. this->Makefile = mf;
  110. // Check whether this is a DLL platform.
  111. this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
  112. this->Makefile->IsOn("CYGWIN") ||
  113. this->Makefile->IsOn("MINGW"));
  114. // Check whether we are targeting an Android platform.
  115. this->IsAndroid =
  116. strcmp(this->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"),
  117. "Android") == 0;
  118. // Check whether we are targeting an Apple platform.
  119. this->IsApple = this->Makefile->IsOn("APPLE");
  120. // Setup default property values.
  121. if (this->GetType() != cmState::INTERFACE_LIBRARY
  122. && this->GetType() != cmState::UTILITY)
  123. {
  124. this->SetPropertyDefault("ANDROID_API", 0);
  125. this->SetPropertyDefault("ANDROID_API_MIN", 0);
  126. this->SetPropertyDefault("ANDROID_ARCH", 0);
  127. this->SetPropertyDefault("ANDROID_STL_TYPE", 0);
  128. this->SetPropertyDefault("ANDROID_SKIP_ANT_STEP", 0);
  129. this->SetPropertyDefault("ANDROID_PROCESS_MAX", 0);
  130. this->SetPropertyDefault("ANDROID_PROGUARD", 0);
  131. this->SetPropertyDefault("ANDROID_PROGUARD_CONFIG_PATH", 0);
  132. this->SetPropertyDefault("ANDROID_SECURE_PROPS_PATH", 0);
  133. this->SetPropertyDefault("ANDROID_NATIVE_LIB_DIRECTORIES", 0);
  134. this->SetPropertyDefault("ANDROID_NATIVE_LIB_DEPENDENCIES", 0);
  135. this->SetPropertyDefault("ANDROID_JAVA_SOURCE_DIR", 0);
  136. this->SetPropertyDefault("ANDROID_JAR_DIRECTORIES", 0);
  137. this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", 0);
  138. this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", 0);
  139. this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", 0);
  140. this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
  141. this->SetPropertyDefault("INSTALL_RPATH", "");
  142. this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
  143. this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
  144. this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
  145. this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0);
  146. this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0);
  147. this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
  148. this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0);
  149. this->SetPropertyDefault("COMPILE_PDB_OUTPUT_DIRECTORY", 0);
  150. this->SetPropertyDefault("Fortran_FORMAT", 0);
  151. this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
  152. this->SetPropertyDefault("GNUtoMS", 0);
  153. this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
  154. this->SetPropertyDefault("AUTOMOC", 0);
  155. this->SetPropertyDefault("AUTOUIC", 0);
  156. this->SetPropertyDefault("AUTORCC", 0);
  157. this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
  158. this->SetPropertyDefault("AUTOUIC_OPTIONS", 0);
  159. this->SetPropertyDefault("AUTORCC_OPTIONS", 0);
  160. this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
  161. this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
  162. this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
  163. this->SetPropertyDefault("MACOSX_BUNDLE", 0);
  164. this->SetPropertyDefault("MACOSX_RPATH", 0);
  165. this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
  166. this->SetPropertyDefault("C_COMPILER_LAUNCHER", 0);
  167. this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", 0);
  168. this->SetPropertyDefault("C_STANDARD", 0);
  169. this->SetPropertyDefault("C_STANDARD_REQUIRED", 0);
  170. this->SetPropertyDefault("C_EXTENSIONS", 0);
  171. this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", 0);
  172. this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", 0);
  173. this->SetPropertyDefault("CXX_STANDARD", 0);
  174. this->SetPropertyDefault("CXX_STANDARD_REQUIRED", 0);
  175. this->SetPropertyDefault("CXX_EXTENSIONS", 0);
  176. this->SetPropertyDefault("LINK_SEARCH_START_STATIC", 0);
  177. this->SetPropertyDefault("LINK_SEARCH_END_STATIC", 0);
  178. }
  179. // Collect the set of configuration types.
  180. std::vector<std::string> configNames;
  181. mf->GetConfigurations(configNames);
  182. // Setup per-configuration property default values.
  183. if (this->GetType() != cmState::UTILITY)
  184. {
  185. const char* configProps[] = {
  186. "ARCHIVE_OUTPUT_DIRECTORY_",
  187. "LIBRARY_OUTPUT_DIRECTORY_",
  188. "RUNTIME_OUTPUT_DIRECTORY_",
  189. "PDB_OUTPUT_DIRECTORY_",
  190. "COMPILE_PDB_OUTPUT_DIRECTORY_",
  191. "MAP_IMPORTED_CONFIG_",
  192. 0};
  193. for(std::vector<std::string>::iterator ci = configNames.begin();
  194. ci != configNames.end(); ++ci)
  195. {
  196. std::string configUpper = cmSystemTools::UpperCase(*ci);
  197. for(const char** p = configProps; *p; ++p)
  198. {
  199. if (this->TargetTypeValue == cmState::INTERFACE_LIBRARY
  200. && strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0)
  201. {
  202. continue;
  203. }
  204. std::string property = *p;
  205. property += configUpper;
  206. this->SetPropertyDefault(property, 0);
  207. }
  208. // Initialize per-configuration name postfix property from the
  209. // variable only for non-executable targets. This preserves
  210. // compatibility with previous CMake versions in which executables
  211. // did not support this variable. Projects may still specify the
  212. // property directly.
  213. if(this->TargetTypeValue != cmState::EXECUTABLE
  214. && this->TargetTypeValue != cmState::INTERFACE_LIBRARY)
  215. {
  216. std::string property = cmSystemTools::UpperCase(*ci);
  217. property += "_POSTFIX";
  218. this->SetPropertyDefault(property, 0);
  219. }
  220. }
  221. }
  222. // Save the backtrace of target construction.
  223. this->Backtrace = this->Makefile->GetBacktrace();
  224. if (!this->IsImported())
  225. {
  226. // Initialize the INCLUDE_DIRECTORIES property based on the current value
  227. // of the same directory property:
  228. const cmStringRange parentIncludes =
  229. this->Makefile->GetIncludeDirectoriesEntries();
  230. const cmBacktraceRange parentIncludesBts =
  231. this->Makefile->GetIncludeDirectoriesBacktraces();
  232. this->Internal->IncludeDirectoriesEntries.insert(
  233. this->Internal->IncludeDirectoriesEntries.end(),
  234. parentIncludes.begin(), parentIncludes.end());
  235. this->Internal->IncludeDirectoriesBacktraces.insert(
  236. this->Internal->IncludeDirectoriesBacktraces.end(),
  237. parentIncludesBts.begin(), parentIncludesBts.end());
  238. const std::set<std::string> parentSystemIncludes =
  239. this->Makefile->GetSystemIncludeDirectories();
  240. this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(),
  241. parentSystemIncludes.end());
  242. const cmStringRange parentOptions =
  243. this->Makefile->GetCompileOptionsEntries();
  244. const cmBacktraceRange parentOptionsBts =
  245. this->Makefile->GetCompileOptionsBacktraces();
  246. this->Internal->CompileOptionsEntries.insert(
  247. this->Internal->CompileOptionsEntries.end(),
  248. parentOptions.begin(), parentOptions.end());
  249. this->Internal->CompileOptionsBacktraces.insert(
  250. this->Internal->CompileOptionsBacktraces.end(),
  251. parentOptionsBts.begin(), parentOptionsBts.end());
  252. }
  253. if (this->GetType() != cmState::INTERFACE_LIBRARY
  254. && this->GetType() != cmState::UTILITY)
  255. {
  256. this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
  257. this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
  258. this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0);
  259. }
  260. if(this->TargetTypeValue == cmState::EXECUTABLE)
  261. {
  262. this->SetPropertyDefault("ANDROID_GUI", 0);
  263. this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", 0);
  264. this->SetPropertyDefault("ENABLE_EXPORTS", 0);
  265. }
  266. if(this->TargetTypeValue == cmState::SHARED_LIBRARY
  267. || this->TargetTypeValue == cmState::MODULE_LIBRARY)
  268. {
  269. this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
  270. }
  271. if(this->TargetTypeValue == cmState::SHARED_LIBRARY)
  272. {
  273. this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0);
  274. }
  275. if (this->GetType() != cmState::INTERFACE_LIBRARY
  276. && this->GetType() != cmState::UTILITY)
  277. {
  278. this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
  279. }
  280. // Record current policies for later use.
  281. this->Makefile->RecordPolicies(this->PolicyMap);
  282. if (this->TargetTypeValue == cmState::INTERFACE_LIBRARY)
  283. {
  284. // This policy is checked in a few conditions. The properties relevant
  285. // to the policy are always ignored for cmState::INTERFACE_LIBRARY targets,
  286. // so ensure that the conditions don't lead to nonsense.
  287. this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
  288. }
  289. if (this->GetType() != cmState::INTERFACE_LIBRARY
  290. && this->GetType() != cmState::UTILITY)
  291. {
  292. this->SetPropertyDefault("JOB_POOL_COMPILE", 0);
  293. this->SetPropertyDefault("JOB_POOL_LINK", 0);
  294. }
  295. }
  296. //----------------------------------------------------------------------------
  297. void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
  298. {
  299. if(this->Utilities.insert(u).second && makefile)
  300. {
  301. UtilityBacktraces.insert(std::make_pair(u, makefile->GetBacktrace()));
  302. }
  303. }
  304. //----------------------------------------------------------------------------
  305. cmListFileBacktrace const* cmTarget::GetUtilityBacktrace(
  306. const std::string& u) const
  307. {
  308. std::map<std::string, cmListFileBacktrace>::const_iterator i =
  309. this->UtilityBacktraces.find(u);
  310. if(i == this->UtilityBacktraces.end()) return 0;
  311. return &i->second;
  312. }
  313. //----------------------------------------------------------------------------
  314. void cmTarget::FinishConfigure()
  315. {
  316. // Erase any cached link information that might have been comptued
  317. // on-demand during the configuration. This ensures that build
  318. // system generation uses up-to-date information even if other cache
  319. // invalidation code in this source file is buggy.
  320. #if defined(_WIN32) && !defined(__CYGWIN__)
  321. // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
  322. if(this->Makefile->GetGlobalGenerator()->IsForVS6())
  323. {
  324. this->AnalyzeLibDependenciesForVS6(*this->Makefile);
  325. }
  326. #endif
  327. }
  328. //----------------------------------------------------------------------------
  329. cmListFileBacktrace const& cmTarget::GetBacktrace() const
  330. {
  331. return this->Backtrace;
  332. }
  333. //----------------------------------------------------------------------------
  334. bool cmTarget::IsExecutableWithExports() const
  335. {
  336. return (this->GetType() == cmState::EXECUTABLE &&
  337. this->GetPropertyAsBool("ENABLE_EXPORTS"));
  338. }
  339. //----------------------------------------------------------------------------
  340. bool cmTarget::IsLinkable() const
  341. {
  342. return (this->GetType() == cmState::STATIC_LIBRARY ||
  343. this->GetType() == cmState::SHARED_LIBRARY ||
  344. this->GetType() == cmState::MODULE_LIBRARY ||
  345. this->GetType() == cmState::UNKNOWN_LIBRARY ||
  346. this->GetType() == cmState::INTERFACE_LIBRARY ||
  347. this->IsExecutableWithExports());
  348. }
  349. //----------------------------------------------------------------------------
  350. bool cmTarget::HasImportLibrary() const
  351. {
  352. return (this->DLLPlatform &&
  353. (this->GetType() == cmState::SHARED_LIBRARY ||
  354. this->IsExecutableWithExports()));
  355. }
  356. //----------------------------------------------------------------------------
  357. bool cmTarget::IsFrameworkOnApple() const
  358. {
  359. return (this->GetType() == cmState::SHARED_LIBRARY &&
  360. this->Makefile->IsOn("APPLE") &&
  361. this->GetPropertyAsBool("FRAMEWORK"));
  362. }
  363. //----------------------------------------------------------------------------
  364. bool cmTarget::IsAppBundleOnApple() const
  365. {
  366. return (this->GetType() == cmState::EXECUTABLE &&
  367. this->Makefile->IsOn("APPLE") &&
  368. this->GetPropertyAsBool("MACOSX_BUNDLE"));
  369. }
  370. //----------------------------------------------------------------------------
  371. bool cmTarget::IsCFBundleOnApple() const
  372. {
  373. return (this->GetType() == cmState::MODULE_LIBRARY &&
  374. this->Makefile->IsOn("APPLE") &&
  375. this->GetPropertyAsBool("BUNDLE"));
  376. }
  377. //----------------------------------------------------------------------------
  378. bool cmTarget::IsXCTestOnApple() const
  379. {
  380. return (this->IsCFBundleOnApple() &&
  381. this->GetPropertyAsBool("XCTEST"));
  382. }
  383. //----------------------------------------------------------------------------
  384. void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
  385. {
  386. if (!srcs.empty())
  387. {
  388. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  389. this->Internal->SourceEntries.push_back(cmJoin(srcs, ";"));
  390. this->Internal->SourceBacktraces.push_back(lfbt);
  391. }
  392. }
  393. //----------------------------------------------------------------------------
  394. void cmTarget::AddSources(std::vector<std::string> const& srcs)
  395. {
  396. std::string srcFiles;
  397. const char* sep = "";
  398. for(std::vector<std::string>::const_iterator i = srcs.begin();
  399. i != srcs.end(); ++i)
  400. {
  401. std::string filename = *i;
  402. const char* src = filename.c_str();
  403. if(!(src[0] == '$' && src[1] == '<'))
  404. {
  405. if(!filename.empty())
  406. {
  407. filename = this->ProcessSourceItemCMP0049(filename);
  408. if(filename.empty())
  409. {
  410. return;
  411. }
  412. }
  413. this->Makefile->GetOrCreateSource(filename);
  414. }
  415. srcFiles += sep;
  416. srcFiles += filename;
  417. sep = ";";
  418. }
  419. if (!srcFiles.empty())
  420. {
  421. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  422. this->Internal->SourceEntries.push_back(srcFiles);
  423. this->Internal->SourceBacktraces.push_back(lfbt);
  424. }
  425. }
  426. //----------------------------------------------------------------------------
  427. std::string cmTarget::ProcessSourceItemCMP0049(const std::string& s)
  428. {
  429. std::string src = s;
  430. // For backwards compatibility replace varibles in source names.
  431. // This should eventually be removed.
  432. this->Makefile->ExpandVariablesInString(src);
  433. if (src != s)
  434. {
  435. std::ostringstream e;
  436. bool noMessage = false;
  437. cmake::MessageType messageType = cmake::AUTHOR_WARNING;
  438. switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0049))
  439. {
  440. case cmPolicies::WARN:
  441. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0049) << "\n";
  442. break;
  443. case cmPolicies::OLD:
  444. noMessage = true;
  445. break;
  446. case cmPolicies::REQUIRED_ALWAYS:
  447. case cmPolicies::REQUIRED_IF_USED:
  448. case cmPolicies::NEW:
  449. messageType = cmake::FATAL_ERROR;
  450. }
  451. if (!noMessage)
  452. {
  453. e << "Legacy variable expansion in source file \""
  454. << s << "\" expanded to \"" << src << "\" in target \""
  455. << this->GetName() << "\". This behavior will be removed in a "
  456. "future version of CMake.";
  457. this->Makefile->IssueMessage(messageType, e.str());
  458. if (messageType == cmake::FATAL_ERROR)
  459. {
  460. return "";
  461. }
  462. }
  463. }
  464. return src;
  465. }
  466. //----------------------------------------------------------------------------
  467. cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
  468. {
  469. std::string src = this->ProcessSourceItemCMP0049(s);
  470. if(!s.empty() && src.empty())
  471. {
  472. return 0;
  473. }
  474. return this->AddSource(src);
  475. }
  476. //----------------------------------------------------------------------------
  477. struct CreateLocation
  478. {
  479. cmMakefile const* Makefile;
  480. CreateLocation(cmMakefile const* mf)
  481. : Makefile(mf)
  482. {
  483. }
  484. cmSourceFileLocation operator()(const std::string& filename)
  485. {
  486. return cmSourceFileLocation(this->Makefile, filename);
  487. }
  488. };
  489. //----------------------------------------------------------------------------
  490. struct LocationMatcher
  491. {
  492. const cmSourceFileLocation& Needle;
  493. LocationMatcher(const cmSourceFileLocation& needle)
  494. : Needle(needle)
  495. {
  496. }
  497. bool operator()(cmSourceFileLocation &loc)
  498. {
  499. return loc.Matches(this->Needle);
  500. }
  501. };
  502. //----------------------------------------------------------------------------
  503. struct TargetPropertyEntryFinder
  504. {
  505. private:
  506. const cmSourceFileLocation& Needle;
  507. public:
  508. TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
  509. : Needle(needle)
  510. {
  511. }
  512. bool operator()(std::string const& entry)
  513. {
  514. std::vector<std::string> files;
  515. cmSystemTools::ExpandListArgument(entry, files);
  516. std::vector<cmSourceFileLocation> locations(files.size());
  517. std::transform(files.begin(), files.end(), locations.begin(),
  518. CreateLocation(this->Needle.GetMakefile()));
  519. return std::find_if(locations.begin(), locations.end(),
  520. LocationMatcher(this->Needle)) != locations.end();
  521. }
  522. };
  523. //----------------------------------------------------------------------------
  524. cmSourceFile* cmTarget::AddSource(const std::string& src)
  525. {
  526. cmSourceFileLocation sfl(this->Makefile, src);
  527. if (std::find_if(this->Internal->SourceEntries.begin(),
  528. this->Internal->SourceEntries.end(),
  529. TargetPropertyEntryFinder(sfl))
  530. == this->Internal->SourceEntries.end())
  531. {
  532. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  533. this->Internal->SourceEntries.push_back(src);
  534. this->Internal->SourceBacktraces.push_back(lfbt);
  535. }
  536. if (cmGeneratorExpression::Find(src) != std::string::npos)
  537. {
  538. return 0;
  539. }
  540. return this->Makefile->GetOrCreateSource(src);
  541. }
  542. //----------------------------------------------------------------------------
  543. void cmTarget::MergeLinkLibraries( cmMakefile& mf,
  544. const std::string& selfname,
  545. const LinkLibraryVectorType& libs )
  546. {
  547. // Only add on libraries we haven't added on before.
  548. // Assumption: the global link libraries could only grow, never shrink
  549. LinkLibraryVectorType::const_iterator i = libs.begin();
  550. i += this->PrevLinkedLibraries.size();
  551. for( ; i != libs.end(); ++i )
  552. {
  553. // This is equivalent to the target_link_libraries plain signature.
  554. this->AddLinkLibrary( mf, selfname, i->first, i->second );
  555. this->AppendProperty("INTERFACE_LINK_LIBRARIES",
  556. this->GetDebugGeneratorExpressions(i->first, i->second).c_str());
  557. }
  558. this->PrevLinkedLibraries = libs;
  559. }
  560. //----------------------------------------------------------------------------
  561. void cmTarget::AddLinkDirectory(const std::string& d)
  562. {
  563. // Make sure we don't add unnecessary search directories.
  564. if(this->LinkDirectoriesEmmitted.insert(d).second)
  565. {
  566. this->LinkDirectories.push_back(d);
  567. }
  568. }
  569. //----------------------------------------------------------------------------
  570. const std::vector<std::string>& cmTarget::GetLinkDirectories() const
  571. {
  572. return this->LinkDirectories;
  573. }
  574. //----------------------------------------------------------------------------
  575. cmTargetLinkLibraryType cmTarget::ComputeLinkType(
  576. const std::string& config) const
  577. {
  578. // No configuration is always optimized.
  579. if(config.empty())
  580. {
  581. return OPTIMIZED_LibraryType;
  582. }
  583. // Get the list of configurations considered to be DEBUG.
  584. std::vector<std::string> debugConfigs =
  585. this->Makefile->GetCMakeInstance()->GetDebugConfigs();
  586. // Check if any entry in the list matches this configuration.
  587. std::string configUpper = cmSystemTools::UpperCase(config);
  588. if (std::find(debugConfigs.begin(), debugConfigs.end(), configUpper) !=
  589. debugConfigs.end())
  590. {
  591. return DEBUG_LibraryType;
  592. }
  593. // The current configuration is not a debug configuration.
  594. return OPTIMIZED_LibraryType;
  595. }
  596. //----------------------------------------------------------------------------
  597. void cmTarget::ClearDependencyInformation( cmMakefile& mf,
  598. const std::string& target )
  599. {
  600. // Clear the dependencies. The cache variable must exist iff we are
  601. // recording dependency information for this target.
  602. std::string depname = target;
  603. depname += "_LIB_DEPENDS";
  604. if (this->RecordDependencies)
  605. {
  606. mf.AddCacheDefinition(depname, "",
  607. "Dependencies for target", cmState::STATIC);
  608. }
  609. else
  610. {
  611. if (mf.GetDefinition( depname ))
  612. {
  613. std::string message = "Target ";
  614. message += target;
  615. message += " has dependency information when it shouldn't.\n";
  616. message += "Your cache is probably stale. Please remove the entry\n ";
  617. message += depname;
  618. message += "\nfrom the cache.";
  619. cmSystemTools::Error( message.c_str() );
  620. }
  621. }
  622. }
  623. //----------------------------------------------------------------------------
  624. bool cmTarget::NameResolvesToFramework(const std::string& libname) const
  625. {
  626. return this->Makefile->GetGlobalGenerator()->
  627. NameResolvesToFramework(libname);
  628. }
  629. //----------------------------------------------------------------------------
  630. std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
  631. cmTargetLinkLibraryType llt) const
  632. {
  633. if (llt == GENERAL_LibraryType)
  634. {
  635. return value;
  636. }
  637. // Get the list of configurations considered to be DEBUG.
  638. std::vector<std::string> debugConfigs =
  639. this->Makefile->GetCMakeInstance()->GetDebugConfigs();
  640. std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
  641. if (debugConfigs.size() > 1)
  642. {
  643. for(std::vector<std::string>::const_iterator
  644. li = debugConfigs.begin() + 1; li != debugConfigs.end(); ++li)
  645. {
  646. configString += ",$<CONFIG:" + *li + ">";
  647. }
  648. configString = "$<OR:" + configString + ">";
  649. }
  650. if (llt == OPTIMIZED_LibraryType)
  651. {
  652. configString = "$<NOT:" + configString + ">";
  653. }
  654. return "$<" + configString + ":" + value + ">";
  655. }
  656. //----------------------------------------------------------------------------
  657. static std::string targetNameGenex(const std::string& lib)
  658. {
  659. return "$<TARGET_NAME:" + lib + ">";
  660. }
  661. //----------------------------------------------------------------------------
  662. bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
  663. cmListFileContext const& lfc)
  664. {
  665. bool ret = true;
  666. if (!this->TLLCommands.empty())
  667. {
  668. if (this->TLLCommands.back().first != signature)
  669. {
  670. ret = false;
  671. }
  672. }
  673. if (this->TLLCommands.empty() || this->TLLCommands.back().second != lfc)
  674. {
  675. this->TLLCommands.push_back(std::make_pair(signature, lfc));
  676. }
  677. return ret;
  678. }
  679. //----------------------------------------------------------------------------
  680. void cmTarget::GetTllSignatureTraces(std::ostringstream &s,
  681. TLLSignature sig) const
  682. {
  683. const char *sigString = (sig == cmTarget::KeywordTLLSignature ? "keyword"
  684. : "plain");
  685. s << "The uses of the " << sigString << " signature are here:\n";
  686. typedef std::vector<std::pair<TLLSignature, cmListFileContext> > Container;
  687. cmOutputConverter converter(this->GetMakefile()->GetStateSnapshot());
  688. for(Container::const_iterator it = this->TLLCommands.begin();
  689. it != this->TLLCommands.end(); ++it)
  690. {
  691. if (it->first == sig)
  692. {
  693. cmListFileContext lfc = it->second;
  694. lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
  695. s << " * " << lfc << std::endl;
  696. }
  697. }
  698. }
  699. //----------------------------------------------------------------------------
  700. void cmTarget::AddLinkLibrary(cmMakefile& mf,
  701. const std::string& target,
  702. const std::string& lib,
  703. cmTargetLinkLibraryType llt)
  704. {
  705. cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
  706. {
  707. const bool isNonImportedTarget = tgt && !tgt->IsImported();
  708. const std::string libName =
  709. (isNonImportedTarget && llt != GENERAL_LibraryType)
  710. ? targetNameGenex(lib)
  711. : lib;
  712. this->AppendProperty("LINK_LIBRARIES",
  713. this->GetDebugGeneratorExpressions(libName,
  714. llt).c_str());
  715. }
  716. if (cmGeneratorExpression::Find(lib) != std::string::npos
  717. || (tgt && tgt->GetType() == cmState::INTERFACE_LIBRARY)
  718. || (target == lib ))
  719. {
  720. return;
  721. }
  722. cmTarget::LibraryID tmp;
  723. tmp.first = lib;
  724. tmp.second = llt;
  725. #if defined(_WIN32) && !defined(__CYGWIN__)
  726. this->LinkLibrariesForVS6.push_back( tmp );
  727. #endif
  728. this->OriginalLinkLibraries.push_back(tmp);
  729. // Add the explicit dependency information for this target. This is
  730. // simply a set of libraries separated by ";". There should always
  731. // be a trailing ";". These library names are not canonical, in that
  732. // they may be "-framework x", "-ly", "/path/libz.a", etc.
  733. // We shouldn't remove duplicates here because external libraries
  734. // may be purposefully duplicated to handle recursive dependencies,
  735. // and we removing one instance will break the link line. Duplicates
  736. // will be appropriately eliminated at emit time.
  737. if(this->RecordDependencies)
  738. {
  739. std::string targetEntry = target;
  740. targetEntry += "_LIB_DEPENDS";
  741. std::string dependencies;
  742. const char* old_val = mf.GetDefinition( targetEntry );
  743. if( old_val )
  744. {
  745. dependencies += old_val;
  746. }
  747. switch (llt)
  748. {
  749. case GENERAL_LibraryType:
  750. dependencies += "general";
  751. break;
  752. case DEBUG_LibraryType:
  753. dependencies += "debug";
  754. break;
  755. case OPTIMIZED_LibraryType:
  756. dependencies += "optimized";
  757. break;
  758. }
  759. dependencies += ";";
  760. dependencies += lib;
  761. dependencies += ";";
  762. mf.AddCacheDefinition( targetEntry, dependencies.c_str(),
  763. "Dependencies for the target",
  764. cmState::STATIC );
  765. }
  766. }
  767. //----------------------------------------------------------------------------
  768. void
  769. cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs)
  770. {
  771. this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
  772. }
  773. cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
  774. {
  775. return cmMakeRange(this->Internal->IncludeDirectoriesEntries);
  776. }
  777. cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
  778. {
  779. return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
  780. }
  781. cmStringRange cmTarget::GetCompileOptionsEntries() const
  782. {
  783. return cmMakeRange(this->Internal->CompileOptionsEntries);
  784. }
  785. cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
  786. {
  787. return cmMakeRange(this->Internal->CompileOptionsBacktraces);
  788. }
  789. cmStringRange cmTarget::GetCompileFeaturesEntries() const
  790. {
  791. return cmMakeRange(this->Internal->CompileFeaturesEntries);
  792. }
  793. cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
  794. {
  795. return cmMakeRange(this->Internal->CompileFeaturesBacktraces);
  796. }
  797. cmStringRange cmTarget::GetCompileDefinitionsEntries() const
  798. {
  799. return cmMakeRange(this->Internal->CompileDefinitionsEntries);
  800. }
  801. cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
  802. {
  803. return cmMakeRange(this->Internal->CompileDefinitionsBacktraces);
  804. }
  805. cmStringRange cmTarget::GetSourceEntries() const
  806. {
  807. return cmMakeRange(this->Internal->SourceEntries);
  808. }
  809. cmBacktraceRange cmTarget::GetSourceBacktraces() const
  810. {
  811. return cmMakeRange(this->Internal->SourceBacktraces);
  812. }
  813. cmStringRange cmTarget::GetLinkImplementationEntries() const
  814. {
  815. return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
  816. }
  817. cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
  818. {
  819. return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
  820. }
  821. #if defined(_WIN32) && !defined(__CYGWIN__)
  822. //----------------------------------------------------------------------------
  823. void
  824. cmTarget::AnalyzeLibDependenciesForVS6( const cmMakefile& mf )
  825. {
  826. // There are two key parts of the dependency analysis: (1)
  827. // determining the libraries in the link line, and (2) constructing
  828. // the dependency graph for those libraries.
  829. //
  830. // The latter is done using the cache entries that record the
  831. // dependencies of each library.
  832. //
  833. // The former is a more thorny issue, since it is not clear how to
  834. // determine if two libraries listed on the link line refer to the a
  835. // single library or not. For example, consider the link "libraries"
  836. // /usr/lib/libtiff.so -ltiff
  837. // Is this one library or two? The solution implemented here is the
  838. // simplest (and probably the only practical) one: two libraries are
  839. // the same if their "link strings" are identical. Thus, the two
  840. // libraries above are considered distinct. This also means that for
  841. // dependency analysis to be effective, the CMake user must specify
  842. // libraries build by his project without using any linker flags or
  843. // file extensions. That is,
  844. // LINK_LIBRARIES( One Two )
  845. // instead of
  846. // LINK_LIBRARIES( -lOne ${binarypath}/libTwo.a )
  847. // The former is probably what most users would do, but it never
  848. // hurts to document the assumptions. :-) Therefore, in the analysis
  849. // code, the "canonical name" of a library is simply its name as
  850. // given to a LINK_LIBRARIES command.
  851. //
  852. // Also, we will leave the original link line intact; we will just add any
  853. // dependencies that were missing.
  854. //
  855. // There is a problem with recursive external libraries
  856. // (i.e. libraries with no dependency information that are
  857. // recursively dependent). We must make sure that the we emit one of
  858. // the libraries twice to satisfy the recursion, but we shouldn't
  859. // emit it more times than necessary. In particular, we must make
  860. // sure that handling this improbable case doesn't cost us when
  861. // dealing with the common case of non-recursive libraries. The
  862. // solution is to assume that the recursion is satisfied at one node
  863. // of the dependency tree. To illustrate, assume libA and libB are
  864. // extrenal and mutually dependent. Suppose libX depends on
  865. // libA, and libY on libA and libX. Then
  866. // TARGET_LINK_LIBRARIES( Y X A B A )
  867. // TARGET_LINK_LIBRARIES( X A B A )
  868. // TARGET_LINK_LIBRARIES( Exec Y )
  869. // would result in "-lY -lX -lA -lB -lA". This is the correct way to
  870. // specify the dependencies, since the mutual dependency of A and B
  871. // is resolved *every time libA is specified*.
  872. //
  873. // Something like
  874. // TARGET_LINK_LIBRARIES( Y X A B A )
  875. // TARGET_LINK_LIBRARIES( X A B )
  876. // TARGET_LINK_LIBRARIES( Exec Y )
  877. // would result in "-lY -lX -lA -lB", and the mutual dependency
  878. // information is lost. This is because in some case (Y), the mutual
  879. // dependency of A and B is listed, while in another other case (X),
  880. // it is not. Depending on which line actually emits A, the mutual
  881. // dependency may or may not be on the final link line. We can't
  882. // handle this pathalogical case cleanly without emitting extra
  883. // libraries for the normal cases. Besides, the dependency
  884. // information for X is wrong anyway: if we build an executable
  885. // depending on X alone, we would not have the mutual dependency on
  886. // A and B resolved.
  887. //
  888. // IMPROVEMENTS:
  889. // -- The current algorithm will not always pick the "optimal" link line
  890. // when recursive dependencies are present. It will instead break the
  891. // cycles at an aribtrary point. The majority of projects won't have
  892. // cyclic dependencies, so this is probably not a big deal. Note that
  893. // the link line is always correct, just not necessary optimal.
  894. {
  895. // Expand variables in link library names. This is for backwards
  896. // compatibility with very early CMake versions and should
  897. // eventually be removed. This code was moved here from the end of
  898. // old source list processing code which was called just before this
  899. // method.
  900. for(LinkLibraryVectorType::iterator p = this->LinkLibrariesForVS6.begin();
  901. p != this->LinkLibrariesForVS6.end(); ++p)
  902. {
  903. this->Makefile->ExpandVariablesInString(p->first, true, true);
  904. }
  905. }
  906. // The dependency map.
  907. DependencyMap dep_map;
  908. // 1. Build the dependency graph
  909. //
  910. for(LinkLibraryVectorType::reverse_iterator lib
  911. = this->LinkLibrariesForVS6.rbegin();
  912. lib != this->LinkLibrariesForVS6.rend(); ++lib)
  913. {
  914. this->GatherDependenciesForVS6( mf, *lib, dep_map);
  915. }
  916. // 2. Remove any dependencies that are already satisfied in the original
  917. // link line.
  918. //
  919. for(LinkLibraryVectorType::iterator lib = this->LinkLibrariesForVS6.begin();
  920. lib != this->LinkLibrariesForVS6.end(); ++lib)
  921. {
  922. for( LinkLibraryVectorType::iterator lib2 = lib;
  923. lib2 != this->LinkLibrariesForVS6.end(); ++lib2)
  924. {
  925. this->DeleteDependencyForVS6( dep_map, *lib, *lib2);
  926. }
  927. }
  928. // 3. Create the new link line by simply emitting any dependencies that are
  929. // missing. Start from the back and keep adding.
  930. //
  931. std::set<DependencyMap::key_type> done, visited;
  932. std::vector<DependencyMap::key_type> newLinkLibrariesForVS6;
  933. for(LinkLibraryVectorType::reverse_iterator lib =
  934. this->LinkLibrariesForVS6.rbegin();
  935. lib != this->LinkLibrariesForVS6.rend(); ++lib)
  936. {
  937. // skip zero size library entries, this may happen
  938. // if a variable expands to nothing.
  939. if (!lib->first.empty())
  940. {
  941. this->EmitForVS6( *lib, dep_map, done, visited, newLinkLibrariesForVS6 );
  942. }
  943. }
  944. // 4. Add the new libraries to the link line.
  945. //
  946. for( std::vector<DependencyMap::key_type>::reverse_iterator k =
  947. newLinkLibrariesForVS6.rbegin();
  948. k != newLinkLibrariesForVS6.rend(); ++k )
  949. {
  950. // get the llt from the dep_map
  951. this->LinkLibrariesForVS6.push_back( std::make_pair(k->first,k->second) );
  952. }
  953. this->LinkLibrariesForVS6Analyzed = true;
  954. }
  955. //----------------------------------------------------------------------------
  956. void cmTarget::InsertDependencyForVS6( DependencyMap& depMap,
  957. const LibraryID& lib,
  958. const LibraryID& dep)
  959. {
  960. depMap[lib].push_back(dep);
  961. }
  962. //----------------------------------------------------------------------------
  963. void cmTarget::DeleteDependencyForVS6( DependencyMap& depMap,
  964. const LibraryID& lib,
  965. const LibraryID& dep)
  966. {
  967. // Make sure there is an entry in the map for lib. If so, delete all
  968. // dependencies to dep. There may be repeated entries because of
  969. // external libraries that are specified multiple times.
  970. DependencyMap::iterator map_itr = depMap.find( lib );
  971. if( map_itr != depMap.end() )
  972. {
  973. DependencyList& depList = map_itr->second;
  974. DependencyList::iterator begin =
  975. std::remove(depList.begin(), depList.end(), dep);
  976. depList.erase(begin, depList.end());
  977. }
  978. }
  979. //----------------------------------------------------------------------------
  980. void cmTarget::EmitForVS6(const LibraryID lib,
  981. const DependencyMap& dep_map,
  982. std::set<LibraryID>& emitted,
  983. std::set<LibraryID>& visited,
  984. DependencyList& link_line )
  985. {
  986. // It's already been emitted
  987. if( emitted.find(lib) != emitted.end() )
  988. {
  989. return;
  990. }
  991. // Emit the dependencies only if this library node hasn't been
  992. // visited before. If it has, then we have a cycle. The recursion
  993. // that got us here should take care of everything.
  994. if( visited.insert(lib).second )
  995. {
  996. if( dep_map.find(lib) != dep_map.end() ) // does it have dependencies?
  997. {
  998. const DependencyList& dep_on = dep_map.find( lib )->second;
  999. DependencyList::const_reverse_iterator i;
  1000. // To cater for recursive external libraries, we must emit
  1001. // duplicates on this link line *unless* they were emitted by
  1002. // some other node, in which case we assume that the recursion
  1003. // was resolved then. We making the simplifying assumption that
  1004. // any duplicates on a single link line are on purpose, and must
  1005. // be preserved.
  1006. // This variable will keep track of the libraries that were
  1007. // emitted directly from the current node, and not from a
  1008. // recursive call. This way, if we come across a library that
  1009. // has already been emitted, we repeat it iff it has been
  1010. // emitted here.
  1011. std::set<DependencyMap::key_type> emitted_here;
  1012. for( i = dep_on.rbegin(); i != dep_on.rend(); ++i )
  1013. {
  1014. if( emitted_here.find(*i) != emitted_here.end() )
  1015. {
  1016. // a repeat. Must emit.
  1017. emitted.insert(*i);
  1018. link_line.push_back( *i );
  1019. }
  1020. else
  1021. {
  1022. // Emit only if no-one else has
  1023. if( emitted.find(*i) == emitted.end() )
  1024. {
  1025. // emit dependencies
  1026. this->EmitForVS6( *i, dep_map, emitted, visited, link_line );
  1027. // emit self
  1028. emitted.insert(*i);
  1029. emitted_here.insert(*i);
  1030. link_line.push_back( *i );
  1031. }
  1032. }
  1033. }
  1034. }
  1035. }
  1036. }
  1037. //----------------------------------------------------------------------------
  1038. void cmTarget::GatherDependenciesForVS6( const cmMakefile& mf,
  1039. const LibraryID& lib,
  1040. DependencyMap& dep_map)
  1041. {
  1042. // If the library is already in the dependency map, then it has
  1043. // already been fully processed.
  1044. if( dep_map.find(lib) != dep_map.end() )
  1045. {
  1046. return;
  1047. }
  1048. const char* deps = mf.GetDefinition( lib.first+"_LIB_DEPENDS" );
  1049. if( deps && strcmp(deps,"") != 0 )
  1050. {
  1051. // Make sure this library is in the map, even if it has an empty
  1052. // set of dependencies. This distinguishes the case of explicitly
  1053. // no dependencies with that of unspecified dependencies.
  1054. dep_map[lib];
  1055. // Parse the dependency information, which is a set of
  1056. // type, library pairs separated by ";". There is always a trailing ";".
  1057. cmTargetLinkLibraryType llt = GENERAL_LibraryType;
  1058. std::string depline = deps;
  1059. std::string::size_type start = 0;
  1060. std::string::size_type end;
  1061. end = depline.find( ";", start );
  1062. while( end != std::string::npos )
  1063. {
  1064. std::string l = depline.substr( start, end-start );
  1065. if(!l.empty())
  1066. {
  1067. if (l == "debug")
  1068. {
  1069. llt = DEBUG_LibraryType;
  1070. }
  1071. else if (l == "optimized")
  1072. {
  1073. llt = OPTIMIZED_LibraryType;
  1074. }
  1075. else if (l == "general")
  1076. {
  1077. llt = GENERAL_LibraryType;
  1078. }
  1079. else
  1080. {
  1081. LibraryID lib2(l,llt);
  1082. this->InsertDependencyForVS6( dep_map, lib, lib2);
  1083. this->GatherDependenciesForVS6( mf, lib2, dep_map);
  1084. llt = GENERAL_LibraryType;
  1085. }
  1086. }
  1087. start = end+1; // skip the ;
  1088. end = depline.find( ";", start );
  1089. }
  1090. // cannot depend on itself
  1091. this->DeleteDependencyForVS6( dep_map, lib, lib);
  1092. }
  1093. }
  1094. #endif
  1095. //----------------------------------------------------------------------------
  1096. static bool whiteListedInterfaceProperty(const std::string& prop)
  1097. {
  1098. if(cmHasLiteralPrefix(prop, "INTERFACE_"))
  1099. {
  1100. return true;
  1101. }
  1102. static UNORDERED_SET<std::string> builtIns;
  1103. if (builtIns.empty())
  1104. {
  1105. builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
  1106. builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
  1107. builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
  1108. builtIns.insert("COMPATIBLE_INTERFACE_STRING");
  1109. builtIns.insert("EXPORT_NAME");
  1110. builtIns.insert("IMPORTED");
  1111. builtIns.insert("NAME");
  1112. builtIns.insert("TYPE");
  1113. }
  1114. if (builtIns.count(prop))
  1115. {
  1116. return true;
  1117. }
  1118. if (cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_"))
  1119. {
  1120. return true;
  1121. }
  1122. return false;
  1123. }
  1124. //----------------------------------------------------------------------------
  1125. void cmTarget::SetProperty(const std::string& prop, const char* value)
  1126. {
  1127. if (this->GetType() == cmState::INTERFACE_LIBRARY
  1128. && !whiteListedInterfaceProperty(prop))
  1129. {
  1130. std::ostringstream e;
  1131. e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
  1132. "The property \"" << prop << "\" is not allowed.";
  1133. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1134. return;
  1135. }
  1136. else if (prop == "NAME")
  1137. {
  1138. std::ostringstream e;
  1139. e << "NAME property is read-only\n";
  1140. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1141. return;
  1142. }
  1143. else if(prop == "INCLUDE_DIRECTORIES")
  1144. {
  1145. this->Internal->IncludeDirectoriesEntries.clear();
  1146. this->Internal->IncludeDirectoriesBacktraces.clear();
  1147. if (value)
  1148. {
  1149. this->Internal->IncludeDirectoriesEntries.push_back(value);
  1150. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1151. this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
  1152. }
  1153. }
  1154. else if(prop == "COMPILE_OPTIONS")
  1155. {
  1156. this->Internal->CompileOptionsEntries.clear();
  1157. this->Internal->CompileOptionsBacktraces.clear();
  1158. if (value)
  1159. {
  1160. this->Internal->CompileOptionsEntries.push_back(value);
  1161. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1162. this->Internal->CompileOptionsBacktraces.push_back(lfbt);
  1163. }
  1164. }
  1165. else if(prop == "COMPILE_FEATURES")
  1166. {
  1167. this->Internal->CompileFeaturesEntries.clear();
  1168. this->Internal->CompileFeaturesBacktraces.clear();
  1169. if (value)
  1170. {
  1171. this->Internal->CompileFeaturesEntries.push_back(value);
  1172. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1173. this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
  1174. }
  1175. }
  1176. else if(prop == "COMPILE_DEFINITIONS")
  1177. {
  1178. this->Internal->CompileDefinitionsEntries.clear();
  1179. this->Internal->CompileDefinitionsBacktraces.clear();
  1180. if (value)
  1181. {
  1182. this->Internal->CompileDefinitionsEntries.push_back(value);
  1183. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1184. this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
  1185. }
  1186. }
  1187. else if(prop == "EXPORT_NAME" && this->IsImported())
  1188. {
  1189. std::ostringstream e;
  1190. e << "EXPORT_NAME property can't be set on imported targets (\""
  1191. << this->Name << "\")\n";
  1192. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1193. }
  1194. else if (prop == "LINK_LIBRARIES")
  1195. {
  1196. this->Internal->LinkImplementationPropertyEntries.clear();
  1197. this->Internal->LinkImplementationPropertyBacktraces.clear();
  1198. if (value)
  1199. {
  1200. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1201. this->Internal->LinkImplementationPropertyEntries.push_back(value);
  1202. this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
  1203. }
  1204. }
  1205. else if (prop == "SOURCES")
  1206. {
  1207. if(this->IsImported())
  1208. {
  1209. std::ostringstream e;
  1210. e << "SOURCES property can't be set on imported targets (\""
  1211. << this->Name << "\")\n";
  1212. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1213. return;
  1214. }
  1215. this->Internal->SourceEntries.clear();
  1216. this->Internal->SourceBacktraces.clear();
  1217. if (value)
  1218. {
  1219. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1220. this->Internal->SourceEntries.push_back(value);
  1221. this->Internal->SourceBacktraces.push_back(lfbt);
  1222. }
  1223. }
  1224. else
  1225. {
  1226. this->Properties.SetProperty(prop, value);
  1227. this->MaybeInvalidatePropertyCache(prop);
  1228. }
  1229. }
  1230. //----------------------------------------------------------------------------
  1231. void cmTarget::AppendProperty(const std::string& prop, const char* value,
  1232. bool asString)
  1233. {
  1234. if (this->GetType() == cmState::INTERFACE_LIBRARY
  1235. && !whiteListedInterfaceProperty(prop))
  1236. {
  1237. std::ostringstream e;
  1238. e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
  1239. "The property \"" << prop << "\" is not allowed.";
  1240. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1241. return;
  1242. }
  1243. else if (prop == "NAME")
  1244. {
  1245. std::ostringstream e;
  1246. e << "NAME property is read-only\n";
  1247. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1248. return;
  1249. }
  1250. else if(prop == "INCLUDE_DIRECTORIES")
  1251. {
  1252. if (value && *value)
  1253. {
  1254. this->Internal->IncludeDirectoriesEntries.push_back(value);
  1255. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1256. this->Internal->IncludeDirectoriesBacktraces.push_back(lfbt);
  1257. }
  1258. }
  1259. else if(prop == "COMPILE_OPTIONS")
  1260. {
  1261. if (value && *value)
  1262. {
  1263. this->Internal->CompileOptionsEntries.push_back(value);
  1264. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1265. this->Internal->CompileOptionsBacktraces.push_back(lfbt);
  1266. }
  1267. }
  1268. else if(prop == "COMPILE_FEATURES")
  1269. {
  1270. if (value && *value)
  1271. {
  1272. this->Internal->CompileFeaturesEntries.push_back(value);
  1273. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1274. this->Internal->CompileFeaturesBacktraces.push_back(lfbt);
  1275. }
  1276. }
  1277. else if(prop == "COMPILE_DEFINITIONS")
  1278. {
  1279. if (value && *value)
  1280. {
  1281. this->Internal->CompileDefinitionsEntries.push_back(value);
  1282. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1283. this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
  1284. }
  1285. }
  1286. else if(prop == "EXPORT_NAME" && this->IsImported())
  1287. {
  1288. std::ostringstream e;
  1289. e << "EXPORT_NAME property can't be set on imported targets (\""
  1290. << this->Name << "\")\n";
  1291. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1292. }
  1293. else if (prop == "LINK_LIBRARIES")
  1294. {
  1295. if (value && *value)
  1296. {
  1297. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1298. this->Internal->LinkImplementationPropertyEntries.push_back(value);
  1299. this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
  1300. }
  1301. }
  1302. else if (prop == "SOURCES")
  1303. {
  1304. if(this->IsImported())
  1305. {
  1306. std::ostringstream e;
  1307. e << "SOURCES property can't be set on imported targets (\""
  1308. << this->Name << "\")\n";
  1309. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  1310. return;
  1311. }
  1312. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1313. this->Internal->SourceEntries.push_back(value);
  1314. this->Internal->SourceBacktraces.push_back(lfbt);
  1315. }
  1316. else
  1317. {
  1318. this->Properties.AppendProperty(prop, value, asString);
  1319. this->MaybeInvalidatePropertyCache(prop);
  1320. }
  1321. }
  1322. //----------------------------------------------------------------------------
  1323. std::string cmTarget::GetExportName() const
  1324. {
  1325. const char *exportName = this->GetProperty("EXPORT_NAME");
  1326. if (exportName && *exportName)
  1327. {
  1328. if (!cmGeneratorExpression::IsValidTargetName(exportName))
  1329. {
  1330. std::ostringstream e;
  1331. e << "EXPORT_NAME property \"" << exportName << "\" for \""
  1332. << this->GetName() << "\": is not valid.";
  1333. cmSystemTools::Error(e.str().c_str());
  1334. return "";
  1335. }
  1336. return exportName;
  1337. }
  1338. return this->GetName();
  1339. }
  1340. //----------------------------------------------------------------------------
  1341. void cmTarget::AppendBuildInterfaceIncludes()
  1342. {
  1343. if(this->GetType() != cmState::SHARED_LIBRARY &&
  1344. this->GetType() != cmState::STATIC_LIBRARY &&
  1345. this->GetType() != cmState::MODULE_LIBRARY &&
  1346. this->GetType() != cmState::INTERFACE_LIBRARY &&
  1347. !this->IsExecutableWithExports())
  1348. {
  1349. return;
  1350. }
  1351. if (this->BuildInterfaceIncludesAppended)
  1352. {
  1353. return;
  1354. }
  1355. this->BuildInterfaceIncludesAppended = true;
  1356. if (this->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE"))
  1357. {
  1358. const char *binDir = this->Makefile->GetCurrentBinaryDirectory();
  1359. const char *srcDir = this->Makefile->GetCurrentSourceDirectory();
  1360. const std::string dirs = std::string(binDir ? binDir : "")
  1361. + std::string(binDir ? ";" : "")
  1362. + std::string(srcDir ? srcDir : "");
  1363. if (!dirs.empty())
  1364. {
  1365. this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
  1366. ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
  1367. }
  1368. }
  1369. }
  1370. //----------------------------------------------------------------------------
  1371. void cmTarget::InsertInclude(std::string const& entry,
  1372. cmListFileBacktrace const& bt,
  1373. bool before)
  1374. {
  1375. std::vector<std::string>::iterator position =
  1376. before ? this->Internal->IncludeDirectoriesEntries.begin()
  1377. : this->Internal->IncludeDirectoriesEntries.end();
  1378. std::vector<cmListFileBacktrace>::iterator btPosition =
  1379. before ? this->Internal->IncludeDirectoriesBacktraces.begin()
  1380. : this->Internal->IncludeDirectoriesBacktraces.end();
  1381. this->Internal->IncludeDirectoriesEntries.insert(position, entry);
  1382. this->Internal->IncludeDirectoriesBacktraces.insert(btPosition, bt);
  1383. }
  1384. //----------------------------------------------------------------------------
  1385. void cmTarget::InsertCompileOption(std::string const& entry,
  1386. cmListFileBacktrace const& bt,
  1387. bool before)
  1388. {
  1389. std::vector<std::string>::iterator position =
  1390. before ? this->Internal->CompileOptionsEntries.begin()
  1391. : this->Internal->CompileOptionsEntries.end();
  1392. std::vector<cmListFileBacktrace>::iterator btPosition =
  1393. before ? this->Internal->CompileOptionsBacktraces.begin()
  1394. : this->Internal->CompileOptionsBacktraces.end();
  1395. this->Internal->CompileOptionsEntries.insert(position, entry);
  1396. this->Internal->CompileOptionsBacktraces.insert(btPosition, bt);
  1397. }
  1398. //----------------------------------------------------------------------------
  1399. void cmTarget::InsertCompileDefinition(std::string const& entry,
  1400. cmListFileBacktrace const& bt)
  1401. {
  1402. this->Internal->CompileDefinitionsEntries.push_back(entry);
  1403. this->Internal->CompileDefinitionsBacktraces.push_back(bt);
  1404. }
  1405. //----------------------------------------------------------------------------
  1406. void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
  1407. {
  1408. // Wipe out maps caching information affected by this property.
  1409. if(this->IsImported() && cmHasLiteralPrefix(prop, "IMPORTED"))
  1410. {
  1411. this->ImportInfoMap.clear();
  1412. }
  1413. }
  1414. //----------------------------------------------------------------------------
  1415. static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
  1416. const std::string& prop, const char* value, cmMakefile* context,
  1417. bool imported)
  1418. {
  1419. // Look for link-type keywords in the value.
  1420. static cmsys::RegularExpression
  1421. keys("(^|;)(debug|optimized|general)(;|$)");
  1422. if(!keys.find(value))
  1423. {
  1424. return;
  1425. }
  1426. // Support imported and non-imported versions of the property.
  1427. const char* base = (imported?
  1428. "IMPORTED_LINK_INTERFACE_LIBRARIES" :
  1429. "LINK_INTERFACE_LIBRARIES");
  1430. // Report an error.
  1431. std::ostringstream e;
  1432. e << "Property " << prop << " may not contain link-type keyword \""
  1433. << keys.match(2) << "\". "
  1434. << "The " << base << " property has a per-configuration "
  1435. << "version called " << base << "_<CONFIG> which may be "
  1436. << "used to specify per-configuration rules.";
  1437. if(!imported)
  1438. {
  1439. e << " "
  1440. << "Alternatively, an IMPORTED library may be created, configured "
  1441. << "with a per-configuration location, and then named in the "
  1442. << "property value. "
  1443. << "See the add_library command's IMPORTED mode for details."
  1444. << "\n"
  1445. << "If you have a list of libraries that already contains the "
  1446. << "keyword, use the target_link_libraries command with its "
  1447. << "LINK_INTERFACE_LIBRARIES mode to set the property. "
  1448. << "The command automatically recognizes link-type keywords and sets "
  1449. << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
  1450. << "properties accordingly.";
  1451. }
  1452. context->IssueMessage(cmake::FATAL_ERROR, e.str());
  1453. }
  1454. //----------------------------------------------------------------------------
  1455. static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
  1456. cmMakefile* context)
  1457. {
  1458. // Look for link-type keywords in the value.
  1459. static cmsys::RegularExpression
  1460. keys("(^|;)(debug|optimized|general)(;|$)");
  1461. if(!keys.find(value))
  1462. {
  1463. return;
  1464. }
  1465. // Report an error.
  1466. std::ostringstream e;
  1467. e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
  1468. "keyword \"" << keys.match(2) << "\". The INTERFACE_LINK_LIBRARIES "
  1469. "property may contain configuration-sensitive generator-expressions "
  1470. "which may be used to specify per-configuration rules.";
  1471. context->IssueMessage(cmake::FATAL_ERROR, e.str());
  1472. }
  1473. //----------------------------------------------------------------------------
  1474. void cmTarget::CheckProperty(const std::string& prop,
  1475. cmMakefile* context) const
  1476. {
  1477. // Certain properties need checking.
  1478. if(cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES"))
  1479. {
  1480. if(const char* value = this->GetProperty(prop))
  1481. {
  1482. cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
  1483. }
  1484. }
  1485. if(cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES"))
  1486. {
  1487. if(const char* value = this->GetProperty(prop))
  1488. {
  1489. cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
  1490. }
  1491. }
  1492. if(cmHasLiteralPrefix(prop, "INTERFACE_LINK_LIBRARIES"))
  1493. {
  1494. if(const char* value = this->GetProperty(prop))
  1495. {
  1496. cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
  1497. }
  1498. }
  1499. }
  1500. //----------------------------------------------------------------------------
  1501. void cmTarget::MarkAsImported()
  1502. {
  1503. this->IsImportedTarget = true;
  1504. }
  1505. //----------------------------------------------------------------------------
  1506. bool cmTarget::HaveWellDefinedOutputFiles() const
  1507. {
  1508. return
  1509. this->GetType() == cmState::STATIC_LIBRARY ||
  1510. this->GetType() == cmState::SHARED_LIBRARY ||
  1511. this->GetType() == cmState::MODULE_LIBRARY ||
  1512. this->GetType() == cmState::EXECUTABLE;
  1513. }
  1514. //----------------------------------------------------------------------------
  1515. const char* cmTarget::ImportedGetLocation(const std::string& config) const
  1516. {
  1517. static std::string location;
  1518. assert(this->IsImported());
  1519. location = this->ImportedGetFullPath(config, false);
  1520. return location.c_str();
  1521. }
  1522. //----------------------------------------------------------------------------
  1523. void cmTarget::GetTargetVersion(int& major, int& minor) const
  1524. {
  1525. int patch;
  1526. this->GetTargetVersion(false, major, minor, patch);
  1527. }
  1528. //----------------------------------------------------------------------------
  1529. void cmTarget::GetTargetVersion(bool soversion,
  1530. int& major, int& minor, int& patch) const
  1531. {
  1532. // Set the default values.
  1533. major = 0;
  1534. minor = 0;
  1535. patch = 0;
  1536. assert(this->GetType() != cmState::INTERFACE_LIBRARY);
  1537. // Look for a VERSION or SOVERSION property.
  1538. const char* prop = soversion? "SOVERSION" : "VERSION";
  1539. if(const char* version = this->GetProperty(prop))
  1540. {
  1541. // Try to parse the version number and store the results that were
  1542. // successfully parsed.
  1543. int parsed_major;
  1544. int parsed_minor;
  1545. int parsed_patch;
  1546. switch(sscanf(version, "%d.%d.%d",
  1547. &parsed_major, &parsed_minor, &parsed_patch))
  1548. {
  1549. case 3: patch = parsed_patch; // no break!
  1550. case 2: minor = parsed_minor; // no break!
  1551. case 1: major = parsed_major; // no break!
  1552. default: break;
  1553. }
  1554. }
  1555. }
  1556. //----------------------------------------------------------------------------
  1557. bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
  1558. {
  1559. if (this->IsImported())
  1560. {
  1561. return true;
  1562. }
  1563. std::ostringstream e;
  1564. const char *modal = 0;
  1565. cmake::MessageType messageType = cmake::AUTHOR_WARNING;
  1566. switch (context->GetPolicyStatus(cmPolicies::CMP0026))
  1567. {
  1568. case cmPolicies::WARN:
  1569. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0026) << "\n";
  1570. modal = "should";
  1571. case cmPolicies::OLD:
  1572. break;
  1573. case cmPolicies::REQUIRED_ALWAYS:
  1574. case cmPolicies::REQUIRED_IF_USED:
  1575. case cmPolicies::NEW:
  1576. modal = "may";
  1577. messageType = cmake::FATAL_ERROR;
  1578. }
  1579. if (modal)
  1580. {
  1581. e << "The LOCATION property " << modal << " not be read from target \""
  1582. << this->GetName() << "\". Use the target name directly with "
  1583. "add_custom_command, or use the generator expression $<TARGET_FILE>, "
  1584. "as appropriate.\n";
  1585. context->IssueMessage(messageType, e.str());
  1586. }
  1587. return messageType != cmake::FATAL_ERROR;
  1588. }
  1589. //----------------------------------------------------------------------------
  1590. const char *cmTarget::GetProperty(const std::string& prop) const
  1591. {
  1592. return this->GetProperty(prop, this->Makefile);
  1593. }
  1594. //----------------------------------------------------------------------------
  1595. const char *cmTarget::GetProperty(const std::string& prop,
  1596. cmMakefile* context) const
  1597. {
  1598. if (this->GetType() == cmState::INTERFACE_LIBRARY
  1599. && !whiteListedInterfaceProperty(prop))
  1600. {
  1601. std::ostringstream e;
  1602. e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
  1603. "The property \"" << prop << "\" is not allowed.";
  1604. context->IssueMessage(cmake::FATAL_ERROR, e.str());
  1605. return 0;
  1606. }
  1607. // Watch for special "computed" properties that are dependent on
  1608. // other properties or variables. Always recompute them.
  1609. if(this->GetType() == cmState::EXECUTABLE ||
  1610. this->GetType() == cmState::STATIC_LIBRARY ||
  1611. this->GetType() == cmState::SHARED_LIBRARY ||
  1612. this->GetType() == cmState::MODULE_LIBRARY ||
  1613. this->GetType() == cmState::UNKNOWN_LIBRARY)
  1614. {
  1615. static const std::string propLOCATION = "LOCATION";
  1616. if(prop == propLOCATION)
  1617. {
  1618. if (!this->HandleLocationPropertyPolicy(context))
  1619. {
  1620. return 0;
  1621. }
  1622. // Set the LOCATION property of the target.
  1623. //
  1624. // For an imported target this is the location of an arbitrary
  1625. // available configuration.
  1626. //
  1627. if(this->IsImported())
  1628. {
  1629. this->Properties.SetProperty(
  1630. propLOCATION, this->ImportedGetFullPath("", false).c_str());
  1631. }
  1632. else
  1633. {
  1634. // For a non-imported target this is deprecated because it
  1635. // cannot take into account the per-configuration name of the
  1636. // target because the configuration type may not be known at
  1637. // CMake time.
  1638. cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
  1639. gg->CreateGenerationObjects();
  1640. cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
  1641. this->Properties.SetProperty(propLOCATION,
  1642. gt->GetLocationForBuild());
  1643. }
  1644. }
  1645. // Support "LOCATION_<CONFIG>".
  1646. else if(cmHasLiteralPrefix(prop, "LOCATION_"))
  1647. {
  1648. if (!this->HandleLocationPropertyPolicy(context))
  1649. {
  1650. return 0;
  1651. }
  1652. const char* configName = prop.c_str() + 9;
  1653. if (this->IsImported())
  1654. {
  1655. this->Properties.SetProperty(
  1656. prop, this->ImportedGetFullPath(configName, false).c_str());
  1657. }
  1658. else
  1659. {
  1660. cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
  1661. gg->CreateGenerationObjects();
  1662. cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
  1663. this->Properties.SetProperty(
  1664. prop, gt->GetFullPath(configName, false).c_str());
  1665. }
  1666. }
  1667. // Support "<CONFIG>_LOCATION".
  1668. else if(cmHasLiteralSuffix(prop, "_LOCATION"))
  1669. {
  1670. std::string configName(prop.c_str(), prop.size() - 9);
  1671. if(configName != "IMPORTED")
  1672. {
  1673. if (!this->HandleLocationPropertyPolicy(context))
  1674. {
  1675. return 0;
  1676. }
  1677. if (this->IsImported())
  1678. {
  1679. this->Properties.SetProperty(
  1680. prop, this->ImportedGetFullPath(configName, false).c_str());
  1681. }
  1682. else
  1683. {
  1684. cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
  1685. gg->CreateGenerationObjects();
  1686. cmGeneratorTarget* gt = gg->GetGeneratorTarget(this);
  1687. this->Properties.SetProperty(
  1688. prop, gt->GetFullPath(configName, false).c_str());
  1689. }
  1690. }
  1691. }
  1692. }
  1693. static UNORDERED_SET<std::string> specialProps;
  1694. #define MAKE_STATIC_PROP(PROP) \
  1695. static const std::string prop##PROP = #PROP
  1696. MAKE_STATIC_PROP(LINK_LIBRARIES);
  1697. MAKE_STATIC_PROP(TYPE);
  1698. MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
  1699. MAKE_STATIC_PROP(COMPILE_FEATURES);
  1700. MAKE_STATIC_PROP(COMPILE_OPTIONS);
  1701. MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
  1702. MAKE_STATIC_PROP(IMPORTED);
  1703. MAKE_STATIC_PROP(NAME);
  1704. MAKE_STATIC_PROP(BINARY_DIR);
  1705. MAKE_STATIC_PROP(SOURCE_DIR);
  1706. MAKE_STATIC_PROP(SOURCES);
  1707. #undef MAKE_STATIC_PROP
  1708. if(specialProps.empty())
  1709. {
  1710. specialProps.insert(propLINK_LIBRARIES);
  1711. specialProps.insert(propTYPE);
  1712. specialProps.insert(propINCLUDE_DIRECTORIES);
  1713. specialProps.insert(propCOMPILE_FEATURES);
  1714. specialProps.insert(propCOMPILE_OPTIONS);
  1715. specialProps.insert(propCOMPILE_DEFINITIONS);
  1716. specialProps.insert(propIMPORTED);
  1717. specialProps.insert(propNAME);
  1718. specialProps.insert(propBINARY_DIR);
  1719. specialProps.insert(propSOURCE_DIR);
  1720. specialProps.insert(propSOURCES);
  1721. }
  1722. if(specialProps.count(prop))
  1723. {
  1724. if(prop == propLINK_LIBRARIES)
  1725. {
  1726. if (this->Internal->LinkImplementationPropertyEntries.empty())
  1727. {
  1728. return 0;
  1729. }
  1730. static std::string output;
  1731. output = cmJoin(this->Internal->LinkImplementationPropertyEntries, ";");
  1732. return output.c_str();
  1733. }
  1734. // the type property returns what type the target is
  1735. else if (prop == propTYPE)
  1736. {
  1737. return cmTarget::GetTargetTypeName(this->GetType());
  1738. }
  1739. else if(prop == propINCLUDE_DIRECTORIES)
  1740. {
  1741. if (this->Internal->IncludeDirectoriesEntries.empty())
  1742. {
  1743. return 0;
  1744. }
  1745. static std::string output;
  1746. output = cmJoin(this->Internal->IncludeDirectoriesEntries, ";");
  1747. return output.c_str();
  1748. }
  1749. else if(prop == propCOMPILE_FEATURES)
  1750. {
  1751. if (this->Internal->CompileFeaturesEntries.empty())
  1752. {
  1753. return 0;
  1754. }
  1755. static std::string output;
  1756. output = cmJoin(this->Internal->CompileFeaturesEntries, ";");
  1757. return output.c_str();
  1758. }
  1759. else if(prop == propCOMPILE_OPTIONS)
  1760. {
  1761. if (this->Internal->CompileOptionsEntries.empty())
  1762. {
  1763. return 0;
  1764. }
  1765. static std::string output;
  1766. output = cmJoin(this->Internal->CompileOptionsEntries, ";");
  1767. return output.c_str();
  1768. }
  1769. else if(prop == propCOMPILE_DEFINITIONS)
  1770. {
  1771. if (this->Internal->CompileDefinitionsEntries.empty())
  1772. {
  1773. return 0;
  1774. }
  1775. static std::string output;
  1776. output = cmJoin(this->Internal->CompileDefinitionsEntries, ";");
  1777. return output.c_str();
  1778. }
  1779. else if (prop == propIMPORTED)
  1780. {
  1781. return this->IsImported()?"TRUE":"FALSE";
  1782. }
  1783. else if (prop == propNAME)
  1784. {
  1785. return this->GetName().c_str();
  1786. }
  1787. else if (prop == propBINARY_DIR)
  1788. {
  1789. return this->GetMakefile()->GetCurrentBinaryDirectory();
  1790. }
  1791. else if (prop == propSOURCE_DIR)
  1792. {
  1793. return this->GetMakefile()->GetCurrentSourceDirectory();
  1794. }
  1795. else if(prop == propSOURCES)
  1796. {
  1797. if (this->Internal->SourceEntries.empty())
  1798. {
  1799. return 0;
  1800. }
  1801. std::ostringstream ss;
  1802. const char* sep = "";
  1803. for(std::vector<std::string>::const_iterator
  1804. i = this->Internal->SourceEntries.begin();
  1805. i != this->Internal->SourceEntries.end(); ++i)
  1806. {
  1807. std::string const& entry = *i;
  1808. std::vector<std::string> files;
  1809. cmSystemTools::ExpandListArgument(entry, files);
  1810. for (std::vector<std::string>::const_iterator
  1811. li = files.begin(); li != files.end(); ++li)
  1812. {
  1813. if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
  1814. (*li)[li->size() - 1] == '>')
  1815. {
  1816. std::string objLibName = li->substr(17, li->size()-18);
  1817. if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
  1818. {
  1819. ss << sep;
  1820. sep = ";";
  1821. ss << *li;
  1822. continue;
  1823. }
  1824. bool addContent = false;
  1825. bool noMessage = true;
  1826. std::ostringstream e;
  1827. cmake::MessageType messageType = cmake::AUTHOR_WARNING;
  1828. switch(context->GetPolicyStatus(cmPolicies::CMP0051))
  1829. {
  1830. case cmPolicies::WARN:
  1831. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n";
  1832. noMessage = false;
  1833. case cmPolicies::OLD:
  1834. break;
  1835. case cmPolicies::REQUIRED_ALWAYS:
  1836. case cmPolicies::REQUIRED_IF_USED:
  1837. case cmPolicies::NEW:
  1838. addContent = true;
  1839. }
  1840. if (!noMessage)
  1841. {
  1842. e << "Target \"" << this->Name << "\" contains "
  1843. "$<TARGET_OBJECTS> generator expression in its sources list. "
  1844. "This content was not previously part of the SOURCES property "
  1845. "when that property was read at configure time. Code reading "
  1846. "that property needs to be adapted to ignore the generator "
  1847. "expression using the string(GENEX_STRIP) command.";
  1848. context->IssueMessage(messageType, e.str());
  1849. }
  1850. if (addContent)
  1851. {
  1852. ss << sep;
  1853. sep = ";";
  1854. ss << *li;
  1855. }
  1856. }
  1857. else if (cmGeneratorExpression::Find(*li) == std::string::npos)
  1858. {
  1859. ss << sep;
  1860. sep = ";";
  1861. ss << *li;
  1862. }
  1863. else
  1864. {
  1865. cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
  1866. // Construct what is known about this source file location.
  1867. cmSourceFileLocation const& location = sf->GetLocation();
  1868. std::string sname = location.GetDirectory();
  1869. if(!sname.empty())
  1870. {
  1871. sname += "/";
  1872. }
  1873. sname += location.GetName();
  1874. ss << sep;
  1875. sep = ";";
  1876. // Append this list entry.
  1877. ss << sname;
  1878. }
  1879. }
  1880. }
  1881. this->Properties.SetProperty("SOURCES", ss.str().c_str());
  1882. }
  1883. }
  1884. const char *retVal = this->Properties.GetPropertyValue(prop);
  1885. if (!retVal)
  1886. {
  1887. const bool chain = this->GetMakefile()->GetState()->
  1888. IsPropertyChained(prop, cmProperty::TARGET);
  1889. if (chain)
  1890. {
  1891. return this->Makefile->GetProperty(prop, chain);
  1892. }
  1893. }
  1894. return retVal;
  1895. }
  1896. //----------------------------------------------------------------------------
  1897. bool cmTarget::GetPropertyAsBool(const std::string& prop) const
  1898. {
  1899. return cmSystemTools::IsOn(this->GetProperty(prop));
  1900. }
  1901. //----------------------------------------------------------------------------
  1902. const char* cmTarget::GetSuffixVariableInternal(bool implib) const
  1903. {
  1904. switch(this->GetType())
  1905. {
  1906. case cmState::STATIC_LIBRARY:
  1907. return "CMAKE_STATIC_LIBRARY_SUFFIX";
  1908. case cmState::SHARED_LIBRARY:
  1909. return (implib
  1910. ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
  1911. : "CMAKE_SHARED_LIBRARY_SUFFIX");
  1912. case cmState::MODULE_LIBRARY:
  1913. return (implib
  1914. ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
  1915. : "CMAKE_SHARED_MODULE_SUFFIX");
  1916. case cmState::EXECUTABLE:
  1917. return (implib
  1918. ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
  1919. // Android GUI application packages store the native
  1920. // binary as a shared library.
  1921. : (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")?
  1922. "CMAKE_SHARED_LIBRARY_SUFFIX" : "CMAKE_EXECUTABLE_SUFFIX"));
  1923. default:
  1924. break;
  1925. }
  1926. return "";
  1927. }
  1928. //----------------------------------------------------------------------------
  1929. const char* cmTarget::GetPrefixVariableInternal(bool implib) const
  1930. {
  1931. switch(this->GetType())
  1932. {
  1933. case cmState::STATIC_LIBRARY:
  1934. return "CMAKE_STATIC_LIBRARY_PREFIX";
  1935. case cmState::SHARED_LIBRARY:
  1936. return (implib
  1937. ? "CMAKE_IMPORT_LIBRARY_PREFIX"
  1938. : "CMAKE_SHARED_LIBRARY_PREFIX");
  1939. case cmState::MODULE_LIBRARY:
  1940. return (implib
  1941. ? "CMAKE_IMPORT_LIBRARY_PREFIX"
  1942. : "CMAKE_SHARED_MODULE_PREFIX");
  1943. case cmState::EXECUTABLE:
  1944. return (implib
  1945. ? "CMAKE_IMPORT_LIBRARY_PREFIX"
  1946. // Android GUI application packages store the native
  1947. // binary as a shared library.
  1948. : (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")?
  1949. "CMAKE_SHARED_LIBRARY_PREFIX" : ""));
  1950. default:
  1951. break;
  1952. }
  1953. return "";
  1954. }
  1955. //----------------------------------------------------------------------------
  1956. std::string
  1957. cmTarget::GetFullNameImported(const std::string& config, bool implib) const
  1958. {
  1959. return cmSystemTools::GetFilenameName(
  1960. this->ImportedGetFullPath(config, implib));
  1961. }
  1962. //----------------------------------------------------------------------------
  1963. std::string
  1964. cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
  1965. {
  1966. std::string result;
  1967. if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
  1968. {
  1969. result = implib? info->ImportLibrary : info->Location;
  1970. }
  1971. if(result.empty())
  1972. {
  1973. result = this->GetName();
  1974. result += "-NOTFOUND";
  1975. }
  1976. return result;
  1977. }
  1978. //----------------------------------------------------------------------------
  1979. void cmTarget::ComputeVersionedName(std::string& vName,
  1980. std::string const& prefix,
  1981. std::string const& base,
  1982. std::string const& suffix,
  1983. std::string const& name,
  1984. const char* version) const
  1985. {
  1986. vName = this->IsApple? (prefix+base) : name;
  1987. if(version)
  1988. {
  1989. vName += ".";
  1990. vName += version;
  1991. }
  1992. vName += this->IsApple? suffix : std::string();
  1993. }
  1994. //----------------------------------------------------------------------------
  1995. void cmTarget::SetPropertyDefault(const std::string& property,
  1996. const char* default_value)
  1997. {
  1998. // Compute the name of the variable holding the default value.
  1999. std::string var = "CMAKE_";
  2000. var += property;
  2001. if(const char* value = this->Makefile->GetDefinition(var))
  2002. {
  2003. this->SetProperty(property, value);
  2004. }
  2005. else if(default_value)
  2006. {
  2007. this->SetProperty(property, default_value);
  2008. }
  2009. }
  2010. //----------------------------------------------------------------------------
  2011. std::string cmTarget::GetFrameworkVersion() const
  2012. {
  2013. assert(this->GetType() != cmState::INTERFACE_LIBRARY);
  2014. if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION"))
  2015. {
  2016. return fversion;
  2017. }
  2018. else if(const char* tversion = this->GetProperty("VERSION"))
  2019. {
  2020. return tversion;
  2021. }
  2022. else
  2023. {
  2024. return "A";
  2025. }
  2026. }
  2027. //----------------------------------------------------------------------------
  2028. const char* cmTarget::GetExportMacro() const
  2029. {
  2030. // Define the symbol for targets that export symbols.
  2031. if(this->GetType() == cmState::SHARED_LIBRARY ||
  2032. this->GetType() == cmState::MODULE_LIBRARY ||
  2033. this->IsExecutableWithExports())
  2034. {
  2035. if(const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL"))
  2036. {
  2037. this->ExportMacro = custom_export_name;
  2038. }
  2039. else
  2040. {
  2041. std::string in = this->GetName();
  2042. in += "_EXPORTS";
  2043. this->ExportMacro = cmSystemTools::MakeCindentifier(in);
  2044. }
  2045. return this->ExportMacro.c_str();
  2046. }
  2047. else
  2048. {
  2049. return 0;
  2050. }
  2051. }
  2052. //----------------------------------------------------------------------------
  2053. void
  2054. cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
  2055. {
  2056. // At configure-time, this method can be called as part of getting the
  2057. // LOCATION property or to export() a file to be include()d. However
  2058. // there is no cmGeneratorTarget at configure-time, so search the SOURCES
  2059. // for TARGET_OBJECTS instead for backwards compatibility with OLD
  2060. // behavior of CMP0024 and CMP0026 only.
  2061. for(std::vector<std::string>::const_iterator
  2062. i = this->Internal->SourceEntries.begin();
  2063. i != this->Internal->SourceEntries.end(); ++i)
  2064. {
  2065. std::string const& entry = *i;
  2066. std::vector<std::string> files;
  2067. cmSystemTools::ExpandListArgument(entry, files);
  2068. for (std::vector<std::string>::const_iterator
  2069. li = files.begin(); li != files.end(); ++li)
  2070. {
  2071. if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
  2072. (*li)[li->size() - 1] == '>')
  2073. {
  2074. std::string objLibName = li->substr(17, li->size()-18);
  2075. if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
  2076. {
  2077. continue;
  2078. }
  2079. cmTarget *objLib = this->Makefile->FindTargetToUse(objLibName);
  2080. if(objLib)
  2081. {
  2082. objlibs.push_back(objLib);
  2083. }
  2084. }
  2085. }
  2086. }
  2087. }
  2088. //----------------------------------------------------------------------------
  2089. cmTarget::ImportInfo const*
  2090. cmTarget::GetImportInfo(const std::string& config) const
  2091. {
  2092. // There is no imported information for non-imported targets.
  2093. if(!this->IsImported())
  2094. {
  2095. return 0;
  2096. }
  2097. // Lookup/compute/cache the import information for this
  2098. // configuration.
  2099. std::string config_upper;
  2100. if(!config.empty())
  2101. {
  2102. config_upper = cmSystemTools::UpperCase(config);
  2103. }
  2104. else
  2105. {
  2106. config_upper = "NOCONFIG";
  2107. }
  2108. ImportInfoMapType::const_iterator i =
  2109. this->ImportInfoMap.find(config_upper);
  2110. if(i == this->ImportInfoMap.end())
  2111. {
  2112. ImportInfo info;
  2113. this->ComputeImportInfo(config_upper, info);
  2114. ImportInfoMapType::value_type entry(config_upper, info);
  2115. i = this->ImportInfoMap.insert(entry).first;
  2116. }
  2117. if(this->GetType() == cmState::INTERFACE_LIBRARY)
  2118. {
  2119. return &i->second;
  2120. }
  2121. // If the location is empty then the target is not available for
  2122. // this configuration.
  2123. if(i->second.Location.empty() && i->second.ImportLibrary.empty())
  2124. {
  2125. return 0;
  2126. }
  2127. // Return the import information.
  2128. return &i->second;
  2129. }
  2130. bool cmTarget::GetMappedConfig(std::string const& desired_config,
  2131. const char** loc,
  2132. const char** imp,
  2133. std::string& suffix) const
  2134. {
  2135. if (this->GetType() == cmState::INTERFACE_LIBRARY)
  2136. {
  2137. // This method attempts to find a config-specific LOCATION for the
  2138. // IMPORTED library. In the case of cmState::INTERFACE_LIBRARY, there is no
  2139. // LOCATION at all, so leaving *loc and *imp unchanged is the appropriate
  2140. // and valid response.
  2141. return true;
  2142. }
  2143. // Track the configuration-specific property suffix.
  2144. suffix = "_";
  2145. suffix += desired_config;
  2146. std::vector<std::string> mappedConfigs;
  2147. {
  2148. std::string mapProp = "MAP_IMPORTED_CONFIG_";
  2149. mapProp += desired_config;
  2150. if(const char* mapValue = this->GetProperty(mapProp))
  2151. {
  2152. cmSystemTools::ExpandListArgument(mapValue, mappedConfigs);
  2153. }
  2154. }
  2155. // If we needed to find one of the mapped configurations but did not
  2156. // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
  2157. // library or an executable with exports.
  2158. bool allowImp = this->HasImportLibrary();
  2159. // If a mapping was found, check its configurations.
  2160. for(std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
  2161. !*loc && !*imp && mci != mappedConfigs.end(); ++mci)
  2162. {
  2163. // Look for this configuration.
  2164. std::string mcUpper = cmSystemTools::UpperCase(*mci);
  2165. std::string locProp = "IMPORTED_LOCATION_";
  2166. locProp += mcUpper;
  2167. *loc = this->GetProperty(locProp);
  2168. if(allowImp)
  2169. {
  2170. std::string impProp = "IMPORTED_IMPLIB_";
  2171. impProp += mcUpper;
  2172. *imp = this->GetProperty(impProp);
  2173. }
  2174. // If it was found, use it for all properties below.
  2175. if(*loc || *imp)
  2176. {
  2177. suffix = "_";
  2178. suffix += mcUpper;
  2179. }
  2180. }
  2181. // If we needed to find one of the mapped configurations but did not
  2182. // then the target is not found. The project does not want any
  2183. // other configuration.
  2184. if(!mappedConfigs.empty() && !*loc && !*imp)
  2185. {
  2186. return false;
  2187. }
  2188. // If we have not yet found it then there are no mapped
  2189. // configurations. Look for an exact-match.
  2190. if(!*loc && !*imp)
  2191. {
  2192. std::string locProp = "IMPORTED_LOCATION";
  2193. locProp += suffix;
  2194. *loc = this->GetProperty(locProp);
  2195. if(allowImp)
  2196. {
  2197. std::string impProp = "IMPORTED_IMPLIB";
  2198. impProp += suffix;
  2199. *imp = this->GetProperty(impProp);
  2200. }
  2201. }
  2202. // If we have not yet found it then there are no mapped
  2203. // configurations and no exact match.
  2204. if(!*loc && !*imp)
  2205. {
  2206. // The suffix computed above is not useful.
  2207. suffix = "";
  2208. // Look for a configuration-less location. This may be set by
  2209. // manually-written code.
  2210. *loc = this->GetProperty("IMPORTED_LOCATION");
  2211. if(allowImp)
  2212. {
  2213. *imp = this->GetProperty("IMPORTED_IMPLIB");
  2214. }
  2215. }
  2216. // If we have not yet found it then the project is willing to try
  2217. // any available configuration.
  2218. if(!*loc && !*imp)
  2219. {
  2220. std::vector<std::string> availableConfigs;
  2221. if(const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS"))
  2222. {
  2223. cmSystemTools::ExpandListArgument(iconfigs, availableConfigs);
  2224. }
  2225. for(std::vector<std::string>::const_iterator
  2226. aci = availableConfigs.begin();
  2227. !*loc && !*imp && aci != availableConfigs.end(); ++aci)
  2228. {
  2229. suffix = "_";
  2230. suffix += cmSystemTools::UpperCase(*aci);
  2231. std::string locProp = "IMPORTED_LOCATION";
  2232. locProp += suffix;
  2233. *loc = this->GetProperty(locProp);
  2234. if(allowImp)
  2235. {
  2236. std::string impProp = "IMPORTED_IMPLIB";
  2237. impProp += suffix;
  2238. *imp = this->GetProperty(impProp);
  2239. }
  2240. }
  2241. }
  2242. // If we have not yet found it then the target is not available.
  2243. if(!*loc && !*imp)
  2244. {
  2245. return false;
  2246. }
  2247. return true;
  2248. }
  2249. //----------------------------------------------------------------------------
  2250. void cmTarget::ComputeImportInfo(std::string const& desired_config,
  2251. ImportInfo& info) const
  2252. {
  2253. // This method finds information about an imported target from its
  2254. // properties. The "IMPORTED_" namespace is reserved for properties
  2255. // defined by the project exporting the target.
  2256. // Initialize members.
  2257. info.NoSOName = false;
  2258. const char* loc = 0;
  2259. const char* imp = 0;
  2260. std::string suffix;
  2261. if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
  2262. {
  2263. return;
  2264. }
  2265. // Get the link interface.
  2266. {
  2267. std::string linkProp = "INTERFACE_LINK_LIBRARIES";
  2268. const char *propertyLibs = this->GetProperty(linkProp);
  2269. if (this->GetType() != cmState::INTERFACE_LIBRARY)
  2270. {
  2271. if(!propertyLibs)
  2272. {
  2273. linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
  2274. linkProp += suffix;
  2275. propertyLibs = this->GetProperty(linkProp);
  2276. }
  2277. if(!propertyLibs)
  2278. {
  2279. linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
  2280. propertyLibs = this->GetProperty(linkProp);
  2281. }
  2282. }
  2283. if(propertyLibs)
  2284. {
  2285. info.LibrariesProp = linkProp;
  2286. info.Libraries = propertyLibs;
  2287. }
  2288. }
  2289. if(this->GetType() == cmState::INTERFACE_LIBRARY)
  2290. {
  2291. return;
  2292. }
  2293. // A provided configuration has been chosen. Load the
  2294. // configuration's properties.
  2295. // Get the location.
  2296. if(loc)
  2297. {
  2298. info.Location = loc;
  2299. }
  2300. else
  2301. {
  2302. std::string impProp = "IMPORTED_LOCATION";
  2303. impProp += suffix;
  2304. if(const char* config_location = this->GetProperty(impProp))
  2305. {
  2306. info.Location = config_location;
  2307. }
  2308. else if(const char* location = this->GetProperty("IMPORTED_LOCATION"))
  2309. {
  2310. info.Location = location;
  2311. }
  2312. }
  2313. // Get the soname.
  2314. if(this->GetType() == cmState::SHARED_LIBRARY)
  2315. {
  2316. std::string soProp = "IMPORTED_SONAME";
  2317. soProp += suffix;
  2318. if(const char* config_soname = this->GetProperty(soProp))
  2319. {
  2320. info.SOName = config_soname;
  2321. }
  2322. else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
  2323. {
  2324. info.SOName = soname;
  2325. }
  2326. }
  2327. // Get the "no-soname" mark.
  2328. if(this->GetType() == cmState::SHARED_LIBRARY)
  2329. {
  2330. std::string soProp = "IMPORTED_NO_SONAME";
  2331. soProp += suffix;
  2332. if(const char* config_no_soname = this->GetProperty(soProp))
  2333. {
  2334. info.NoSOName = cmSystemTools::IsOn(config_no_soname);
  2335. }
  2336. else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME"))
  2337. {
  2338. info.NoSOName = cmSystemTools::IsOn(no_soname);
  2339. }
  2340. }
  2341. // Get the import library.
  2342. if(imp)
  2343. {
  2344. info.ImportLibrary = imp;
  2345. }
  2346. else if(this->GetType() == cmState::SHARED_LIBRARY ||
  2347. this->IsExecutableWithExports())
  2348. {
  2349. std::string impProp = "IMPORTED_IMPLIB";
  2350. impProp += suffix;
  2351. if(const char* config_implib = this->GetProperty(impProp))
  2352. {
  2353. info.ImportLibrary = config_implib;
  2354. }
  2355. else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
  2356. {
  2357. info.ImportLibrary = implib;
  2358. }
  2359. }
  2360. // Get the link dependencies.
  2361. {
  2362. std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
  2363. linkProp += suffix;
  2364. if(const char* config_libs = this->GetProperty(linkProp))
  2365. {
  2366. info.SharedDeps = config_libs;
  2367. }
  2368. else if(const char* libs =
  2369. this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
  2370. {
  2371. info.SharedDeps = libs;
  2372. }
  2373. }
  2374. // Get the link languages.
  2375. if(this->LinkLanguagePropagatesToDependents())
  2376. {
  2377. std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
  2378. linkProp += suffix;
  2379. if(const char* config_libs = this->GetProperty(linkProp))
  2380. {
  2381. info.Languages = config_libs;
  2382. }
  2383. else if(const char* libs =
  2384. this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
  2385. {
  2386. info.Languages = libs;
  2387. }
  2388. }
  2389. // Get the cyclic repetition count.
  2390. if(this->GetType() == cmState::STATIC_LIBRARY)
  2391. {
  2392. std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
  2393. linkProp += suffix;
  2394. if(const char* config_reps = this->GetProperty(linkProp))
  2395. {
  2396. sscanf(config_reps, "%u", &info.Multiplicity);
  2397. }
  2398. else if(const char* reps =
  2399. this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
  2400. {
  2401. sscanf(reps, "%u", &info.Multiplicity);
  2402. }
  2403. }
  2404. }
  2405. //----------------------------------------------------------------------------
  2406. std::string cmTarget::CheckCMP0004(std::string const& item) const
  2407. {
  2408. // Strip whitespace off the library names because we used to do this
  2409. // in case variables were expanded at generate time. We no longer
  2410. // do the expansion but users link to libraries like " ${VAR} ".
  2411. std::string lib = item;
  2412. std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
  2413. if(pos != lib.npos)
  2414. {
  2415. lib = lib.substr(pos, lib.npos);
  2416. }
  2417. pos = lib.find_last_not_of(" \t\r\n");
  2418. if(pos != lib.npos)
  2419. {
  2420. lib = lib.substr(0, pos+1);
  2421. }
  2422. if(lib != item)
  2423. {
  2424. cmake* cm = this->Makefile->GetCMakeInstance();
  2425. switch(this->GetPolicyStatusCMP0004())
  2426. {
  2427. case cmPolicies::WARN:
  2428. {
  2429. std::ostringstream w;
  2430. w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0004) << "\n"
  2431. << "Target \"" << this->GetName() << "\" links to item \""
  2432. << item << "\" which has leading or trailing whitespace.";
  2433. cm->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
  2434. this->GetBacktrace());
  2435. }
  2436. case cmPolicies::OLD:
  2437. break;
  2438. case cmPolicies::NEW:
  2439. {
  2440. std::ostringstream e;
  2441. e << "Target \"" << this->GetName() << "\" links to item \""
  2442. << item << "\" which has leading or trailing whitespace. "
  2443. << "This is now an error according to policy CMP0004.";
  2444. cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
  2445. }
  2446. break;
  2447. case cmPolicies::REQUIRED_IF_USED:
  2448. case cmPolicies::REQUIRED_ALWAYS:
  2449. {
  2450. std::ostringstream e;
  2451. e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0004) << "\n"
  2452. << "Target \"" << this->GetName() << "\" links to item \""
  2453. << item << "\" which has leading or trailing whitespace.";
  2454. cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
  2455. }
  2456. break;
  2457. }
  2458. }
  2459. return lib;
  2460. }
  2461. //----------------------------------------------------------------------------
  2462. cmTargetInternalPointer::cmTargetInternalPointer()
  2463. {
  2464. this->Pointer = new cmTargetInternals;
  2465. }
  2466. //----------------------------------------------------------------------------
  2467. cmTargetInternalPointer
  2468. ::cmTargetInternalPointer(cmTargetInternalPointer const& r)
  2469. {
  2470. // Ideally cmTarget instances should never be copied. However until
  2471. // we can make a sweep to remove that, this copy constructor avoids
  2472. // allowing the resources (Internals) to be copied.
  2473. this->Pointer = new cmTargetInternals(*r.Pointer);
  2474. }
  2475. //----------------------------------------------------------------------------
  2476. cmTargetInternalPointer::~cmTargetInternalPointer()
  2477. {
  2478. delete this->Pointer;
  2479. }
  2480. //----------------------------------------------------------------------------
  2481. cmTargetInternalPointer&
  2482. cmTargetInternalPointer::operator=(cmTargetInternalPointer const& r)
  2483. {
  2484. if(this == &r) { return *this; } // avoid warning on HP about self check
  2485. // Ideally cmTarget instances should never be copied. However until
  2486. // we can make a sweep to remove that, this copy constructor avoids
  2487. // allowing the resources (Internals) to be copied.
  2488. cmTargetInternals* oldPointer = this->Pointer;
  2489. this->Pointer = new cmTargetInternals(*r.Pointer);
  2490. delete oldPointer;
  2491. return *this;
  2492. }