root/simulator/trunk/vendor/cmake/Source/cmGlobalCodeBlocksGenerator.h

Revision 1018, 12.7 kB (checked in by sehenley, 1 year ago)

Vendor update to cmake-2.6.4

Line 
1 //    OSRail -- a network enabled railroad operations simulator and utilities
2 //    Copyright (C) 2007,2008 Samuel E. Henley sehenley@comcast.net
3 //
4 //    This program is free software; you can redistribute it and/or modify
5 //    it under the terms of the GNU General Public License as published by
6 //    the Free Software Foundation; either version 2 of the License, or
7 //    (at your option) any later version.
8 //
9 //    This program is distributed in the hope that it will be useful,
10 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //    GNU General Public License for more details.
13 //
14 //    You should have received a copy of the GNU General Public License along
15 //    with this program; if not, write to the Free Software Foundation, Inc.,
16 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 //
18 //
19 //----------------------------------------------------------------------
20 /// \file
21 /// Header file for CodeBlocks Global (Workspace Files) Generator for CMake
22 #ifndef cmGlobaCodeBlocksGenerator_h
23 #define cmGlobaCodeBlocksGenerator_h
24
25 #include "cmGlobalGenerator.h"
26 #include "cmGeneratedFileStream.h"
27
28 #if defined(CMAKE_BUILD_WITH_CMAKE)
29 # include <cmsys/MD5.h>
30 #endif
31
32 #include "cmSystemTools.h"
33
34 class cmLocalCodeBlocksGenerator;
35
36 namespace codeblocksgenerator
37 {
38     /// Global list of targets for workspace
39     class Dependent
40     {
41     public:
42         Dependent(){}
43         Dependent( const Dependent& ref ) : target( ref.target ), project_file( ref.project_file ){}
44
45         const Dependent& operator=( const Dependent& ref )
46         {
47             if( &ref != this )
48             {
49                 target = ref.target;
50                 project_file = ref.project_file;
51             }
52
53             return *this;
54         }
55
56         const cmTarget* target;
57         std::string project_file;
58     };
59
60 } //namespace codeblocksgenerator
61
62
63 ///cmGlobalCodeBlocksGenerator is responsable for overseeing the generation process for the cmakelists file tree
64 class cmGlobalCodeBlocksGenerator : public  cmGlobalGenerator
65 {
66 public:
67     /// Free any memory allocated with the GlobalGenerator
68     cmGlobalCodeBlocksGenerator();
69     virtual ~cmGlobalCodeBlocksGenerator();
70
71     static cmGlobalGenerator* New(){ return new cmGlobalCodeBlocksGenerator; }
72
73     /// Create a local generator appropriate to this Global Generator
74     virtual cmLocalGenerator* CreateLocalGenerator();
75
76     /// Get the name for this generator
77     virtual const char* GetName() const { return GetActualName(); };
78     static const char*  GetActualName() { return "CodeBlocks"; }
79
80     /// Get the documentation entry for this generator.  */
81     virtual void GetDocumentation( cmDocumentationEntry& entry ) const;
82
83     /// Create LocalGenerators and process the CMakeLists files. This does not
84     /// actually produce any makefiles, DSPs, etc.
85     virtual void Configure();
86
87     /// Generate the all required files for building this project/tree. This
88     /// basically creates a series of LocalGenerators for each directory and
89     /// requests that they Generate.
90     virtual void Generate();
91
92      /// Try to determine system infomation such as shared library
93      /// extension, pthreads, byte order etc.
94      virtual void EnableLanguage(std::vector<std::string>const& languages, cmMakefile *, bool optional);
95
96     /// Create a build comand
97     virtual std::string GenerateBuildCommand( const char* makeProgram,
98                                               const char* projectName,
99                                               const char* additionalOptions,
100                                               const char* targetName,
101                                               const char* config,
102                                               bool ignoreErrors,
103                                               bool fast );
104
105     void gatherWorkspaceTargets( cmMakefile* makefile );
106     std::map< std::string, codeblocksgenerator::Dependent >& getWorkspaceTargetList(){ return workspace_target_list; }
107
108 private:
109
110     /// Create a CodeBlocks workspace file.
111     void writeWorkspaceFile();
112
113     /// A list used to build dependence list for projects
114     /// in the workspace.
115     std::map< std::string, codeblocksgenerator::Dependent > workspace_target_list; //Name, project file
116
117 };
118
119
120 //////////////////////////////////// Generator Utilities ///////////////////////////////////////
121
122 namespace codeblocksgenerator
123 {
124
125     template < const int T >
126     class CodeBlocksGeneratorException : public std::exception
127     {
128     public:
129         CodeBlocksGeneratorException(){}
130         virtual const char* what() const throw();
131     };
132
133     template<> inline const char* CodeBlocksGeneratorException<  0 >::what() const throw() { return (const char*) "Break"; }
134     template<> inline const char* CodeBlocksGeneratorException<  1 >::what() const throw() { return (const char*) "Program Logic Error in insertProjectWorkspace"; }
135     template<> inline const char* CodeBlocksGeneratorException<  2 >::what() const throw() { return (const char*) "Program Logic Error in insertProject"; }
136
137     typedef CodeBlocksGeneratorException<  0 > debug_break;
138     typedef CodeBlocksGeneratorException<  1 > program_error_insert_project_workspace;
139     typedef CodeBlocksGeneratorException<  2 > program_error_insert_project;
140
141     const int Executable          = 0x0001;
142     const int Static_library      = 0x0002;
143     const int Shared_library      = 0x0004;
144     const int Module_library      = 0x0008;
145     const int Utility             = 0x0010;
146     const int Global_target       = 0x0020;
147     const int Install_files       = 0x0040;
148     const int Install_programs    = 0x0080;
149     const int Install_directory   = 0x0100;
150     const int Unknown_library     = 0x0200;
151     const int All                 = 0x03ff;
152
153     inline int convertTargetType( const cmTarget::TargetType n )
154     {
155         int result = Executable;
156         result <<= n;
157         return result;
158
159     }
160
161
162     /// write the workspace header
163     /// \param directory - location of workspace
164     /// \param name - workspace name
165     /// \return full workspace path
166     std::string writeWorkspaceHeader( const std::string& directory, const std::string& name );
167
168     /// write the project header
169     /// \param directory - location of project
170     /// \param name - project name
171     /// \return full project path
172     std::string writeProjectHeader( const std::string& directory, const std::string& name );
173
174
175     /// write a project and its dependencies into the workspace file
176     /// \param project_file - path of the project file
177     /// \param workspace_file - path of the workspace  file
178     /// \param depends - list  project dependencies
179     /// \param active - make this the active project
180     void insertProjectWorkspace( const std::string& project_file,
181                                  const std::string& workspace_file,
182                                  const std::vector< std::string >& depends,
183                                  bool active = false );
184
185
186
187
188     /// write a Utility project file
189     /// \param target the utility tartget
190     /// \param project_file = the utility project cbp file path
191     /// \param mf - cmMakefile from cmake
192     void writeUtilityProject( cmMakefile* mf, const cmTarget& target, const std::string& workspace_directory, const std::string& project_file );
193
194     /// write a Excutable or Library project file
195     /// \param target the tartget
196     /// \param project_file = the project cbp file path
197     /// \param mf - cmMakefile from cmake
198     void writeProject( cmMakefile* mf, const cmTarget& target, const std::string& project_directory,
199                        const std::string& project_file, std::vector<const cmTarget*>& workspace_depends );
200
201
202     class Buffer
203     {
204     public:
205         std::vector<char> buffer;
206         std::vector<char> hold;
207         bool redirect;
208         int tabs;
209         bool new_line;
210         /// Insert a string into a file
211         /// \param before - before this string
212         /// \param file - this file path
213         /// \return false fail
214        bool insertBuffer( const char* before, const std::string file )
215        {
216             std::ifstream is( file.c_str() );
217             std::string base(( std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());
218             is.close();
219
220             size_t start = base.find( before );
221             if( start != std::string::npos )
222             {
223                  std::ofstream os( file.c_str() );
224                  std::copy( base.data(), &base.data()[start], std::ostreambuf_iterator<char>(os) );
225                  std::copy( buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os) );
226                  std::copy( &base.data()[start], &base.data()[base.size()], std::ostreambuf_iterator<char>(os) );
227                  os.close();
228                  return true;
229             }
230
231             return false; //error
232         }
233
234         bool writeBuffer( const std::string file )
235         {
236             #if defined( CMAKE_BUILD_WITH_CMAKE )
237                 if( cmSystemTools::FileExists( file.c_str() ) )
238                 {
239                     std::ifstream is( file.c_str() );
240                     std::string base(( std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>());
241                     is.close();
242
243                     char md5out[32];
244                     cmsysMD5* md5 = cmsysMD5_New();
245                     cmsysMD5_Initialize( md5 );
246                     cmsysMD5_Append( md5, reinterpret_cast<unsigned char const*>(base.data()), base.size() );
247                     cmsysMD5_FinalizeHex(md5, md5out);
248                     std::string file_md5( md5out, 32 );
249
250                     cmsysMD5_Initialize( md5 );
251                     cmsysMD5_Append( md5, reinterpret_cast<unsigned char const*>(&buffer[0]), buffer.size() );
252                     cmsysMD5_FinalizeHex( md5, md5out );
253                     cmsysMD5_Delete(md5);
254                     std::string buffer_md5( md5out, 32 );
255
256                     if( buffer_md5.compare( &file_md5[0] ) == 0 )return true;
257                 }
258
259             #endif
260             std::ofstream os( file.c_str() );
261             std::copy( buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os) );
262             os.close();
263
264             return true;
265         }
266
267         void add( const char ch )
268         {
269             if( redirect )hold.push_back( ch );
270             else buffer.push_back( ch );
271         }
272
273         void isNewLine()
274         {
275             if( new_line )
276             {
277                 for( int i=0; i < tabs; i++ ) add( '\t' );
278                 new_line = false;
279             }
280         }
281
282         bool isHold() { return !hold.empty(); }
283
284         void clear()
285         {
286             buffer.clear();
287             tabs = 0;
288             new_line = true;
289             hold.clear();
290             redirect = false;
291         }
292     };
293
294     inline Buffer& operator<<( Buffer& context, const char* string )
295     {
296         context.isNewLine();
297         const char* p = string;
298         while( *p != '\0' )context.add( *p++ );
299         return context;
300     }
301
302     inline Buffer& operator<<( Buffer& context, const char& ch )
303     {
304         context.isNewLine();
305         context.add( ch );
306         return context;
307     }
308
309     inline Buffer& operator<<( Buffer& context, const std::string& string )
310     {
311         context.isNewLine();
312         const char* p = string.c_str();
313         while( *p != '\0' )context.add( *p++ );
314         return context;
315     }
316
317     inline Buffer& operator<<( Buffer& context, Buffer& (*pf)( Buffer& context ) )
318     {
319         return pf( context );
320     }
321
322     inline Buffer& endl( Buffer& context )
323     {
324         context << '\n';
325         context.new_line = true;
326         return context;
327     }
328
329     inline Buffer& advance( Buffer& context )
330     {
331         context.tabs++;
332         return context;
333     }
334
335     inline Buffer& retreat( Buffer& context )
336     {
337         if ( context.tabs )context.tabs--;
338         return context;
339     }
340
341     inline Buffer& quote( Buffer& context )
342     {
343         context << '\"';
344         return context;
345     }
346
347     inline Buffer& less( Buffer& context )
348     {
349         context << '<';
350         return context;
351     }
352
353     inline Buffer& greater( Buffer& context )
354     {
355         context << '>';
356         return context;
357     }
358
359     inline Buffer& endelement( Buffer& context )
360     {
361         context << "/>";
362         return context;
363     }
364
365     inline Buffer& redirect( Buffer& context )
366     {
367         context.redirect = true;
368         context.hold.clear();
369         return context;
370     }
371
372     inline Buffer& direct( Buffer& context )
373     {
374         context.redirect = false;
375         return context;
376     }
377
378     inline Buffer& flush( Buffer& context )
379     {
380         context.redirect = false;
381         for( size_t i=0; i< context.hold.size(); i++ ) context.add( context.hold[i] );
382         context.hold.clear();
383         return context;
384     }
385
386 }  //namespace codeblocksgenerator
387
388
389
390 #endif  //cmGlobalCodeBlocksGenerator_h
Note: See TracBrowser for help on using the browser.