beginnings of makefile output
[reactos.git] / reactos / tools / rbuild / project.cpp
1
2 #include "pch.h"
3
4 #include "rbuild.h"
5
6 using std::string;
7 using std::vector;
8
9 #ifdef WIN32
10 #define EXEPOSTFIX ".exe"
11 #define SEP "\\"
12 string FixSep ( const string& s )
13 {
14 string s2(s);
15 char* p = strchr ( &s2[0], '/' );
16 while ( p )
17 {
18 *p++ = '\\';
19 p = strchr ( p, '/' );
20 }
21 return s2;
22 }
23 #else
24 #define EXEPOSTFIX
25 #define SEP "/"
26 string FixSep ( const string& s )
27 {
28 string s2(s);
29 char* p = strchr ( &s2[0], '\\' );
30 while ( p )
31 {
32 *p++ = '/';
33 p = strchr ( p, '\\' );
34 }
35 return s2;
36 }
37 #endif
38
39 Project::Project()
40 {
41 }
42
43 Project::Project(const string& filename)
44 {
45 if ( !xmlfile.open ( filename ) )
46 throw FileNotFoundException ( filename );
47 ReadXml();
48 }
49
50 Project::~Project()
51 {
52 for ( size_t i = 0; i < modules.size(); i++ )
53 delete modules[i];
54 delete head;
55 }
56
57 void Project::ReadXml()
58 {
59 Path path;
60
61 head = XMLParse ( xmlfile, path );
62 if ( !head )
63 throw InvalidBuildFileException ( "Document contains no 'project' tag." );
64
65 if ( head->name != "project" )
66 {
67 throw InvalidBuildFileException ( "Expected 'project', got '%s'.",
68 head->name.c_str());
69 }
70
71 this->ProcessXML ( *head, "." );
72 }
73
74 void
75 Project::ProcessXML ( const XMLElement& e, const string& path )
76 {
77 const XMLAttribute *att;
78 string subpath(path);
79 if ( e.name == "project" )
80 {
81 att = e.GetAttribute ( "name", false );
82 if ( !att )
83 name = "Unnamed";
84 else
85 name = att->value;
86 }
87 else if ( e.name == "module" )
88 {
89 att = e.GetAttribute ( "name", true );
90 if ( !att )
91 return;
92 Module* module = new Module ( e, att->value, path );
93 modules.push_back ( module );
94 module->ProcessXML ( e, path );
95 return;
96 }
97 else if ( e.name == "directory" )
98 {
99 // this code is duplicated between Project::ProcessXML() and Module::ProcessXML() :(
100 const XMLAttribute* att = e.GetAttribute ( "name", true );
101 if ( !att )
102 return;
103 subpath = path + "/" + att->value;
104 }
105 for ( size_t i = 0; i < e.subElements.size(); i++ )
106 ProcessXML ( *e.subElements[i], subpath );
107 }
108
109 bool
110 Project::GenerateOutput()
111 {
112 const XMLAttribute* att;
113 size_t i;
114
115 att = head->GetAttribute ( "makefile", true );
116 if ( !att )
117 return false;
118 FILE* f = fopen ( att->value.c_str(), "w" );
119 if ( !f )
120 {
121 throw Exception ( "Unable to open '%s' for output", att->value.c_str() );
122 return false;
123 }
124 fprintf ( f, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
125
126 // generate module list:
127 fprintf ( f, "all: " );
128 for ( i = 0; i < modules.size(); i++ )
129 {
130 Module& m = *modules[i];
131 fprintf ( f, " %s" SEP "%s" EXEPOSTFIX, FixSep(m.path).c_str(), m.name.c_str() );
132 }
133 fprintf ( f, "\n\n" );
134
135 return true;
136 }