cmGhsMultiTargetGenerator.cxx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  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 "cmGhsMultiTargetGenerator.h"
  4. #include "cmGeneratedFileStream.h"
  5. #include "cmGeneratorTarget.h"
  6. #include "cmGlobalGhsMultiGenerator.h"
  7. #include "cmLinkLineComputer.h"
  8. #include "cmLocalGhsMultiGenerator.h"
  9. #include "cmMakefile.h"
  10. #include "cmSourceFile.h"
  11. #include "cmTarget.h"
  12. #include <assert.h>
  13. std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
  14. cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
  15. : GeneratorTarget(target)
  16. , LocalGenerator(
  17. static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
  18. , Makefile(target->Target->GetMakefile())
  19. , TargetGroup(DetermineIfTargetGroup(target))
  20. , DynamicDownload(false)
  21. {
  22. this->RelBuildFilePath = this->GetRelBuildFilePath(target);
  23. this->RelOutputFileName = this->RelBuildFilePath + target->GetName() + ".a";
  24. this->RelBuildFileName = this->RelBuildFilePath;
  25. this->RelBuildFileName += this->GetBuildFileName(target);
  26. std::string absPathToRoot = this->GetAbsPathToRoot(target);
  27. absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
  28. this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
  29. this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
  30. this->AbsOutputFileName = absPathToRoot + this->RelOutputFileName;
  31. }
  32. cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
  33. {
  34. cmDeleteAll(this->FolderBuildStreams);
  35. }
  36. std::string cmGhsMultiTargetGenerator::GetRelBuildFilePath(
  37. const cmGeneratorTarget* target)
  38. {
  39. std::string output = target->GetEffectiveFolderName();
  40. cmSystemTools::ConvertToUnixSlashes(output);
  41. if (!output.empty()) {
  42. output += "/";
  43. }
  44. output += target->GetName() + "/";
  45. return output;
  46. }
  47. std::string cmGhsMultiTargetGenerator::GetAbsPathToRoot(
  48. const cmGeneratorTarget* target)
  49. {
  50. return target->GetLocalGenerator()->GetBinaryDirectory();
  51. }
  52. std::string cmGhsMultiTargetGenerator::GetAbsBuildFilePath(
  53. const cmGeneratorTarget* target)
  54. {
  55. std::string output;
  56. output = cmGhsMultiTargetGenerator::GetAbsPathToRoot(target);
  57. output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
  58. output += cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
  59. return output;
  60. }
  61. std::string cmGhsMultiTargetGenerator::GetRelBuildFileName(
  62. const cmGeneratorTarget* target)
  63. {
  64. std::string output;
  65. output = cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
  66. output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
  67. output += cmGhsMultiTargetGenerator::GetBuildFileName(target);
  68. return output;
  69. }
  70. std::string cmGhsMultiTargetGenerator::GetBuildFileName(
  71. const cmGeneratorTarget* target)
  72. {
  73. std::string output;
  74. output = target->GetName();
  75. output += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
  76. return output;
  77. }
  78. std::string cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(
  79. std::string const& input)
  80. {
  81. std::string output(input);
  82. if (!cmHasLiteralSuffix(output, "/")) {
  83. output += "/";
  84. }
  85. return output;
  86. }
  87. void cmGhsMultiTargetGenerator::Generate()
  88. {
  89. std::vector<cmSourceFile*> objectSources = this->GetSources();
  90. if (!objectSources.empty() && this->IncludeThisTarget()) {
  91. if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str())) {
  92. cmSystemTools::MakeDirectory(this->AbsBuildFilePath.c_str());
  93. }
  94. cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
  95. &this->FolderBuildStreams);
  96. cmGlobalGhsMultiGenerator::OpenBuildFileStream(
  97. this->GetFolderBuildStreams());
  98. std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  99. if (0 == config.length()) {
  100. config = "RELEASE";
  101. }
  102. const std::string language(
  103. this->GeneratorTarget->GetLinkerLanguage(config));
  104. config = cmSystemTools::UpperCase(config);
  105. this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
  106. if (this->DynamicDownload) {
  107. *this->GetFolderBuildStreams() << "#component integrity_dynamic_download"
  108. << std::endl;
  109. }
  110. GhsMultiGpj::WriteGpjTag(this->GetGpjTag(), this->GetFolderBuildStreams());
  111. cmGlobalGhsMultiGenerator::WriteDisclaimer(this->GetFolderBuildStreams());
  112. bool const notKernel = this->IsNotKernel(config, language);
  113. this->WriteTypeSpecifics(config, notKernel);
  114. this->SetCompilerFlags(config, language, notKernel);
  115. this->WriteCompilerFlags(config, language);
  116. this->WriteCompilerDefinitions(config, language);
  117. this->WriteIncludes(config, language);
  118. if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
  119. this->WriteTargetLinkLibraries(config, language);
  120. }
  121. this->WriteCustomCommands();
  122. std::map<const cmSourceFile*, std::string> objectNames =
  123. cmGhsMultiTargetGenerator::GetObjectNames(
  124. &objectSources, this->LocalGenerator, this->GeneratorTarget);
  125. this->WriteSources(objectSources, objectNames);
  126. }
  127. }
  128. bool cmGhsMultiTargetGenerator::IncludeThisTarget()
  129. {
  130. bool output = true;
  131. char const* excludeFromAll =
  132. this->GeneratorTarget->GetProperty("EXCLUDE_FROM_ALL");
  133. if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
  134. '\0' == excludeFromAll[1]) {
  135. output = false;
  136. }
  137. return output;
  138. }
  139. std::vector<cmSourceFile*> cmGhsMultiTargetGenerator::GetSources() const
  140. {
  141. std::vector<cmSourceFile*> output;
  142. std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  143. this->GeneratorTarget->GetSourceFiles(output, config);
  144. return output;
  145. }
  146. GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const
  147. {
  148. return cmGhsMultiTargetGenerator::GetGpjTag(this->GeneratorTarget);
  149. }
  150. GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(
  151. const cmGeneratorTarget* target)
  152. {
  153. GhsMultiGpj::Types output;
  154. if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target)) {
  155. output = GhsMultiGpj::INTERGRITY_APPLICATION;
  156. } else if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
  157. output = GhsMultiGpj::LIBRARY;
  158. } else {
  159. output = GhsMultiGpj::PROGRAM;
  160. }
  161. return output;
  162. }
  163. cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
  164. const
  165. {
  166. return static_cast<cmGlobalGhsMultiGenerator*>(
  167. this->LocalGenerator->GetGlobalGenerator());
  168. }
  169. void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string& config,
  170. bool const notKernel)
  171. {
  172. std::string outputDir(this->GetOutputDirectory(config));
  173. std::string outputFilename(this->GetOutputFilename(config));
  174. if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
  175. std::string const static_library_suffix =
  176. this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
  177. *this->GetFolderBuildStreams() << " -o \"" << outputDir
  178. << outputFilename << static_library_suffix
  179. << "\"" << std::endl;
  180. } else if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
  181. if (notKernel && !this->IsTargetGroup()) {
  182. *this->GetFolderBuildStreams() << " -relprog" << std::endl;
  183. }
  184. if (this->IsTargetGroup()) {
  185. *this->GetFolderBuildStreams()
  186. << " -o \"" << outputDir << outputFilename << ".elf\"" << std::endl;
  187. *this->GetFolderBuildStreams() << " :extraOutputFile=\"" << outputDir
  188. << outputFilename << ".elf.ael\""
  189. << std::endl;
  190. } else {
  191. std::string const executable_suffix =
  192. this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
  193. *this->GetFolderBuildStreams() << " -o \"" << outputDir
  194. << outputFilename << executable_suffix
  195. << "\"" << std::endl;
  196. }
  197. }
  198. }
  199. void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
  200. const std::string& language,
  201. bool const notKernel)
  202. {
  203. std::map<std::string, std::string>::iterator i =
  204. this->FlagsByLanguage.find(language);
  205. if (i == this->FlagsByLanguage.end()) {
  206. std::string flags;
  207. const char* lang = language.c_str();
  208. if (notKernel) {
  209. this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
  210. lang, config);
  211. } else {
  212. this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
  213. lang + std::string("_GHS_KERNEL"),
  214. config);
  215. }
  216. this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
  217. config);
  218. this->LocalGenerator->AddVisibilityPresetFlags(
  219. flags, this->GeneratorTarget, lang);
  220. // Append old-style preprocessor definition flags.
  221. if (this->Makefile->GetDefineFlags() != " ") {
  222. this->LocalGenerator->AppendFlags(flags,
  223. this->Makefile->GetDefineFlags());
  224. }
  225. // Add target-specific flags.
  226. this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, lang,
  227. config);
  228. std::map<std::string, std::string>::value_type entry(language, flags);
  229. i = this->FlagsByLanguage.insert(entry).first;
  230. }
  231. }
  232. std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
  233. std::string const& config)
  234. {
  235. std::map<std::string, std::string>::iterator i =
  236. this->DefinesByLanguage.find(language);
  237. if (i == this->DefinesByLanguage.end()) {
  238. std::set<std::string> defines;
  239. const char* lang = language.c_str();
  240. // Add the export symbol definition for shared library objects.
  241. if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) {
  242. this->LocalGenerator->AppendDefines(defines, exportMacro);
  243. }
  244. // Add preprocessor definitions for this target and configuration.
  245. this->LocalGenerator->AddCompileDefinitions(defines, this->GeneratorTarget,
  246. config, language);
  247. std::string definesString;
  248. this->LocalGenerator->JoinDefines(defines, definesString, lang);
  249. std::map<std::string, std::string>::value_type entry(language,
  250. definesString);
  251. i = this->DefinesByLanguage.insert(entry).first;
  252. }
  253. return i->second;
  254. }
  255. void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::string const&,
  256. const std::string& language)
  257. {
  258. std::map<std::string, std::string>::iterator flagsByLangI =
  259. this->FlagsByLanguage.find(language);
  260. if (flagsByLangI != this->FlagsByLanguage.end()) {
  261. if (!flagsByLangI->second.empty()) {
  262. *this->GetFolderBuildStreams() << " " << flagsByLangI->second
  263. << std::endl;
  264. }
  265. }
  266. }
  267. void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
  268. const std::string& config, const std::string& language)
  269. {
  270. std::vector<std::string> compileDefinitions;
  271. this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
  272. language);
  273. for (std::vector<std::string>::const_iterator cdI =
  274. compileDefinitions.begin();
  275. cdI != compileDefinitions.end(); ++cdI) {
  276. *this->GetFolderBuildStreams() << " -D" << (*cdI) << std::endl;
  277. }
  278. }
  279. void cmGhsMultiTargetGenerator::WriteIncludes(const std::string& config,
  280. const std::string& language)
  281. {
  282. std::vector<std::string> includes;
  283. this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
  284. language, config);
  285. for (std::vector<std::string>::const_iterator includes_i = includes.begin();
  286. includes_i != includes.end(); ++includes_i) {
  287. *this->GetFolderBuildStreams() << " -I\"" << *includes_i << "\""
  288. << std::endl;
  289. }
  290. }
  291. void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
  292. std::string const& config, std::string const& language)
  293. {
  294. // library directories
  295. cmTargetDependSet tds =
  296. this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
  297. for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
  298. ++tdsI) {
  299. const cmGeneratorTarget* tg = *tdsI;
  300. *this->GetFolderBuildStreams() << " -L\"" << GetAbsBuildFilePath(tg)
  301. << "\"" << std::endl;
  302. }
  303. // library targets
  304. cmTarget::LinkLibraryVectorType llv =
  305. this->GeneratorTarget->Target->GetOriginalLinkLibraries();
  306. for (cmTarget::LinkLibraryVectorType::const_iterator llvI = llv.begin();
  307. llvI != llv.end(); ++llvI) {
  308. std::string libName = llvI->first;
  309. // if it is a user defined target get the full path to the lib
  310. cmTarget* tg(GetGlobalGenerator()->FindTarget(libName));
  311. if (NULL != tg) {
  312. libName = tg->GetName() + ".a";
  313. }
  314. *this->GetFolderBuildStreams() << " -l\"" << libName << "\""
  315. << std::endl;
  316. }
  317. if (!this->TargetGroup) {
  318. std::string linkLibraries;
  319. std::string flags;
  320. std::string linkFlags;
  321. std::string frameworkPath;
  322. std::string linkPath;
  323. std::string createRule =
  324. this->GeneratorTarget->GetCreateRuleVariable(language, config);
  325. bool useWatcomQuote =
  326. this->Makefile->IsOn(createRule + "_USE_WATCOM_QUOTE");
  327. std::unique_ptr<cmLinkLineComputer> linkLineComputer(
  328. this->GetGlobalGenerator()->CreateLinkLineComputer(
  329. this->LocalGenerator,
  330. this->LocalGenerator->GetStateSnapshot().GetDirectory()));
  331. linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
  332. this->LocalGenerator->GetTargetFlags(
  333. linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
  334. frameworkPath, linkPath, this->GeneratorTarget);
  335. linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
  336. if (!linkPath.empty()) {
  337. linkPath = " " + linkPath.substr(0U, linkPath.size() - 1U);
  338. *this->GetFolderBuildStreams() << linkPath;
  339. }
  340. if (!linkFlags.empty()) {
  341. *this->GetFolderBuildStreams() << " " << linkFlags << std::endl;
  342. }
  343. }
  344. }
  345. void cmGhsMultiTargetGenerator::WriteCustomCommands()
  346. {
  347. WriteCustomCommandsHelper(this->GeneratorTarget->GetPreBuildCommands(),
  348. cmTarget::PRE_BUILD);
  349. WriteCustomCommandsHelper(this->GeneratorTarget->GetPostBuildCommands(),
  350. cmTarget::POST_BUILD);
  351. }
  352. void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
  353. std::vector<cmCustomCommand> const& commandsSet,
  354. cmTarget::CustomCommandType const commandType)
  355. {
  356. for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
  357. commandsSet.begin();
  358. commandsSetI != commandsSet.end(); ++commandsSetI) {
  359. cmCustomCommandLines const& commands = commandsSetI->GetCommandLines();
  360. for (cmCustomCommandLines::const_iterator commandI = commands.begin();
  361. commandI != commands.end(); ++commandI) {
  362. switch (commandType) {
  363. case cmTarget::PRE_BUILD:
  364. *this->GetFolderBuildStreams() << " :preexecShellSafe=";
  365. break;
  366. case cmTarget::POST_BUILD:
  367. *this->GetFolderBuildStreams() << " :postexecShellSafe=";
  368. break;
  369. default:
  370. assert("Only pre and post are supported");
  371. }
  372. cmCustomCommandLine const& command = *commandI;
  373. for (cmCustomCommandLine::const_iterator commandLineI = command.begin();
  374. commandLineI != command.end(); ++commandLineI) {
  375. std::string subCommandE =
  376. this->LocalGenerator->EscapeForShell(*commandLineI, true);
  377. if (!command.empty()) {
  378. *this->GetFolderBuildStreams()
  379. << (command.begin() == commandLineI ? "'" : " ");
  380. // Need to double escape backslashes
  381. cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
  382. }
  383. *this->GetFolderBuildStreams() << subCommandE;
  384. }
  385. if (!command.empty()) {
  386. *this->GetFolderBuildStreams() << "'" << std::endl;
  387. }
  388. }
  389. }
  390. }
  391. std::map<const cmSourceFile*, std::string>
  392. cmGhsMultiTargetGenerator::GetObjectNames(
  393. std::vector<cmSourceFile*>* const objectSources,
  394. cmLocalGhsMultiGenerator* const localGhsMultiGenerator,
  395. cmGeneratorTarget* const generatorTarget)
  396. {
  397. std::map<std::string, std::vector<cmSourceFile*>> filenameToSource;
  398. std::map<cmSourceFile*, std::string> sourceToFilename;
  399. for (std::vector<cmSourceFile*>::const_iterator sf = objectSources->begin();
  400. sf != objectSources->end(); ++sf) {
  401. const std::string filename =
  402. cmSystemTools::GetFilenameName((*sf)->GetFullPath());
  403. const std::string lower_filename = cmSystemTools::LowerCase(filename);
  404. filenameToSource[lower_filename].push_back(*sf);
  405. sourceToFilename[*sf] = lower_filename;
  406. }
  407. std::vector<cmSourceFile*> duplicateSources;
  408. for (std::map<std::string, std::vector<cmSourceFile*>>::const_iterator
  409. msvSourceI = filenameToSource.begin();
  410. msvSourceI != filenameToSource.end(); ++msvSourceI) {
  411. if (msvSourceI->second.size() > 1) {
  412. duplicateSources.insert(duplicateSources.end(),
  413. msvSourceI->second.begin(),
  414. msvSourceI->second.end());
  415. }
  416. }
  417. std::map<const cmSourceFile*, std::string> objectNamesCorrected;
  418. for (std::vector<cmSourceFile*>::const_iterator sf =
  419. duplicateSources.begin();
  420. sf != duplicateSources.end(); ++sf) {
  421. std::string const longestObjectDirectory(
  422. cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
  423. localGhsMultiGenerator, generatorTarget, *sf));
  424. std::string objFilenameName =
  425. localGhsMultiGenerator->GetObjectFileNameWithoutTarget(
  426. **sf, longestObjectDirectory);
  427. cmsys::SystemTools::ReplaceString(objFilenameName, "/", "_");
  428. objectNamesCorrected[*sf] = objFilenameName;
  429. }
  430. return objectNamesCorrected;
  431. }
  432. void cmGhsMultiTargetGenerator::WriteSources(
  433. std::vector<cmSourceFile*> const& objectSources,
  434. std::map<const cmSourceFile*, std::string> const& objectNames)
  435. {
  436. for (std::vector<cmSourceFile*>::const_iterator si = objectSources.begin();
  437. si != objectSources.end(); ++si) {
  438. std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
  439. std::string const& sourceFullPath = (*si)->GetFullPath();
  440. cmSourceGroup* sourceGroup =
  441. this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
  442. std::string sgPath = sourceGroup->GetFullName();
  443. cmSystemTools::ConvertToUnixSlashes(sgPath);
  444. cmGlobalGhsMultiGenerator::AddFilesUpToPath(
  445. this->GetFolderBuildStreams(), &this->FolderBuildStreams,
  446. this->LocalGenerator->GetBinaryDirectory().c_str(), sgPath,
  447. GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
  448. std::string fullSourcePath((*si)->GetFullPath());
  449. if ((*si)->GetExtension() == "int" || (*si)->GetExtension() == "bsp") {
  450. *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
  451. } else {
  452. // WORKAROUND: GHS MULTI needs the path to use backslashes without quotes
  453. // to open files in search as of version 6.1.6
  454. cmsys::SystemTools::ReplaceString(fullSourcePath, "/", "\\");
  455. *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
  456. }
  457. if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
  458. "bsp" != (*si)->GetExtension()) {
  459. this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
  460. if (objectNames.end() != objectNames.find(*si)) {
  461. *this->FolderBuildStreams[sgPath]
  462. << " -o \"" << objectNames.find(*si)->second << "\"" << std::endl;
  463. }
  464. this->WriteObjectDir(this->FolderBuildStreams[sgPath],
  465. this->AbsBuildFilePath + sgPath);
  466. }
  467. }
  468. }
  469. void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
  470. cmGeneratedFileStream* fileStream, cmSourceFile* sourceFile)
  471. {
  472. const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
  473. if (NULL != rawLangProp) {
  474. std::string sourceLangProp(rawLangProp);
  475. std::string extension(sourceFile->GetExtension());
  476. if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
  477. *fileStream << " -dotciscxx" << std::endl;
  478. }
  479. }
  480. }
  481. void cmGhsMultiTargetGenerator::WriteObjectDir(
  482. cmGeneratedFileStream* fileStream, std::string const& dir)
  483. {
  484. std::string workingDir(dir);
  485. cmSystemTools::ConvertToUnixSlashes(workingDir);
  486. if (!workingDir.empty()) {
  487. workingDir += "/";
  488. }
  489. workingDir += "Objs";
  490. *fileStream << " -object_dir=\"" << workingDir << "\"" << std::endl;
  491. }
  492. std::string cmGhsMultiTargetGenerator::GetOutputDirectory(
  493. const std::string& config) const
  494. {
  495. std::string outputDir(AbsBuildFilePath);
  496. const char* runtimeOutputProp =
  497. this->GeneratorTarget->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
  498. if (NULL != runtimeOutputProp) {
  499. outputDir = runtimeOutputProp;
  500. }
  501. std::string configCapped(cmSystemTools::UpperCase(config));
  502. const char* runtimeOutputSProp = this->GeneratorTarget->GetProperty(
  503. "RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
  504. if (NULL != runtimeOutputSProp) {
  505. outputDir = runtimeOutputSProp;
  506. }
  507. cmSystemTools::ConvertToUnixSlashes(outputDir);
  508. if (!outputDir.empty()) {
  509. outputDir += "/";
  510. }
  511. return outputDir;
  512. }
  513. std::string cmGhsMultiTargetGenerator::GetOutputFilename(
  514. const std::string& config) const
  515. {
  516. std::string outputFilename(this->GeneratorTarget->GetName());
  517. const char* outputNameProp =
  518. this->GeneratorTarget->GetProperty("OUTPUT_NAME");
  519. if (NULL != outputNameProp) {
  520. outputFilename = outputNameProp;
  521. }
  522. std::string configCapped(cmSystemTools::UpperCase(config));
  523. const char* outputNameSProp =
  524. this->GeneratorTarget->GetProperty(configCapped + "_OUTPUT_NAME");
  525. if (NULL != outputNameSProp) {
  526. outputFilename = outputNameSProp;
  527. }
  528. return outputFilename;
  529. }
  530. std::string cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
  531. cmLocalGhsMultiGenerator const* localGhsMultiGenerator,
  532. cmGeneratorTarget* const generatorTarget, cmSourceFile* const sourceFile)
  533. {
  534. std::string dir_max;
  535. dir_max +=
  536. localGhsMultiGenerator->GetMakefile()->GetCurrentBinaryDirectory();
  537. dir_max += "/";
  538. dir_max += generatorTarget->Target->GetName();
  539. dir_max += "/";
  540. std::vector<cmSourceGroup> sourceGroups(
  541. localGhsMultiGenerator->GetMakefile()->GetSourceGroups());
  542. std::string const& sourceFullPath = sourceFile->GetFullPath();
  543. cmSourceGroup* sourceGroup =
  544. localGhsMultiGenerator->GetMakefile()->FindSourceGroup(sourceFullPath,
  545. sourceGroups);
  546. std::string const& sgPath = sourceGroup->GetFullName();
  547. dir_max += sgPath;
  548. dir_max += "/Objs/libs/";
  549. dir_max += generatorTarget->Target->GetName();
  550. dir_max += "/";
  551. return dir_max;
  552. }
  553. bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const& config,
  554. const std::string& language)
  555. {
  556. bool output;
  557. std::vector<std::string> options;
  558. this->GeneratorTarget->GetCompileOptions(options, config, language);
  559. output =
  560. options.end() == std::find(options.begin(), options.end(), "-kernel");
  561. return output;
  562. }
  563. bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
  564. const cmGeneratorTarget* target)
  565. {
  566. bool output = false;
  567. std::vector<cmSourceFile*> sources;
  568. std::string config =
  569. target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
  570. target->GetSourceFiles(sources, config);
  571. for (std::vector<cmSourceFile*>::const_iterator sources_i = sources.begin();
  572. sources.end() != sources_i; ++sources_i) {
  573. if ("int" == (*sources_i)->GetExtension()) {
  574. output = true;
  575. }
  576. }
  577. return output;
  578. }
  579. bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
  580. std::string const& config, const std::string& language)
  581. {
  582. std::vector<std::string> options;
  583. bool output = false;
  584. this->GeneratorTarget->GetCompileOptions(options, config, language);
  585. for (std::vector<std::string>::const_iterator options_i = options.begin();
  586. options_i != options.end(); ++options_i) {
  587. std::string option = *options_i;
  588. if (this->DDOption == option) {
  589. output = true;
  590. }
  591. }
  592. return output;
  593. }