cmCPluginAPI.cxx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. /*
  11. this file contains the implementation of the C API to CMake. Generally
  12. these routines just manipulate arguments and then call the associated
  13. methods on the CMake classes. */
  14. #include "cmMakefile.h"
  15. #include "cmCPluginAPI.h"
  16. #include "cmVersion.h"
  17. #include "cmSourceFile.h"
  18. #include <stdlib.h>
  19. #ifdef __QNX__
  20. # include <malloc.h> /* for malloc/free on QNX */
  21. #endif
  22. extern "C"
  23. {
  24. void CCONV *cmGetClientData(void *info)
  25. {
  26. return ((cmLoadedCommandInfo *)info)->ClientData;
  27. }
  28. void CCONV cmSetClientData(void *info, void *cd)
  29. {
  30. ((cmLoadedCommandInfo *)info)->ClientData = cd;
  31. }
  32. void CCONV cmSetError(void *info, const char *err)
  33. {
  34. if (((cmLoadedCommandInfo *)info)->Error)
  35. {
  36. free(((cmLoadedCommandInfo *)info)->Error);
  37. }
  38. ((cmLoadedCommandInfo *)info)->Error = strdup(err);
  39. }
  40. unsigned int CCONV cmGetCacheMajorVersion(void *arg)
  41. {
  42. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  43. cmCacheManager *manager = mf->GetCMakeInstance()->GetCacheManager();
  44. return manager->GetCacheMajorVersion();
  45. }
  46. unsigned int CCONV cmGetCacheMinorVersion(void *arg)
  47. {
  48. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  49. cmCacheManager *manager = mf->GetCMakeInstance()->GetCacheManager();
  50. return manager->GetCacheMinorVersion();
  51. }
  52. unsigned int CCONV cmGetMajorVersion(void *)
  53. {
  54. return cmVersion::GetMajorVersion();
  55. }
  56. unsigned int CCONV cmGetMinorVersion(void *)
  57. {
  58. return cmVersion::GetMinorVersion();
  59. }
  60. void CCONV cmAddDefinition(void *arg, const char* name, const char* value)
  61. {
  62. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  63. mf->AddDefinition(name,value);
  64. }
  65. /* Add a definition to this makefile and the global cmake cache. */
  66. void CCONV cmAddCacheDefinition(void *arg, const char* name,
  67. const char* value, const char* doc, int type)
  68. {
  69. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  70. switch (type)
  71. {
  72. case CM_CACHE_BOOL:
  73. mf->AddCacheDefinition(name,value,doc,
  74. cmCacheManager::BOOL);
  75. break;
  76. case CM_CACHE_PATH:
  77. mf->AddCacheDefinition(name,value,doc,
  78. cmCacheManager::PATH);
  79. break;
  80. case CM_CACHE_FILEPATH:
  81. mf->AddCacheDefinition(name,value,doc,
  82. cmCacheManager::FILEPATH);
  83. break;
  84. case CM_CACHE_STRING:
  85. mf->AddCacheDefinition(name,value,doc,
  86. cmCacheManager::STRING);
  87. break;
  88. case CM_CACHE_INTERNAL:
  89. mf->AddCacheDefinition(name,value,doc,
  90. cmCacheManager::INTERNAL);
  91. break;
  92. case CM_CACHE_STATIC:
  93. mf->AddCacheDefinition(name,value,doc,
  94. cmCacheManager::STATIC);
  95. break;
  96. }
  97. }
  98. const char* CCONV cmGetProjectName(void *arg)
  99. {
  100. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  101. return mf->GetProjectName();
  102. }
  103. const char* CCONV cmGetHomeDirectory(void *arg)
  104. {
  105. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  106. return mf->GetHomeDirectory();
  107. }
  108. const char* CCONV cmGetHomeOutputDirectory(void *arg)
  109. {
  110. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  111. return mf->GetHomeOutputDirectory();
  112. }
  113. const char* CCONV cmGetStartDirectory(void *arg)
  114. {
  115. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  116. return mf->GetStartDirectory();
  117. }
  118. const char* CCONV cmGetStartOutputDirectory(void *arg)
  119. {
  120. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  121. return mf->GetStartOutputDirectory();
  122. }
  123. const char* CCONV cmGetCurrentDirectory(void *arg)
  124. {
  125. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  126. return mf->GetCurrentDirectory();
  127. }
  128. const char* CCONV cmGetCurrentOutputDirectory(void *arg)
  129. {
  130. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  131. return mf->GetCurrentOutputDirectory();
  132. }
  133. const char* CCONV cmGetDefinition(void *arg,const char*def)
  134. {
  135. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  136. return mf->GetDefinition(def);
  137. }
  138. int CCONV cmIsOn(void *arg, const char* name)
  139. {
  140. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  141. return static_cast<int>(mf->IsOn(name));
  142. }
  143. /** Check if a command exists. */
  144. int CCONV cmCommandExists(void *arg, const char* name)
  145. {
  146. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  147. return static_cast<int>(mf->CommandExists(name));
  148. }
  149. void CCONV cmAddDefineFlag(void *arg, const char* definition)
  150. {
  151. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  152. mf->AddDefineFlag(definition);
  153. }
  154. void CCONV cmAddLinkDirectoryForTarget(void *arg, const char *tgt,
  155. const char* d)
  156. {
  157. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  158. mf->AddLinkDirectoryForTarget(tgt,d);
  159. }
  160. void CCONV cmAddExecutable(void *arg, const char *exename,
  161. int numSrcs, const char **srcs, int win32)
  162. {
  163. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  164. std::vector<std::string> srcs2;
  165. int i;
  166. for (i = 0; i < numSrcs; ++i)
  167. {
  168. srcs2.push_back(srcs[i]);
  169. }
  170. cmTarget* tg = mf->AddExecutable(exename, srcs2);
  171. if ( win32 )
  172. {
  173. tg->SetProperty("WIN32_EXECUTABLE", "ON");
  174. }
  175. }
  176. void CCONV cmAddUtilityCommand(void *arg, const char* utilityName,
  177. const char* command,
  178. const char* arguments,
  179. int all,
  180. int numDepends,
  181. const char **depends,
  182. int,
  183. const char **)
  184. {
  185. // Get the makefile instance. Perform an extra variable expansion
  186. // now because the API caller expects it.
  187. cmMakefile* mf = static_cast<cmMakefile*>(arg);
  188. // Construct the command line for the command.
  189. cmCustomCommandLine commandLine;
  190. std::string expand = command;
  191. commandLine.push_back(mf->ExpandVariablesInString(expand));
  192. if(arguments && arguments[0])
  193. {
  194. // TODO: Parse arguments!
  195. expand = arguments;
  196. commandLine.push_back(mf->ExpandVariablesInString(expand));
  197. }
  198. cmCustomCommandLines commandLines;
  199. commandLines.push_back(commandLine);
  200. // Accumulate the list of dependencies.
  201. std::vector<std::string> depends2;
  202. for(int i = 0; i < numDepends; ++i)
  203. {
  204. expand = depends[i];
  205. depends2.push_back(mf->ExpandVariablesInString(expand));
  206. }
  207. // Pass the call to the makefile instance.
  208. mf->AddUtilityCommand(utilityName, (all ? false : true),
  209. 0, depends2, commandLines);
  210. }
  211. void CCONV cmAddCustomCommand(void *arg, const char* source,
  212. const char* command,
  213. int numArgs, const char **args,
  214. int numDepends, const char **depends,
  215. int numOutputs, const char **outputs,
  216. const char *target)
  217. {
  218. // Get the makefile instance. Perform an extra variable expansion
  219. // now because the API caller expects it.
  220. cmMakefile* mf = static_cast<cmMakefile*>(arg);
  221. // Construct the command line for the command.
  222. cmCustomCommandLine commandLine;
  223. std::string expand = command;
  224. commandLine.push_back(mf->ExpandVariablesInString(expand));
  225. for(int i=0; i < numArgs; ++i)
  226. {
  227. expand = args[i];
  228. commandLine.push_back(mf->ExpandVariablesInString(expand));
  229. }
  230. cmCustomCommandLines commandLines;
  231. commandLines.push_back(commandLine);
  232. // Accumulate the list of dependencies.
  233. std::vector<std::string> depends2;
  234. for(int i = 0; i < numDepends; ++i)
  235. {
  236. expand = depends[i];
  237. depends2.push_back(mf->ExpandVariablesInString(expand));
  238. }
  239. // Accumulate the list of outputs.
  240. std::vector<std::string> outputs2;
  241. for(int i = 0; i < numOutputs; ++i)
  242. {
  243. expand = outputs[i];
  244. outputs2.push_back(mf->ExpandVariablesInString(expand));
  245. }
  246. // Pass the call to the makefile instance.
  247. const char* no_comment = 0;
  248. mf->AddCustomCommandOldStyle(target, outputs2, depends2, source,
  249. commandLines, no_comment);
  250. }
  251. void CCONV cmAddCustomCommandToOutput(void *arg, const char* output,
  252. const char* command,
  253. int numArgs, const char **args,
  254. const char* main_dependency,
  255. int numDepends, const char **depends)
  256. {
  257. // Get the makefile instance. Perform an extra variable expansion
  258. // now because the API caller expects it.
  259. cmMakefile* mf = static_cast<cmMakefile*>(arg);
  260. // Construct the command line for the command.
  261. cmCustomCommandLine commandLine;
  262. std::string expand = command;
  263. commandLine.push_back(mf->ExpandVariablesInString(expand));
  264. for(int i=0; i < numArgs; ++i)
  265. {
  266. expand = args[i];
  267. commandLine.push_back(mf->ExpandVariablesInString(expand));
  268. }
  269. cmCustomCommandLines commandLines;
  270. commandLines.push_back(commandLine);
  271. // Accumulate the list of dependencies.
  272. std::vector<std::string> depends2;
  273. for(int i = 0; i < numDepends; ++i)
  274. {
  275. expand = depends[i];
  276. depends2.push_back(mf->ExpandVariablesInString(expand));
  277. }
  278. // Pass the call to the makefile instance.
  279. const char* no_comment = 0;
  280. const char* no_working_dir = 0;
  281. mf->AddCustomCommandToOutput(output, depends2, main_dependency,
  282. commandLines, no_comment, no_working_dir);
  283. }
  284. void CCONV cmAddCustomCommandToTarget(void *arg, const char* target,
  285. const char* command,
  286. int numArgs, const char **args,
  287. int commandType)
  288. {
  289. // Get the makefile instance.
  290. cmMakefile* mf = static_cast<cmMakefile*>(arg);
  291. // Construct the command line for the command. Perform an extra
  292. // variable expansion now because the API caller expects it.
  293. cmCustomCommandLine commandLine;
  294. std::string expand = command;
  295. commandLine.push_back(mf->ExpandVariablesInString(expand));
  296. for(int i=0; i < numArgs; ++i)
  297. {
  298. expand = args[i];
  299. commandLine.push_back(mf->ExpandVariablesInString(expand));
  300. }
  301. cmCustomCommandLines commandLines;
  302. commandLines.push_back(commandLine);
  303. // Select the command type.
  304. cmTarget::CustomCommandType cctype = cmTarget::POST_BUILD;
  305. switch (commandType)
  306. {
  307. case CM_PRE_BUILD:
  308. cctype = cmTarget::PRE_BUILD;
  309. break;
  310. case CM_PRE_LINK:
  311. cctype = cmTarget::PRE_LINK;
  312. break;
  313. case CM_POST_BUILD:
  314. cctype = cmTarget::POST_BUILD;
  315. break;
  316. }
  317. // Pass the call to the makefile instance.
  318. std::vector<std::string> no_byproducts;
  319. std::vector<std::string> no_depends;
  320. const char* no_comment = 0;
  321. const char* no_working_dir = 0;
  322. mf->AddCustomCommandToTarget(target, no_byproducts, no_depends, commandLines,
  323. cctype, no_comment, no_working_dir);
  324. }
  325. void CCONV cmAddLinkLibraryForTarget(void *arg, const char *tgt,
  326. const char*value, int libtype)
  327. {
  328. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  329. switch (libtype)
  330. {
  331. case CM_LIBRARY_GENERAL:
  332. mf->AddLinkLibraryForTarget(tgt,value, cmTarget::GENERAL);
  333. break;
  334. case CM_LIBRARY_DEBUG:
  335. mf->AddLinkLibraryForTarget(tgt,value, cmTarget::DEBUG);
  336. break;
  337. case CM_LIBRARY_OPTIMIZED:
  338. mf->AddLinkLibraryForTarget(tgt,value, cmTarget::OPTIMIZED);
  339. break;
  340. }
  341. }
  342. void CCONV cmAddLibrary(void *arg, const char *libname, int shared,
  343. int numSrcs, const char **srcs)
  344. {
  345. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  346. std::vector<std::string> srcs2;
  347. int i;
  348. for (i = 0; i < numSrcs; ++i)
  349. {
  350. srcs2.push_back(srcs[i]);
  351. }
  352. mf->AddLibrary(libname,
  353. (shared? cmTarget::SHARED_LIBRARY : cmTarget::STATIC_LIBRARY),
  354. srcs2);
  355. }
  356. char CCONV *cmExpandVariablesInString(void *arg, const char *source,
  357. int escapeQuotes, int atOnly)
  358. {
  359. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  360. std::string barf = source;
  361. std::string result =
  362. mf->ExpandVariablesInString(barf,
  363. (escapeQuotes ? true : false),
  364. (atOnly ? true : false));
  365. char *res = static_cast<char *>(malloc(result.size() + 1));
  366. if (result.size())
  367. {
  368. strcpy(res,result.c_str());
  369. }
  370. res[result.size()] = '\0';
  371. return res;
  372. }
  373. int CCONV cmExecuteCommand(void *arg, const char *name,
  374. int numArgs, const char **args)
  375. {
  376. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  377. cmListFileFunction lff;
  378. lff.Name = name;
  379. for(int i = 0; i < numArgs; ++i)
  380. {
  381. // Assume all arguments are quoted.
  382. lff.Arguments.push_back(
  383. cmListFileArgument(args[i], cmListFileArgument::Quoted,
  384. "[CMake-Plugin]", 0));
  385. }
  386. cmExecutionStatus status;
  387. return mf->ExecuteCommand(lff,status);
  388. }
  389. void CCONV cmExpandSourceListArguments(void *arg,
  390. int numArgs,
  391. const char **args,
  392. int *resArgc,
  393. char ***resArgv,
  394. unsigned int startArgumentIndex)
  395. {
  396. (void)arg;
  397. (void)startArgumentIndex;
  398. std::vector<std::string> result;
  399. int i;
  400. for (i = 0; i < numArgs; ++i)
  401. {
  402. result.push_back(args[i]);
  403. }
  404. int resargc = static_cast<int>(result.size());
  405. char **resargv = 0;
  406. if (resargc)
  407. {
  408. resargv = (char **)malloc(resargc*sizeof(char *));
  409. }
  410. for (i = 0; i < resargc; ++i)
  411. {
  412. resargv[i] = strdup(result[i].c_str());
  413. }
  414. *resArgc = resargc;
  415. *resArgv = resargv;
  416. }
  417. void CCONV cmFreeArguments(int argc, char **argv)
  418. {
  419. int i;
  420. for (i = 0; i < argc; ++i)
  421. {
  422. free(argv[i]);
  423. }
  424. if (argv)
  425. {
  426. free(argv);
  427. }
  428. }
  429. int CCONV cmGetTotalArgumentSize(int argc, char **argv)
  430. {
  431. int i;
  432. int result = 0;
  433. for (i = 0; i < argc; ++i)
  434. {
  435. if (argv[i])
  436. {
  437. result = result + static_cast<int>(strlen(argv[i]));
  438. }
  439. }
  440. return result;
  441. }
  442. // Source file proxy object to support the old cmSourceFile/cmMakefile
  443. // API for source files.
  444. struct cmCPluginAPISourceFile
  445. {
  446. cmCPluginAPISourceFile(): RealSourceFile(0) {}
  447. cmSourceFile* RealSourceFile;
  448. std::string SourceName;
  449. std::string SourceExtension;
  450. std::string FullPath;
  451. std::vector<std::string> Depends;
  452. cmPropertyMap Properties;
  453. };
  454. // Keep a map from real cmSourceFile instances stored in a makefile to
  455. // the CPluginAPI proxy source file.
  456. class cmCPluginAPISourceFileMap:
  457. public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
  458. {
  459. public:
  460. typedef std::map<cmSourceFile*, cmCPluginAPISourceFile*> derived;
  461. typedef derived::iterator iterator;
  462. typedef derived::value_type value_type;
  463. ~cmCPluginAPISourceFileMap()
  464. {
  465. for(iterator i=this->begin(); i != this->end(); ++i)
  466. {
  467. delete i->second;
  468. }
  469. }
  470. };
  471. cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
  472. void * CCONV cmCreateSourceFile(void)
  473. {
  474. return (void*)new cmCPluginAPISourceFile;
  475. }
  476. void * CCONV cmCreateNewSourceFile(void *arg)
  477. {
  478. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  479. cmCPluginAPISourceFile *sf = new cmCPluginAPISourceFile;
  480. sf->Properties.SetCMakeInstance(mf->GetCMakeInstance());
  481. return (void*)sf;
  482. }
  483. void CCONV cmDestroySourceFile(void *arg)
  484. {
  485. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  486. // Only delete if it was created by cmCreateSourceFile or
  487. // cmCreateNewSourceFile and is therefore not in the map.
  488. if(!sf->RealSourceFile)
  489. {
  490. delete sf;
  491. }
  492. }
  493. void CCONV *cmGetSource(void *arg, const char *name)
  494. {
  495. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  496. if(cmSourceFile* rsf = mf->GetSource(name))
  497. {
  498. // Lookup the proxy source file object for this source.
  499. cmCPluginAPISourceFileMap::iterator i = cmCPluginAPISourceFiles.find(rsf);
  500. if(i == cmCPluginAPISourceFiles.end())
  501. {
  502. // Create a proxy source file object for this source.
  503. cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
  504. sf->RealSourceFile = rsf;
  505. sf->FullPath = rsf->GetFullPath();
  506. sf->SourceName =
  507. cmSystemTools::GetFilenameWithoutLastExtension(sf->FullPath);
  508. sf->SourceExtension =
  509. cmSystemTools::GetFilenameLastExtension(sf->FullPath);
  510. // Store the proxy in the map so it can be re-used and deleted later.
  511. cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
  512. i = cmCPluginAPISourceFiles.insert(entry).first;
  513. }
  514. return (void *)i->second;
  515. }
  516. else
  517. {
  518. return 0;
  519. }
  520. }
  521. void * CCONV cmAddSource(void *arg, void *arg2)
  522. {
  523. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  524. cmCPluginAPISourceFile* osf = static_cast<cmCPluginAPISourceFile*>(arg2);
  525. if(osf->FullPath.empty())
  526. {
  527. return 0;
  528. }
  529. // Create the real cmSourceFile instance and copy over saved information.
  530. cmSourceFile* rsf = mf->GetOrCreateSource(osf->FullPath);
  531. rsf->GetProperties() = osf->Properties;
  532. for(std::vector<std::string>::iterator i = osf->Depends.begin();
  533. i != osf->Depends.end(); ++i)
  534. {
  535. rsf->AddDepend(i->c_str());
  536. }
  537. // Create the proxy for the real source file.
  538. cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
  539. sf->RealSourceFile = rsf;
  540. sf->FullPath = osf->FullPath;
  541. sf->SourceName = osf->SourceName;
  542. sf->SourceExtension = osf->SourceExtension;
  543. // Store the proxy in the map so it can be re-used and deleted later.
  544. cmCPluginAPISourceFiles[rsf] = sf;
  545. return (void *)sf;
  546. }
  547. const char * CCONV cmSourceFileGetSourceName(void *arg)
  548. {
  549. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  550. return sf->SourceName.c_str();
  551. }
  552. const char * CCONV cmSourceFileGetFullPath(void *arg)
  553. {
  554. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  555. return sf->FullPath.c_str();
  556. }
  557. const char * CCONV cmSourceFileGetProperty(void *arg,const char *prop)
  558. {
  559. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  560. if(cmSourceFile* rsf = sf->RealSourceFile)
  561. {
  562. return rsf->GetProperty(prop);
  563. }
  564. else
  565. {
  566. if(!strcmp(prop,"LOCATION"))
  567. {
  568. return sf->FullPath.c_str();
  569. }
  570. bool chain = false;
  571. // Ignore chain because old code will not expect it and it is a
  572. // pain to implement here anyway.
  573. return sf->Properties.GetPropertyValue(prop, cmProperty::SOURCE_FILE,
  574. chain);
  575. }
  576. }
  577. int CCONV cmSourceFileGetPropertyAsBool(void *arg,const char *prop)
  578. {
  579. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  580. if(cmSourceFile* rsf = sf->RealSourceFile)
  581. {
  582. return rsf->GetPropertyAsBool(prop) ? 1:0;
  583. }
  584. else
  585. {
  586. return cmSystemTools::IsOn(cmSourceFileGetProperty(arg, prop))? 1:0;
  587. }
  588. }
  589. void CCONV cmSourceFileSetProperty(void *arg,const char *prop,
  590. const char *value)
  591. {
  592. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  593. if(cmSourceFile* rsf = sf->RealSourceFile)
  594. {
  595. rsf->SetProperty(prop, value);
  596. }
  597. else if(prop)
  598. {
  599. if(!value) { value = "NOTFOUND"; }
  600. sf->Properties.SetProperty(prop, value, cmProperty::SOURCE_FILE);
  601. }
  602. }
  603. void CCONV cmSourceFileAddDepend(void *arg, const char *depend)
  604. {
  605. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  606. if(cmSourceFile* rsf = sf->RealSourceFile)
  607. {
  608. rsf->AddDepend(depend);
  609. }
  610. else
  611. {
  612. sf->Depends.push_back(depend);
  613. }
  614. }
  615. void CCONV cmSourceFileSetName(void *arg, const char* name, const char* dir,
  616. int numSourceExtensions,
  617. const char **sourceExtensions,
  618. int numHeaderExtensions,
  619. const char **headerExtensions)
  620. {
  621. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  622. if(sf->RealSourceFile)
  623. {
  624. // SetName is allowed only on temporary source files created by
  625. // the command for building and passing to AddSource.
  626. return;
  627. }
  628. std::vector<std::string> sourceExts;
  629. std::vector<std::string> headerExts;
  630. int i;
  631. for (i = 0; i < numSourceExtensions; ++i)
  632. {
  633. sourceExts.push_back(sourceExtensions[i]);
  634. }
  635. for (i = 0; i < numHeaderExtensions; ++i)
  636. {
  637. headerExts.push_back(headerExtensions[i]);
  638. }
  639. // Save the original name given.
  640. sf->SourceName = name;
  641. // Convert the name to a full path in case the given name is a
  642. // relative path.
  643. std::string pathname = cmSystemTools::CollapseFullPath(name, dir);
  644. // First try and see whether the listed file can be found
  645. // as is without extensions added on.
  646. std::string hname = pathname;
  647. if(cmSystemTools::FileExists(hname.c_str()))
  648. {
  649. sf->SourceName = cmSystemTools::GetFilenamePath(name);
  650. if ( sf->SourceName.size() > 0 )
  651. {
  652. sf->SourceName += "/";
  653. }
  654. sf->SourceName += cmSystemTools::GetFilenameWithoutLastExtension(name);
  655. std::string::size_type pos = hname.rfind('.');
  656. if(pos != std::string::npos)
  657. {
  658. sf->SourceExtension = hname.substr(pos+1, hname.size()-pos);
  659. if ( cmSystemTools::FileIsFullPath(name) )
  660. {
  661. std::string::size_type pos2 = hname.rfind('/');
  662. if(pos2 != std::string::npos)
  663. {
  664. sf->SourceName = hname.substr(pos2+1, pos - pos2-1);
  665. }
  666. }
  667. }
  668. sf->FullPath = hname;
  669. return;
  670. }
  671. // Next, try the various source extensions
  672. for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
  673. ext != sourceExts.end(); ++ext )
  674. {
  675. hname = pathname;
  676. hname += ".";
  677. hname += *ext;
  678. if(cmSystemTools::FileExists(hname.c_str()))
  679. {
  680. sf->SourceExtension = *ext;
  681. sf->FullPath = hname;
  682. return;
  683. }
  684. }
  685. // Finally, try the various header extensions
  686. for( std::vector<std::string>::const_iterator ext = headerExts.begin();
  687. ext != headerExts.end(); ++ext )
  688. {
  689. hname = pathname;
  690. hname += ".";
  691. hname += *ext;
  692. if(cmSystemTools::FileExists(hname.c_str()))
  693. {
  694. sf->SourceExtension = *ext;
  695. sf->FullPath = hname;
  696. return;
  697. }
  698. }
  699. std::ostringstream e;
  700. e << "Cannot find source file \"" << pathname << "\"";
  701. e << "\n\nTried extensions";
  702. for( std::vector<std::string>::const_iterator ext = sourceExts.begin();
  703. ext != sourceExts.end(); ++ext )
  704. {
  705. e << " ." << *ext;
  706. }
  707. for( std::vector<std::string>::const_iterator ext = headerExts.begin();
  708. ext != headerExts.end(); ++ext )
  709. {
  710. e << " ." << *ext;
  711. }
  712. cmSystemTools::Error(e.str().c_str());
  713. return;
  714. }
  715. void CCONV cmSourceFileSetName2(void *arg, const char* name, const char* dir,
  716. const char *ext, int headerFileOnly)
  717. {
  718. cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
  719. if(sf->RealSourceFile)
  720. {
  721. // SetName is allowed only on temporary source files created by
  722. // the command for building and passing to AddSource.
  723. return;
  724. }
  725. // Implement the old SetName method code here.
  726. if(headerFileOnly)
  727. {
  728. sf->Properties.SetProperty("HEADER_FILE_ONLY", "1",
  729. cmProperty::SOURCE_FILE);
  730. }
  731. sf->SourceName = name;
  732. std::string fname = sf->SourceName;
  733. if(ext && strlen(ext))
  734. {
  735. fname += ".";
  736. fname += ext;
  737. }
  738. sf->FullPath = cmSystemTools::CollapseFullPath(fname.c_str(), dir);
  739. cmSystemTools::ConvertToUnixSlashes(sf->FullPath);
  740. sf->SourceExtension = ext;
  741. }
  742. char * CCONV cmGetFilenameWithoutExtension(const char *name)
  743. {
  744. std::string sres = cmSystemTools::GetFilenameWithoutExtension(name);
  745. char *result = (char *)malloc(sres.size()+1);
  746. strcpy(result,sres.c_str());
  747. return result;
  748. }
  749. char * CCONV cmGetFilenamePath(const char *name)
  750. {
  751. std::string sres = cmSystemTools::GetFilenamePath(name);
  752. char *result = (char *)malloc(sres.size()+1);
  753. strcpy(result,sres.c_str());
  754. return result;
  755. }
  756. char * CCONV cmCapitalized(const char *name)
  757. {
  758. std::string sres = cmSystemTools::Capitalized(name);
  759. char *result = (char *)malloc(sres.size()+1);
  760. strcpy(result,sres.c_str());
  761. return result;
  762. }
  763. void CCONV cmCopyFileIfDifferent(const char *name1, const char *name2)
  764. {
  765. cmSystemTools::CopyFileIfDifferent(name1,name2);
  766. }
  767. void CCONV cmRemoveFile(const char *name)
  768. {
  769. cmSystemTools::RemoveFile(name);
  770. }
  771. void CCONV cmDisplayStatus(void *arg, const char* message)
  772. {
  773. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  774. mf->DisplayStatus(message, -1);
  775. }
  776. void CCONV cmFree(void *data)
  777. {
  778. free(data);
  779. }
  780. void CCONV DefineSourceFileProperty (void *arg, const char *name,
  781. const char *briefDocs,
  782. const char *longDocs,
  783. int chained)
  784. {
  785. cmMakefile *mf = static_cast<cmMakefile *>(arg);
  786. mf->GetCMakeInstance()->DefineProperty(name,cmProperty::SOURCE_FILE,
  787. briefDocs, longDocs,
  788. chained != 0);
  789. }
  790. } // close the extern "C" scope
  791. cmCAPI cmStaticCAPI =
  792. {
  793. cmGetClientData,
  794. cmGetTotalArgumentSize,
  795. cmFreeArguments,
  796. cmSetClientData,
  797. cmSetError,
  798. cmAddCacheDefinition,
  799. cmAddCustomCommand,
  800. cmAddDefineFlag,
  801. cmAddDefinition,
  802. cmAddExecutable,
  803. cmAddLibrary,
  804. cmAddLinkDirectoryForTarget,
  805. cmAddLinkLibraryForTarget,
  806. cmAddUtilityCommand,
  807. cmCommandExists,
  808. cmExecuteCommand,
  809. cmExpandSourceListArguments,
  810. cmExpandVariablesInString,
  811. cmGetCacheMajorVersion,
  812. cmGetCacheMinorVersion,
  813. cmGetCurrentDirectory,
  814. cmGetCurrentOutputDirectory,
  815. cmGetDefinition,
  816. cmGetHomeDirectory,
  817. cmGetHomeOutputDirectory,
  818. cmGetMajorVersion,
  819. cmGetMinorVersion,
  820. cmGetProjectName,
  821. cmGetStartDirectory,
  822. cmGetStartOutputDirectory,
  823. cmIsOn,
  824. cmAddSource,
  825. cmCreateSourceFile,
  826. cmDestroySourceFile,
  827. cmGetSource,
  828. cmSourceFileAddDepend,
  829. cmSourceFileGetProperty,
  830. cmSourceFileGetPropertyAsBool,
  831. cmSourceFileGetSourceName,
  832. cmSourceFileGetFullPath,
  833. cmSourceFileSetName,
  834. cmSourceFileSetName2,
  835. cmSourceFileSetProperty,
  836. cmCapitalized,
  837. cmCopyFileIfDifferent,
  838. cmGetFilenameWithoutExtension,
  839. cmGetFilenamePath,
  840. cmRemoveFile,
  841. cmFree,
  842. cmAddCustomCommandToOutput,
  843. cmAddCustomCommandToTarget,
  844. cmDisplayStatus,
  845. cmCreateNewSourceFile,
  846. DefineSourceFileProperty,
  847. };