}
-/* static */ string
-Environment::GetVariable ( const string& name )
-{
- char* value = getenv ( name.c_str () );
- if ( value != NULL && strlen ( value ) > 0 )
- return ssprintf ( "%s",
- value );
- else
- return "";
-}
-
-
Directory::Directory ( const string& name_ )
: name(name_)
{
string
Directory::ReplaceVariable ( string name,
- string value,
- string path )
+ string value,
+ string path )
{
size_t i = path.find ( name );
if ( i != string::npos )
return path;
}
-string
-Directory::GetEnvironmentVariablePathOrDefault ( const string& name,
- const string& defaultValue )
-{
- const string& environmentVariableValue = Environment::GetVariable ( name );
- if ( environmentVariableValue.length () > 0 )
- return NormalizeFilename ( environmentVariableValue );
- else
- return defaultValue;
-}
-
-string
-Directory::GetIntermediatePath ()
-{
- return GetEnvironmentVariablePathOrDefault ( "ROS_INTERMEDIATE",
- "obj-i386" );
-}
-
-string
-Directory::GetOutputPath ()
-{
- return GetEnvironmentVariablePathOrDefault ( "ROS_OUTPUT",
- "output-i386" );
-}
-
-string
-Directory::GetInstallPath ()
-{
- return GetEnvironmentVariablePathOrDefault ( "ROS_INSTALL",
- "reactos" );
-}
-
void
Directory::ResolveVariablesInPath ( char* buf,
- string path )
+ string path )
{
- string s = ReplaceVariable ( "$(INTERMEDIATE)", GetIntermediatePath (), path );
- s = ReplaceVariable ( "$(OUTPUT)", GetOutputPath (), s );
- s = ReplaceVariable ( "$(INSTALL)", GetInstallPath (), s );
+ string s = ReplaceVariable ( "$(INTERMEDIATE)", Environment::GetIntermediatePath (), path );
+ s = ReplaceVariable ( "$(OUTPUT)", Environment::GetOutputPath (), s );
+ s = ReplaceVariable ( "$(INSTALL)", Environment::GetInstallPath (), s );
strcpy ( buf, s.c_str () );
}
void
Directory::GenerateTree ( const string& parent,
- bool verbose )
+ bool verbose )
{
string path;
void
Directory::CreateRule ( FILE* f,
- const string& parent )
+ const string& parent )
{
string path;
public:
MingwFactory() : Factory ( "mingw" ) {}
Backend* operator() ( Project& project,
- bool verbose,
- bool cleanAsYouGo )
+ Configuration& configuration )
{
return new MingwBackend ( project,
- verbose,
- cleanAsYouGo );
+ configuration );
}
} factory;
MingwBackend::MingwBackend ( Project& project,
- bool verbose,
- bool cleanAsYouGo )
- : Backend ( project, verbose, cleanAsYouGo ),
+ Configuration& configuration )
+ : Backend ( project, configuration ),
intermediateDirectory ( new Directory ("$(INTERMEDIATE)" ) ),
outputDirectory ( new Directory ( "$(OUTPUT)" ) ),
installDirectory ( new Directory ( "$(INSTALL)" ) )
{
+ compilerPrefix = "";
}
MingwBackend::~MingwBackend()
string
MingwBackend::AddDirectoryTarget ( const string& directory,
- Directory* directoryTree )
+ Directory* directoryTree )
{
- directoryTree->Add ( directory.c_str() );
+ if ( directory.length () > 0)
+ directoryTree->Add ( directory.c_str() );
return directoryTree->name;
}
for ( i = 0; i < ProjectNode.modules.size (); i++ )
{
Module& module = *ProjectNode.modules[i];
+ if ( !module.enabled )
+ continue;
MingwModuleHandler* h = MingwModuleHandler::InstanciateHandler (
module,
this );
GenerateAllTarget ( v );
GenerateInitTarget ();
+ GenerateRegTestsRunTarget ();
for ( i = 0; i < iend; i++ )
v[i]->GenerateOtherMacros();
h.GenerateInvocations ();
h.GenerateCleanTarget ();
h.GenerateInstallTarget ();
+ h.GenerateDependsTarget ();
delete v[i];
}
printf ( "done\n" );
}
-
+
void
MingwBackend::Process ()
+{
+ if ( configuration.CheckDependenciesForModuleOnly )
+ CheckAutomaticDependenciesForModuleOnly ();
+ else
+ ProcessNormal ();
+}
+
+void
+MingwBackend::CheckAutomaticDependenciesForModuleOnly ()
+{
+ if ( configuration.AutomaticDependencies )
+ {
+ Module* module = ProjectNode.LocateModule ( configuration.CheckDependenciesForModuleOnlyModule );
+ if ( module == NULL )
+ {
+ printf ( "Module '%s' does not exist\n",
+ configuration.CheckDependenciesForModuleOnlyModule.c_str () );
+ return;
+ }
+
+ printf ( "Checking automatic dependencies for module '%s'...",
+ module->name.c_str () );
+ AutomaticDependency automaticDependency ( ProjectNode );
+ automaticDependency.CheckAutomaticDependencies ( *module,
+ configuration.Verbose );
+ printf ( "done\n" );
+ }
+}
+
+void
+MingwBackend::ProcessNormal ()
{
DetectCompiler ();
+ DetectNetwideAssembler ();
DetectPipeSupport ();
DetectPCHSupport ();
CreateMakefile ();
GenerateXmlBuildFilesMacro ();
ProcessModules ();
GenerateInstallTarget ();
+ GenerateTestTarget ();
GenerateDirectoryTargets ();
GenerateDirectories ();
+ UnpackWineResources ();
+ GenerateTestSupportCode ();
+ GenerateProxyMakefiles ();
CheckAutomaticDependencies ();
CloseMakefile ();
}
fprintf ( fMakefile, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
}
+string
+MingwBackend::GenerateIncludesAndDefines ( IfableData& data ) const
+{
+ string includeParameters = MingwModuleHandler::GenerateGccIncludeParametersFromVector ( data.includes );
+ string defineParameters = MingwModuleHandler::GenerateGccDefineParametersFromVector ( data.defines );
+ return includeParameters + " " + defineParameters;
+}
+
void
MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation,
IfableData& data ) const
{
- size_t i;
-
fprintf (
fMakefile,
"PROJECT_CFLAGS %s",
assignmentOperation );
- for ( i = 0; i < data.compilerFlags.size(); i++ )
- {
- fprintf (
- fMakefile,
- " %s",
- data.compilerFlags[i]->flag.c_str() );
- }
-
- for ( i = 0; i < data.includes.size(); i++ )
- {
- fprintf (
- fMakefile,
- " -I%s",
- data.includes[i]->directory.c_str() );
- }
+ fprintf ( fMakefile,
+ " %s",
+ GenerateIncludesAndDefines ( data ).c_str() );
- for ( i = 0; i < data.defines.size(); i++ )
- {
- Define& d = *data.defines[i];
- fprintf (
- fMakefile,
- " -D%s",
- d.name.c_str() );
- if ( d.value.size() )
- fprintf (
- fMakefile,
- "=%s",
- d.value.c_str() );
- }
fprintf ( fMakefile, "\n" );
}
prop.value.c_str() );
}
- if ( data.includes.size() || data.defines.size() || data.compilerFlags.size() )
+ if ( data.includes.size() || data.defines.size() )
{
GenerateProjectCFlagsMacro ( assignmentOperation,
data );
If& rIf = *data.ifs[i];
if ( rIf.data.defines.size()
|| rIf.data.includes.size()
- || rIf.data.compilerFlags.size()
|| rIf.data.ifs.size() )
{
fprintf (
}
}
+void
+MingwBackend::GenerateProjectGccOptionsMacro ( const char* assignmentOperation,
+ IfableData& data ) const
+{
+ size_t i;
+
+ fprintf (
+ fMakefile,
+ "PROJECT_GCCOPTIONS %s",
+ assignmentOperation );
+
+ for ( i = 0; i < data.compilerFlags.size(); i++ )
+ {
+ fprintf (
+ fMakefile,
+ " %s",
+ data.compilerFlags[i]->flag.c_str() );
+ }
+
+ fprintf ( fMakefile, "\n" );
+}
+
+void
+MingwBackend::GenerateProjectGccOptions (
+ const char* assignmentOperation,
+ IfableData& data ) const
+{
+ size_t i;
+
+ if ( data.compilerFlags.size() )
+ {
+ GenerateProjectGccOptionsMacro ( assignmentOperation,
+ data );
+ }
+
+ for ( i = 0; i < data.ifs.size(); i++ )
+ {
+ If& rIf = *data.ifs[i];
+ if ( rIf.data.compilerFlags.size()
+ || rIf.data.ifs.size() )
+ {
+ fprintf (
+ fMakefile,
+ "ifeq (\"$(%s)\",\"%s\")\n",
+ rIf.property.c_str(),
+ rIf.value.c_str() );
+ GenerateProjectGccOptions (
+ "+=",
+ rIf.data );
+ fprintf (
+ fMakefile,
+ "endif\n\n" );
+ }
+ }
+}
+
string
MingwBackend::GenerateProjectLFLAGS () const
{
void
MingwBackend::GenerateGlobalVariables () const
{
- GenerateGlobalCFlagsAndProperties (
- "=",
- ProjectNode.non_if_data );
+ fprintf ( fMakefile,
+ "PREFIX := %s\n",
+ compilerPrefix.c_str () );
+ fprintf ( fMakefile,
+ "nasm := %s\n",
+ nasmCommand.c_str () );
+
+ GenerateGlobalCFlagsAndProperties ( "=", ProjectNode.non_if_data );
+ GenerateProjectGccOptions ( "=", ProjectNode.non_if_data );
fprintf ( fMakefile, "PROJECT_RCFLAGS := $(PROJECT_CFLAGS)\n" );
fprintf ( fMakefile, "PROJECT_WIDLFLAGS := $(PROJECT_CFLAGS)\n" );
fprintf ( fMakefile, "PROJECT_LFLAGS := %s\n",
GenerateProjectLFLAGS ().c_str () );
fprintf ( fMakefile, "PROJECT_CFLAGS += -Wall\n" );
+ fprintf ( fMakefile, "PROJECT_CFLAGS += $(PROJECT_GCCOPTIONS)\n" );
fprintf ( fMakefile, "\n" );
}
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
Module& module = *ProjectNode.modules[i];
+ if ( !module.enabled )
+ continue;
if ( module.type == BuildTool )
{
if ( dependencies.length () > 0 )
fprintf ( fMakefile, "\n" );
}
+void
+MingwBackend::GenerateRegTestsRunTarget () const
+{
+ fprintf ( fMakefile,
+ "REGTESTS_RUN_TARGET = regtests.dll\n" );
+ fprintf ( fMakefile,
+ "$(REGTESTS_RUN_TARGET): $(REGTESTS_TARGET)\n" );
+ fprintf ( fMakefile,
+ "\t$(cp) $(REGTESTS_TARGET) $(REGTESTS_RUN_TARGET)\n" );
+ fprintf ( fMakefile, "\n" );
+}
+
void
MingwBackend::GenerateXmlBuildFilesMacro() const
{
else
{
fprintf ( fMakefile,
- " \\\n",
- xmlbuildFilenames.c_str () );
+ " \\\n" );
}
xmlbuildFilenames.resize ( 0 );
}
fprintf ( fMakefile, "\n" );
}
+string
+MingwBackend::GetBin2ResExecutable ()
+{
+ return NormalizeFilename ( Environment::GetOutputPath () + SSEP + "tools/bin2res/bin2res" + EXEPOSTFIX );
+}
+
void
-MingwBackend::CheckAutomaticDependencies ()
+MingwBackend::UnpackWineResources ()
+{
+ printf ( "Unpacking WINE resources..." );
+ WineResource wineResource ( ProjectNode,
+ GetBin2ResExecutable () );
+ wineResource.UnpackResources ( configuration.Verbose );
+ printf ( "done\n" );
+}
+
+void
+MingwBackend::GenerateTestSupportCode ()
{
- printf ( "Checking automatic dependencies..." );
- AutomaticDependency automaticDependency ( ProjectNode );
- automaticDependency.Process ();
- automaticDependency.CheckAutomaticDependencies ( verbose );
+ printf ( "Generating test support code..." );
+ TestSupportCode testSupportCode ( ProjectNode );
+ testSupportCode.GenerateTestSupportCode ( configuration.Verbose );
printf ( "done\n" );
}
+string
+MingwBackend::GetProxyMakefileTree () const
+{
+ if ( configuration.GenerateProxyMakefilesInSourceTree )
+ return "";
+ else
+ return Environment::GetOutputPath ();
+}
+
+void
+MingwBackend::GenerateProxyMakefiles ()
+{
+ printf ( "Generating proxy makefiles..." );
+ ProxyMakefile proxyMakefile ( ProjectNode );
+ proxyMakefile.GenerateProxyMakefiles ( configuration.Verbose,
+ GetProxyMakefileTree () );
+ printf ( "done\n" );
+}
+
+void
+MingwBackend::CheckAutomaticDependencies ()
+{
+ if ( configuration.AutomaticDependencies )
+ {
+ printf ( "Checking automatic dependencies..." );
+ AutomaticDependency automaticDependency ( ProjectNode );
+ automaticDependency.CheckAutomaticDependencies ( configuration.Verbose );
+ printf ( "done\n" );
+ }
+}
+
bool
MingwBackend::IncludeDirectoryTarget ( const string& directory ) const
{
MingwBackend::GenerateDirectories ()
{
printf ( "Creating directories..." );
- intermediateDirectory->GenerateTree ( "", verbose );
- outputDirectory->GenerateTree ( "", verbose );
- installDirectory->GenerateTree ( "", verbose );
+ intermediateDirectory->GenerateTree ( "", configuration.Verbose );
+ outputDirectory->GenerateTree ( "", configuration.Verbose );
+ if ( !configuration.MakeHandlesInstallDirectories )
+ installDirectory->GenerateTree ( "", configuration.Verbose );
printf ( "done\n" );
}
MingwBackend::TryToDetectThisCompiler ( const string& compiler )
{
string command = ssprintf (
- "%s -v 2>%s",
+ "%s -v 1>%s 2>%s",
compiler.c_str (),
+ NUL,
NUL );
int exitcode = system ( command.c_str () );
return (exitcode == 0);
const string& ROS_PREFIXValue = Environment::GetVariable ( "ROS_PREFIX" );
if ( ROS_PREFIXValue.length () > 0 )
{
- compilerCommand = ROS_PREFIXValue + "-gcc";
+ compilerPrefix = ROS_PREFIXValue;
+ compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
#if defined(WIN32)
if ( !detectedCompiler )
{
+ compilerPrefix = "";
compilerCommand = "gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
#endif
if ( !detectedCompiler )
{
- compilerCommand = "mingw32-gcc";
+ compilerPrefix = "mingw32";
+ compilerCommand = compilerPrefix + "-gcc";
detectedCompiler = TryToDetectThisCompiler ( compilerCommand );
}
if ( detectedCompiler )
printf ( "not detected\n" );
}
+bool
+MingwBackend::TryToDetectThisNetwideAssembler ( const string& assembler )
+{
+ string command = ssprintf (
+ "%s -h 1>%s 2>%s",
+ assembler.c_str (),
+ NUL,
+ NUL );
+ int exitcode = system ( command.c_str () );
+ return (exitcode == 0);
+}
+
+void
+MingwBackend::DetectNetwideAssembler ()
+{
+ printf ( "Detecting netwide assembler..." );
+
+ nasmCommand = "nasm";
+ bool detectedNasm = TryToDetectThisNetwideAssembler ( nasmCommand );
+#if defined(WIN32)
+ if ( !detectedNasm )
+ {
+ nasmCommand = "nasmw";
+ detectedNasm = TryToDetectThisNetwideAssembler ( nasmCommand );
+ }
+#endif
+ if ( detectedNasm )
+ printf ( "detected (%s)\n", nasmCommand.c_str () );
+ else
+ printf ( "not detected\n" );
+}
+
void
MingwBackend::DetectPipeSupport ()
{
string pipe_detectionObjectFilename = ReplaceExtension ( pipe_detection,
".o" );
string command = ssprintf (
- "%s -pipe -c %s -o %s 2>%s",
+ "%s -pipe -c %s -o %s 1>%s 2>%s",
compilerCommand.c_str (),
pipe_detection.c_str (),
pipe_detectionObjectFilename.c_str (),
+ NUL,
NUL );
int exitcode = system ( command.c_str () );
FILE* f = fopen ( pipe_detectionObjectFilename.c_str (), "rb" );
string path = "tools" SSEP "rbuild" SSEP "backend" SSEP "mingw" SSEP "pch_detection.h";
string cmd = ssprintf (
- "%s -c %s 2>%s",
+ "%s -c %s 1>%s 2>%s",
compilerCommand.c_str (),
path.c_str (),
+ NUL,
NUL );
system ( cmd.c_str () );
path += ".gch";
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
const Module& module = *ProjectNode.modules[i];
+ if ( !module.enabled )
+ continue;
if ( module.installName.length () > 0 )
{
- string targetFilenameNoFixup = module.installBase + SSEP + module.installName;
+ string targetFilenameNoFixup;
+ if ( module.installBase.length () > 0 )
+ targetFilenameNoFixup = module.installBase + SSEP + module.installName;
+ else
+ targetFilenameNoFixup = module.installName;
string targetFilename = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( targetFilenameNoFixup ),
installDirectory );
void
MingwBackend::OutputInstallTarget ( const string& sourceFilename,
- const string& targetFilename,
- const string& targetDirectory )
+ const string& targetFilename,
+ const string& targetDirectory )
{
+ string fullTargetFilename;
+ if ( targetDirectory.length () > 0)
+ fullTargetFilename = targetDirectory + SSEP + targetFilename;
+ else
+ fullTargetFilename = targetFilename;
string normalizedTargetFilename = MingwModuleHandler::PassThruCacheDirectory (
- NormalizeFilename ( targetDirectory + SSEP + targetFilename ),
+ NormalizeFilename ( fullTargetFilename ),
installDirectory );
string normalizedTargetDirectory = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( targetDirectory ),
{
const InstallFile& installfile = *ProjectNode.installfiles[i];
OutputInstallTarget ( installfile.GetPath (),
- installfile.newname,
- installfile.base );
+ installfile.newname,
+ installfile.base );
}
}
for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
{
const Module& module = *ProjectNode.modules[i];
+ if ( !module.enabled )
+ continue;
if ( module.installName.length () > 0 )
{
string sourceFilename = MingwModuleHandler::PassThruCacheDirectory (
NormalizeFilename ( module.GetPath () ),
outputDirectory );
OutputInstallTarget ( sourceFilename,
- module.installName,
- module.installBase );
+ module.installName,
+ module.installBase );
}
}
}
vector<string> vInstallTargetFiles;
GetInstallTargetFiles ( vInstallTargetFiles );
string installTargetFiles = v2s ( vInstallTargetFiles, 5 );
+ string registryTargetFiles = GetRegistryTargetFiles ();
fprintf ( fMakefile,
- "install: %s install_registry\n",
- installTargetFiles.c_str () );
+ "install: %s %s\n",
+ installTargetFiles.c_str (),
+ registryTargetFiles.c_str () );
OutputNonModuleInstallTargets ();
OutputModuleInstallTargets ();
OutputRegistryInstallTarget ();
"\n" );
}
+void
+MingwBackend::GetModuleTestTargets (
+ vector<string>& out ) const
+{
+ for ( size_t i = 0; i < ProjectNode.modules.size (); i++ )
+ {
+ const Module& module = *ProjectNode.modules[i];
+ if ( !module.enabled )
+ continue;
+ if ( module.type == Test )
+ out.push_back ( module.name );
+ }
+}
+
+void
+MingwBackend::GenerateTestTarget ()
+{
+ vector<string> vTestTargets;
+ GetModuleTestTargets ( vTestTargets );
+ string testTargets = v2s ( vTestTargets, 5 );
+
+ fprintf ( fMakefile,
+ "test: %s\n",
+ testTargets.c_str () );
+ fprintf ( fMakefile,
+ "\n" );
+}
+
void
MingwBackend::GenerateDirectoryTargets ()
{