2 * Copyright (C) 2005 Casper S. Hornstrup
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.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 #include "../../pch.h"
22 #include "modulehandler.h"
26 #define pclose _pclose
34 typedef set
<string
> set_string
;
38 v2s ( const string_list
& v
, int wrap_at
)
44 for ( size_t i
= 0; i
< v
.size(); i
++ )
48 if ( wrap_at
> 0 && wrap_count
++ == wrap_at
)
58 static class MingwFactory
: public Backend::Factory
61 MingwFactory() : Factory ( "mingw" ) {}
62 Backend
* operator() ( Project
& project
,
63 Configuration
& configuration
)
65 return new MingwBackend ( project
,
71 MingwBackend::MingwBackend ( Project
& project
,
72 Configuration
& configuration
)
73 : Backend ( project
, configuration
),
74 intermediateDirectory ( new Directory ("$(INTERMEDIATE)" ) ),
75 outputDirectory ( new Directory ( "$(OUTPUT)" ) ),
76 installDirectory ( new Directory ( "$(INSTALL)" ) )
81 MingwBackend::~MingwBackend()
83 delete intermediateDirectory
;
84 delete outputDirectory
;
85 delete installDirectory
;
89 MingwBackend::AddDirectoryTarget ( const string
& directory
,
90 Directory
* directoryTree
)
92 if ( directory
.length () > 0)
93 directoryTree
->Add ( directory
.c_str() );
94 return directoryTree
->name
;
98 MingwBackend::CanEnablePreCompiledHeaderSupportForModule ( const Module
& module
)
100 if ( !configuration
.CompilationUnitsEnabled
)
103 const vector
<CompilationUnit
*>& compilationUnits
= module
.non_if_data
.compilationUnits
;
105 for ( i
= 0; i
< compilationUnits
.size (); i
++ )
107 CompilationUnit
& compilationUnit
= *compilationUnits
[i
];
108 if ( compilationUnit
.files
.size () != 1 )
111 // intentionally make a copy so that we can append more work in
112 // the middle of processing without having to go recursive
113 vector
<If
*> v
= module
.non_if_data
.ifs
;
114 for ( i
= 0; i
< v
.size (); i
++ )
118 // check for sub-ifs to add to list
119 const vector
<If
*>& ifs
= rIf
.data
.ifs
;
120 for ( j
= 0; j
< ifs
.size (); j
++ )
121 v
.push_back ( ifs
[j
] );
122 const vector
<CompilationUnit
*>& compilationUnits
= rIf
.data
.compilationUnits
;
123 for ( j
= 0; j
< compilationUnits
.size (); j
++ )
125 CompilationUnit
& compilationUnit
= *compilationUnits
[j
];
126 if ( compilationUnit
.files
.size () != 1 )
134 MingwBackend::ProcessModules ()
136 printf ( "Processing modules..." );
138 vector
<MingwModuleHandler
*> v
;
140 for ( i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
142 Module
& module
= *ProjectNode
.modules
[i
];
143 if ( !module
.enabled
)
145 MingwModuleHandler
* h
= MingwModuleHandler::InstanciateHandler (
148 if ( use_pch
&& CanEnablePreCompiledHeaderSupportForModule ( module
) )
149 h
->EnablePreCompiledHeaderSupport ();
150 if ( module
.host
== HostDefault
)
152 module
.host
= h
->DefaultHost();
153 assert ( module
.host
!= HostDefault
);
158 size_t iend
= v
.size ();
160 for ( i
= 0; i
< iend
; i
++ )
161 v
[i
]->GenerateObjectMacro();
162 fprintf ( fMakefile
, "\n" );
163 for ( i
= 0; i
< iend
; i
++ )
164 v
[i
]->GenerateTargetMacro();
165 fprintf ( fMakefile
, "\n" );
167 GenerateAllTarget ( v
);
168 GenerateInitTarget ();
169 GenerateRegTestsRunTarget ();
171 for ( i
= 0; i
< iend
; i
++ )
172 v
[i
]->GenerateOtherMacros();
174 for ( i
= 0; i
< iend
; i
++ )
176 MingwModuleHandler
& h
= *v
[i
];
177 h
.GeneratePreconditionDependencies ();
179 h
.GenerateInvocations ();
180 h
.GenerateCleanTarget ();
181 h
.GenerateInstallTarget ();
182 h
.GenerateDependsTarget ();
190 MingwBackend::Process ()
192 if ( configuration
.CheckDependenciesForModuleOnly
)
193 CheckAutomaticDependenciesForModuleOnly ();
199 MingwBackend::CheckAutomaticDependenciesForModuleOnly ()
201 if ( configuration
.AutomaticDependencies
)
203 Module
* module
= ProjectNode
.LocateModule ( configuration
.CheckDependenciesForModuleOnlyModule
);
204 if ( module
== NULL
)
206 printf ( "Module '%s' does not exist\n",
207 configuration
.CheckDependenciesForModuleOnlyModule
.c_str () );
211 printf ( "Checking automatic dependencies for module '%s'...",
212 module
->name
.c_str () );
213 AutomaticDependency
automaticDependency ( ProjectNode
);
214 automaticDependency
.CheckAutomaticDependenciesForModule ( *module
,
215 configuration
.Verbose
);
221 MingwBackend::ProcessNormal ()
225 DetectNetwideAssembler ();
226 DetectPipeSupport ();
230 GenerateGlobalVariables ();
231 GenerateXmlBuildFilesMacro ();
233 GenerateInstallTarget ();
234 GenerateTestTarget ();
235 GenerateDirectoryTargets ();
236 GenerateDirectories ();
237 UnpackWineResources ();
238 GenerateTestSupportCode ();
239 GenerateCompilationUnitSupportCode ();
241 GenerateProxyMakefiles ();
242 CheckAutomaticDependencies ();
247 MingwBackend::CreateMakefile ()
249 fMakefile
= fopen ( ProjectNode
.makefile
.c_str (), "w" );
251 throw AccessDeniedException ( ProjectNode
.makefile
);
252 MingwModuleHandler::SetBackend ( this );
253 MingwModuleHandler::SetMakefile ( fMakefile
);
257 MingwBackend::CloseMakefile () const
260 fclose ( fMakefile
);
264 MingwBackend::GenerateHeader () const
266 fprintf ( fMakefile
, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
270 MingwBackend::GenerateIncludesAndDefines ( IfableData
& data
) const
272 string includeParameters
= MingwModuleHandler::GenerateGccIncludeParametersFromVector ( data
.includes
);
273 string defineParameters
= MingwModuleHandler::GenerateGccDefineParametersFromVector ( data
.defines
);
274 return includeParameters
+ " " + defineParameters
;
278 MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation
,
279 IfableData
& data
) const
284 assignmentOperation
);
288 GenerateIncludesAndDefines ( data
).c_str() );
290 fprintf ( fMakefile
, "\n" );
294 MingwBackend::GenerateGlobalCFlagsAndProperties (
295 const char* assignmentOperation
,
296 IfableData
& data
) const
300 for ( i
= 0; i
< data
.properties
.size(); i
++ )
302 Property
& prop
= *data
.properties
[i
];
303 fprintf ( fMakefile
, "%s := %s\n",
305 prop
.value
.c_str() );
308 if ( data
.includes
.size() || data
.defines
.size() )
310 GenerateProjectCFlagsMacro ( assignmentOperation
,
314 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
316 If
& rIf
= *data
.ifs
[i
];
317 if ( rIf
.data
.defines
.size()
318 || rIf
.data
.includes
.size()
319 || rIf
.data
.ifs
.size() )
323 "ifeq (\"$(%s)\",\"%s\")\n",
324 rIf
.property
.c_str(),
326 GenerateGlobalCFlagsAndProperties (
337 MingwBackend::GenerateProjectGccOptionsMacro ( const char* assignmentOperation
,
338 IfableData
& data
) const
344 "PROJECT_GCCOPTIONS %s",
345 assignmentOperation
);
347 for ( i
= 0; i
< data
.compilerFlags
.size(); i
++ )
352 data
.compilerFlags
[i
]->flag
.c_str() );
355 fprintf ( fMakefile
, "\n" );
359 MingwBackend::GenerateProjectGccOptions (
360 const char* assignmentOperation
,
361 IfableData
& data
) const
365 if ( data
.compilerFlags
.size() )
367 GenerateProjectGccOptionsMacro ( assignmentOperation
,
371 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
373 If
& rIf
= *data
.ifs
[i
];
374 if ( rIf
.data
.compilerFlags
.size()
375 || rIf
.data
.ifs
.size() )
379 "ifeq (\"$(%s)\",\"%s\")\n",
380 rIf
.property
.c_str(),
382 GenerateProjectGccOptions (
393 MingwBackend::GenerateProjectLFLAGS () const
396 for ( size_t i
= 0; i
< ProjectNode
.linkerFlags
.size (); i
++ )
398 LinkerFlag
& linkerFlag
= *ProjectNode
.linkerFlags
[i
];
399 if ( lflags
.length () > 0 )
401 lflags
+= linkerFlag
.flag
;
407 MingwBackend::GenerateGlobalVariables () const
411 compilerPrefix
.c_str () );
414 nasmCommand
.c_str () );
416 GenerateGlobalCFlagsAndProperties ( "=", ProjectNode
.non_if_data
);
417 GenerateProjectGccOptions ( "=", ProjectNode
.non_if_data
);
419 fprintf ( fMakefile
, "PROJECT_RCFLAGS := $(PROJECT_CFLAGS)\n" );
420 fprintf ( fMakefile
, "PROJECT_WIDLFLAGS := $(PROJECT_CFLAGS)\n" );
421 fprintf ( fMakefile
, "PROJECT_LFLAGS := %s\n",
422 GenerateProjectLFLAGS ().c_str () );
423 fprintf ( fMakefile
, "PROJECT_CFLAGS += -Wall\n" );
424 fprintf ( fMakefile
, "PROJECT_CFLAGS += $(PROJECT_GCCOPTIONS)\n" );
425 fprintf ( fMakefile
, "\n" );
429 MingwBackend::IncludeInAllTarget ( const Module
& module
) const
431 if ( MingwModuleHandler::ReferenceObjects ( module
) )
433 if ( module
.type
== BootSector
)
435 if ( module
.type
== Iso
)
437 if ( module
.type
== LiveIso
)
439 if ( module
.type
== Test
)
441 if ( module
.type
== Alias
)
447 MingwBackend::GenerateAllTarget ( const vector
<MingwModuleHandler
*>& handlers
) const
449 fprintf ( fMakefile
, "all:" );
451 size_t iend
= handlers
.size ();
452 for ( size_t i
= 0; i
< iend
; i
++ )
454 const Module
& module
= handlers
[i
]->module
;
455 if ( IncludeInAllTarget ( module
) )
457 if ( wrap_count
++ == 5 )
458 fprintf ( fMakefile
, " \\\n\t\t" ), wrap_count
= 0;
461 GetTargetMacro(module
).c_str () );
464 fprintf ( fMakefile
, "\n\t\n\n" );
468 MingwBackend::GetBuildToolDependencies () const
471 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
473 Module
& module
= *ProjectNode
.modules
[i
];
474 if ( !module
.enabled
)
476 if ( module
.type
== BuildTool
)
478 if ( dependencies
.length () > 0 )
480 dependencies
+= module
.GetDependencyPath ();
487 MingwBackend::GenerateInitTarget () const
491 GetBuildToolDependencies ().c_str () );
492 fprintf ( fMakefile
, "\n" );
496 MingwBackend::GenerateRegTestsRunTarget () const
499 "REGTESTS_RUN_TARGET = regtests.dll\n" );
501 "$(REGTESTS_RUN_TARGET): $(REGTESTS_TARGET)\n" );
503 "\t$(cp) $(REGTESTS_TARGET) $(REGTESTS_RUN_TARGET)\n" );
504 fprintf ( fMakefile
, "\n" );
508 MingwBackend::GenerateXmlBuildFilesMacro() const
511 "XMLBUILDFILES = %s \\\n",
512 ProjectNode
.GetProjectFilename ().c_str () );
513 string xmlbuildFilenames
;
514 int numberOfExistingFiles
= 0;
515 for ( size_t i
= 0; i
< ProjectNode
.xmlbuildfiles
.size (); i
++ )
517 XMLInclude
& xmlbuildfile
= *ProjectNode
.xmlbuildfiles
[i
];
518 if ( !xmlbuildfile
.fileExists
)
520 numberOfExistingFiles
++;
521 if ( xmlbuildFilenames
.length () > 0 )
522 xmlbuildFilenames
+= " ";
523 xmlbuildFilenames
+= NormalizeFilename ( xmlbuildfile
.topIncludeFilename
);
524 if ( numberOfExistingFiles
% 5 == 4 || i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
528 xmlbuildFilenames
.c_str ());
529 if ( i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
531 fprintf ( fMakefile
, "\n" );
538 xmlbuildFilenames
.resize ( 0 );
540 numberOfExistingFiles
++;
542 fprintf ( fMakefile
, "\n" );
546 MingwBackend::GetBin2ResExecutable ()
548 return NormalizeFilename ( Environment::GetOutputPath () + sSep
+ "tools/bin2res/bin2res" + ExePostfix
);
552 MingwBackend::UnpackWineResources ()
554 printf ( "Unpacking WINE resources..." );
555 WineResource
wineResource ( ProjectNode
,
556 GetBin2ResExecutable () );
557 wineResource
.UnpackResources ( configuration
.Verbose
);
562 MingwBackend::GenerateTestSupportCode ()
564 printf ( "Generating test support code..." );
565 TestSupportCode
testSupportCode ( ProjectNode
);
566 testSupportCode
.GenerateTestSupportCode ( configuration
.Verbose
);
571 MingwBackend::GenerateCompilationUnitSupportCode ()
573 if ( configuration
.CompilationUnitsEnabled
)
575 printf ( "Generating compilation unit support code..." );
576 CompilationUnitSupportCode
compilationUnitSupportCode ( ProjectNode
);
577 compilationUnitSupportCode
.Generate ( configuration
.Verbose
);
583 MingwBackend::GenerateSysSetup ()
585 printf ( "Generating syssetup.inf..." );
586 SysSetupGenerator
sysSetupGenerator ( ProjectNode
);
587 sysSetupGenerator
.Generate ();
592 MingwBackend::GetProxyMakefileTree () const
594 if ( configuration
.GenerateProxyMakefilesInSourceTree
)
597 return Environment::GetOutputPath ();
601 MingwBackend::GenerateProxyMakefiles ()
603 printf ( "Generating proxy makefiles..." );
604 ProxyMakefile
proxyMakefile ( ProjectNode
);
605 proxyMakefile
.GenerateProxyMakefiles ( configuration
.Verbose
,
606 GetProxyMakefileTree () );
611 MingwBackend::CheckAutomaticDependencies ()
613 if ( configuration
.AutomaticDependencies
)
615 printf ( "Checking automatic dependencies..." );
616 AutomaticDependency
automaticDependency ( ProjectNode
);
617 automaticDependency
.CheckAutomaticDependencies ( configuration
.Verbose
);
623 MingwBackend::IncludeDirectoryTarget ( const string
& directory
) const
625 if ( directory
== "$(INTERMEDIATE)" + sSep
+ "tools")
632 MingwBackend::GenerateDirectories ()
634 printf ( "Creating directories..." );
635 intermediateDirectory
->GenerateTree ( "", configuration
.Verbose
);
636 outputDirectory
->GenerateTree ( "", configuration
.Verbose
);
637 if ( !configuration
.MakeHandlesInstallDirectories
)
638 installDirectory
->GenerateTree ( "", configuration
.Verbose
);
643 MingwBackend::TryToDetectThisCompiler ( const string
& compiler
)
645 string command
= ssprintf (
647 FixSeparatorForSystemCommand(compiler
).c_str (),
650 int exitcode
= system ( command
.c_str () );
651 return (exitcode
== 0);
655 MingwBackend::DetectCompiler ()
657 printf ( "Detecting compiler..." );
659 bool detectedCompiler
= false;
660 const string
& ROS_PREFIXValue
= Environment::GetVariable ( "ROS_PREFIX" );
661 if ( ROS_PREFIXValue
.length () > 0 )
663 compilerPrefix
= ROS_PREFIXValue
;
664 compilerCommand
= compilerPrefix
+ "-gcc";
665 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
668 if ( !detectedCompiler
)
671 compilerCommand
= "gcc";
672 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
675 if ( !detectedCompiler
)
677 compilerPrefix
= "mingw32";
678 compilerCommand
= compilerPrefix
+ "-gcc";
679 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
681 if ( detectedCompiler
)
682 printf ( "detected (%s)\n", compilerCommand
.c_str () );
684 printf ( "not detected\n" );
688 MingwBackend::TryToDetectThisNetwideAssembler ( const string
& assembler
)
690 string command
= ssprintf (
692 FixSeparatorForSystemCommand(assembler
).c_str (),
695 int exitcode
= system ( command
.c_str () );
696 return (exitcode
== 0);
700 MingwBackend::TryToDetectThisBinutils ( const string
& binutils
)
702 string command
= ssprintf (
704 FixSeparatorForSystemCommand(binutils
).c_str (),
707 int exitcode
= system ( command
.c_str () );
708 return (exitcode
== 0);
712 MingwBackend::GetBinutilsVersion ( const string
& binutilsCommand
)
718 string versionCommand
= ssprintf ( "%s -v",
719 binutilsCommand
.c_str (),
722 fp
= popen ( versionCommand
.c_str () , "r" );
725 ( feof ( fp
) == 0 &&
726 ( ( ch
= fgetc( fp
) ) != -1 ) );
729 buffer
[i
] = (char) ch
;
734 char separators
[] = " ";
736 char *prevtoken
= NULL
;
738 token
= strtok ( buffer
, separators
);
739 while ( token
!= NULL
)
742 token
= strtok ( NULL
, separators
);
744 string version
= string ( prevtoken
);
745 int lastDigit
= version
.find_last_not_of ( "\t\r\n" );
746 if ( lastDigit
!= -1 )
747 return string ( version
, 0, lastDigit
+1 );
753 MingwBackend::IsSupportedBinutilsVersion ( const string
& binutilsVersion
)
755 if ( ( ( strcmp ( binutilsVersion
.c_str (), "20040902") >= 0 ) &&
756 ( strcmp ( binutilsVersion
.c_str (), "20041008") <= 0 ) ) ||
757 ( strcmp ( binutilsVersion
.c_str (), "20031001") < 0 ) )
764 MingwBackend::DetectBinutils ()
766 printf ( "Detecting binutils..." );
768 bool detectedBinutils
= false;
769 const string
& ROS_PREFIXValue
= Environment::GetVariable ( "ROS_PREFIX" );
770 if ( ROS_PREFIXValue
.length () > 0 )
772 binutilsPrefix
= ROS_PREFIXValue
;
773 binutilsCommand
= binutilsPrefix
+ "-ld";
774 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
777 if ( !detectedBinutils
)
780 binutilsCommand
= "ld";
781 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
784 if ( !detectedBinutils
)
786 binutilsPrefix
= "mingw32";
787 binutilsCommand
= binutilsPrefix
+ "-ld";
788 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
790 if ( detectedBinutils
)
792 string binutilsVersion
= GetBinutilsVersion ( binutilsCommand
);
793 if ( IsSupportedBinutilsVersion ( binutilsVersion
) )
794 printf ( "detected (%s)\n", binutilsCommand
.c_str () );
797 printf ( "detected (%s), but with unsupported version (%s)\n",
798 binutilsCommand
.c_str (),
799 binutilsVersion
.c_str () );
800 throw UnsupportedBuildToolException ( binutilsCommand
, binutilsVersion
);
804 printf ( "not detected\n" );
808 MingwBackend::DetectNetwideAssembler ()
810 printf ( "Detecting netwide assembler..." );
812 nasmCommand
= "nasm";
813 bool detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
817 nasmCommand
= "nasmw";
818 detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
823 nasmCommand
= "yasm";
824 detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
827 printf ( "detected (%s)\n", nasmCommand
.c_str () );
829 printf ( "not detected\n" );
833 MingwBackend::DetectPipeSupport ()
835 printf ( "Detecting compiler -pipe support..." );
837 string pipe_detection
= "tools" + sSep
+ "rbuild" + sSep
+ "backend" + sSep
+ "mingw" + sSep
+ "pipe_detection.c";
838 string pipe_detectionObjectFilename
= ReplaceExtension ( pipe_detection
,
840 string command
= ssprintf (
841 "%s -pipe -c %s -o %s 1>%s 2>%s",
842 FixSeparatorForSystemCommand(compilerCommand
).c_str (),
843 pipe_detection
.c_str (),
844 pipe_detectionObjectFilename
.c_str (),
847 int exitcode
= system ( command
.c_str () );
848 FILE* f
= fopen ( pipe_detectionObjectFilename
.c_str (), "rb" );
851 usePipe
= (exitcode
== 0);
853 unlink ( pipe_detectionObjectFilename
.c_str () );
859 printf ( "detected\n" );
861 printf ( "not detected\n" );
865 MingwBackend::DetectPCHSupport ()
867 printf ( "Detecting compiler pre-compiled header support..." );
869 string path
= "tools" + sSep
+ "rbuild" + sSep
+ "backend" + sSep
+ "mingw" + sSep
+ "pch_detection.h";
870 string cmd
= ssprintf (
871 "%s -c %s 1>%s 2>%s",
872 FixSeparatorForSystemCommand(compilerCommand
).c_str (),
876 system ( cmd
.c_str () );
879 FILE* f
= fopen ( path
.c_str (), "rb" );
884 unlink ( path
.c_str () );
890 printf ( "detected\n" );
892 printf ( "not detected\n" );
896 MingwBackend::GetNonModuleInstallTargetFiles (
897 vector
<string
>& out
) const
899 for ( size_t i
= 0; i
< ProjectNode
.installfiles
.size (); i
++ )
901 const InstallFile
& installfile
= *ProjectNode
.installfiles
[i
];
902 string targetFilenameNoFixup
= installfile
.base
+ sSep
+ installfile
.newname
;
903 string targetFilename
= MingwModuleHandler::PassThruCacheDirectory (
904 NormalizeFilename ( targetFilenameNoFixup
),
906 out
.push_back ( targetFilename
);
911 MingwBackend::GetModuleInstallTargetFiles (
912 vector
<string
>& out
) const
914 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
916 const Module
& module
= *ProjectNode
.modules
[i
];
917 if ( !module
.enabled
)
919 if ( module
.installName
.length () > 0 )
921 string targetFilenameNoFixup
;
922 if ( module
.installBase
.length () > 0 )
923 targetFilenameNoFixup
= module
.installBase
+ sSep
+ module
.installName
;
925 targetFilenameNoFixup
= module
.installName
;
926 string targetFilename
= MingwModuleHandler::PassThruCacheDirectory (
927 NormalizeFilename ( targetFilenameNoFixup
),
929 out
.push_back ( targetFilename
);
935 MingwBackend::GetInstallTargetFiles (
936 vector
<string
>& out
) const
938 GetNonModuleInstallTargetFiles ( out
);
939 GetModuleInstallTargetFiles ( out
);
943 MingwBackend::OutputInstallTarget ( const string
& sourceFilename
,
944 const string
& targetFilename
,
945 const string
& targetDirectory
)
947 string fullTargetFilename
;
948 if ( targetDirectory
.length () > 0)
949 fullTargetFilename
= targetDirectory
+ sSep
+ targetFilename
;
951 fullTargetFilename
= targetFilename
;
952 string normalizedTargetFilename
= MingwModuleHandler::PassThruCacheDirectory (
953 NormalizeFilename ( fullTargetFilename
),
955 string normalizedTargetDirectory
= MingwModuleHandler::PassThruCacheDirectory (
956 NormalizeFilename ( targetDirectory
),
960 normalizedTargetFilename
.c_str (),
961 sourceFilename
.c_str (),
962 normalizedTargetDirectory
.c_str () );
966 "\t${cp} %s %s 1>$(NUL)\n",
967 sourceFilename
.c_str (),
968 normalizedTargetFilename
.c_str () );
972 MingwBackend::OutputNonModuleInstallTargets ()
974 for ( size_t i
= 0; i
< ProjectNode
.installfiles
.size (); i
++ )
976 const InstallFile
& installfile
= *ProjectNode
.installfiles
[i
];
977 OutputInstallTarget ( installfile
.GetPath (),
984 MingwBackend::GetAliasedModuleOrModule ( const Module
& module
) const
986 if ( module
.aliasedModuleName
.size () > 0 )
988 const Module
* aliasedModule
= ProjectNode
.LocateModule ( module
.aliasedModuleName
);
989 assert ( aliasedModule
);
990 return *aliasedModule
;
997 MingwBackend::OutputModuleInstallTargets ()
999 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
1001 const Module
& module
= *ProjectNode
.modules
[i
];
1002 if ( !module
.enabled
)
1004 if ( module
.installName
.length () > 0 )
1006 const Module
& aliasedModule
= GetAliasedModuleOrModule ( module
);
1007 string sourceFilename
= MingwModuleHandler::PassThruCacheDirectory (
1008 NormalizeFilename ( aliasedModule
.GetPath () ),
1010 OutputInstallTarget ( sourceFilename
,
1012 module
.installBase
);
1018 MingwBackend::GetRegistrySourceFiles ()
1020 return "bootdata" + sSep
+ "hivecls.inf "
1021 "bootdata" + sSep
+ "hivedef.inf "
1022 "bootdata" + sSep
+ "hiveinst.inf "
1023 "bootdata" + sSep
+ "hivesft.inf "
1024 "bootdata" + sSep
+ "hivesys.inf";
1028 MingwBackend::GetRegistryTargetFiles ()
1030 string system32ConfigDirectory
= NormalizeFilename (
1031 MingwModuleHandler::PassThruCacheDirectory (
1032 "system32" + sSep
+ "config" + sSep
,
1033 installDirectory
) );
1034 return system32ConfigDirectory
+ sSep
+ "default " +
1035 system32ConfigDirectory
+ sSep
+ "sam " +
1036 system32ConfigDirectory
+ sSep
+ "security " +
1037 system32ConfigDirectory
+ sSep
+ "software " +
1038 system32ConfigDirectory
+ sSep
+ "system";
1042 MingwBackend::OutputRegistryInstallTarget ()
1044 string system32ConfigDirectory
= NormalizeFilename (
1045 MingwModuleHandler::PassThruCacheDirectory (
1046 "system32" + sSep
+ "config" + sSep
,
1047 installDirectory
) );
1049 string registrySourceFiles
= GetRegistrySourceFiles ();
1050 string registryTargetFiles
= GetRegistryTargetFiles ();
1051 fprintf ( fMakefile
,
1052 "install_registry: %s\n",
1053 registryTargetFiles
.c_str () );
1054 fprintf ( fMakefile
,
1055 "%s: %s %s $(MKHIVE_TARGET)\n",
1056 registryTargetFiles
.c_str (),
1057 registrySourceFiles
.c_str (),
1058 system32ConfigDirectory
.c_str () );
1059 fprintf ( fMakefile
,
1060 "\t$(ECHO_MKHIVE)\n" );
1061 fprintf ( fMakefile
,
1062 "\t$(MKHIVE_TARGET) bootdata %s bootdata%chiveinst.inf\n",
1063 system32ConfigDirectory
.c_str (),
1065 fprintf ( fMakefile
,
1070 MingwBackend::GenerateInstallTarget ()
1072 vector
<string
> vInstallTargetFiles
;
1073 GetInstallTargetFiles ( vInstallTargetFiles
);
1074 string installTargetFiles
= v2s ( vInstallTargetFiles
, 5 );
1075 string registryTargetFiles
= GetRegistryTargetFiles ();
1077 fprintf ( fMakefile
,
1079 installTargetFiles
.c_str (),
1080 registryTargetFiles
.c_str () );
1081 OutputNonModuleInstallTargets ();
1082 OutputModuleInstallTargets ();
1083 OutputRegistryInstallTarget ();
1084 fprintf ( fMakefile
,
1089 MingwBackend::GetModuleTestTargets (
1090 vector
<string
>& out
) const
1092 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
1094 const Module
& module
= *ProjectNode
.modules
[i
];
1095 if ( !module
.enabled
)
1097 if ( module
.type
== Test
)
1098 out
.push_back ( module
.name
);
1103 MingwBackend::GenerateTestTarget ()
1105 vector
<string
> vTestTargets
;
1106 GetModuleTestTargets ( vTestTargets
);
1107 string testTargets
= v2s ( vTestTargets
, 5 );
1109 fprintf ( fMakefile
,
1111 testTargets
.c_str () );
1112 fprintf ( fMakefile
,
1117 MingwBackend::GenerateDirectoryTargets ()
1119 intermediateDirectory
->CreateRule ( fMakefile
, "" );
1120 outputDirectory
->CreateRule ( fMakefile
, "" );
1121 installDirectory
->CreateRule ( fMakefile
, "" );