cmTarget.cxx 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmTarget.h"
  4. #include "cmsys/RegularExpression.hxx"
  5. #include <algorithm>
  6. #include <assert.h>
  7. #include <initializer_list>
  8. #include <iterator>
  9. #include <set>
  10. #include <sstream>
  11. #include <string.h>
  12. #include <unordered_set>
  13. #include "cmAlgorithms.h"
  14. #include "cmGeneratorExpression.h"
  15. #include "cmGeneratorTarget.h"
  16. #include "cmGlobalGenerator.h"
  17. #include "cmListFileCache.h"
  18. #include "cmMakefile.h"
  19. #include "cmMessageType.h"
  20. #include "cmMessenger.h"
  21. #include "cmProperty.h"
  22. #include "cmRange.h"
  23. #include "cmSourceFile.h"
  24. #include "cmSourceFileLocation.h"
  25. #include "cmSourceFileLocationKind.h"
  26. #include "cmState.h"
  27. #include "cmStateDirectory.h"
  28. #include "cmStateSnapshot.h"
  29. #include "cmSystemTools.h"
  30. #include "cmTargetPropertyComputer.h"
  31. #include "cmake.h"
  32. ///! Append all elements from the second container to the first container
  33. template <class C, class R>
  34. static inline void CApp(C& container, R const& range)
  35. {
  36. container.insert(container.end(), range.begin(), range.end());
  37. }
  38. template <>
  39. const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
  40. cmTarget const* tgt)
  41. {
  42. static std::string loc;
  43. if (tgt->IsImported()) {
  44. loc = tgt->ImportedGetFullPath("", cmStateEnums::RuntimeBinaryArtifact);
  45. return loc.c_str();
  46. }
  47. cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
  48. if (!gg->GetConfigureDoneCMP0026()) {
  49. gg->CreateGenerationObjects();
  50. }
  51. cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
  52. loc = gt->GetLocationForBuild();
  53. return loc.c_str();
  54. }
  55. template <>
  56. const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>(
  57. cmTarget const* tgt, const std::string& config)
  58. {
  59. static std::string loc;
  60. if (tgt->IsImported()) {
  61. loc =
  62. tgt->ImportedGetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
  63. return loc.c_str();
  64. }
  65. cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
  66. if (!gg->GetConfigureDoneCMP0026()) {
  67. gg->CreateGenerationObjects();
  68. }
  69. cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
  70. loc = gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
  71. return loc.c_str();
  72. }
  73. template <>
  74. const char* cmTargetPropertyComputer::GetSources<cmTarget>(
  75. cmTarget const* tgt, cmMessenger* messenger,
  76. cmListFileBacktrace const& context)
  77. {
  78. cmStringRange entries = tgt->GetSourceEntries();
  79. if (entries.empty()) {
  80. return nullptr;
  81. }
  82. std::ostringstream ss;
  83. const char* sep = "";
  84. for (std::string const& entry : entries) {
  85. std::vector<std::string> files;
  86. cmSystemTools::ExpandListArgument(entry, files);
  87. for (std::string const& file : files) {
  88. if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
  89. file.back() == '>') {
  90. std::string objLibName = file.substr(17, file.size() - 18);
  91. if (cmGeneratorExpression::Find(objLibName) != std::string::npos) {
  92. ss << sep;
  93. sep = ";";
  94. ss << file;
  95. continue;
  96. }
  97. bool addContent = false;
  98. bool noMessage = true;
  99. std::ostringstream e;
  100. MessageType messageType = MessageType::AUTHOR_WARNING;
  101. switch (context.GetBottom().GetPolicy(cmPolicies::CMP0051)) {
  102. case cmPolicies::WARN:
  103. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n";
  104. noMessage = false;
  105. case cmPolicies::OLD:
  106. break;
  107. case cmPolicies::REQUIRED_ALWAYS:
  108. case cmPolicies::REQUIRED_IF_USED:
  109. case cmPolicies::NEW:
  110. addContent = true;
  111. }
  112. if (!noMessage) {
  113. e << "Target \"" << tgt->GetName()
  114. << "\" contains $<TARGET_OBJECTS> generator expression in its "
  115. "sources list. This content was not previously part of the "
  116. "SOURCES property when that property was read at configure "
  117. "time. Code reading that property needs to be adapted to "
  118. "ignore the generator expression using the string(GENEX_STRIP) "
  119. "command.";
  120. messenger->IssueMessage(messageType, e.str(), context);
  121. }
  122. if (addContent) {
  123. ss << sep;
  124. sep = ";";
  125. ss << file;
  126. }
  127. } else if (cmGeneratorExpression::Find(file) == std::string::npos) {
  128. ss << sep;
  129. sep = ";";
  130. ss << file;
  131. } else {
  132. cmSourceFile* sf = tgt->GetMakefile()->GetOrCreateSource(file);
  133. // Construct what is known about this source file location.
  134. cmSourceFileLocation const& location = sf->GetLocation();
  135. std::string sname = location.GetDirectory();
  136. if (!sname.empty()) {
  137. sname += "/";
  138. }
  139. sname += location.GetName();
  140. ss << sep;
  141. sep = ";";
  142. // Append this list entry.
  143. ss << sname;
  144. }
  145. }
  146. }
  147. static std::string srcs;
  148. srcs = ss.str();
  149. return srcs.c_str();
  150. }
  151. class cmTargetInternals
  152. {
  153. public:
  154. cmStateEnums::TargetType TargetType;
  155. std::vector<std::string> IncludeDirectoriesEntries;
  156. std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
  157. std::vector<std::string> CompileOptionsEntries;
  158. std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
  159. std::vector<std::string> CompileFeaturesEntries;
  160. std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
  161. std::vector<std::string> CompileDefinitionsEntries;
  162. std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
  163. std::vector<std::string> SourceEntries;
  164. std::vector<cmListFileBacktrace> SourceBacktraces;
  165. std::vector<std::string> LinkOptionsEntries;
  166. std::vector<cmListFileBacktrace> LinkOptionsBacktraces;
  167. std::vector<std::string> LinkDirectoriesEntries;
  168. std::vector<cmListFileBacktrace> LinkDirectoriesBacktraces;
  169. std::vector<std::string> LinkImplementationPropertyEntries;
  170. std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
  171. };
  172. cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
  173. Visibility vis, cmMakefile* mf)
  174. {
  175. assert(mf);
  176. impl->TargetType = type;
  177. this->IsGeneratorProvided = false;
  178. this->Name = name;
  179. this->Makefile = mf;
  180. this->HaveInstallRule = false;
  181. this->DLLPlatform = false;
  182. this->IsAndroid = false;
  183. this->IsImportedTarget =
  184. (vis == VisibilityImported || vis == VisibilityImportedGlobally);
  185. this->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
  186. this->BuildInterfaceIncludesAppended = false;
  187. // Check whether this is a DLL platform.
  188. this->DLLPlatform =
  189. !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
  190. // Check whether we are targeting an Android platform.
  191. this->IsAndroid =
  192. (this->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android");
  193. // Setup default property values.
  194. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  195. this->GetType() != cmStateEnums::UTILITY) {
  196. this->SetPropertyDefault("ANDROID_API", nullptr);
  197. this->SetPropertyDefault("ANDROID_API_MIN", nullptr);
  198. this->SetPropertyDefault("ANDROID_ARCH", nullptr);
  199. this->SetPropertyDefault("ANDROID_STL_TYPE", nullptr);
  200. this->SetPropertyDefault("ANDROID_SKIP_ANT_STEP", nullptr);
  201. this->SetPropertyDefault("ANDROID_PROCESS_MAX", nullptr);
  202. this->SetPropertyDefault("ANDROID_PROGUARD", nullptr);
  203. this->SetPropertyDefault("ANDROID_PROGUARD_CONFIG_PATH", nullptr);
  204. this->SetPropertyDefault("ANDROID_SECURE_PROPS_PATH", nullptr);
  205. this->SetPropertyDefault("ANDROID_NATIVE_LIB_DIRECTORIES", nullptr);
  206. this->SetPropertyDefault("ANDROID_NATIVE_LIB_DEPENDENCIES", nullptr);
  207. this->SetPropertyDefault("ANDROID_JAVA_SOURCE_DIR", nullptr);
  208. this->SetPropertyDefault("ANDROID_JAR_DIRECTORIES", nullptr);
  209. this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", nullptr);
  210. this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", nullptr);
  211. this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", nullptr);
  212. this->SetPropertyDefault("BUILD_RPATH", nullptr);
  213. this->SetPropertyDefault("BUILD_RPATH_USE_ORIGIN", nullptr);
  214. this->SetPropertyDefault("INSTALL_NAME_DIR", nullptr);
  215. this->SetPropertyDefault("INSTALL_RPATH", "");
  216. this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
  217. this->SetPropertyDefault("INTERPROCEDURAL_OPTIMIZATION", nullptr);
  218. this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
  219. this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
  220. this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", nullptr);
  221. this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", nullptr);
  222. this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", nullptr);
  223. this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", nullptr);
  224. this->SetPropertyDefault("COMPILE_PDB_OUTPUT_DIRECTORY", nullptr);
  225. this->SetPropertyDefault("Fortran_FORMAT", nullptr);
  226. this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", nullptr);
  227. this->SetPropertyDefault("Fortran_COMPILER_LAUNCHER", nullptr);
  228. this->SetPropertyDefault("GNUtoMS", nullptr);
  229. this->SetPropertyDefault("OSX_ARCHITECTURES", nullptr);
  230. this->SetPropertyDefault("IOS_INSTALL_COMBINED", nullptr);
  231. this->SetPropertyDefault("AUTOMOC", nullptr);
  232. this->SetPropertyDefault("AUTOUIC", nullptr);
  233. this->SetPropertyDefault("AUTORCC", nullptr);
  234. this->SetPropertyDefault("AUTOGEN_ORIGIN_DEPENDS", nullptr);
  235. this->SetPropertyDefault("AUTOGEN_PARALLEL", nullptr);
  236. this->SetPropertyDefault("AUTOMOC_COMPILER_PREDEFINES", nullptr);
  237. this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", nullptr);
  238. this->SetPropertyDefault("AUTOMOC_MACRO_NAMES", nullptr);
  239. this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", nullptr);
  240. this->SetPropertyDefault("AUTOUIC_OPTIONS", nullptr);
  241. this->SetPropertyDefault("AUTOUIC_SEARCH_PATHS", nullptr);
  242. this->SetPropertyDefault("AUTORCC_OPTIONS", nullptr);
  243. this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", nullptr);
  244. this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", nullptr);
  245. this->SetPropertyDefault("WIN32_EXECUTABLE", nullptr);
  246. this->SetPropertyDefault("MACOSX_BUNDLE", nullptr);
  247. this->SetPropertyDefault("MACOSX_RPATH", nullptr);
  248. this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", nullptr);
  249. this->SetPropertyDefault("BUILD_WITH_INSTALL_NAME_DIR", nullptr);
  250. this->SetPropertyDefault("C_CLANG_TIDY", nullptr);
  251. this->SetPropertyDefault("C_COMPILER_LAUNCHER", nullptr);
  252. this->SetPropertyDefault("C_CPPLINT", nullptr);
  253. this->SetPropertyDefault("C_CPPCHECK", nullptr);
  254. this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", nullptr);
  255. this->SetPropertyDefault("LINK_WHAT_YOU_USE", nullptr);
  256. this->SetPropertyDefault("C_STANDARD", nullptr);
  257. this->SetPropertyDefault("C_STANDARD_REQUIRED", nullptr);
  258. this->SetPropertyDefault("C_EXTENSIONS", nullptr);
  259. this->SetPropertyDefault("CXX_CLANG_TIDY", nullptr);
  260. this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", nullptr);
  261. this->SetPropertyDefault("CXX_CPPLINT", nullptr);
  262. this->SetPropertyDefault("CXX_CPPCHECK", nullptr);
  263. this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", nullptr);
  264. this->SetPropertyDefault("CXX_STANDARD", nullptr);
  265. this->SetPropertyDefault("CXX_STANDARD_REQUIRED", nullptr);
  266. this->SetPropertyDefault("CXX_EXTENSIONS", nullptr);
  267. this->SetPropertyDefault("CUDA_STANDARD", nullptr);
  268. this->SetPropertyDefault("CUDA_STANDARD_REQUIRED", nullptr);
  269. this->SetPropertyDefault("CUDA_EXTENSIONS", nullptr);
  270. this->SetPropertyDefault("CUDA_COMPILER_LAUNCHER", nullptr);
  271. this->SetPropertyDefault("CUDA_SEPARABLE_COMPILATION", nullptr);
  272. this->SetPropertyDefault("LINK_SEARCH_START_STATIC", nullptr);
  273. this->SetPropertyDefault("LINK_SEARCH_END_STATIC", nullptr);
  274. this->SetPropertyDefault("FOLDER", nullptr);
  275. #ifdef __APPLE__
  276. if (this->GetGlobalGenerator()->IsXcode()) {
  277. this->SetPropertyDefault("XCODE_GENERATE_SCHEME", nullptr);
  278. this->SetPropertyDefault("XCODE_SCHEME_ADDRESS_SANITIZER", nullptr);
  279. this->SetPropertyDefault(
  280. "XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN", nullptr);
  281. this->SetPropertyDefault("XCODE_SCHEME_THREAD_SANITIZER", nullptr);
  282. this->SetPropertyDefault("XCODE_SCHEME_THREAD_SANITIZER_STOP", nullptr);
  283. this->SetPropertyDefault("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER",
  284. nullptr);
  285. this->SetPropertyDefault(
  286. "XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP", nullptr);
  287. this->SetPropertyDefault("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER",
  288. nullptr);
  289. this->SetPropertyDefault("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP",
  290. nullptr);
  291. this->SetPropertyDefault("XCODE_SCHEME_MALLOC_SCRIBBLE", nullptr);
  292. this->SetPropertyDefault("XCODE_SCHEME_MALLOC_GUARD_EDGES", nullptr);
  293. this->SetPropertyDefault("XCODE_SCHEME_GUARD_MALLOC", nullptr);
  294. this->SetPropertyDefault("XCODE_SCHEME_ZOMBIE_OBJECTS", nullptr);
  295. this->SetPropertyDefault("XCODE_SCHEME_MALLOC_STACK", nullptr);
  296. this->SetPropertyDefault("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE",
  297. nullptr);
  298. this->SetPropertyDefault("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS", nullptr);
  299. }
  300. #endif
  301. }
  302. // Setup per-configuration property default values.
  303. if (this->GetType() != cmStateEnums::UTILITY) {
  304. static const auto configProps = {
  305. /* clang-format needs this comment to break after the opening brace */
  306. "ARCHIVE_OUTPUT_DIRECTORY_", "LIBRARY_OUTPUT_DIRECTORY_",
  307. "RUNTIME_OUTPUT_DIRECTORY_", "PDB_OUTPUT_DIRECTORY_",
  308. "COMPILE_PDB_OUTPUT_DIRECTORY_", "MAP_IMPORTED_CONFIG_",
  309. "INTERPROCEDURAL_OPTIMIZATION_"
  310. };
  311. // Collect the set of configuration types.
  312. std::vector<std::string> configNames;
  313. mf->GetConfigurations(configNames);
  314. for (std::string const& configName : configNames) {
  315. std::string configUpper = cmSystemTools::UpperCase(configName);
  316. for (auto const& prop : configProps) {
  317. // Interface libraries have no output locations, so honor only
  318. // the configuration map.
  319. if (impl->TargetType == cmStateEnums::INTERFACE_LIBRARY &&
  320. strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) {
  321. continue;
  322. }
  323. std::string property = prop;
  324. property += configUpper;
  325. this->SetPropertyDefault(property, nullptr);
  326. }
  327. // Initialize per-configuration name postfix property from the
  328. // variable only for non-executable targets. This preserves
  329. // compatibility with previous CMake versions in which executables
  330. // did not support this variable. Projects may still specify the
  331. // property directly.
  332. if (impl->TargetType != cmStateEnums::EXECUTABLE &&
  333. impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) {
  334. std::string property = cmSystemTools::UpperCase(configName);
  335. property += "_POSTFIX";
  336. this->SetPropertyDefault(property, nullptr);
  337. }
  338. }
  339. }
  340. // Save the backtrace of target construction.
  341. this->Backtrace = this->Makefile->GetBacktrace();
  342. if (!this->IsImported()) {
  343. // Initialize the INCLUDE_DIRECTORIES property based on the current value
  344. // of the same directory property:
  345. CApp(impl->IncludeDirectoriesEntries,
  346. this->Makefile->GetIncludeDirectoriesEntries());
  347. CApp(impl->IncludeDirectoriesBacktraces,
  348. this->Makefile->GetIncludeDirectoriesBacktraces());
  349. {
  350. auto const& sysInc = this->Makefile->GetSystemIncludeDirectories();
  351. this->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end());
  352. }
  353. CApp(impl->CompileOptionsEntries,
  354. this->Makefile->GetCompileOptionsEntries());
  355. CApp(impl->CompileOptionsBacktraces,
  356. this->Makefile->GetCompileOptionsBacktraces());
  357. CApp(impl->LinkOptionsEntries, this->Makefile->GetLinkOptionsEntries());
  358. CApp(impl->LinkOptionsBacktraces,
  359. this->Makefile->GetLinkOptionsBacktraces());
  360. CApp(impl->LinkDirectoriesEntries,
  361. this->Makefile->GetLinkDirectoriesEntries());
  362. CApp(impl->LinkDirectoriesBacktraces,
  363. this->Makefile->GetLinkDirectoriesBacktraces());
  364. }
  365. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  366. this->GetType() != cmStateEnums::UTILITY) {
  367. this->SetPropertyDefault("C_VISIBILITY_PRESET", nullptr);
  368. this->SetPropertyDefault("CXX_VISIBILITY_PRESET", nullptr);
  369. this->SetPropertyDefault("CUDA_VISIBILITY_PRESET", nullptr);
  370. this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", nullptr);
  371. }
  372. if (impl->TargetType == cmStateEnums::EXECUTABLE) {
  373. this->SetPropertyDefault("ANDROID_GUI", nullptr);
  374. this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", nullptr);
  375. this->SetPropertyDefault("ENABLE_EXPORTS", nullptr);
  376. }
  377. if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
  378. impl->TargetType == cmStateEnums::MODULE_LIBRARY) {
  379. this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
  380. }
  381. if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
  382. impl->TargetType == cmStateEnums::EXECUTABLE) {
  383. this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", nullptr);
  384. }
  385. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  386. this->GetType() != cmStateEnums::UTILITY) {
  387. this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", nullptr);
  388. }
  389. // Record current policies for later use.
  390. this->Makefile->RecordPolicies(this->PolicyMap);
  391. if (impl->TargetType == cmStateEnums::INTERFACE_LIBRARY) {
  392. // This policy is checked in a few conditions. The properties relevant
  393. // to the policy are always ignored for cmStateEnums::INTERFACE_LIBRARY
  394. // targets,
  395. // so ensure that the conditions don't lead to nonsense.
  396. this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
  397. }
  398. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  399. this->GetType() != cmStateEnums::UTILITY) {
  400. this->SetPropertyDefault("JOB_POOL_COMPILE", nullptr);
  401. this->SetPropertyDefault("JOB_POOL_LINK", nullptr);
  402. }
  403. if (impl->TargetType <= cmStateEnums::UTILITY) {
  404. this->SetPropertyDefault("DOTNET_TARGET_FRAMEWORK_VERSION", nullptr);
  405. }
  406. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  407. this->GetType() != cmStateEnums::UTILITY) {
  408. // check for "CMAKE_VS_GLOBALS" variable and set up target properties
  409. // if any
  410. const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
  411. if (globals) {
  412. const std::string genName = mf->GetGlobalGenerator()->GetName();
  413. if (cmHasLiteralPrefix(genName, "Visual Studio")) {
  414. std::vector<std::string> props;
  415. cmSystemTools::ExpandListArgument(globals, props);
  416. const std::string vsGlobal = "VS_GLOBAL_";
  417. for (const std::string& i : props) {
  418. // split NAME=VALUE
  419. const std::string::size_type assignment = i.find('=');
  420. if (assignment != std::string::npos) {
  421. const std::string propName = vsGlobal + i.substr(0, assignment);
  422. const std::string propValue = i.substr(assignment + 1);
  423. this->SetPropertyDefault(propName, propValue.c_str());
  424. }
  425. }
  426. }
  427. }
  428. }
  429. }
  430. cmStateEnums::TargetType cmTarget::GetType() const
  431. {
  432. return impl->TargetType;
  433. }
  434. cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
  435. {
  436. return this->GetMakefile()->GetGlobalGenerator();
  437. }
  438. void cmTarget::AddUtility(std::string const& u, cmMakefile* mf)
  439. {
  440. BT<std::string> util(u, mf ? mf->GetBacktrace() : cmListFileBacktrace());
  441. this->Utilities.insert(util);
  442. }
  443. cmListFileBacktrace const& cmTarget::GetBacktrace() const
  444. {
  445. return this->Backtrace;
  446. }
  447. bool cmTarget::IsExecutableWithExports() const
  448. {
  449. return (this->GetType() == cmStateEnums::EXECUTABLE &&
  450. this->GetPropertyAsBool("ENABLE_EXPORTS"));
  451. }
  452. bool cmTarget::HasImportLibrary() const
  453. {
  454. return (this->DLLPlatform &&
  455. (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
  456. this->IsExecutableWithExports()));
  457. }
  458. bool cmTarget::IsFrameworkOnApple() const
  459. {
  460. return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
  461. this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
  462. this->Makefile->IsOn("APPLE") &&
  463. this->GetPropertyAsBool("FRAMEWORK"));
  464. }
  465. bool cmTarget::IsAppBundleOnApple() const
  466. {
  467. return (this->GetType() == cmStateEnums::EXECUTABLE &&
  468. this->Makefile->IsOn("APPLE") &&
  469. this->GetPropertyAsBool("MACOSX_BUNDLE"));
  470. }
  471. void cmTarget::AddTracedSources(std::vector<std::string> const& srcs)
  472. {
  473. if (!srcs.empty()) {
  474. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  475. impl->SourceEntries.push_back(cmJoin(srcs, ";"));
  476. impl->SourceBacktraces.push_back(lfbt);
  477. }
  478. }
  479. void cmTarget::AddSources(std::vector<std::string> const& srcs)
  480. {
  481. std::string srcFiles;
  482. const char* sep = "";
  483. for (auto filename : srcs) {
  484. if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) {
  485. if (!filename.empty()) {
  486. filename = this->ProcessSourceItemCMP0049(filename);
  487. if (filename.empty()) {
  488. return;
  489. }
  490. }
  491. this->Makefile->GetOrCreateSource(filename);
  492. }
  493. srcFiles += sep;
  494. srcFiles += filename;
  495. sep = ";";
  496. }
  497. if (!srcFiles.empty()) {
  498. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  499. impl->SourceEntries.push_back(std::move(srcFiles));
  500. impl->SourceBacktraces.push_back(lfbt);
  501. }
  502. }
  503. std::string cmTarget::ProcessSourceItemCMP0049(const std::string& s)
  504. {
  505. std::string src = s;
  506. // For backwards compatibility replace variables in source names.
  507. // This should eventually be removed.
  508. this->Makefile->ExpandVariablesInString(src);
  509. if (src != s) {
  510. std::ostringstream e;
  511. bool noMessage = false;
  512. MessageType messageType = MessageType::AUTHOR_WARNING;
  513. switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0049)) {
  514. case cmPolicies::WARN:
  515. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0049) << "\n";
  516. break;
  517. case cmPolicies::OLD:
  518. noMessage = true;
  519. break;
  520. case cmPolicies::REQUIRED_ALWAYS:
  521. case cmPolicies::REQUIRED_IF_USED:
  522. case cmPolicies::NEW:
  523. messageType = MessageType::FATAL_ERROR;
  524. }
  525. if (!noMessage) {
  526. e << "Legacy variable expansion in source file \"" << s
  527. << "\" expanded to \"" << src << "\" in target \"" << this->GetName()
  528. << "\". This behavior will be removed in a "
  529. "future version of CMake.";
  530. this->Makefile->IssueMessage(messageType, e.str());
  531. if (messageType == MessageType::FATAL_ERROR) {
  532. return "";
  533. }
  534. }
  535. }
  536. return src;
  537. }
  538. cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
  539. {
  540. std::string src = this->ProcessSourceItemCMP0049(s);
  541. if (!s.empty() && src.empty()) {
  542. return nullptr;
  543. }
  544. return this->AddSource(src);
  545. }
  546. struct CreateLocation
  547. {
  548. cmMakefile const* Makefile;
  549. CreateLocation(cmMakefile const* mf)
  550. : Makefile(mf)
  551. {
  552. }
  553. cmSourceFileLocation operator()(const std::string& filename)
  554. {
  555. return cmSourceFileLocation(this->Makefile, filename);
  556. }
  557. };
  558. struct LocationMatcher
  559. {
  560. const cmSourceFileLocation& Needle;
  561. LocationMatcher(const cmSourceFileLocation& needle)
  562. : Needle(needle)
  563. {
  564. }
  565. bool operator()(cmSourceFileLocation& loc)
  566. {
  567. return loc.Matches(this->Needle);
  568. }
  569. };
  570. struct TargetPropertyEntryFinder
  571. {
  572. private:
  573. const cmSourceFileLocation& Needle;
  574. public:
  575. TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
  576. : Needle(needle)
  577. {
  578. }
  579. bool operator()(std::string const& entry)
  580. {
  581. std::vector<std::string> files;
  582. cmSystemTools::ExpandListArgument(entry, files);
  583. std::vector<cmSourceFileLocation> locations;
  584. locations.reserve(files.size());
  585. std::transform(files.begin(), files.end(), std::back_inserter(locations),
  586. CreateLocation(this->Needle.GetMakefile()));
  587. return std::find_if(locations.begin(), locations.end(),
  588. LocationMatcher(this->Needle)) != locations.end();
  589. }
  590. };
  591. cmSourceFile* cmTarget::AddSource(const std::string& src, bool before)
  592. {
  593. cmSourceFileLocation sfl(this->Makefile, src,
  594. cmSourceFileLocationKind::Known);
  595. if (std::find_if(impl->SourceEntries.begin(), impl->SourceEntries.end(),
  596. TargetPropertyEntryFinder(sfl)) ==
  597. impl->SourceEntries.end()) {
  598. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  599. impl->SourceEntries.insert(
  600. before ? impl->SourceEntries.begin() : impl->SourceEntries.end(), src);
  601. impl->SourceBacktraces.insert(before ? impl->SourceBacktraces.begin()
  602. : impl->SourceBacktraces.end(),
  603. lfbt);
  604. }
  605. if (cmGeneratorExpression::Find(src) != std::string::npos) {
  606. return nullptr;
  607. }
  608. return this->Makefile->GetOrCreateSource(src, false,
  609. cmSourceFileLocationKind::Known);
  610. }
  611. void cmTarget::ClearDependencyInformation(cmMakefile& mf)
  612. {
  613. std::string depname = this->GetName();
  614. depname += "_LIB_DEPENDS";
  615. mf.RemoveCacheDefinition(depname);
  616. }
  617. std::string cmTarget::GetDebugGeneratorExpressions(
  618. const std::string& value, cmTargetLinkLibraryType llt) const
  619. {
  620. if (llt == GENERAL_LibraryType) {
  621. return value;
  622. }
  623. // Get the list of configurations considered to be DEBUG.
  624. std::vector<std::string> debugConfigs =
  625. this->Makefile->GetCMakeInstance()->GetDebugConfigs();
  626. std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
  627. if (debugConfigs.size() > 1) {
  628. for (std::string const& conf : cmMakeRange(debugConfigs).advance(1)) {
  629. configString += ",$<CONFIG:" + conf + ">";
  630. }
  631. configString = "$<OR:" + configString + ">";
  632. }
  633. if (llt == OPTIMIZED_LibraryType) {
  634. configString = "$<NOT:" + configString + ">";
  635. }
  636. return "$<" + configString + ":" + value + ">";
  637. }
  638. static std::string targetNameGenex(const std::string& lib)
  639. {
  640. return "$<TARGET_NAME:" + lib + ">";
  641. }
  642. bool cmTarget::PushTLLCommandTrace(TLLSignature signature,
  643. cmListFileContext const& lfc)
  644. {
  645. bool ret = true;
  646. if (!this->TLLCommands.empty()) {
  647. if (this->TLLCommands.back().first != signature) {
  648. ret = false;
  649. }
  650. }
  651. if (this->TLLCommands.empty() || this->TLLCommands.back().second != lfc) {
  652. this->TLLCommands.emplace_back(signature, lfc);
  653. }
  654. return ret;
  655. }
  656. void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
  657. {
  658. const char* sigString =
  659. (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain");
  660. s << "The uses of the " << sigString << " signature are here:\n";
  661. cmStateDirectory cmDir =
  662. this->GetMakefile()->GetStateSnapshot().GetDirectory();
  663. for (auto const& cmd : this->TLLCommands) {
  664. if (cmd.first == sig) {
  665. cmListFileContext lfc = cmd.second;
  666. lfc.FilePath = cmDir.ConvertToRelPathIfNotContained(
  667. this->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
  668. s << " * " << lfc << std::endl;
  669. }
  670. }
  671. }
  672. void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
  673. cmTargetLinkLibraryType llt)
  674. {
  675. this->AddLinkLibrary(mf, lib, lib, llt);
  676. }
  677. void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
  678. std::string const& libRef,
  679. cmTargetLinkLibraryType llt)
  680. {
  681. cmTarget* tgt = mf.FindTargetToUse(lib);
  682. {
  683. const bool isNonImportedTarget = tgt && !tgt->IsImported();
  684. const std::string libName =
  685. (isNonImportedTarget && llt != GENERAL_LibraryType)
  686. ? targetNameGenex(libRef)
  687. : libRef;
  688. this->AppendProperty(
  689. "LINK_LIBRARIES",
  690. this->GetDebugGeneratorExpressions(libName, llt).c_str());
  691. }
  692. if (cmGeneratorExpression::Find(lib) != std::string::npos || lib != libRef ||
  693. (tgt &&
  694. (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
  695. tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) ||
  696. (this->Name == lib)) {
  697. return;
  698. }
  699. this->OriginalLinkLibraries.emplace_back(lib, llt);
  700. // Add the explicit dependency information for libraries. This is
  701. // simply a set of libraries separated by ";". There should always
  702. // be a trailing ";". These library names are not canonical, in that
  703. // they may be "-framework x", "-ly", "/path/libz.a", etc.
  704. // We shouldn't remove duplicates here because external libraries
  705. // may be purposefully duplicated to handle recursive dependencies,
  706. // and we removing one instance will break the link line. Duplicates
  707. // will be appropriately eliminated at emit time.
  708. if (impl->TargetType >= cmStateEnums::STATIC_LIBRARY &&
  709. impl->TargetType <= cmStateEnums::MODULE_LIBRARY &&
  710. (this->GetPolicyStatusCMP0073() == cmPolicies::OLD ||
  711. this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) {
  712. std::string targetEntry = this->Name;
  713. targetEntry += "_LIB_DEPENDS";
  714. std::string dependencies;
  715. const char* old_val = mf.GetDefinition(targetEntry);
  716. if (old_val) {
  717. dependencies += old_val;
  718. }
  719. switch (llt) {
  720. case GENERAL_LibraryType:
  721. dependencies += "general";
  722. break;
  723. case DEBUG_LibraryType:
  724. dependencies += "debug";
  725. break;
  726. case OPTIMIZED_LibraryType:
  727. dependencies += "optimized";
  728. break;
  729. }
  730. dependencies += ";";
  731. dependencies += lib;
  732. dependencies += ";";
  733. mf.AddCacheDefinition(targetEntry, dependencies.c_str(),
  734. "Dependencies for the target", cmStateEnums::STATIC);
  735. }
  736. }
  737. void cmTarget::AddSystemIncludeDirectories(const std::set<std::string>& incs)
  738. {
  739. this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
  740. }
  741. cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
  742. {
  743. return cmMakeRange(impl->IncludeDirectoriesEntries);
  744. }
  745. cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
  746. {
  747. return cmMakeRange(impl->IncludeDirectoriesBacktraces);
  748. }
  749. cmStringRange cmTarget::GetCompileOptionsEntries() const
  750. {
  751. return cmMakeRange(impl->CompileOptionsEntries);
  752. }
  753. cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
  754. {
  755. return cmMakeRange(impl->CompileOptionsBacktraces);
  756. }
  757. cmStringRange cmTarget::GetCompileFeaturesEntries() const
  758. {
  759. return cmMakeRange(impl->CompileFeaturesEntries);
  760. }
  761. cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
  762. {
  763. return cmMakeRange(impl->CompileFeaturesBacktraces);
  764. }
  765. cmStringRange cmTarget::GetCompileDefinitionsEntries() const
  766. {
  767. return cmMakeRange(impl->CompileDefinitionsEntries);
  768. }
  769. cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
  770. {
  771. return cmMakeRange(impl->CompileDefinitionsBacktraces);
  772. }
  773. cmStringRange cmTarget::GetSourceEntries() const
  774. {
  775. return cmMakeRange(impl->SourceEntries);
  776. }
  777. cmBacktraceRange cmTarget::GetSourceBacktraces() const
  778. {
  779. return cmMakeRange(impl->SourceBacktraces);
  780. }
  781. cmStringRange cmTarget::GetLinkOptionsEntries() const
  782. {
  783. return cmMakeRange(impl->LinkOptionsEntries);
  784. }
  785. cmBacktraceRange cmTarget::GetLinkOptionsBacktraces() const
  786. {
  787. return cmMakeRange(impl->LinkOptionsBacktraces);
  788. }
  789. cmStringRange cmTarget::GetLinkDirectoriesEntries() const
  790. {
  791. return cmMakeRange(impl->LinkDirectoriesEntries);
  792. }
  793. cmBacktraceRange cmTarget::GetLinkDirectoriesBacktraces() const
  794. {
  795. return cmMakeRange(impl->LinkDirectoriesBacktraces);
  796. }
  797. cmStringRange cmTarget::GetLinkImplementationEntries() const
  798. {
  799. return cmMakeRange(impl->LinkImplementationPropertyEntries);
  800. }
  801. cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
  802. {
  803. return cmMakeRange(impl->LinkImplementationPropertyBacktraces);
  804. }
  805. void cmTarget::SetProperty(const std::string& prop, const char* value)
  806. {
  807. if (!cmTargetPropertyComputer::PassesWhitelist(
  808. this->GetType(), prop, this->Makefile->GetMessenger(),
  809. this->Makefile->GetBacktrace())) {
  810. return;
  811. }
  812. #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
  813. MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
  814. MAKE_STATIC_PROP(COMPILE_FEATURES);
  815. MAKE_STATIC_PROP(COMPILE_OPTIONS);
  816. MAKE_STATIC_PROP(CUDA_PTX_COMPILATION);
  817. MAKE_STATIC_PROP(EXPORT_NAME);
  818. MAKE_STATIC_PROP(IMPORTED_GLOBAL);
  819. MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
  820. MAKE_STATIC_PROP(LINK_OPTIONS);
  821. MAKE_STATIC_PROP(LINK_DIRECTORIES);
  822. MAKE_STATIC_PROP(LINK_LIBRARIES);
  823. MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
  824. MAKE_STATIC_PROP(NAME);
  825. MAKE_STATIC_PROP(SOURCES);
  826. MAKE_STATIC_PROP(TYPE);
  827. #undef MAKE_STATIC_PROP
  828. if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
  829. std::ostringstream e;
  830. e << "MANUALLY_ADDED_DEPENDENCIES property is read-only\n";
  831. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  832. return;
  833. }
  834. if (prop == propNAME) {
  835. std::ostringstream e;
  836. e << "NAME property is read-only\n";
  837. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  838. return;
  839. }
  840. if (prop == propTYPE) {
  841. std::ostringstream e;
  842. e << "TYPE property is read-only\n";
  843. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  844. return;
  845. }
  846. if (prop == propEXPORT_NAME && this->IsImported()) {
  847. std::ostringstream e;
  848. e << "EXPORT_NAME property can't be set on imported targets (\""
  849. << this->Name << "\")\n";
  850. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  851. return;
  852. }
  853. if (prop == propSOURCES && this->IsImported()) {
  854. std::ostringstream e;
  855. e << "SOURCES property can't be set on imported targets (\"" << this->Name
  856. << "\")\n";
  857. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  858. return;
  859. }
  860. if (prop == propIMPORTED_GLOBAL && !this->IsImported()) {
  861. std::ostringstream e;
  862. e << "IMPORTED_GLOBAL property can't be set on non-imported targets (\""
  863. << this->Name << "\")\n";
  864. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  865. return;
  866. }
  867. if (prop == propINCLUDE_DIRECTORIES) {
  868. impl->IncludeDirectoriesEntries.clear();
  869. impl->IncludeDirectoriesBacktraces.clear();
  870. if (value) {
  871. impl->IncludeDirectoriesEntries.emplace_back(value);
  872. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  873. impl->IncludeDirectoriesBacktraces.push_back(lfbt);
  874. }
  875. } else if (prop == propCOMPILE_OPTIONS) {
  876. impl->CompileOptionsEntries.clear();
  877. impl->CompileOptionsBacktraces.clear();
  878. if (value) {
  879. impl->CompileOptionsEntries.emplace_back(value);
  880. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  881. impl->CompileOptionsBacktraces.push_back(lfbt);
  882. }
  883. } else if (prop == propCOMPILE_FEATURES) {
  884. impl->CompileFeaturesEntries.clear();
  885. impl->CompileFeaturesBacktraces.clear();
  886. if (value) {
  887. impl->CompileFeaturesEntries.emplace_back(value);
  888. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  889. impl->CompileFeaturesBacktraces.push_back(lfbt);
  890. }
  891. } else if (prop == propCOMPILE_DEFINITIONS) {
  892. impl->CompileDefinitionsEntries.clear();
  893. impl->CompileDefinitionsBacktraces.clear();
  894. if (value) {
  895. impl->CompileDefinitionsEntries.emplace_back(value);
  896. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  897. impl->CompileDefinitionsBacktraces.push_back(lfbt);
  898. }
  899. } else if (prop == propLINK_OPTIONS) {
  900. impl->LinkOptionsEntries.clear();
  901. impl->LinkOptionsBacktraces.clear();
  902. if (value) {
  903. impl->LinkOptionsEntries.emplace_back(value);
  904. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  905. impl->LinkOptionsBacktraces.push_back(lfbt);
  906. }
  907. } else if (prop == propLINK_DIRECTORIES) {
  908. impl->LinkDirectoriesEntries.clear();
  909. impl->LinkDirectoriesBacktraces.clear();
  910. if (value) {
  911. impl->LinkDirectoriesEntries.emplace_back(value);
  912. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  913. impl->LinkDirectoriesBacktraces.push_back(lfbt);
  914. }
  915. } else if (prop == propLINK_LIBRARIES) {
  916. impl->LinkImplementationPropertyEntries.clear();
  917. impl->LinkImplementationPropertyBacktraces.clear();
  918. if (value) {
  919. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  920. impl->LinkImplementationPropertyEntries.emplace_back(value);
  921. impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
  922. }
  923. } else if (prop == propSOURCES) {
  924. impl->SourceEntries.clear();
  925. impl->SourceBacktraces.clear();
  926. if (value) {
  927. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  928. impl->SourceEntries.emplace_back(value);
  929. impl->SourceBacktraces.push_back(lfbt);
  930. }
  931. } else if (prop == propIMPORTED_GLOBAL) {
  932. if (!cmSystemTools::IsOn(value)) {
  933. std::ostringstream e;
  934. e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\""
  935. << this->Name << "\")\n";
  936. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  937. return;
  938. }
  939. /* no need to change anything if value does not change */
  940. if (!this->ImportedGloballyVisible) {
  941. this->ImportedGloballyVisible = true;
  942. this->GetGlobalGenerator()->IndexTarget(this);
  943. }
  944. } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
  945. !this->CheckImportedLibName(prop, value ? value : "")) {
  946. /* error was reported by check method */
  947. } else if (prop == propCUDA_PTX_COMPILATION &&
  948. this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
  949. std::ostringstream e;
  950. e << "CUDA_PTX_COMPILATION property can only be applied to OBJECT "
  951. "targets (\""
  952. << this->Name << "\")\n";
  953. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  954. return;
  955. } else {
  956. this->Properties.SetProperty(prop, value);
  957. }
  958. }
  959. void cmTarget::AppendProperty(const std::string& prop, const char* value,
  960. bool asString)
  961. {
  962. if (!cmTargetPropertyComputer::PassesWhitelist(
  963. this->GetType(), prop, this->Makefile->GetMessenger(),
  964. this->Makefile->GetBacktrace())) {
  965. return;
  966. }
  967. if (prop == "NAME") {
  968. std::ostringstream e;
  969. e << "NAME property is read-only\n";
  970. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  971. return;
  972. }
  973. if (prop == "EXPORT_NAME" && this->IsImported()) {
  974. std::ostringstream e;
  975. e << "EXPORT_NAME property can't be set on imported targets (\""
  976. << this->Name << "\")\n";
  977. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  978. return;
  979. }
  980. if (prop == "SOURCES" && this->IsImported()) {
  981. std::ostringstream e;
  982. e << "SOURCES property can't be set on imported targets (\"" << this->Name
  983. << "\")\n";
  984. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  985. return;
  986. }
  987. if (prop == "IMPORTED_GLOBAL") {
  988. std::ostringstream e;
  989. e << "IMPORTED_GLOBAL property can't be appended, only set on imported "
  990. "targets (\""
  991. << this->Name << "\")\n";
  992. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  993. return;
  994. }
  995. if (prop == "INCLUDE_DIRECTORIES") {
  996. if (value && *value) {
  997. impl->IncludeDirectoriesEntries.emplace_back(value);
  998. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  999. impl->IncludeDirectoriesBacktraces.push_back(lfbt);
  1000. }
  1001. } else if (prop == "COMPILE_OPTIONS") {
  1002. if (value && *value) {
  1003. impl->CompileOptionsEntries.emplace_back(value);
  1004. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1005. impl->CompileOptionsBacktraces.push_back(lfbt);
  1006. }
  1007. } else if (prop == "COMPILE_FEATURES") {
  1008. if (value && *value) {
  1009. impl->CompileFeaturesEntries.emplace_back(value);
  1010. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1011. impl->CompileFeaturesBacktraces.push_back(lfbt);
  1012. }
  1013. } else if (prop == "COMPILE_DEFINITIONS") {
  1014. if (value && *value) {
  1015. impl->CompileDefinitionsEntries.emplace_back(value);
  1016. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1017. impl->CompileDefinitionsBacktraces.push_back(lfbt);
  1018. }
  1019. } else if (prop == "LINK_OPTIONS") {
  1020. if (value && *value) {
  1021. impl->LinkOptionsEntries.emplace_back(value);
  1022. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1023. impl->LinkOptionsBacktraces.push_back(lfbt);
  1024. }
  1025. } else if (prop == "LINK_DIRECTORIES") {
  1026. if (value && *value) {
  1027. impl->LinkDirectoriesEntries.emplace_back(value);
  1028. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1029. impl->LinkDirectoriesBacktraces.push_back(lfbt);
  1030. }
  1031. } else if (prop == "LINK_LIBRARIES") {
  1032. if (value && *value) {
  1033. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1034. impl->LinkImplementationPropertyEntries.emplace_back(value);
  1035. impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
  1036. }
  1037. } else if (prop == "SOURCES") {
  1038. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  1039. impl->SourceEntries.emplace_back(value);
  1040. impl->SourceBacktraces.push_back(lfbt);
  1041. } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
  1042. this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
  1043. prop + " property may not be APPENDed.");
  1044. } else {
  1045. this->Properties.AppendProperty(prop, value, asString);
  1046. }
  1047. }
  1048. void cmTarget::AppendBuildInterfaceIncludes()
  1049. {
  1050. if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
  1051. this->GetType() != cmStateEnums::STATIC_LIBRARY &&
  1052. this->GetType() != cmStateEnums::MODULE_LIBRARY &&
  1053. this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  1054. !this->IsExecutableWithExports()) {
  1055. return;
  1056. }
  1057. if (this->BuildInterfaceIncludesAppended) {
  1058. return;
  1059. }
  1060. this->BuildInterfaceIncludesAppended = true;
  1061. if (this->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) {
  1062. std::string dirs = this->Makefile->GetCurrentBinaryDirectory();
  1063. if (!dirs.empty()) {
  1064. dirs += ';';
  1065. }
  1066. dirs += this->Makefile->GetCurrentSourceDirectory();
  1067. if (!dirs.empty()) {
  1068. this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
  1069. ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
  1070. }
  1071. }
  1072. }
  1073. void cmTarget::InsertInclude(std::string const& entry,
  1074. cmListFileBacktrace const& bt, bool before)
  1075. {
  1076. std::vector<std::string>::iterator position = before
  1077. ? impl->IncludeDirectoriesEntries.begin()
  1078. : impl->IncludeDirectoriesEntries.end();
  1079. std::vector<cmListFileBacktrace>::iterator btPosition = before
  1080. ? impl->IncludeDirectoriesBacktraces.begin()
  1081. : impl->IncludeDirectoriesBacktraces.end();
  1082. impl->IncludeDirectoriesEntries.insert(position, entry);
  1083. impl->IncludeDirectoriesBacktraces.insert(btPosition, bt);
  1084. }
  1085. void cmTarget::InsertCompileOption(std::string const& entry,
  1086. cmListFileBacktrace const& bt, bool before)
  1087. {
  1088. std::vector<std::string>::iterator position = before
  1089. ? impl->CompileOptionsEntries.begin()
  1090. : impl->CompileOptionsEntries.end();
  1091. std::vector<cmListFileBacktrace>::iterator btPosition = before
  1092. ? impl->CompileOptionsBacktraces.begin()
  1093. : impl->CompileOptionsBacktraces.end();
  1094. impl->CompileOptionsEntries.insert(position, entry);
  1095. impl->CompileOptionsBacktraces.insert(btPosition, bt);
  1096. }
  1097. void cmTarget::InsertCompileDefinition(std::string const& entry,
  1098. cmListFileBacktrace const& bt)
  1099. {
  1100. impl->CompileDefinitionsEntries.push_back(entry);
  1101. impl->CompileDefinitionsBacktraces.push_back(bt);
  1102. }
  1103. void cmTarget::InsertLinkOption(std::string const& entry,
  1104. cmListFileBacktrace const& bt, bool before)
  1105. {
  1106. std::vector<std::string>::iterator position =
  1107. before ? impl->LinkOptionsEntries.begin() : impl->LinkOptionsEntries.end();
  1108. std::vector<cmListFileBacktrace>::iterator btPosition = before
  1109. ? impl->LinkOptionsBacktraces.begin()
  1110. : impl->LinkOptionsBacktraces.end();
  1111. impl->LinkOptionsEntries.insert(position, entry);
  1112. impl->LinkOptionsBacktraces.insert(btPosition, bt);
  1113. }
  1114. void cmTarget::InsertLinkDirectory(std::string const& entry,
  1115. cmListFileBacktrace const& bt, bool before)
  1116. {
  1117. std::vector<std::string>::iterator position = before
  1118. ? impl->LinkDirectoriesEntries.begin()
  1119. : impl->LinkDirectoriesEntries.end();
  1120. std::vector<cmListFileBacktrace>::iterator btPosition = before
  1121. ? impl->LinkDirectoriesBacktraces.begin()
  1122. : impl->LinkDirectoriesBacktraces.end();
  1123. impl->LinkDirectoriesEntries.insert(position, entry);
  1124. impl->LinkDirectoriesBacktraces.insert(btPosition, bt);
  1125. }
  1126. static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
  1127. const char* value,
  1128. cmMakefile* context,
  1129. bool imported)
  1130. {
  1131. // Look for link-type keywords in the value.
  1132. static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
  1133. if (!keys.find(value)) {
  1134. return;
  1135. }
  1136. // Support imported and non-imported versions of the property.
  1137. const char* base = (imported ? "IMPORTED_LINK_INTERFACE_LIBRARIES"
  1138. : "LINK_INTERFACE_LIBRARIES");
  1139. // Report an error.
  1140. std::ostringstream e;
  1141. e << "Property " << prop << " may not contain link-type keyword \""
  1142. << keys.match(2) << "\". "
  1143. << "The " << base << " property has a per-configuration "
  1144. << "version called " << base << "_<CONFIG> which may be "
  1145. << "used to specify per-configuration rules.";
  1146. if (!imported) {
  1147. e << " "
  1148. << "Alternatively, an IMPORTED library may be created, configured "
  1149. << "with a per-configuration location, and then named in the "
  1150. << "property value. "
  1151. << "See the add_library command's IMPORTED mode for details."
  1152. << "\n"
  1153. << "If you have a list of libraries that already contains the "
  1154. << "keyword, use the target_link_libraries command with its "
  1155. << "LINK_INTERFACE_LIBRARIES mode to set the property. "
  1156. << "The command automatically recognizes link-type keywords and sets "
  1157. << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
  1158. << "properties accordingly.";
  1159. }
  1160. context->IssueMessage(MessageType::FATAL_ERROR, e.str());
  1161. }
  1162. static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
  1163. cmMakefile* context)
  1164. {
  1165. // Look for link-type keywords in the value.
  1166. static cmsys::RegularExpression keys("(^|;)(debug|optimized|general)(;|$)");
  1167. if (!keys.find(value)) {
  1168. return;
  1169. }
  1170. // Report an error.
  1171. std::ostringstream e;
  1172. e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
  1173. "keyword \""
  1174. << keys.match(2)
  1175. << "\". The INTERFACE_LINK_LIBRARIES "
  1176. "property may contain configuration-sensitive generator-expressions "
  1177. "which may be used to specify per-configuration rules.";
  1178. context->IssueMessage(MessageType::FATAL_ERROR, e.str());
  1179. }
  1180. static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target,
  1181. cmMakefile* context)
  1182. {
  1183. std::vector<cmTarget*> targets = context->GetOwnedImportedTargets();
  1184. std::vector<cmTarget*>::const_iterator it =
  1185. std::find(targets.begin(), targets.end(), target);
  1186. if (it == targets.end()) {
  1187. std::ostringstream e;
  1188. e << "Attempt to promote imported target \"" << target->GetName()
  1189. << "\" to global scope (by setting IMPORTED_GLOBAL) "
  1190. "which is not built in this directory.";
  1191. context->IssueMessage(MessageType::FATAL_ERROR, e.str());
  1192. }
  1193. }
  1194. void cmTarget::CheckProperty(const std::string& prop,
  1195. cmMakefile* context) const
  1196. {
  1197. // Certain properties need checking.
  1198. if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
  1199. if (const char* value = this->GetProperty(prop)) {
  1200. cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
  1201. }
  1202. }
  1203. if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
  1204. if (const char* value = this->GetProperty(prop)) {
  1205. cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
  1206. }
  1207. }
  1208. if (prop == "INTERFACE_LINK_LIBRARIES") {
  1209. if (const char* value = this->GetProperty(prop)) {
  1210. cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
  1211. }
  1212. }
  1213. if (prop == "IMPORTED_GLOBAL") {
  1214. if (this->IsImported()) {
  1215. cmTargetCheckIMPORTED_GLOBAL(this, context);
  1216. }
  1217. }
  1218. }
  1219. const char* cmTarget::GetComputedProperty(
  1220. const std::string& prop, cmMessenger* messenger,
  1221. cmListFileBacktrace const& context) const
  1222. {
  1223. return cmTargetPropertyComputer::GetProperty(this, prop, messenger, context);
  1224. }
  1225. const char* cmTarget::GetProperty(const std::string& prop) const
  1226. {
  1227. static std::unordered_set<std::string> specialProps;
  1228. #define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
  1229. MAKE_STATIC_PROP(LINK_LIBRARIES);
  1230. MAKE_STATIC_PROP(TYPE);
  1231. MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
  1232. MAKE_STATIC_PROP(COMPILE_FEATURES);
  1233. MAKE_STATIC_PROP(COMPILE_OPTIONS);
  1234. MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
  1235. MAKE_STATIC_PROP(LINK_OPTIONS);
  1236. MAKE_STATIC_PROP(LINK_DIRECTORIES);
  1237. MAKE_STATIC_PROP(IMPORTED);
  1238. MAKE_STATIC_PROP(IMPORTED_GLOBAL);
  1239. MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
  1240. MAKE_STATIC_PROP(NAME);
  1241. MAKE_STATIC_PROP(BINARY_DIR);
  1242. MAKE_STATIC_PROP(SOURCE_DIR);
  1243. MAKE_STATIC_PROP(SOURCES);
  1244. #undef MAKE_STATIC_PROP
  1245. if (specialProps.empty()) {
  1246. specialProps.insert(propLINK_LIBRARIES);
  1247. specialProps.insert(propTYPE);
  1248. specialProps.insert(propINCLUDE_DIRECTORIES);
  1249. specialProps.insert(propCOMPILE_FEATURES);
  1250. specialProps.insert(propCOMPILE_OPTIONS);
  1251. specialProps.insert(propCOMPILE_DEFINITIONS);
  1252. specialProps.insert(propLINK_OPTIONS);
  1253. specialProps.insert(propLINK_DIRECTORIES);
  1254. specialProps.insert(propIMPORTED);
  1255. specialProps.insert(propIMPORTED_GLOBAL);
  1256. specialProps.insert(propMANUALLY_ADDED_DEPENDENCIES);
  1257. specialProps.insert(propNAME);
  1258. specialProps.insert(propBINARY_DIR);
  1259. specialProps.insert(propSOURCE_DIR);
  1260. specialProps.insert(propSOURCES);
  1261. }
  1262. if (specialProps.count(prop)) {
  1263. if (prop == propLINK_LIBRARIES) {
  1264. if (impl->LinkImplementationPropertyEntries.empty()) {
  1265. return nullptr;
  1266. }
  1267. static std::string output;
  1268. output = cmJoin(impl->LinkImplementationPropertyEntries, ";");
  1269. return output.c_str();
  1270. }
  1271. // the type property returns what type the target is
  1272. if (prop == propTYPE) {
  1273. return cmState::GetTargetTypeName(this->GetType());
  1274. }
  1275. if (prop == propINCLUDE_DIRECTORIES) {
  1276. if (impl->IncludeDirectoriesEntries.empty()) {
  1277. return nullptr;
  1278. }
  1279. static std::string output;
  1280. output = cmJoin(impl->IncludeDirectoriesEntries, ";");
  1281. return output.c_str();
  1282. }
  1283. if (prop == propCOMPILE_FEATURES) {
  1284. if (impl->CompileFeaturesEntries.empty()) {
  1285. return nullptr;
  1286. }
  1287. static std::string output;
  1288. output = cmJoin(impl->CompileFeaturesEntries, ";");
  1289. return output.c_str();
  1290. }
  1291. if (prop == propCOMPILE_OPTIONS) {
  1292. if (impl->CompileOptionsEntries.empty()) {
  1293. return nullptr;
  1294. }
  1295. static std::string output;
  1296. output = cmJoin(impl->CompileOptionsEntries, ";");
  1297. return output.c_str();
  1298. }
  1299. if (prop == propCOMPILE_DEFINITIONS) {
  1300. if (impl->CompileDefinitionsEntries.empty()) {
  1301. return nullptr;
  1302. }
  1303. static std::string output;
  1304. output = cmJoin(impl->CompileDefinitionsEntries, ";");
  1305. return output.c_str();
  1306. }
  1307. if (prop == propLINK_OPTIONS) {
  1308. if (impl->LinkOptionsEntries.empty()) {
  1309. return nullptr;
  1310. }
  1311. static std::string output;
  1312. output = cmJoin(impl->LinkOptionsEntries, ";");
  1313. return output.c_str();
  1314. }
  1315. if (prop == propLINK_DIRECTORIES) {
  1316. if (impl->LinkDirectoriesEntries.empty()) {
  1317. return nullptr;
  1318. }
  1319. static std::string output;
  1320. output = cmJoin(impl->LinkDirectoriesEntries, ";");
  1321. return output.c_str();
  1322. }
  1323. if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
  1324. if (this->Utilities.empty()) {
  1325. return nullptr;
  1326. }
  1327. static std::string output;
  1328. output = cmJoin(this->Utilities, ";");
  1329. return output.c_str();
  1330. }
  1331. if (prop == propIMPORTED) {
  1332. return this->IsImported() ? "TRUE" : "FALSE";
  1333. }
  1334. if (prop == propIMPORTED_GLOBAL) {
  1335. return this->IsImportedGloballyVisible() ? "TRUE" : "FALSE";
  1336. }
  1337. if (prop == propNAME) {
  1338. return this->GetName().c_str();
  1339. }
  1340. if (prop == propBINARY_DIR) {
  1341. return this->GetMakefile()
  1342. ->GetStateSnapshot()
  1343. .GetDirectory()
  1344. .GetCurrentBinary()
  1345. .c_str();
  1346. }
  1347. if (prop == propSOURCE_DIR) {
  1348. return this->GetMakefile()
  1349. ->GetStateSnapshot()
  1350. .GetDirectory()
  1351. .GetCurrentSource()
  1352. .c_str();
  1353. }
  1354. }
  1355. const char* retVal = this->Properties.GetPropertyValue(prop);
  1356. if (!retVal) {
  1357. const bool chain = this->GetMakefile()->GetState()->IsPropertyChained(
  1358. prop, cmProperty::TARGET);
  1359. if (chain) {
  1360. return this->Makefile->GetStateSnapshot().GetDirectory().GetProperty(
  1361. prop, chain);
  1362. }
  1363. }
  1364. return retVal;
  1365. }
  1366. const char* cmTarget::GetSafeProperty(const std::string& prop) const
  1367. {
  1368. const char* ret = this->GetProperty(prop);
  1369. if (!ret) {
  1370. return "";
  1371. }
  1372. return ret;
  1373. }
  1374. bool cmTarget::GetPropertyAsBool(const std::string& prop) const
  1375. {
  1376. return cmSystemTools::IsOn(this->GetProperty(prop));
  1377. }
  1378. const char* cmTarget::GetSuffixVariableInternal(
  1379. cmStateEnums::ArtifactType artifact) const
  1380. {
  1381. switch (this->GetType()) {
  1382. case cmStateEnums::STATIC_LIBRARY:
  1383. return "CMAKE_STATIC_LIBRARY_SUFFIX";
  1384. case cmStateEnums::SHARED_LIBRARY:
  1385. switch (artifact) {
  1386. case cmStateEnums::RuntimeBinaryArtifact:
  1387. return "CMAKE_SHARED_LIBRARY_SUFFIX";
  1388. case cmStateEnums::ImportLibraryArtifact:
  1389. return "CMAKE_IMPORT_LIBRARY_SUFFIX";
  1390. }
  1391. break;
  1392. case cmStateEnums::MODULE_LIBRARY:
  1393. switch (artifact) {
  1394. case cmStateEnums::RuntimeBinaryArtifact:
  1395. return "CMAKE_SHARED_MODULE_SUFFIX";
  1396. case cmStateEnums::ImportLibraryArtifact:
  1397. return "CMAKE_IMPORT_LIBRARY_SUFFIX";
  1398. }
  1399. break;
  1400. case cmStateEnums::EXECUTABLE:
  1401. switch (artifact) {
  1402. case cmStateEnums::RuntimeBinaryArtifact:
  1403. // Android GUI application packages store the native
  1404. // binary as a shared library.
  1405. return (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
  1406. ? "CMAKE_SHARED_LIBRARY_SUFFIX"
  1407. : "CMAKE_EXECUTABLE_SUFFIX");
  1408. case cmStateEnums::ImportLibraryArtifact:
  1409. return "CMAKE_IMPORT_LIBRARY_SUFFIX";
  1410. }
  1411. break;
  1412. default:
  1413. break;
  1414. }
  1415. return "";
  1416. }
  1417. const char* cmTarget::GetPrefixVariableInternal(
  1418. cmStateEnums::ArtifactType artifact) const
  1419. {
  1420. switch (this->GetType()) {
  1421. case cmStateEnums::STATIC_LIBRARY:
  1422. return "CMAKE_STATIC_LIBRARY_PREFIX";
  1423. case cmStateEnums::SHARED_LIBRARY:
  1424. switch (artifact) {
  1425. case cmStateEnums::RuntimeBinaryArtifact:
  1426. return "CMAKE_SHARED_LIBRARY_PREFIX";
  1427. case cmStateEnums::ImportLibraryArtifact:
  1428. return "CMAKE_IMPORT_LIBRARY_PREFIX";
  1429. }
  1430. break;
  1431. case cmStateEnums::MODULE_LIBRARY:
  1432. switch (artifact) {
  1433. case cmStateEnums::RuntimeBinaryArtifact:
  1434. return "CMAKE_SHARED_MODULE_PREFIX";
  1435. case cmStateEnums::ImportLibraryArtifact:
  1436. return "CMAKE_IMPORT_LIBRARY_PREFIX";
  1437. }
  1438. break;
  1439. case cmStateEnums::EXECUTABLE:
  1440. switch (artifact) {
  1441. case cmStateEnums::RuntimeBinaryArtifact:
  1442. // Android GUI application packages store the native
  1443. // binary as a shared library.
  1444. return (this->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")
  1445. ? "CMAKE_SHARED_LIBRARY_PREFIX"
  1446. : "");
  1447. case cmStateEnums::ImportLibraryArtifact:
  1448. return "CMAKE_IMPORT_LIBRARY_PREFIX";
  1449. }
  1450. break;
  1451. default:
  1452. break;
  1453. }
  1454. return "";
  1455. }
  1456. std::string cmTarget::ImportedGetFullPath(
  1457. const std::string& config, cmStateEnums::ArtifactType artifact) const
  1458. {
  1459. assert(this->IsImported());
  1460. // Lookup/compute/cache the import information for this
  1461. // configuration.
  1462. std::string desired_config = config;
  1463. if (config.empty()) {
  1464. desired_config = "NOCONFIG";
  1465. }
  1466. std::string result;
  1467. const char* loc = nullptr;
  1468. const char* imp = nullptr;
  1469. std::string suffix;
  1470. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
  1471. this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
  1472. switch (artifact) {
  1473. case cmStateEnums::RuntimeBinaryArtifact:
  1474. if (loc) {
  1475. result = loc;
  1476. } else {
  1477. std::string impProp = "IMPORTED_LOCATION";
  1478. impProp += suffix;
  1479. if (const char* config_location = this->GetProperty(impProp)) {
  1480. result = config_location;
  1481. } else if (const char* location =
  1482. this->GetProperty("IMPORTED_LOCATION")) {
  1483. result = location;
  1484. }
  1485. }
  1486. break;
  1487. case cmStateEnums::ImportLibraryArtifact:
  1488. if (imp) {
  1489. result = imp;
  1490. } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
  1491. this->IsExecutableWithExports()) {
  1492. std::string impProp = "IMPORTED_IMPLIB";
  1493. impProp += suffix;
  1494. if (const char* config_implib = this->GetProperty(impProp)) {
  1495. result = config_implib;
  1496. } else if (const char* implib =
  1497. this->GetProperty("IMPORTED_IMPLIB")) {
  1498. result = implib;
  1499. }
  1500. }
  1501. break;
  1502. }
  1503. }
  1504. if (result.empty()) {
  1505. result = this->GetName();
  1506. result += "-NOTFOUND";
  1507. }
  1508. return result;
  1509. }
  1510. void cmTarget::SetPropertyDefault(const std::string& property,
  1511. const char* default_value)
  1512. {
  1513. // Compute the name of the variable holding the default value.
  1514. std::string var = "CMAKE_";
  1515. var += property;
  1516. if (const char* value = this->Makefile->GetDefinition(var)) {
  1517. this->SetProperty(property, value);
  1518. } else if (default_value) {
  1519. this->SetProperty(property, default_value);
  1520. }
  1521. }
  1522. bool cmTarget::CheckImportedLibName(std::string const& prop,
  1523. std::string const& value) const
  1524. {
  1525. if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY ||
  1526. !this->IsImported()) {
  1527. this->Makefile->IssueMessage(
  1528. MessageType::FATAL_ERROR,
  1529. prop +
  1530. " property may be set only on imported INTERFACE library targets.");
  1531. return false;
  1532. }
  1533. if (!value.empty()) {
  1534. if (value[0] == '-') {
  1535. this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
  1536. prop + " property value\n " + value +
  1537. "\nmay not start with '-'.");
  1538. return false;
  1539. }
  1540. std::string::size_type bad = value.find_first_of(":/\\;");
  1541. if (bad != std::string::npos) {
  1542. this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
  1543. prop + " property value\n " + value +
  1544. "\nmay not contain '" +
  1545. value.substr(bad, 1) + "'.");
  1546. return false;
  1547. }
  1548. }
  1549. return true;
  1550. }
  1551. bool cmTarget::GetMappedConfig(std::string const& desired_config,
  1552. const char** loc, const char** imp,
  1553. std::string& suffix) const
  1554. {
  1555. std::string config_upper;
  1556. if (!desired_config.empty()) {
  1557. config_upper = cmSystemTools::UpperCase(desired_config);
  1558. }
  1559. std::string locPropBase;
  1560. if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
  1561. locPropBase = "IMPORTED_LIBNAME";
  1562. } else if (this->GetType() == cmStateEnums::OBJECT_LIBRARY) {
  1563. locPropBase = "IMPORTED_OBJECTS";
  1564. } else {
  1565. locPropBase = "IMPORTED_LOCATION";
  1566. }
  1567. // Track the configuration-specific property suffix.
  1568. suffix = "_";
  1569. suffix += config_upper;
  1570. std::vector<std::string> mappedConfigs;
  1571. {
  1572. std::string mapProp = "MAP_IMPORTED_CONFIG_";
  1573. mapProp += config_upper;
  1574. if (const char* mapValue = this->GetProperty(mapProp)) {
  1575. cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
  1576. }
  1577. }
  1578. // If we needed to find one of the mapped configurations but did not
  1579. // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
  1580. // library or an executable with exports.
  1581. bool allowImp = this->HasImportLibrary();
  1582. // If a mapping was found, check its configurations.
  1583. for (std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
  1584. !*loc && !*imp && mci != mappedConfigs.end(); ++mci) {
  1585. // Look for this configuration.
  1586. if (mci->empty()) {
  1587. // An empty string in the mapping has a special meaning:
  1588. // look up the config-less properties.
  1589. *loc = this->GetProperty(locPropBase);
  1590. if (allowImp) {
  1591. *imp = this->GetProperty("IMPORTED_IMPLIB");
  1592. }
  1593. // If it was found, set the suffix.
  1594. if (*loc || *imp) {
  1595. suffix.clear();
  1596. }
  1597. } else {
  1598. std::string mcUpper = cmSystemTools::UpperCase(*mci);
  1599. std::string locProp = locPropBase + "_";
  1600. locProp += mcUpper;
  1601. *loc = this->GetProperty(locProp);
  1602. if (allowImp) {
  1603. std::string impProp = "IMPORTED_IMPLIB_";
  1604. impProp += mcUpper;
  1605. *imp = this->GetProperty(impProp);
  1606. }
  1607. // If it was found, use it for all properties below.
  1608. if (*loc || *imp) {
  1609. suffix = "_";
  1610. suffix += mcUpper;
  1611. }
  1612. }
  1613. }
  1614. // If we needed to find one of the mapped configurations but did not
  1615. // then the target location is not found. The project does not want
  1616. // any other configuration.
  1617. if (!mappedConfigs.empty() && !*loc && !*imp) {
  1618. // Interface libraries are always available because their
  1619. // library name is optional so it is okay to leave *loc empty.
  1620. return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
  1621. }
  1622. // If we have not yet found it then there are no mapped
  1623. // configurations. Look for an exact-match.
  1624. if (!*loc && !*imp) {
  1625. std::string locProp = locPropBase;
  1626. locProp += suffix;
  1627. *loc = this->GetProperty(locProp);
  1628. if (allowImp) {
  1629. std::string impProp = "IMPORTED_IMPLIB";
  1630. impProp += suffix;
  1631. *imp = this->GetProperty(impProp);
  1632. }
  1633. }
  1634. // If we have not yet found it then there are no mapped
  1635. // configurations and no exact match.
  1636. if (!*loc && !*imp) {
  1637. // The suffix computed above is not useful.
  1638. suffix.clear();
  1639. // Look for a configuration-less location. This may be set by
  1640. // manually-written code.
  1641. *loc = this->GetProperty(locPropBase);
  1642. if (allowImp) {
  1643. *imp = this->GetProperty("IMPORTED_IMPLIB");
  1644. }
  1645. }
  1646. // If we have not yet found it then the project is willing to try
  1647. // any available configuration.
  1648. if (!*loc && !*imp) {
  1649. std::vector<std::string> availableConfigs;
  1650. if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
  1651. cmSystemTools::ExpandListArgument(iconfigs, availableConfigs);
  1652. }
  1653. for (std::vector<std::string>::const_iterator aci =
  1654. availableConfigs.begin();
  1655. !*loc && !*imp && aci != availableConfigs.end(); ++aci) {
  1656. suffix = "_";
  1657. suffix += cmSystemTools::UpperCase(*aci);
  1658. std::string locProp = locPropBase;
  1659. locProp += suffix;
  1660. *loc = this->GetProperty(locProp);
  1661. if (allowImp) {
  1662. std::string impProp = "IMPORTED_IMPLIB";
  1663. impProp += suffix;
  1664. *imp = this->GetProperty(impProp);
  1665. }
  1666. }
  1667. }
  1668. // If we have not yet found it then the target location is not available.
  1669. if (!*loc && !*imp) {
  1670. // Interface libraries are always available because their
  1671. // library name is optional so it is okay to leave *loc empty.
  1672. return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
  1673. }
  1674. return true;
  1675. }
  1676. cmTargetInternalPointer::cmTargetInternalPointer()
  1677. {
  1678. this->Pointer = new cmTargetInternals;
  1679. }
  1680. cmTargetInternalPointer::cmTargetInternalPointer(
  1681. cmTargetInternalPointer const& r)
  1682. {
  1683. // Ideally cmTarget instances should never be copied. However until
  1684. // we can make a sweep to remove that, this copy constructor avoids
  1685. // allowing the resources (Internals) to be copied.
  1686. this->Pointer = new cmTargetInternals(*r.Pointer);
  1687. }
  1688. cmTargetInternalPointer::~cmTargetInternalPointer()
  1689. {
  1690. delete this->Pointer;
  1691. }
  1692. cmTargetInternalPointer& cmTargetInternalPointer::operator=(
  1693. cmTargetInternalPointer const& r)
  1694. {
  1695. if (this == &r) {
  1696. return *this;
  1697. } // avoid warning on HP about self check
  1698. // Ideally cmTarget instances should never be copied. However until
  1699. // we can make a sweep to remove that, this copy constructor avoids
  1700. // allowing the resources (Internals) to be copied.
  1701. cmTargetInternals* oldPointer = this->Pointer;
  1702. this->Pointer = new cmTargetInternals(*r.Pointer);
  1703. delete oldPointer;
  1704. return *this;
  1705. }