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 ();
240 GenerateProxyMakefiles ();
241 CheckAutomaticDependencies ();
246 MingwBackend::CreateMakefile ()
248 fMakefile
= fopen ( ProjectNode
.makefile
.c_str (), "w" );
250 throw AccessDeniedException ( ProjectNode
.makefile
);
251 MingwModuleHandler::SetBackend ( this );
252 MingwModuleHandler::SetMakefile ( fMakefile
);
256 MingwBackend::CloseMakefile () const
259 fclose ( fMakefile
);
263 MingwBackend::GenerateHeader () const
265 fprintf ( fMakefile
, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
269 MingwBackend::GenerateIncludesAndDefines ( IfableData
& data
) const
271 string includeParameters
= MingwModuleHandler::GenerateGccIncludeParametersFromVector ( data
.includes
);
272 string defineParameters
= MingwModuleHandler::GenerateGccDefineParametersFromVector ( data
.defines
);
273 return includeParameters
+ " " + defineParameters
;
277 MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation
,
278 IfableData
& data
) const
283 assignmentOperation
);
287 GenerateIncludesAndDefines ( data
).c_str() );
289 fprintf ( fMakefile
, "\n" );
293 MingwBackend::GenerateGlobalCFlagsAndProperties (
294 const char* assignmentOperation
,
295 IfableData
& data
) const
299 for ( i
= 0; i
< data
.properties
.size(); i
++ )
301 Property
& prop
= *data
.properties
[i
];
302 fprintf ( fMakefile
, "%s := %s\n",
304 prop
.value
.c_str() );
307 if ( data
.includes
.size() || data
.defines
.size() )
309 GenerateProjectCFlagsMacro ( assignmentOperation
,
313 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
315 If
& rIf
= *data
.ifs
[i
];
316 if ( rIf
.data
.defines
.size()
317 || rIf
.data
.includes
.size()
318 || rIf
.data
.ifs
.size() )
322 "ifeq (\"$(%s)\",\"%s\")\n",
323 rIf
.property
.c_str(),
325 GenerateGlobalCFlagsAndProperties (
336 MingwBackend::GenerateProjectGccOptionsMacro ( const char* assignmentOperation
,
337 IfableData
& data
) const
343 "PROJECT_GCCOPTIONS %s",
344 assignmentOperation
);
346 for ( i
= 0; i
< data
.compilerFlags
.size(); i
++ )
351 data
.compilerFlags
[i
]->flag
.c_str() );
354 fprintf ( fMakefile
, "\n" );
358 MingwBackend::GenerateProjectGccOptions (
359 const char* assignmentOperation
,
360 IfableData
& data
) const
364 if ( data
.compilerFlags
.size() )
366 GenerateProjectGccOptionsMacro ( assignmentOperation
,
370 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
372 If
& rIf
= *data
.ifs
[i
];
373 if ( rIf
.data
.compilerFlags
.size()
374 || rIf
.data
.ifs
.size() )
378 "ifeq (\"$(%s)\",\"%s\")\n",
379 rIf
.property
.c_str(),
381 GenerateProjectGccOptions (
392 MingwBackend::GenerateProjectLFLAGS () const
395 for ( size_t i
= 0; i
< ProjectNode
.linkerFlags
.size (); i
++ )
397 LinkerFlag
& linkerFlag
= *ProjectNode
.linkerFlags
[i
];
398 if ( lflags
.length () > 0 )
400 lflags
+= linkerFlag
.flag
;
406 MingwBackend::GenerateGlobalVariables () const
410 compilerPrefix
.c_str () );
413 nasmCommand
.c_str () );
415 GenerateGlobalCFlagsAndProperties ( "=", ProjectNode
.non_if_data
);
416 GenerateProjectGccOptions ( "=", ProjectNode
.non_if_data
);
418 fprintf ( fMakefile
, "PROJECT_RCFLAGS := $(PROJECT_CFLAGS)\n" );
419 fprintf ( fMakefile
, "PROJECT_WIDLFLAGS := $(PROJECT_CFLAGS)\n" );
420 fprintf ( fMakefile
, "PROJECT_LFLAGS := %s\n",
421 GenerateProjectLFLAGS ().c_str () );
422 fprintf ( fMakefile
, "PROJECT_CFLAGS += -Wall\n" );
423 fprintf ( fMakefile
, "PROJECT_CFLAGS += $(PROJECT_GCCOPTIONS)\n" );
424 fprintf ( fMakefile
, "\n" );
428 MingwBackend::IncludeInAllTarget ( const Module
& module
) const
430 if ( MingwModuleHandler::ReferenceObjects ( module
) )
432 if ( module
.type
== BootSector
)
434 if ( module
.type
== Iso
)
436 if ( module
.type
== LiveIso
)
438 if ( module
.type
== Test
)
440 if ( module
.type
== Alias
)
446 MingwBackend::GenerateAllTarget ( const vector
<MingwModuleHandler
*>& handlers
) const
448 fprintf ( fMakefile
, "all:" );
450 size_t iend
= handlers
.size ();
451 for ( size_t i
= 0; i
< iend
; i
++ )
453 const Module
& module
= handlers
[i
]->module
;
454 if ( IncludeInAllTarget ( module
) )
456 if ( wrap_count
++ == 5 )
457 fprintf ( fMakefile
, " \\\n\t\t" ), wrap_count
= 0;
460 GetTargetMacro(module
).c_str () );
463 fprintf ( fMakefile
, "\n\t\n\n" );
467 MingwBackend::GetBuildToolDependencies () const
470 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
472 Module
& module
= *ProjectNode
.modules
[i
];
473 if ( !module
.enabled
)
475 if ( module
.type
== BuildTool
)
477 if ( dependencies
.length () > 0 )
479 dependencies
+= module
.GetDependencyPath ();
486 MingwBackend::GenerateInitTarget () const
490 GetBuildToolDependencies ().c_str () );
491 fprintf ( fMakefile
, "\n" );
495 MingwBackend::GenerateRegTestsRunTarget () const
498 "REGTESTS_RUN_TARGET = regtests.dll\n" );
500 "$(REGTESTS_RUN_TARGET): $(REGTESTS_TARGET)\n" );
502 "\t$(cp) $(REGTESTS_TARGET) $(REGTESTS_RUN_TARGET)\n" );
503 fprintf ( fMakefile
, "\n" );
507 MingwBackend::GenerateXmlBuildFilesMacro() const
510 "XMLBUILDFILES = %s \\\n",
511 ProjectNode
.GetProjectFilename ().c_str () );
512 string xmlbuildFilenames
;
513 int numberOfExistingFiles
= 0;
514 for ( size_t i
= 0; i
< ProjectNode
.xmlbuildfiles
.size (); i
++ )
516 XMLInclude
& xmlbuildfile
= *ProjectNode
.xmlbuildfiles
[i
];
517 if ( !xmlbuildfile
.fileExists
)
519 numberOfExistingFiles
++;
520 if ( xmlbuildFilenames
.length () > 0 )
521 xmlbuildFilenames
+= " ";
522 xmlbuildFilenames
+= NormalizeFilename ( xmlbuildfile
.topIncludeFilename
);
523 if ( numberOfExistingFiles
% 5 == 4 || i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
527 xmlbuildFilenames
.c_str ());
528 if ( i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
530 fprintf ( fMakefile
, "\n" );
537 xmlbuildFilenames
.resize ( 0 );
539 numberOfExistingFiles
++;
541 fprintf ( fMakefile
, "\n" );
545 MingwBackend::GetBin2ResExecutable ()
547 return NormalizeFilename ( Environment::GetOutputPath () + sSep
+ "tools/bin2res/bin2res" + ExePostfix
);
551 MingwBackend::UnpackWineResources ()
553 printf ( "Unpacking WINE resources..." );
554 WineResource
wineResource ( ProjectNode
,
555 GetBin2ResExecutable () );
556 wineResource
.UnpackResources ( configuration
.Verbose
);
561 MingwBackend::GenerateTestSupportCode ()
563 printf ( "Generating test support code..." );
564 TestSupportCode
testSupportCode ( ProjectNode
);
565 testSupportCode
.GenerateTestSupportCode ( configuration
.Verbose
);
570 MingwBackend::GenerateCompilationUnitSupportCode ()
572 if ( configuration
.CompilationUnitsEnabled
)
574 printf ( "Generating compilation unit support code..." );
575 CompilationUnitSupportCode
compilationUnitSupportCode ( ProjectNode
);
576 compilationUnitSupportCode
.Generate ( configuration
.Verbose
);
582 MingwBackend::GetProxyMakefileTree () const
584 if ( configuration
.GenerateProxyMakefilesInSourceTree
)
587 return Environment::GetOutputPath ();
591 MingwBackend::GenerateProxyMakefiles ()
593 printf ( "Generating proxy makefiles..." );
594 ProxyMakefile
proxyMakefile ( ProjectNode
);
595 proxyMakefile
.GenerateProxyMakefiles ( configuration
.Verbose
,
596 GetProxyMakefileTree () );
601 MingwBackend::CheckAutomaticDependencies ()
603 if ( configuration
.AutomaticDependencies
)
605 printf ( "Checking automatic dependencies..." );
606 AutomaticDependency
automaticDependency ( ProjectNode
);
607 automaticDependency
.CheckAutomaticDependencies ( configuration
.Verbose
);
613 MingwBackend::IncludeDirectoryTarget ( const string
& directory
) const
615 if ( directory
== "$(INTERMEDIATE)" + sSep
+ "tools")
622 MingwBackend::GenerateDirectories ()
624 printf ( "Creating directories..." );
625 intermediateDirectory
->GenerateTree ( "", configuration
.Verbose
);
626 outputDirectory
->GenerateTree ( "", configuration
.Verbose
);
627 if ( !configuration
.MakeHandlesInstallDirectories
)
628 installDirectory
->GenerateTree ( "", configuration
.Verbose
);
633 MingwBackend::TryToDetectThisCompiler ( const string
& compiler
)
635 string command
= ssprintf (
637 FixSeparatorForSystemCommand(compiler
).c_str (),
640 int exitcode
= system ( command
.c_str () );
641 return (exitcode
== 0);
645 MingwBackend::DetectCompiler ()
647 printf ( "Detecting compiler..." );
649 bool detectedCompiler
= false;
650 const string
& ROS_PREFIXValue
= Environment::GetVariable ( "ROS_PREFIX" );
651 if ( ROS_PREFIXValue
.length () > 0 )
653 compilerPrefix
= ROS_PREFIXValue
;
654 compilerCommand
= compilerPrefix
+ "-gcc";
655 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
658 if ( !detectedCompiler
)
661 compilerCommand
= "gcc";
662 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
665 if ( !detectedCompiler
)
667 compilerPrefix
= "mingw32";
668 compilerCommand
= compilerPrefix
+ "-gcc";
669 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
671 if ( detectedCompiler
)
672 printf ( "detected (%s)\n", compilerCommand
.c_str () );
674 printf ( "not detected\n" );
678 MingwBackend::TryToDetectThisNetwideAssembler ( const string
& assembler
)
680 string command
= ssprintf (
682 FixSeparatorForSystemCommand(assembler
).c_str (),
685 int exitcode
= system ( command
.c_str () );
686 return (exitcode
== 0);
690 MingwBackend::TryToDetectThisBinutils ( const string
& binutils
)
692 string command
= ssprintf (
694 FixSeparatorForSystemCommand(binutils
).c_str (),
697 int exitcode
= system ( command
.c_str () );
698 return (exitcode
== 0);
702 MingwBackend::GetBinutilsVersion ( const string
& binutilsCommand
)
708 string versionCommand
= ssprintf ( "%s -v",
709 binutilsCommand
.c_str (),
712 fp
= popen ( versionCommand
.c_str () , "r" );
715 ( feof ( fp
) == 0 &&
716 ( ( ch
= fgetc( fp
) ) != -1 ) );
719 buffer
[i
] = (char) ch
;
724 char separators
[] = " ";
726 char *prevtoken
= NULL
;
728 token
= strtok ( buffer
, separators
);
729 while ( token
!= NULL
)
732 token
= strtok ( NULL
, separators
);
734 string version
= string ( prevtoken
);
735 int lastDigit
= version
.find_last_not_of ( "\t\r\n" );
736 if ( lastDigit
!= -1 )
737 return string ( version
, 0, lastDigit
+1 );
743 MingwBackend::IsSupportedBinutilsVersion ( const string
& binutilsVersion
)
745 if ( ( ( strcmp ( binutilsVersion
.c_str (), "20040902") >= 0 ) &&
746 ( strcmp ( binutilsVersion
.c_str (), "20041008") <= 0 ) ) ||
747 ( strcmp ( binutilsVersion
.c_str (), "20031001") < 0 ) )
754 MingwBackend::DetectBinutils ()
756 printf ( "Detecting binutils..." );
758 bool detectedBinutils
= false;
759 const string
& ROS_PREFIXValue
= Environment::GetVariable ( "ROS_PREFIX" );
760 if ( ROS_PREFIXValue
.length () > 0 )
762 binutilsPrefix
= ROS_PREFIXValue
;
763 binutilsCommand
= binutilsPrefix
+ "-ld";
764 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
767 if ( !detectedBinutils
)
770 binutilsCommand
= "ld";
771 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
774 if ( !detectedBinutils
)
776 binutilsPrefix
= "mingw32";
777 binutilsCommand
= binutilsPrefix
+ "-ld";
778 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
780 if ( detectedBinutils
)
782 string binutilsVersion
= GetBinutilsVersion ( binutilsCommand
);
783 if ( IsSupportedBinutilsVersion ( binutilsVersion
) )
784 printf ( "detected (%s)\n", binutilsCommand
.c_str () );
787 printf ( "detected (%s), but with unsupported version (%s)\n",
788 binutilsCommand
.c_str (),
789 binutilsVersion
.c_str () );
790 throw UnsupportedBuildToolException ( binutilsCommand
, binutilsVersion
);
794 printf ( "not detected\n" );
798 MingwBackend::DetectNetwideAssembler ()
800 printf ( "Detecting netwide assembler..." );
802 nasmCommand
= "nasm";
803 bool detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
807 nasmCommand
= "nasmw";
808 detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
813 nasmCommand
= "yasm";
814 detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
817 printf ( "detected (%s)\n", nasmCommand
.c_str () );
819 printf ( "not detected\n" );
823 MingwBackend::DetectPipeSupport ()
825 printf ( "Detecting compiler -pipe support..." );
827 string pipe_detection
= "tools" + sSep
+ "rbuild" + sSep
+ "backend" + sSep
+ "mingw" + sSep
+ "pipe_detection.c";
828 string pipe_detectionObjectFilename
= ReplaceExtension ( pipe_detection
,
830 string command
= ssprintf (
831 "%s -pipe -c %s -o %s 1>%s 2>%s",
832 FixSeparatorForSystemCommand(compilerCommand
).c_str (),
833 pipe_detection
.c_str (),
834 pipe_detectionObjectFilename
.c_str (),
837 int exitcode
= system ( command
.c_str () );
838 FILE* f
= fopen ( pipe_detectionObjectFilename
.c_str (), "rb" );
841 usePipe
= (exitcode
== 0);
843 unlink ( pipe_detectionObjectFilename
.c_str () );
849 printf ( "detected\n" );
851 printf ( "not detected\n" );
855 MingwBackend::DetectPCHSupport ()
857 printf ( "Detecting compiler pre-compiled header support..." );
859 string path
= "tools" + sSep
+ "rbuild" + sSep
+ "backend" + sSep
+ "mingw" + sSep
+ "pch_detection.h";
860 string cmd
= ssprintf (
861 "%s -c %s 1>%s 2>%s",
862 FixSeparatorForSystemCommand(compilerCommand
).c_str (),
866 system ( cmd
.c_str () );
869 FILE* f
= fopen ( path
.c_str (), "rb" );
874 unlink ( path
.c_str () );
880 printf ( "detected\n" );
882 printf ( "not detected\n" );
886 MingwBackend::GetNonModuleInstallTargetFiles (
887 vector
<string
>& out
) const
889 for ( size_t i
= 0; i
< ProjectNode
.installfiles
.size (); i
++ )
891 const InstallFile
& installfile
= *ProjectNode
.installfiles
[i
];
892 string targetFilenameNoFixup
= installfile
.base
+ sSep
+ installfile
.newname
;
893 string targetFilename
= MingwModuleHandler::PassThruCacheDirectory (
894 NormalizeFilename ( targetFilenameNoFixup
),
896 out
.push_back ( targetFilename
);
901 MingwBackend::GetModuleInstallTargetFiles (
902 vector
<string
>& out
) const
904 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
906 const Module
& module
= *ProjectNode
.modules
[i
];
907 if ( !module
.enabled
)
909 if ( module
.installName
.length () > 0 )
911 string targetFilenameNoFixup
;
912 if ( module
.installBase
.length () > 0 )
913 targetFilenameNoFixup
= module
.installBase
+ sSep
+ module
.installName
;
915 targetFilenameNoFixup
= module
.installName
;
916 string targetFilename
= MingwModuleHandler::PassThruCacheDirectory (
917 NormalizeFilename ( targetFilenameNoFixup
),
919 out
.push_back ( targetFilename
);
925 MingwBackend::GetInstallTargetFiles (
926 vector
<string
>& out
) const
928 GetNonModuleInstallTargetFiles ( out
);
929 GetModuleInstallTargetFiles ( out
);
933 MingwBackend::OutputInstallTarget ( const string
& sourceFilename
,
934 const string
& targetFilename
,
935 const string
& targetDirectory
)
937 string fullTargetFilename
;
938 if ( targetDirectory
.length () > 0)
939 fullTargetFilename
= targetDirectory
+ sSep
+ targetFilename
;
941 fullTargetFilename
= targetFilename
;
942 string normalizedTargetFilename
= MingwModuleHandler::PassThruCacheDirectory (
943 NormalizeFilename ( fullTargetFilename
),
945 string normalizedTargetDirectory
= MingwModuleHandler::PassThruCacheDirectory (
946 NormalizeFilename ( targetDirectory
),
950 normalizedTargetFilename
.c_str (),
951 sourceFilename
.c_str (),
952 normalizedTargetDirectory
.c_str () );
956 "\t${cp} %s %s 1>$(NUL)\n",
957 sourceFilename
.c_str (),
958 normalizedTargetFilename
.c_str () );
962 MingwBackend::OutputNonModuleInstallTargets ()
964 for ( size_t i
= 0; i
< ProjectNode
.installfiles
.size (); i
++ )
966 const InstallFile
& installfile
= *ProjectNode
.installfiles
[i
];
967 OutputInstallTarget ( installfile
.GetPath (),
974 MingwBackend::GetAliasedModuleOrModule ( const Module
& module
) const
976 if ( module
.aliasedModuleName
.size () > 0 )
978 const Module
* aliasedModule
= ProjectNode
.LocateModule ( module
.aliasedModuleName
);
979 assert ( aliasedModule
);
980 return *aliasedModule
;
987 MingwBackend::OutputModuleInstallTargets ()
989 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
991 const Module
& module
= *ProjectNode
.modules
[i
];
992 if ( !module
.enabled
)
994 if ( module
.installName
.length () > 0 )
996 const Module
& aliasedModule
= GetAliasedModuleOrModule ( module
);
997 string sourceFilename
= MingwModuleHandler::PassThruCacheDirectory (
998 NormalizeFilename ( aliasedModule
.GetPath () ),
1000 OutputInstallTarget ( sourceFilename
,
1002 module
.installBase
);
1008 MingwBackend::GetRegistrySourceFiles ()
1010 return "bootdata" + sSep
+ "hivecls.inf "
1011 "bootdata" + sSep
+ "hivedef.inf "
1012 "bootdata" + sSep
+ "hiveinst.inf "
1013 "bootdata" + sSep
+ "hivesft.inf "
1014 "bootdata" + sSep
+ "hivesys.inf";
1018 MingwBackend::GetRegistryTargetFiles ()
1020 string system32ConfigDirectory
= NormalizeFilename (
1021 MingwModuleHandler::PassThruCacheDirectory (
1022 "system32" + sSep
+ "config" + sSep
,
1023 installDirectory
) );
1024 return system32ConfigDirectory
+ sSep
+ "default " +
1025 system32ConfigDirectory
+ sSep
+ "sam " +
1026 system32ConfigDirectory
+ sSep
+ "security " +
1027 system32ConfigDirectory
+ sSep
+ "software " +
1028 system32ConfigDirectory
+ sSep
+ "system";
1032 MingwBackend::OutputRegistryInstallTarget ()
1034 string system32ConfigDirectory
= NormalizeFilename (
1035 MingwModuleHandler::PassThruCacheDirectory (
1036 "system32" + sSep
+ "config" + sSep
,
1037 installDirectory
) );
1039 string registrySourceFiles
= GetRegistrySourceFiles ();
1040 string registryTargetFiles
= GetRegistryTargetFiles ();
1041 fprintf ( fMakefile
,
1042 "install_registry: %s\n",
1043 registryTargetFiles
.c_str () );
1044 fprintf ( fMakefile
,
1045 "%s: %s %s $(MKHIVE_TARGET)\n",
1046 registryTargetFiles
.c_str (),
1047 registrySourceFiles
.c_str (),
1048 system32ConfigDirectory
.c_str () );
1049 fprintf ( fMakefile
,
1050 "\t$(ECHO_MKHIVE)\n" );
1051 fprintf ( fMakefile
,
1052 "\t$(MKHIVE_TARGET) bootdata %s bootdata%chiveinst.inf\n",
1053 system32ConfigDirectory
.c_str (),
1055 fprintf ( fMakefile
,
1060 MingwBackend::GenerateInstallTarget ()
1062 vector
<string
> vInstallTargetFiles
;
1063 GetInstallTargetFiles ( vInstallTargetFiles
);
1064 string installTargetFiles
= v2s ( vInstallTargetFiles
, 5 );
1065 string registryTargetFiles
= GetRegistryTargetFiles ();
1067 fprintf ( fMakefile
,
1069 installTargetFiles
.c_str (),
1070 registryTargetFiles
.c_str () );
1071 OutputNonModuleInstallTargets ();
1072 OutputModuleInstallTargets ();
1073 OutputRegistryInstallTarget ();
1074 fprintf ( fMakefile
,
1079 MingwBackend::GetModuleTestTargets (
1080 vector
<string
>& out
) const
1082 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
1084 const Module
& module
= *ProjectNode
.modules
[i
];
1085 if ( !module
.enabled
)
1087 if ( module
.type
== Test
)
1088 out
.push_back ( module
.name
);
1093 MingwBackend::GenerateTestTarget ()
1095 vector
<string
> vTestTargets
;
1096 GetModuleTestTargets ( vTestTargets
);
1097 string testTargets
= v2s ( vTestTargets
, 5 );
1099 fprintf ( fMakefile
,
1101 testTargets
.c_str () );
1102 fprintf ( fMakefile
,
1107 MingwBackend::GenerateDirectoryTargets ()
1109 intermediateDirectory
->CreateRule ( fMakefile
, "" );
1110 outputDirectory
->CreateRule ( fMakefile
, "" );
1111 installDirectory
->CreateRule ( fMakefile
, "" );