11 Environment::GetVariable ( const string
& name
)
13 char* value
= getenv ( name
.c_str () );
14 if ( value
!= NULL
&& strlen ( value
) > 0 )
15 return ssprintf ( "%s",
22 Environment::GetEnvironmentVariablePathOrDefault ( const string
& name
,
23 const string
& defaultValue
)
25 const string
& environmentVariableValue
= Environment::GetVariable ( name
);
26 if ( environmentVariableValue
.length () > 0 )
27 return NormalizeFilename ( environmentVariableValue
);
33 Environment::GetIntermediatePath ()
35 return GetEnvironmentVariablePathOrDefault ( "ROS_INTERMEDIATE",
40 Environment::GetOutputPath ()
42 return GetEnvironmentVariablePathOrDefault ( "ROS_OUTPUT",
47 Environment::GetInstallPath ()
49 return GetEnvironmentVariablePathOrDefault ( "ROS_INSTALL",
54 Project::Project ( const string
& filename
)
65 for ( i
= 0; i
< modules
.size (); i
++ )
67 for ( i
= 0; i
< linkerFlags
.size (); i
++ )
68 delete linkerFlags
[i
];
69 for ( i
= 0; i
< cdfiles
.size (); i
++ )
71 for ( i
= 0; i
< installfiles
.size (); i
++ )
72 delete installfiles
[i
];
77 Project::LookupProperty ( const string
& name
) const
79 for ( size_t i
= 0; i
< non_if_data
.properties
.size (); i
++ )
81 const Property
* property
= non_if_data
.properties
[i
];
82 if ( property
->name
== name
)
89 Project::ResolveNextProperty ( string
& s
) const
91 size_t i
= s
.find ( "${" );
92 if ( i
== string::npos
)
94 if ( i
!= string::npos
)
97 if ( s
[i
+ 1] == '{' )
101 size_t j
= s
.find ( endCharacter
);
102 if ( j
!= string::npos
)
104 int propertyNameLength
= j
- i
- 2;
105 string propertyName
= s
.substr ( i
+ 2, propertyNameLength
);
106 const Property
* property
= LookupProperty ( propertyName
);
107 if ( property
!= NULL
)
108 return s
.replace ( i
, propertyNameLength
+ 3, property
->value
);
115 Project::ResolveProperties ( const string
& s
) const
122 s2
= ResolveNextProperty ( s3
);
123 } while ( s2
!= s3
);
128 Project::SetConfigurationOption ( char* s
,
130 string
* alternativeName
)
132 const Property
* property
= LookupProperty ( name
);
133 if ( property
!= NULL
&& property
->value
.length () > 0 )
137 property
->name
.c_str (),
138 property
->value
.c_str () );
140 else if ( property
!= NULL
)
144 property
->name
.c_str () );
146 else if ( alternativeName
!= NULL
)
150 alternativeName
->c_str () );
155 Project::SetConfigurationOption ( char* s
,
158 SetConfigurationOption ( s
, name
, NULL
);
162 Project::WriteConfigurationFile ()
167 buf
= (char*) malloc ( 10*1024 );
169 throw OutOfMemoryException ();
172 s
= s
+ sprintf ( s
, "/* Automatically generated. " );
173 s
= s
+ sprintf ( s
, "Edit config.xml to change configuration */\n" );
174 s
= s
+ sprintf ( s
, "#ifndef __INCLUDE_CONFIG_H\n" );
175 s
= s
+ sprintf ( s
, "#define __INCLUDE_CONFIG_H\n" );
177 SetConfigurationOption ( s
, "ARCH" );
178 SetConfigurationOption ( s
, "OPTIMIZED" );
179 SetConfigurationOption ( s
, "MP", new string ( "UP" ) );
180 SetConfigurationOption ( s
, "ACPI" );
181 SetConfigurationOption ( s
, "_3GB" );
183 s
= s
+ sprintf ( s
, "#endif /* __INCLUDE_CONFIG_H */\n" );
185 FileSupportCode::WriteIfChanged ( buf
, "include" SSEP
"roscfg.h" );
191 Project::ExecuteInvocations ()
193 for ( size_t i
= 0; i
< modules
.size (); i
++ )
194 modules
[i
]->InvokeModule ();
201 head
= XMLLoadFile ( xmlfile
, path
, xmlbuildfiles
);
203 for ( size_t i
= 0; i
< head
->subElements
.size (); i
++ )
205 if ( head
->subElements
[i
]->name
== "project" )
207 node
= head
->subElements
[i
];
209 this->ProcessXML ( path
);
214 throw InvalidBuildFileException (
216 "Document contains no 'project' tag." );
220 Project::ProcessXML ( const string
& path
)
222 const XMLAttribute
*att
;
223 if ( node
->name
!= "project" )
224 throw Exception ( "internal tool error: Project::ProcessXML() called with non-<project> node" );
226 att
= node
->GetAttribute ( "name", false );
232 att
= node
->GetAttribute ( "makefile", true );
234 makefile
= att
->value
;
237 for ( i
= 0; i
< node
->subElements
.size (); i
++ )
238 ProcessXMLSubElement ( *node
->subElements
[i
], path
);
239 for ( i
= 0; i
< modules
.size (); i
++ )
240 modules
[i
]->ProcessXML ();
241 for ( i
= 0; i
< linkerFlags
.size (); i
++ )
242 linkerFlags
[i
]->ProcessXML ();
243 non_if_data
.ProcessXML ();
244 for ( i
= 0; i
< cdfiles
.size (); i
++ )
245 cdfiles
[i
]->ProcessXML ();
246 for ( i
= 0; i
< installfiles
.size (); i
++ )
247 installfiles
[i
]->ProcessXML ();
251 Project::ProcessXMLSubElement ( const XMLElement
& e
,
255 bool subs_invalid
= false;
256 string
subpath(path
);
257 if ( e
.name
== "module" )
260 throw InvalidBuildFileException (
262 "<module> is not a valid sub-element of <if>" );
263 Module
* module
= new Module ( *this, e
, path
);
264 if ( LocateModule ( module
->name
) )
265 throw InvalidBuildFileException (
267 "module name conflict: '%s' (originally defined at %s)",
268 module
->name
.c_str(),
269 module
->node
.location
.c_str() );
270 modules
.push_back ( module
);
271 return; // defer processing until later
273 else if ( e
.name
== "cdfile" )
275 CDFile
* cdfile
= new CDFile ( *this, e
, path
);
276 cdfiles
.push_back ( cdfile
);
279 else if ( e
.name
== "installfile" )
281 InstallFile
* installfile
= new InstallFile ( *this, e
, path
);
282 installfiles
.push_back ( installfile
);
285 else if ( e
.name
== "directory" )
287 const XMLAttribute
* att
= e
.GetAttribute ( "name", true );
289 subpath
= GetSubPath ( e
.location
, path
, att
->value
);
291 else if ( e
.name
== "include" )
293 Include
* include
= new Include ( *this, &e
);
295 pIf
->data
.includes
.push_back ( include
);
297 non_if_data
.includes
.push_back ( include
);
300 else if ( e
.name
== "define" )
302 Define
* define
= new Define ( *this, e
);
304 pIf
->data
.defines
.push_back ( define
);
306 non_if_data
.defines
.push_back ( define
);
309 else if ( e
.name
== "compilerflag" )
311 CompilerFlag
* pCompilerFlag
= new CompilerFlag ( *this, e
);
313 pIf
->data
.compilerFlags
.push_back ( pCompilerFlag
);
315 non_if_data
.compilerFlags
.push_back ( pCompilerFlag
);
318 else if ( e
.name
== "linkerflag" )
320 linkerFlags
.push_back ( new LinkerFlag ( *this, e
) );
323 else if ( e
.name
== "if" )
326 pIf
= new If ( e
, *this, NULL
);
328 pOldIf
->data
.ifs
.push_back ( pIf
);
330 non_if_data
.ifs
.push_back ( pIf
);
331 subs_invalid
= false;
333 else if ( e
.name
== "ifnot" )
336 pIf
= new If ( e
, *this, NULL
, true );
338 pOldIf
->data
.ifs
.push_back ( pIf
);
340 non_if_data
.ifs
.push_back ( pIf
);
341 subs_invalid
= false;
343 else if ( e
.name
== "property" )
345 Property
* property
= new Property ( e
, *this, NULL
);
347 pIf
->data
.properties
.push_back ( property
);
349 non_if_data
.properties
.push_back ( property
);
351 if ( subs_invalid
&& e
.subElements
.size() )
352 throw InvalidBuildFileException (
354 "<%s> cannot have sub-elements",
356 for ( size_t i
= 0; i
< e
.subElements
.size (); i
++ )
357 ProcessXMLSubElement ( *e
.subElements
[i
], subpath
, pIf
);
361 Project::LocateModule ( const string
& name
)
363 for ( size_t i
= 0; i
< modules
.size (); i
++ )
365 if (modules
[i
]->name
== name
)
373 Project::LocateModule ( const string
& name
) const
375 for ( size_t i
= 0; i
< modules
.size (); i
++ )
377 if ( modules
[i
]->name
== name
)
385 Project::GetProjectFilename () const