cmGhsMultiTargetGenerator.cxx 19 KB

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