cmGhsMultiTargetGenerator.cxx 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  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 "cmComputeLinkInformation.h"
  5. #include "cmGeneratedFileStream.h"
  6. #include "cmGeneratorTarget.h"
  7. #include "cmGlobalGhsMultiGenerator.h"
  8. #include "cmLinkLineComputer.h"
  9. #include "cmLocalGhsMultiGenerator.h"
  10. #include "cmMakefile.h"
  11. #include "cmSourceFile.h"
  12. #include "cmSourceGroup.h"
  13. #include "cmTarget.h"
  14. std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
  15. cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
  16. : GeneratorTarget(target)
  17. , LocalGenerator(
  18. static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
  19. , Makefile(target->Target->GetMakefile())
  20. , TargetGroup(DetermineIfTargetGroup(target))
  21. , DynamicDownload(false)
  22. , Name(target->GetName())
  23. {
  24. // Store the configuration name that is being used
  25. if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
  26. // Use the build type given by the user.
  27. this->ConfigName = config;
  28. } else {
  29. // No configuration type given.
  30. this->ConfigName.clear();
  31. }
  32. }
  33. cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
  34. {
  35. }
  36. void cmGhsMultiTargetGenerator::Generate()
  37. {
  38. // Determine type of target for this project
  39. switch (this->GeneratorTarget->GetType()) {
  40. case cmStateEnums::EXECUTABLE: {
  41. // Get the name of the executable to generate.
  42. std::string targetName;
  43. std::string targetNameImport;
  44. std::string targetNamePDB;
  45. this->GeneratorTarget->GetExecutableNames(
  46. targetName, this->TargetNameReal, targetNameImport, targetNamePDB,
  47. this->ConfigName);
  48. if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
  49. this->GeneratorTarget)) {
  50. this->TagType = GhsMultiGpj::INTERGRITY_APPLICATION;
  51. } else {
  52. this->TagType = GhsMultiGpj::PROGRAM;
  53. }
  54. break;
  55. }
  56. case cmStateEnums::STATIC_LIBRARY: {
  57. std::string targetName;
  58. std::string targetNameSO;
  59. std::string targetNameImport;
  60. std::string targetNamePDB;
  61. this->GeneratorTarget->GetLibraryNames(
  62. targetName, targetNameSO, this->TargetNameReal, targetNameImport,
  63. targetNamePDB, this->ConfigName);
  64. this->TagType = GhsMultiGpj::LIBRARY;
  65. break;
  66. }
  67. case cmStateEnums::SHARED_LIBRARY: {
  68. std::string msg = "add_library(<name> SHARED ...) not supported: ";
  69. msg += this->Name;
  70. cmSystemTools::Message(msg.c_str());
  71. return;
  72. }
  73. case cmStateEnums::OBJECT_LIBRARY: {
  74. std::string msg = "add_library(<name> OBJECT ...) not supported: ";
  75. msg += this->Name;
  76. cmSystemTools::Message(msg.c_str());
  77. return;
  78. }
  79. case cmStateEnums::MODULE_LIBRARY: {
  80. std::string msg = "add_library(<name> MODULE ...) not supported: ";
  81. msg += this->Name;
  82. cmSystemTools::Message(msg.c_str());
  83. return;
  84. }
  85. case cmStateEnums::UTILITY: {
  86. std::string msg = "add_custom_target(<name> ...) not supported: ";
  87. msg += this->Name;
  88. cmSystemTools::Message(msg.c_str());
  89. return;
  90. }
  91. default:
  92. return;
  93. }
  94. // Tell the global generator the name of the project file
  95. this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
  96. this->Name.c_str());
  97. this->GeneratorTarget->Target->SetProperty(
  98. "GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
  99. this->GenerateTarget();
  100. }
  101. void cmGhsMultiTargetGenerator::GenerateTarget()
  102. {
  103. // Skip if empty or not included in build
  104. if (!this->GetSources().empty() && this->IncludeThisTarget()) {
  105. // Open the filestream in copy-if-different mode.
  106. std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
  107. fname += "/";
  108. fname += this->Name;
  109. fname += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
  110. cmGeneratedFileStream fout(fname.c_str());
  111. fout.SetCopyIfDifferent(true);
  112. this->GetGlobalGenerator()->WriteFileHeader(fout);
  113. GhsMultiGpj::WriteGpjTag(this->TagType, fout);
  114. const std::string language(
  115. this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
  116. this->DynamicDownload =
  117. this->DetermineIfDynamicDownload(this->ConfigName, language);
  118. if (this->DynamicDownload) {
  119. fout << "#component integrity_dynamic_download" << std::endl;
  120. }
  121. this->WriteTargetSpecifics(fout, this->ConfigName);
  122. this->SetCompilerFlags(this->ConfigName, language);
  123. this->WriteCompilerFlags(fout, this->ConfigName, language);
  124. this->WriteCompilerDefinitions(fout, this->ConfigName, language);
  125. this->WriteIncludes(fout, this->ConfigName, language);
  126. this->WriteTargetLinkLine(fout, this->ConfigName);
  127. this->WriteCustomCommands(fout);
  128. this->WriteSources(fout);
  129. fout.Close();
  130. }
  131. }
  132. bool cmGhsMultiTargetGenerator::IncludeThisTarget()
  133. {
  134. bool output = true;
  135. char const* excludeFromAll =
  136. this->GeneratorTarget->GetProperty("EXCLUDE_FROM_ALL");
  137. if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
  138. '\0' == excludeFromAll[1]) {
  139. output = false;
  140. }
  141. return output;
  142. }
  143. std::vector<cmSourceFile*> cmGhsMultiTargetGenerator::GetSources() const
  144. {
  145. std::vector<cmSourceFile*> output;
  146. this->GeneratorTarget->GetSourceFiles(output, this->ConfigName);
  147. return output;
  148. }
  149. cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
  150. const
  151. {
  152. return static_cast<cmGlobalGhsMultiGenerator*>(
  153. this->LocalGenerator->GetGlobalGenerator());
  154. }
  155. void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
  156. const std::string& config)
  157. {
  158. std::string outpath;
  159. std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
  160. // set target binary file destination
  161. outpath = this->GeneratorTarget->GetDirectory(config);
  162. outpath = this->LocalGenerator->ConvertToRelativePath(rootpath, outpath);
  163. fout << " :binDirRelative=\"" << outpath << "\"" << std::endl;
  164. fout << " -o \"" << this->TargetNameReal << "\"" << std::endl;
  165. // set target object file destination
  166. outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
  167. fout << " :outputDirRelative=\"" << outpath << "\"" << std::endl;
  168. }
  169. void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
  170. const std::string& language)
  171. {
  172. std::map<std::string, std::string>::iterator i =
  173. this->FlagsByLanguage.find(language);
  174. if (i == this->FlagsByLanguage.end()) {
  175. std::string flags;
  176. const char* lang = language.c_str();
  177. this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
  178. config);
  179. this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
  180. config);
  181. this->LocalGenerator->AddVisibilityPresetFlags(
  182. flags, this->GeneratorTarget, lang);
  183. // Append old-style preprocessor definition flags.
  184. if (this->Makefile->GetDefineFlags() != " ") {
  185. this->LocalGenerator->AppendFlags(flags,
  186. this->Makefile->GetDefineFlags());
  187. }
  188. // Add target-specific flags.
  189. this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, lang,
  190. config);
  191. std::map<std::string, std::string>::value_type entry(language, flags);
  192. i = this->FlagsByLanguage.insert(entry).first;
  193. }
  194. }
  195. std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
  196. std::string const& config)
  197. {
  198. std::map<std::string, std::string>::iterator i =
  199. this->DefinesByLanguage.find(language);
  200. if (i == this->DefinesByLanguage.end()) {
  201. std::set<std::string> defines;
  202. const char* lang = language.c_str();
  203. // Add preprocessor definitions for this target and configuration.
  204. this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, config,
  205. language, defines);
  206. std::string definesString;
  207. this->LocalGenerator->JoinDefines(defines, definesString, lang);
  208. std::map<std::string, std::string>::value_type entry(language,
  209. definesString);
  210. i = this->DefinesByLanguage.insert(entry).first;
  211. }
  212. return i->second;
  213. }
  214. void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
  215. std::string const&,
  216. const std::string& language)
  217. {
  218. std::map<std::string, std::string>::iterator flagsByLangI =
  219. this->FlagsByLanguage.find(language);
  220. if (flagsByLangI != this->FlagsByLanguage.end()) {
  221. if (!flagsByLangI->second.empty()) {
  222. std::vector<std::string> ghsCompFlags =
  223. cmSystemTools::ParseArguments(flagsByLangI->second.c_str());
  224. for (auto& f : ghsCompFlags) {
  225. fout << " " << f << std::endl;
  226. }
  227. }
  228. }
  229. }
  230. void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
  231. std::ostream& fout, const std::string& config, const std::string& language)
  232. {
  233. std::vector<std::string> compileDefinitions;
  234. this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
  235. language);
  236. for (std::vector<std::string>::const_iterator cdI =
  237. compileDefinitions.begin();
  238. cdI != compileDefinitions.end(); ++cdI) {
  239. fout << " -D" << (*cdI) << std::endl;
  240. }
  241. }
  242. void cmGhsMultiTargetGenerator::WriteIncludes(std::ostream& fout,
  243. const std::string& config,
  244. const std::string& language)
  245. {
  246. std::vector<std::string> includes;
  247. this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
  248. language, config);
  249. for (std::vector<std::string>::const_iterator includes_i = includes.begin();
  250. includes_i != includes.end(); ++includes_i) {
  251. fout << " -I\"" << *includes_i << "\"" << std::endl;
  252. }
  253. }
  254. void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
  255. std::string const& config)
  256. {
  257. if (this->TagType == GhsMultiGpj::INTERGRITY_APPLICATION) {
  258. return;
  259. }
  260. std::string linkLibraries;
  261. std::string flags;
  262. std::string linkFlags;
  263. std::string frameworkPath;
  264. std::string linkPath;
  265. std::unique_ptr<cmLinkLineComputer> linkLineComputer(
  266. this->GetGlobalGenerator()->CreateLinkLineComputer(
  267. this->LocalGenerator,
  268. this->LocalGenerator->GetStateSnapshot().GetDirectory()));
  269. this->LocalGenerator->GetTargetFlags(
  270. linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
  271. frameworkPath, linkPath, this->GeneratorTarget);
  272. // write out link options
  273. std::vector<std::string> lopts =
  274. cmSystemTools::ParseArguments(linkFlags.c_str());
  275. for (auto& l : lopts) {
  276. fout << " " << l << std::endl;
  277. }
  278. // write out link search paths
  279. // must be quoted for paths that contain spaces
  280. std::vector<std::string> lpath =
  281. cmSystemTools::ParseArguments(linkPath.c_str());
  282. for (auto& l : lpath) {
  283. fout << " -L\"" << l << "\"" << std::endl;
  284. }
  285. // write out link libs
  286. // must be quoted for filepaths that contains spaces
  287. std::string cbd = this->LocalGenerator->GetCurrentBinaryDirectory();
  288. std::vector<std::string> llibs =
  289. cmSystemTools::ParseArguments(linkLibraries.c_str());
  290. for (auto& l : llibs) {
  291. if (l.compare(0, 2, "-l") == 0) {
  292. fout << " \"" << l << "\"" << std::endl;
  293. } else {
  294. std::string rl = cmSystemTools::CollapseCombinedPath(cbd, l);
  295. fout << " -l\"" << rl << "\"" << std::endl;
  296. }
  297. }
  298. }
  299. void cmGhsMultiTargetGenerator::WriteCustomCommands(std::ostream& fout)
  300. {
  301. WriteCustomCommandsHelper(fout, this->GeneratorTarget->GetPreBuildCommands(),
  302. cmTarget::PRE_BUILD);
  303. WriteCustomCommandsHelper(
  304. fout, this->GeneratorTarget->GetPostBuildCommands(), cmTarget::POST_BUILD);
  305. }
  306. void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
  307. std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
  308. cmTarget::CustomCommandType const commandType)
  309. {
  310. for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
  311. commandsSet.begin();
  312. commandsSetI != commandsSet.end(); ++commandsSetI) {
  313. cmCustomCommandLines const& commands = commandsSetI->GetCommandLines();
  314. for (cmCustomCommandLines::const_iterator commandI = commands.begin();
  315. commandI != commands.end(); ++commandI) {
  316. switch (commandType) {
  317. case cmTarget::PRE_BUILD:
  318. fout << " :preexecShellSafe=";
  319. break;
  320. case cmTarget::POST_BUILD:
  321. fout << " :postexecShellSafe=";
  322. break;
  323. default:
  324. assert("Only pre and post are supported");
  325. }
  326. cmCustomCommandLine const& command = *commandI;
  327. for (cmCustomCommandLine::const_iterator commandLineI = command.begin();
  328. commandLineI != command.end(); ++commandLineI) {
  329. std::string subCommandE =
  330. this->LocalGenerator->EscapeForShell(*commandLineI, true);
  331. if (!command.empty()) {
  332. fout << (command.begin() == commandLineI ? "'" : " ");
  333. // Need to double escape backslashes
  334. cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
  335. }
  336. fout << subCommandE;
  337. }
  338. if (!command.empty()) {
  339. fout << "'" << std::endl;
  340. }
  341. }
  342. }
  343. }
  344. std::map<const cmSourceFile*, std::string>
  345. cmGhsMultiTargetGenerator::GetObjectNames(
  346. std::vector<cmSourceFile*>* const objectSources,
  347. cmLocalGhsMultiGenerator* const localGhsMultiGenerator,
  348. cmGeneratorTarget* const generatorTarget)
  349. {
  350. std::map<std::string, std::vector<cmSourceFile*>> filenameToSource;
  351. std::map<cmSourceFile*, std::string> sourceToFilename;
  352. for (std::vector<cmSourceFile*>::const_iterator sf = objectSources->begin();
  353. sf != objectSources->end(); ++sf) {
  354. const std::string filename =
  355. cmSystemTools::GetFilenameName((*sf)->GetFullPath());
  356. const std::string lower_filename = cmSystemTools::LowerCase(filename);
  357. filenameToSource[lower_filename].push_back(*sf);
  358. sourceToFilename[*sf] = lower_filename;
  359. }
  360. std::vector<cmSourceFile*> duplicateSources;
  361. for (std::map<std::string, std::vector<cmSourceFile*>>::const_iterator
  362. msvSourceI = filenameToSource.begin();
  363. msvSourceI != filenameToSource.end(); ++msvSourceI) {
  364. if (msvSourceI->second.size() > 1) {
  365. duplicateSources.insert(duplicateSources.end(),
  366. msvSourceI->second.begin(),
  367. msvSourceI->second.end());
  368. }
  369. }
  370. std::map<const cmSourceFile*, std::string> objectNamesCorrected;
  371. for (std::vector<cmSourceFile*>::const_iterator sf =
  372. duplicateSources.begin();
  373. sf != duplicateSources.end(); ++sf) {
  374. std::string const longestObjectDirectory(
  375. cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
  376. localGhsMultiGenerator, generatorTarget, *sf));
  377. std::string objFilenameName =
  378. localGhsMultiGenerator->GetObjectFileNameWithoutTarget(
  379. **sf, longestObjectDirectory);
  380. cmsys::SystemTools::ReplaceString(objFilenameName, "/", "_");
  381. objectNamesCorrected[*sf] = objFilenameName;
  382. }
  383. return objectNamesCorrected;
  384. }
  385. void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
  386. {
  387. /* vector of all sources for this target */
  388. std::vector<cmSourceFile*> sources = this->GetSources();
  389. /* vector of all groups defined for this target
  390. * -- but the vector is not expanded with sub groups or in any useful order
  391. */
  392. std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
  393. /* for each source file assign it to its group */
  394. std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
  395. std::set<std::string> groupNames;
  396. for (auto& sf : sources) {
  397. cmSourceGroup* sourceGroup =
  398. this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups);
  399. std::string gn = sourceGroup->GetFullName();
  400. groupFiles[gn].push_back(sf);
  401. groupNames.insert(gn);
  402. }
  403. /* list of known groups and the order they are displayed in a project file */
  404. const std::vector<std::string> standardGroups = {
  405. "Header Files", "Source Files", "CMake Rules",
  406. "Object Files", "Object Libraries", "Resources"
  407. };
  408. /* list of groups in the order they are displayed in a project file*/
  409. std::vector<std::string> groupFilesList(groupFiles.size());
  410. /* put the groups in the order they should be listed
  411. * - standard groups first, and then everything else
  412. * in the order used by std::map.
  413. */
  414. int i = 0;
  415. for (const std::string& gn : standardGroups) {
  416. auto n = groupNames.find(gn);
  417. if (n != groupNames.end()) {
  418. groupFilesList[i] = *n;
  419. i += 1;
  420. groupNames.erase(gn);
  421. }
  422. }
  423. { /* catch-all group - is last item */
  424. std::string gn = "";
  425. auto n = groupNames.find(gn);
  426. if (n != groupNames.end()) {
  427. groupFilesList.back() = *n;
  428. groupNames.erase(gn);
  429. }
  430. }
  431. for (auto& n : groupNames) {
  432. groupFilesList[i] = n;
  433. i += 1;
  434. }
  435. /* sort the files within each group */
  436. for (auto& n : groupFilesList) {
  437. std::sort(groupFiles[n].begin(), groupFiles[n].end(),
  438. [](cmSourceFile* l, cmSourceFile* r) {
  439. return l->GetFullPath() < r->GetFullPath();
  440. });
  441. }
  442. /* get all the object names for these sources */
  443. std::map<const cmSourceFile*, std::string> objectNames =
  444. cmGhsMultiTargetGenerator::GetObjectNames(&sources, this->LocalGenerator,
  445. this->GeneratorTarget);
  446. /* list of open project files */
  447. std::vector<cmGeneratedFileStream*> gfiles;
  448. /* write files into the proper project file
  449. * -- groups go into main project file
  450. * unless FOLDER property or variable is set.
  451. */
  452. for (auto& sg : groupFilesList) {
  453. std::ostream* fout;
  454. bool useProjectFile =
  455. cmSystemTools::IsOn(
  456. this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
  457. cmSystemTools::IsOn(
  458. this->Makefile->GetDefinition("GHS_NO_SOURCE_GROUP_FILE"));
  459. if (useProjectFile || sg.empty()) {
  460. fout = &fout_proj;
  461. } else {
  462. // Open the filestream in copy-if-different mode.
  463. std::string gname = sg;
  464. cmsys::SystemTools::ReplaceString(gname, "\\", "_");
  465. std::string lpath =
  466. this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
  467. lpath += "/";
  468. lpath += gname;
  469. lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
  470. std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory();
  471. fpath += "/";
  472. fpath += lpath;
  473. cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath.c_str());
  474. f->SetCopyIfDifferent(true);
  475. gfiles.push_back(f);
  476. fout = f;
  477. this->GetGlobalGenerator()->WriteFileHeader(*f);
  478. GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, *f);
  479. fout_proj << lpath << " ";
  480. GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, fout_proj);
  481. }
  482. if (useProjectFile) {
  483. if (sg.empty()) {
  484. *fout << "{comment} Others" << std::endl;
  485. } else {
  486. *fout << "{comment} " << sg << std::endl;
  487. }
  488. }
  489. /* output rule for each source file */
  490. for (const cmSourceFile* si : groupFiles[sg]) {
  491. // Convert filename to native system
  492. // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on
  493. // windows when opening some files from the search window.
  494. std::string fname(si->GetFullPath());
  495. cmSystemTools::ConvertToOutputSlashes(fname);
  496. *fout << fname << std::endl;
  497. if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
  498. "bsp" != si->GetExtension()) {
  499. this->WriteObjectLangOverride(*fout, si);
  500. if (objectNames.end() != objectNames.find(si)) {
  501. *fout << " -o \"" << objectNames.find(si)->second << "\""
  502. << std::endl;
  503. }
  504. }
  505. }
  506. }
  507. for (cmGeneratedFileStream* f : gfiles) {
  508. f->Close();
  509. }
  510. }
  511. void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
  512. std::ostream& fout, const cmSourceFile* sourceFile)
  513. {
  514. const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
  515. if (NULL != rawLangProp) {
  516. std::string sourceLangProp(rawLangProp);
  517. std::string extension(sourceFile->GetExtension());
  518. if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
  519. fout << " -dotciscxx" << std::endl;
  520. }
  521. }
  522. }
  523. std::string cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
  524. cmLocalGhsMultiGenerator const* localGhsMultiGenerator,
  525. cmGeneratorTarget* const generatorTarget, cmSourceFile* const sourceFile)
  526. {
  527. std::string dir_max;
  528. dir_max +=
  529. localGhsMultiGenerator->GetMakefile()->GetCurrentBinaryDirectory();
  530. dir_max += "/";
  531. dir_max += generatorTarget->Target->GetName();
  532. dir_max += "/";
  533. std::vector<cmSourceGroup> sourceGroups(
  534. localGhsMultiGenerator->GetMakefile()->GetSourceGroups());
  535. std::string const& sourceFullPath = sourceFile->GetFullPath();
  536. cmSourceGroup* sourceGroup =
  537. localGhsMultiGenerator->GetMakefile()->FindSourceGroup(sourceFullPath,
  538. sourceGroups);
  539. std::string const& sgPath = sourceGroup->GetFullName();
  540. dir_max += sgPath;
  541. dir_max += "/Objs/libs/";
  542. dir_max += generatorTarget->Target->GetName();
  543. dir_max += "/";
  544. return dir_max;
  545. }
  546. bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
  547. const cmGeneratorTarget* target)
  548. {
  549. bool output = false;
  550. std::vector<cmSourceFile*> sources;
  551. std::string config =
  552. target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
  553. target->GetSourceFiles(sources, config);
  554. for (std::vector<cmSourceFile*>::const_iterator sources_i = sources.begin();
  555. sources.end() != sources_i; ++sources_i) {
  556. if ("int" == (*sources_i)->GetExtension()) {
  557. output = true;
  558. }
  559. }
  560. return output;
  561. }
  562. bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
  563. std::string const& config, const std::string& language)
  564. {
  565. std::vector<std::string> options;
  566. bool output = false;
  567. this->GeneratorTarget->GetCompileOptions(options, config, language);
  568. for (std::vector<std::string>::const_iterator options_i = options.begin();
  569. options_i != options.end(); ++options_i) {
  570. std::string option = *options_i;
  571. if (this->DDOption == option) {
  572. output = true;
  573. }
  574. }
  575. return output;
  576. }