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"
24 #define pclose _pclose
28 #include "modulehandler.h"
31 #define MKDIR(s) mkdir(s)
33 #define MKDIR(s) mkdir(s, 0755)
41 typedef set
<string
> set_string
;
45 v2s ( const string_list
& v
, int wrap_at
)
51 for ( size_t i
= 0; i
< v
.size(); i
++ )
55 if ( wrap_at
> 0 && wrap_count
++ == wrap_at
)
65 Directory::Directory ( const string
& name_
)
71 Directory::Add ( const char* subdir
)
74 string s1
= string ( subdir
);
75 if ( ( i
= s1
.find ( '$' ) ) != string::npos
)
77 throw InvalidOperationException ( __FILE__
,
79 "No environment variables can be used here. Path was %s",
83 const char* p
= strpbrk ( subdir
, "/\\" );
85 p
= subdir
+ strlen(subdir
);
86 string
s ( subdir
, p
-subdir
);
87 if ( subdirs
.find(s
) == subdirs
.end() )
88 subdirs
[s
] = new Directory(s
);
90 subdirs
[s
]->Add ( p
);
94 Directory::mkdir_p ( const char* path
)
98 directory
= opendir ( path
);
99 if ( directory
!= NULL
)
101 closedir ( directory
);
106 if ( MKDIR ( path
) != 0 )
109 if ( errno
== EEXIST
)
112 throw AccessDeniedException ( string ( path
) );
118 Directory::CreateDirectory ( string path
)
122 if ( isalpha ( path
[0] ) && path
[1] == ':' && path
[2] == CSEP
)
124 nextIndex
= path
.find ( CSEP
, 3);
127 nextIndex
= path
.find ( CSEP
);
129 bool directoryWasCreated
= false;
130 while ( nextIndex
!= string::npos
)
132 nextIndex
= path
.find ( CSEP
, index
+ 1 );
133 directoryWasCreated
= mkdir_p ( path
.substr ( 0, nextIndex
).c_str () );
136 return directoryWasCreated
;
140 Directory::ReplaceVariable ( string name
,
144 size_t i
= path
.find ( name
);
145 if ( i
!= string::npos
)
146 return path
.replace ( i
, name
.length (), value
);
152 Directory::ResolveVariablesInPath ( char* buf
,
155 string s
= ReplaceVariable ( "$(INTERMEDIATE)", Environment::GetIntermediatePath (), path
);
156 s
= ReplaceVariable ( "$(OUTPUT)", Environment::GetOutputPath (), s
);
157 s
= ReplaceVariable ( "$(INSTALL)", Environment::GetInstallPath (), s
);
158 strcpy ( buf
, s
.c_str () );
162 Directory::GenerateTree ( const string
& parent
,
167 if ( parent
.size () > 0 )
171 path
= parent
+ SSEP
+ name
;
172 ResolveVariablesInPath ( buf
, path
);
173 if ( CreateDirectory ( buf
) && verbose
)
174 printf ( "Created %s\n", buf
);
179 for ( directory_map::iterator i
= subdirs
.begin ();
183 i
->second
->GenerateTree ( path
, verbose
);
188 Directory::EscapeSpaces ( string path
)
195 newpath
= newpath
+ "\\ ";
197 newpath
= newpath
+ *p
;
204 Directory::CreateRule ( FILE* f
,
205 const string
& parent
)
209 if ( parent
.size() > 0 )
211 string escapedParent
= EscapeSpaces ( parent
);
214 escapedParent
.c_str (),
216 EscapeSpaces ( name
).c_str (),
217 escapedParent
.c_str () );
220 "\t$(ECHO_MKDIR)\n" );
225 path
= parent
+ SSEP
+ name
;
230 for ( directory_map::iterator i
= subdirs
.begin();
234 i
->second
->CreateRule ( f
, path
);
239 static class MingwFactory
: public Backend::Factory
242 MingwFactory() : Factory ( "mingw" ) {}
243 Backend
* operator() ( Project
& project
,
244 Configuration
& configuration
)
246 return new MingwBackend ( project
,
252 MingwBackend::MingwBackend ( Project
& project
,
253 Configuration
& configuration
)
254 : Backend ( project
, configuration
),
255 intermediateDirectory ( new Directory ("$(INTERMEDIATE)" ) ),
256 outputDirectory ( new Directory ( "$(OUTPUT)" ) ),
257 installDirectory ( new Directory ( "$(INSTALL)" ) )
262 MingwBackend::~MingwBackend()
264 delete intermediateDirectory
;
265 delete outputDirectory
;
266 delete installDirectory
;
270 MingwBackend::AddDirectoryTarget ( const string
& directory
,
271 Directory
* directoryTree
)
273 if ( directory
.length () > 0)
274 directoryTree
->Add ( directory
.c_str() );
275 return directoryTree
->name
;
279 MingwBackend::ProcessModules ()
281 printf ( "Processing modules..." );
283 vector
<MingwModuleHandler
*> v
;
285 for ( i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
287 Module
& module
= *ProjectNode
.modules
[i
];
288 if ( !module
.enabled
)
290 MingwModuleHandler
* h
= MingwModuleHandler::InstanciateHandler (
293 if ( module
.host
== HostDefault
)
295 module
.host
= h
->DefaultHost();
296 assert ( module
.host
!= HostDefault
);
301 size_t iend
= v
.size ();
303 for ( i
= 0; i
< iend
; i
++ )
304 v
[i
]->GenerateObjectMacro();
305 fprintf ( fMakefile
, "\n" );
306 for ( i
= 0; i
< iend
; i
++ )
307 v
[i
]->GenerateTargetMacro();
308 fprintf ( fMakefile
, "\n" );
310 GenerateAllTarget ( v
);
311 GenerateInitTarget ();
312 GenerateRegTestsRunTarget ();
314 for ( i
= 0; i
< iend
; i
++ )
315 v
[i
]->GenerateOtherMacros();
317 for ( i
= 0; i
< iend
; i
++ )
319 MingwModuleHandler
& h
= *v
[i
];
320 h
.GeneratePreconditionDependencies ();
322 h
.GenerateInvocations ();
323 h
.GenerateCleanTarget ();
324 h
.GenerateInstallTarget ();
325 h
.GenerateDependsTarget ();
333 MingwBackend::Process ()
335 if ( configuration
.CheckDependenciesForModuleOnly
)
336 CheckAutomaticDependenciesForModuleOnly ();
342 MingwBackend::CheckAutomaticDependenciesForModuleOnly ()
344 if ( configuration
.AutomaticDependencies
)
346 Module
* module
= ProjectNode
.LocateModule ( configuration
.CheckDependenciesForModuleOnlyModule
);
347 if ( module
== NULL
)
349 printf ( "Module '%s' does not exist\n",
350 configuration
.CheckDependenciesForModuleOnlyModule
.c_str () );
354 printf ( "Checking automatic dependencies for module '%s'...",
355 module
->name
.c_str () );
356 AutomaticDependency
automaticDependency ( ProjectNode
);
357 automaticDependency
.CheckAutomaticDependenciesForModule ( *module
,
358 configuration
.Verbose
);
364 MingwBackend::ProcessNormal ()
368 DetectNetwideAssembler ();
369 DetectPipeSupport ();
373 GenerateGlobalVariables ();
374 GenerateXmlBuildFilesMacro ();
376 GenerateInstallTarget ();
377 GenerateTestTarget ();
378 GenerateDirectoryTargets ();
379 GenerateDirectories ();
380 UnpackWineResources ();
381 GenerateTestSupportCode ();
382 GenerateProxyMakefiles ();
383 CheckAutomaticDependencies ();
388 MingwBackend::CreateMakefile ()
390 fMakefile
= fopen ( ProjectNode
.makefile
.c_str (), "w" );
392 throw AccessDeniedException ( ProjectNode
.makefile
);
393 MingwModuleHandler::SetBackend ( this );
394 MingwModuleHandler::SetMakefile ( fMakefile
);
395 MingwModuleHandler::SetUsePch ( use_pch
);
399 MingwBackend::CloseMakefile () const
402 fclose ( fMakefile
);
406 MingwBackend::GenerateHeader () const
408 fprintf ( fMakefile
, "# THIS FILE IS AUTOMATICALLY GENERATED, EDIT 'ReactOS.xml' INSTEAD\n\n" );
412 MingwBackend::GenerateIncludesAndDefines ( IfableData
& data
) const
414 string includeParameters
= MingwModuleHandler::GenerateGccIncludeParametersFromVector ( data
.includes
);
415 string defineParameters
= MingwModuleHandler::GenerateGccDefineParametersFromVector ( data
.defines
);
416 return includeParameters
+ " " + defineParameters
;
420 MingwBackend::GenerateProjectCFlagsMacro ( const char* assignmentOperation
,
421 IfableData
& data
) const
426 assignmentOperation
);
430 GenerateIncludesAndDefines ( data
).c_str() );
432 fprintf ( fMakefile
, "\n" );
436 MingwBackend::GenerateGlobalCFlagsAndProperties (
437 const char* assignmentOperation
,
438 IfableData
& data
) const
442 for ( i
= 0; i
< data
.properties
.size(); i
++ )
444 Property
& prop
= *data
.properties
[i
];
445 fprintf ( fMakefile
, "%s := %s\n",
447 prop
.value
.c_str() );
450 if ( data
.includes
.size() || data
.defines
.size() )
452 GenerateProjectCFlagsMacro ( assignmentOperation
,
456 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
458 If
& rIf
= *data
.ifs
[i
];
459 if ( rIf
.data
.defines
.size()
460 || rIf
.data
.includes
.size()
461 || rIf
.data
.ifs
.size() )
465 "ifeq (\"$(%s)\",\"%s\")\n",
466 rIf
.property
.c_str(),
468 GenerateGlobalCFlagsAndProperties (
479 MingwBackend::GenerateProjectGccOptionsMacro ( const char* assignmentOperation
,
480 IfableData
& data
) const
486 "PROJECT_GCCOPTIONS %s",
487 assignmentOperation
);
489 for ( i
= 0; i
< data
.compilerFlags
.size(); i
++ )
494 data
.compilerFlags
[i
]->flag
.c_str() );
497 fprintf ( fMakefile
, "\n" );
501 MingwBackend::GenerateProjectGccOptions (
502 const char* assignmentOperation
,
503 IfableData
& data
) const
507 if ( data
.compilerFlags
.size() )
509 GenerateProjectGccOptionsMacro ( assignmentOperation
,
513 for ( i
= 0; i
< data
.ifs
.size(); i
++ )
515 If
& rIf
= *data
.ifs
[i
];
516 if ( rIf
.data
.compilerFlags
.size()
517 || rIf
.data
.ifs
.size() )
521 "ifeq (\"$(%s)\",\"%s\")\n",
522 rIf
.property
.c_str(),
524 GenerateProjectGccOptions (
535 MingwBackend::GenerateProjectLFLAGS () const
538 for ( size_t i
= 0; i
< ProjectNode
.linkerFlags
.size (); i
++ )
540 LinkerFlag
& linkerFlag
= *ProjectNode
.linkerFlags
[i
];
541 if ( lflags
.length () > 0 )
543 lflags
+= linkerFlag
.flag
;
549 MingwBackend::GenerateGlobalVariables () const
553 compilerPrefix
.c_str () );
556 nasmCommand
.c_str () );
558 GenerateGlobalCFlagsAndProperties ( "=", ProjectNode
.non_if_data
);
559 GenerateProjectGccOptions ( "=", ProjectNode
.non_if_data
);
561 fprintf ( fMakefile
, "PROJECT_RCFLAGS := $(PROJECT_CFLAGS)\n" );
562 fprintf ( fMakefile
, "PROJECT_WIDLFLAGS := $(PROJECT_CFLAGS)\n" );
563 fprintf ( fMakefile
, "PROJECT_LFLAGS := %s\n",
564 GenerateProjectLFLAGS ().c_str () );
565 fprintf ( fMakefile
, "PROJECT_CFLAGS += -Wall\n" );
566 fprintf ( fMakefile
, "PROJECT_CFLAGS += $(PROJECT_GCCOPTIONS)\n" );
567 fprintf ( fMakefile
, "\n" );
571 MingwBackend::IncludeInAllTarget ( const Module
& module
) const
573 if ( MingwModuleHandler::ReferenceObjects ( module
) )
575 if ( module
.type
== BootSector
)
577 if ( module
.type
== Iso
)
579 if ( module
.type
== LiveIso
)
581 if ( module
.type
== Test
)
583 if ( module
.type
== Alias
)
589 MingwBackend::GenerateAllTarget ( const vector
<MingwModuleHandler
*>& handlers
) const
591 fprintf ( fMakefile
, "all:" );
593 size_t iend
= handlers
.size ();
594 for ( size_t i
= 0; i
< iend
; i
++ )
596 const Module
& module
= handlers
[i
]->module
;
597 if ( IncludeInAllTarget ( module
) )
599 if ( wrap_count
++ == 5 )
600 fprintf ( fMakefile
, " \\\n\t\t" ), wrap_count
= 0;
603 GetTargetMacro(module
).c_str () );
606 fprintf ( fMakefile
, "\n\t\n\n" );
610 MingwBackend::GetBuildToolDependencies () const
613 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
615 Module
& module
= *ProjectNode
.modules
[i
];
616 if ( !module
.enabled
)
618 if ( module
.type
== BuildTool
)
620 if ( dependencies
.length () > 0 )
622 dependencies
+= module
.GetDependencyPath ();
629 MingwBackend::GenerateInitTarget () const
633 GetBuildToolDependencies ().c_str () );
634 fprintf ( fMakefile
, "\n" );
638 MingwBackend::GenerateRegTestsRunTarget () const
641 "REGTESTS_RUN_TARGET = regtests.dll\n" );
643 "$(REGTESTS_RUN_TARGET): $(REGTESTS_TARGET)\n" );
645 "\t$(cp) $(REGTESTS_TARGET) $(REGTESTS_RUN_TARGET)\n" );
646 fprintf ( fMakefile
, "\n" );
650 MingwBackend::GenerateXmlBuildFilesMacro() const
653 "XMLBUILDFILES = %s \\\n",
654 ProjectNode
.GetProjectFilename ().c_str () );
655 string xmlbuildFilenames
;
656 int numberOfExistingFiles
= 0;
657 for ( size_t i
= 0; i
< ProjectNode
.xmlbuildfiles
.size (); i
++ )
659 XMLInclude
& xmlbuildfile
= *ProjectNode
.xmlbuildfiles
[i
];
660 if ( !xmlbuildfile
.fileExists
)
662 numberOfExistingFiles
++;
663 if ( xmlbuildFilenames
.length () > 0 )
664 xmlbuildFilenames
+= " ";
665 xmlbuildFilenames
+= NormalizeFilename ( xmlbuildfile
.topIncludeFilename
);
666 if ( numberOfExistingFiles
% 5 == 4 || i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
670 xmlbuildFilenames
.c_str ());
671 if ( i
== ProjectNode
.xmlbuildfiles
.size () - 1 )
673 fprintf ( fMakefile
, "\n" );
680 xmlbuildFilenames
.resize ( 0 );
682 numberOfExistingFiles
++;
684 fprintf ( fMakefile
, "\n" );
688 MingwBackend::GetBin2ResExecutable ()
690 return NormalizeFilename ( Environment::GetOutputPath () + SSEP
+ "tools/bin2res/bin2res" + EXEPOSTFIX
);
694 MingwBackend::UnpackWineResources ()
696 printf ( "Unpacking WINE resources..." );
697 WineResource
wineResource ( ProjectNode
,
698 GetBin2ResExecutable () );
699 wineResource
.UnpackResources ( configuration
.Verbose
);
704 MingwBackend::GenerateTestSupportCode ()
706 printf ( "Generating test support code..." );
707 TestSupportCode
testSupportCode ( ProjectNode
);
708 testSupportCode
.GenerateTestSupportCode ( configuration
.Verbose
);
713 MingwBackend::GetProxyMakefileTree () const
715 if ( configuration
.GenerateProxyMakefilesInSourceTree
)
718 return Environment::GetOutputPath ();
722 MingwBackend::GenerateProxyMakefiles ()
724 printf ( "Generating proxy makefiles..." );
725 ProxyMakefile
proxyMakefile ( ProjectNode
);
726 proxyMakefile
.GenerateProxyMakefiles ( configuration
.Verbose
,
727 GetProxyMakefileTree () );
732 MingwBackend::CheckAutomaticDependencies ()
734 if ( configuration
.AutomaticDependencies
)
736 printf ( "Checking automatic dependencies..." );
737 AutomaticDependency
automaticDependency ( ProjectNode
);
738 automaticDependency
.CheckAutomaticDependencies ( configuration
.Verbose
);
744 MingwBackend::IncludeDirectoryTarget ( const string
& directory
) const
746 if ( directory
== "$(INTERMEDIATE)" SSEP
"tools")
753 MingwBackend::GenerateDirectories ()
755 printf ( "Creating directories..." );
756 intermediateDirectory
->GenerateTree ( "", configuration
.Verbose
);
757 outputDirectory
->GenerateTree ( "", configuration
.Verbose
);
758 if ( !configuration
.MakeHandlesInstallDirectories
)
759 installDirectory
->GenerateTree ( "", configuration
.Verbose
);
764 MingwBackend::TryToDetectThisCompiler ( const string
& compiler
)
766 string command
= ssprintf (
771 int exitcode
= system ( command
.c_str () );
772 return (exitcode
== 0);
776 MingwBackend::DetectCompiler ()
778 printf ( "Detecting compiler..." );
780 bool detectedCompiler
= false;
781 const string
& ROS_PREFIXValue
= Environment::GetVariable ( "ROS_PREFIX" );
782 if ( ROS_PREFIXValue
.length () > 0 )
784 compilerPrefix
= ROS_PREFIXValue
;
785 compilerCommand
= compilerPrefix
+ "-gcc";
786 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
789 if ( !detectedCompiler
)
792 compilerCommand
= "gcc";
793 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
796 if ( !detectedCompiler
)
798 compilerPrefix
= "mingw32";
799 compilerCommand
= compilerPrefix
+ "-gcc";
800 detectedCompiler
= TryToDetectThisCompiler ( compilerCommand
);
802 if ( detectedCompiler
)
803 printf ( "detected (%s)\n", compilerCommand
.c_str () );
805 printf ( "not detected\n" );
809 MingwBackend::TryToDetectThisNetwideAssembler ( const string
& assembler
)
811 string command
= ssprintf (
816 int exitcode
= system ( command
.c_str () );
817 return (exitcode
== 0);
821 MingwBackend::TryToDetectThisBinutils ( const string
& binutils
)
823 string command
= ssprintf (
828 int exitcode
= system ( command
.c_str () );
829 return (exitcode
== 0);
833 MingwBackend::GetBinutilsVersion ( const string
& binutilsCommand
)
839 string versionCommand
= ssprintf ( "%s -v",
840 binutilsCommand
.c_str (),
843 fp
= popen ( versionCommand
.c_str () , "r" );
846 ( feof ( fp
) == 0 &&
847 ( ( ch
= fgetc( fp
) ) != -1 ) );
850 buffer
[i
] = (char) ch
;
855 char separators
[] = " ";
859 token
= strtok ( buffer
, separators
);
860 while ( token
!= NULL
)
863 token
= strtok ( NULL
, separators
);
865 string version
= string ( prevtoken
);
866 int lastDigit
= version
.find_last_not_of ( "\t\r\n" );
867 if ( lastDigit
!= -1 )
868 return string ( version
, 0, lastDigit
+1 );
874 MingwBackend::IsSupportedBinutilsVersion ( const string
& binutilsVersion
)
876 if ( ( ( strcmp ( binutilsVersion
.c_str (), "20040902") >= 0 ) &&
877 ( strcmp ( binutilsVersion
.c_str (), "20041008") <= 0 ) ) ||
878 ( strcmp ( binutilsVersion
.c_str (), "20031001") < 0 ) )
885 MingwBackend::DetectBinutils ()
887 printf ( "Detecting binutils..." );
889 bool detectedBinutils
= false;
890 const string
& ROS_PREFIXValue
= Environment::GetVariable ( "ROS_PREFIX" );
891 if ( ROS_PREFIXValue
.length () > 0 )
893 binutilsPrefix
= ROS_PREFIXValue
;
894 binutilsCommand
= binutilsPrefix
+ "-ld";
895 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
898 if ( !detectedBinutils
)
901 binutilsCommand
= "ld";
902 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
905 if ( !detectedBinutils
)
907 binutilsPrefix
= "mingw32";
908 binutilsCommand
= binutilsPrefix
+ "-ld";
909 detectedBinutils
= TryToDetectThisBinutils ( binutilsCommand
);
911 if ( detectedBinutils
)
913 string binutilsVersion
= GetBinutilsVersion ( binutilsCommand
);
914 if ( IsSupportedBinutilsVersion ( binutilsVersion
) )
915 printf ( "detected (%s)\n", binutilsCommand
.c_str () );
918 printf ( "detected (%s), but with unsupported version (%s)\n",
919 binutilsCommand
.c_str (),
920 binutilsVersion
.c_str () );
921 throw UnsupportedBuildToolException ( binutilsCommand
, binutilsVersion
);
925 printf ( "not detected\n" );
929 MingwBackend::DetectNetwideAssembler ()
931 printf ( "Detecting netwide assembler..." );
933 nasmCommand
= "nasm";
934 bool detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
938 nasmCommand
= "nasmw";
939 detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
944 nasmCommand
= "yasm";
945 detectedNasm
= TryToDetectThisNetwideAssembler ( nasmCommand
);
948 printf ( "detected (%s)\n", nasmCommand
.c_str () );
950 printf ( "not detected\n" );
954 MingwBackend::DetectPipeSupport ()
956 printf ( "Detecting compiler -pipe support..." );
958 string pipe_detection
= "tools" SSEP
"rbuild" SSEP
"backend" SSEP
"mingw" SSEP
"pipe_detection.c";
959 string pipe_detectionObjectFilename
= ReplaceExtension ( pipe_detection
,
961 string command
= ssprintf (
962 "%s -pipe -c %s -o %s 1>%s 2>%s",
963 compilerCommand
.c_str (),
964 pipe_detection
.c_str (),
965 pipe_detectionObjectFilename
.c_str (),
968 int exitcode
= system ( command
.c_str () );
969 FILE* f
= fopen ( pipe_detectionObjectFilename
.c_str (), "rb" );
972 usePipe
= (exitcode
== 0);
974 unlink ( pipe_detectionObjectFilename
.c_str () );
980 printf ( "detected\n" );
982 printf ( "not detected\n" );
986 MingwBackend::DetectPCHSupport ()
988 printf ( "Detecting compiler pre-compiled header support..." );
990 string path
= "tools" SSEP
"rbuild" SSEP
"backend" SSEP
"mingw" SSEP
"pch_detection.h";
991 string cmd
= ssprintf (
992 "%s -c %s 1>%s 2>%s",
993 compilerCommand
.c_str (),
997 system ( cmd
.c_str () );
1000 FILE* f
= fopen ( path
.c_str (), "rb" );
1005 unlink ( path
.c_str () );
1011 printf ( "detected\n" );
1013 printf ( "not detected\n" );
1017 MingwBackend::GetNonModuleInstallTargetFiles (
1018 vector
<string
>& out
) const
1020 for ( size_t i
= 0; i
< ProjectNode
.installfiles
.size (); i
++ )
1022 const InstallFile
& installfile
= *ProjectNode
.installfiles
[i
];
1023 string targetFilenameNoFixup
= installfile
.base
+ SSEP
+ installfile
.newname
;
1024 string targetFilename
= MingwModuleHandler::PassThruCacheDirectory (
1025 NormalizeFilename ( targetFilenameNoFixup
),
1027 out
.push_back ( targetFilename
);
1032 MingwBackend::GetModuleInstallTargetFiles (
1033 vector
<string
>& out
) const
1035 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
1037 const Module
& module
= *ProjectNode
.modules
[i
];
1038 if ( !module
.enabled
)
1040 if ( module
.installName
.length () > 0 )
1042 string targetFilenameNoFixup
;
1043 if ( module
.installBase
.length () > 0 )
1044 targetFilenameNoFixup
= module
.installBase
+ SSEP
+ module
.installName
;
1046 targetFilenameNoFixup
= module
.installName
;
1047 string targetFilename
= MingwModuleHandler::PassThruCacheDirectory (
1048 NormalizeFilename ( targetFilenameNoFixup
),
1050 out
.push_back ( targetFilename
);
1056 MingwBackend::GetInstallTargetFiles (
1057 vector
<string
>& out
) const
1059 GetNonModuleInstallTargetFiles ( out
);
1060 GetModuleInstallTargetFiles ( out
);
1064 MingwBackend::OutputInstallTarget ( const string
& sourceFilename
,
1065 const string
& targetFilename
,
1066 const string
& targetDirectory
)
1068 string fullTargetFilename
;
1069 if ( targetDirectory
.length () > 0)
1070 fullTargetFilename
= targetDirectory
+ SSEP
+ targetFilename
;
1072 fullTargetFilename
= targetFilename
;
1073 string normalizedTargetFilename
= MingwModuleHandler::PassThruCacheDirectory (
1074 NormalizeFilename ( fullTargetFilename
),
1076 string normalizedTargetDirectory
= MingwModuleHandler::PassThruCacheDirectory (
1077 NormalizeFilename ( targetDirectory
),
1079 fprintf ( fMakefile
,
1081 normalizedTargetFilename
.c_str (),
1082 sourceFilename
.c_str (),
1083 normalizedTargetDirectory
.c_str () );
1084 fprintf ( fMakefile
,
1086 fprintf ( fMakefile
,
1087 "\t${cp} %s %s 1>$(NUL)\n",
1088 sourceFilename
.c_str (),
1089 normalizedTargetFilename
.c_str () );
1093 MingwBackend::OutputNonModuleInstallTargets ()
1095 for ( size_t i
= 0; i
< ProjectNode
.installfiles
.size (); i
++ )
1097 const InstallFile
& installfile
= *ProjectNode
.installfiles
[i
];
1098 OutputInstallTarget ( installfile
.GetPath (),
1099 installfile
.newname
,
1105 MingwBackend::GetAliasedModuleOrModule ( const Module
& module
) const
1107 if ( module
.aliasedModuleName
.size () > 0 )
1109 const Module
* aliasedModule
= ProjectNode
.LocateModule ( module
.aliasedModuleName
);
1110 assert ( aliasedModule
);
1111 return *aliasedModule
;
1118 MingwBackend::OutputModuleInstallTargets ()
1120 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
1122 const Module
& module
= *ProjectNode
.modules
[i
];
1123 if ( !module
.enabled
)
1125 if ( module
.installName
.length () > 0 )
1127 const Module
& aliasedModule
= GetAliasedModuleOrModule ( module
);
1128 string sourceFilename
= MingwModuleHandler::PassThruCacheDirectory (
1129 NormalizeFilename ( aliasedModule
.GetPath () ),
1131 OutputInstallTarget ( sourceFilename
,
1133 module
.installBase
);
1139 MingwBackend::GetRegistrySourceFiles ()
1141 return "bootdata" SSEP
"hivecls.inf "
1142 "bootdata" SSEP
"hivedef.inf "
1143 "bootdata" SSEP
"hiveinst.inf "
1144 "bootdata" SSEP
"hivesft.inf "
1145 "bootdata" SSEP
"hivesys.inf";
1149 MingwBackend::GetRegistryTargetFiles ()
1151 string system32ConfigDirectory
= NormalizeFilename (
1152 MingwModuleHandler::PassThruCacheDirectory (
1153 "system32" SSEP
"config" SSEP
,
1154 installDirectory
) );
1155 return system32ConfigDirectory
+ SSEP
"default " +
1156 system32ConfigDirectory
+ SSEP
"sam " +
1157 system32ConfigDirectory
+ SSEP
"security " +
1158 system32ConfigDirectory
+ SSEP
"software " +
1159 system32ConfigDirectory
+ SSEP
"system";
1163 MingwBackend::OutputRegistryInstallTarget ()
1165 string system32ConfigDirectory
= NormalizeFilename (
1166 MingwModuleHandler::PassThruCacheDirectory (
1167 "system32" SSEP
"config" SSEP
,
1168 installDirectory
) );
1170 string registrySourceFiles
= GetRegistrySourceFiles ();
1171 string registryTargetFiles
= GetRegistryTargetFiles ();
1172 fprintf ( fMakefile
,
1173 "install_registry: %s\n",
1174 registryTargetFiles
.c_str () );
1175 fprintf ( fMakefile
,
1176 "%s: %s %s $(MKHIVE_TARGET)\n",
1177 registryTargetFiles
.c_str (),
1178 registrySourceFiles
.c_str (),
1179 system32ConfigDirectory
.c_str () );
1180 fprintf ( fMakefile
,
1181 "\t$(ECHO_MKHIVE)\n" );
1182 fprintf ( fMakefile
,
1183 "\t$(MKHIVE_TARGET) bootdata %s bootdata" SSEP
"hiveinst.inf\n",
1184 system32ConfigDirectory
.c_str () );
1185 fprintf ( fMakefile
,
1190 MingwBackend::GenerateInstallTarget ()
1192 vector
<string
> vInstallTargetFiles
;
1193 GetInstallTargetFiles ( vInstallTargetFiles
);
1194 string installTargetFiles
= v2s ( vInstallTargetFiles
, 5 );
1195 string registryTargetFiles
= GetRegistryTargetFiles ();
1197 fprintf ( fMakefile
,
1199 installTargetFiles
.c_str (),
1200 registryTargetFiles
.c_str () );
1201 OutputNonModuleInstallTargets ();
1202 OutputModuleInstallTargets ();
1203 OutputRegistryInstallTarget ();
1204 fprintf ( fMakefile
,
1209 MingwBackend::GetModuleTestTargets (
1210 vector
<string
>& out
) const
1212 for ( size_t i
= 0; i
< ProjectNode
.modules
.size (); i
++ )
1214 const Module
& module
= *ProjectNode
.modules
[i
];
1215 if ( !module
.enabled
)
1217 if ( module
.type
== Test
)
1218 out
.push_back ( module
.name
);
1223 MingwBackend::GenerateTestTarget ()
1225 vector
<string
> vTestTargets
;
1226 GetModuleTestTargets ( vTestTargets
);
1227 string testTargets
= v2s ( vTestTargets
, 5 );
1229 fprintf ( fMakefile
,
1231 testTargets
.c_str () );
1232 fprintf ( fMakefile
,
1237 MingwBackend::GenerateDirectoryTargets ()
1239 intermediateDirectory
->CreateRule ( fMakefile
, "" );
1240 outputDirectory
->CreateRule ( fMakefile
, "" );
1241 installDirectory
->CreateRule ( fMakefile
, "" );