Changed the uses of EdkLogger
[people/mcb30/basetools.git] / Source / Python / AutoGen / GenMake.py
1 ## @file\r
2 # Create makefile for MS nmake and GNU make\r
3 #\r
4 # Copyright (c) 2007, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
6 # are licensed and made available under the terms and conditions of the BSD License\r
7 # which accompanies this distribution.  The full text of the license may be found at\r
8 # http://opensource.org/licenses/bsd-license.php\r
9 #\r
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 #\r
13 \r
14 ## Import Modules\r
15 #\r
16 import os\r
17 import sys\r
18 import string\r
19 import re\r
20 import os.path as path\r
21 \r
22 from Common.EdkIIWorkspaceBuild import *\r
23 from Common.EdkIIWorkspace import *\r
24 from Common.BuildToolError import *\r
25 from Common.Misc import *\r
26 from BuildInfo import *\r
27 from BuildEngine import *\r
28 \r
29 gIncludePattern = re.compile("^[ #]*include[ ]+[\"<]*([^\"< >]+)[>\" ]*$", re.MULTILINE | re.UNICODE)\r
30 gMacroPattern = re.compile("[_A-Z][_A-Z0-9]*\(.+\)", re.UNICODE)\r
31 \r
32 gMakefileHeader = '''#\r
33 # DO NOT EDIT\r
34 # This file is auto-generated by build utility\r
35 #\r
36 # Module Name:\r
37 #\r
38 #   %s\r
39 #\r
40 # Abstract:\r
41 #\r
42 #   Auto-generated makefile for building modules and libraries\r
43 #\r
44 '''\r
45 \r
46 gLibraryMakeCommand = '''cd %(makedir)s\r
47 \t$(MAKE) $(MAKE_FLAGS) %(target)s\r
48 \tcd $(MODULE_BUILD_DIR)'''\r
49 \r
50 gMakeType = ""\r
51 if sys.platform == "win32":\r
52     gMakeType = "nmake"\r
53 else:\r
54     gMakeType = "gmake"\r
55 \r
56 gMakefileName = {"nmake" : "Makefile", "gmake" : "GNUmakefile"}\r
57 \r
58 gDirectorySeparator = {"nmake" : "\\", "gmake" : "/"}\r
59 \r
60 gCreateDirectoryCommand = {"nmake" : "mkdir", "gmake" : "mkdir -p"}\r
61 gRemoveDirectoryCommand = {"nmake" : "rmdir /s /q", "gmake" : "rm -r -f"}\r
62 gRemoveFileCommand = {"nmake" : "del /f /q", "gmake" : "rm -f"}\r
63 gCopyFileCommand = {"nmake" : "copy /y", "gmake" : "cp -f"}\r
64 gCreateDirectoryCommandTemplate = {"nmake" : 'if not exist %(dir)s mkdir %(dir)s',\r
65                                    "gmake" : "test ! -e %(dir)s && mkdir -p %(dir)s"}\r
66 gRemoveDirectoryCommandTemplate = {"nmake" : 'if exist %(dir)s rmdir /s /q %(dir)s',\r
67                                    "gmake" : "test -e %(dir)s && rm -r -f %(dir)s"}\r
68 \r
69 #   $(CP)     copy file command\r
70 #   $(MV)     move file command\r
71 #   $(RM)     remove file command\r
72 #   $(MD)     create dir command\r
73 #   $(RD)     remove dir command\r
74 #\r
75 #   $(TCP)     copy file if destination file doesn't exist\r
76 #   $(TMV)     move file if destination file doesn't exist\r
77 #   $(TRM)     remove file if destination file exists\r
78 #   $(TMD)     create dir if destination dir doesn't exist\r
79 #   $(TRD)     remove dir if destination dir exists\r
80 gShellCommand = {\r
81     "nmake" : {\r
82         "CP"    :   "copy /y",\r
83         "MV"    :   "move /y",\r
84         "RM"    :   "del /f /q",\r
85         "MD"    :   "mkdir",\r
86         "RD"    :   "rmdir /s /q",\r
87     },\r
88 \r
89     "gmake" : {\r
90         "CP"    :   "cp -f",\r
91         "MV"    :   "mv -f",\r
92         "RM"    :   "rm -f",\r
93         "MD"    :   "mkdir -p",\r
94         "RD"    :   "rm -r -f",\r
95     }\r
96 }\r
97 gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
98 \r
99 gStartGroupFlag = {"MSFT" : "", "GCC" : "-(", "INTEL" : ""}\r
100 gEndGroupFlag = {"MSFT" : "", "GCC" : "-)", "INTEL" : ""}\r
101 \r
102 gCustomMakefileTemplate = '''\r
103 ${makefile_header}\r
104 \r
105 #\r
106 # Platform Macro Definition\r
107 #\r
108 PLATFORM_NAME = ${platform_name}\r
109 PLATFORM_GUID = ${platform_guid}\r
110 PLATFORM_VERSION = ${platform_version}\r
111 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
112 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
113 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
114 \r
115 #\r
116 # Module Macro Definition\r
117 #\r
118 MODULE_NAME = ${module_name}\r
119 MODULE_GUID = ${module_guid}\r
120 MODULE_VERSION = ${module_version}\r
121 MODULE_TYPE = ${module_type}\r
122 MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
123 BASE_NAME = $(MODULE_NAME)\r
124 MODULE_RELATIVE_DIR = ${module_relative_directory}\r
125 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}\r
126 \r
127 #\r
128 # Build Configuration Macro Definition\r
129 #\r
130 ARCH = ${architecture}\r
131 TOOLCHAIN_TAG = ${toolchain_tag}\r
132 TARGET = ${build_target}\r
133 \r
134 #\r
135 # Build Directory Macro Definition\r
136 #\r
137 PLATFORM_BUILD_DIR = ${platform_build_directory}\r
138 BUILD_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}\r
139 BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
140 LIB_DIR = $(BIN_DIR)\r
141 MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}\r
142 OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT\r
143 DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG\r
144 DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
145 DEST_DIR_DEBUG = $(DEBUG_DIR)\r
146 \r
147 #\r
148 # Default Tools Flags Macro Definition (from tools_def.txt by default)\r
149 #\r
150 ${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}\r
151 ${END}\r
152 \r
153 #\r
154 # Platform Tools Flags Macro Definition (from platform description file)\r
155 #\r
156 ${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}\r
157 ${END}\r
158 \r
159 #\r
160 # Platform Tools Flags Macro Definition (from platform description file)\r
161 #\r
162 ${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}\r
163 ${END}\r
164 \r
165 #\r
166 # ToolsFlagMacro\r
167 #\r
168 ${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)\r
169 ${END}\r
170 MAKE_FLAGS = /nologo\r
171 \r
172 #\r
173 # ToolsPathMacro\r
174 #\r
175 ${BEGIN}${tool_code} = ${tool_path}\r
176 ${END}\r
177 \r
178 ${custom_makefile_content}\r
179 \r
180 #\r
181 # Target used when called from platform makefile, which will bypass the build of dependent libraries\r
182 #\r
183 \r
184 pbuild: init all\r
185 \r
186 \r
187 #\r
188 # Target used for library build, which will bypass the build of dependent libraries\r
189 #\r
190 \r
191 lbuild: init all\r
192 \r
193 \r
194 #\r
195 # ModuleTarget\r
196 #\r
197 \r
198 mbuild: init all\r
199 \r
200 \r
201 #\r
202 # Initialization target: print build information and create necessary directories\r
203 #\r
204 init:\r
205 \t-@echo Building ... $(MODULE_NAME) $(MODULE_VERSION) [$(ARCH)] in platform $(PLATFORM_NAME) $(PLATFORM_VERSION)\r
206 \t${BEGIN}@${create_directory_command}\r
207 \t${END}\r
208 \r
209 '''\r
210 \r
211 gModuleMakefileTemplate = '''\r
212 ${makefile_header}\r
213 \r
214 #\r
215 # Platform Macro Definition\r
216 #\r
217 PLATFORM_NAME = ${platform_name}\r
218 PLATFORM_GUID = ${platform_guid}\r
219 PLATFORM_VERSION = ${platform_version}\r
220 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
221 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
222 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
223 \r
224 #\r
225 # Module Macro Definition\r
226 #\r
227 MODULE_NAME = ${module_name}\r
228 MODULE_GUID = ${module_guid}\r
229 MODULE_VERSION = ${module_version}\r
230 MODULE_TYPE = ${module_type}\r
231 MODULE_FILE_BASE_NAME = ${module_file_base_name}\r
232 BASE_NAME = $(MODULE_NAME)\r
233 MODULE_RELATIVE_DIR = ${module_relative_directory}\r
234 MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}\r
235 \r
236 #\r
237 # Build Configuration Macro Definition\r
238 #\r
239 ARCH = ${architecture}\r
240 TOOLCHAIN_TAG = ${toolchain_tag}\r
241 TARGET = ${build_target}\r
242 \r
243 #\r
244 # Build Directory Macro Definition\r
245 #\r
246 PLATFORM_BUILD_DIR = ${platform_build_directory}\r
247 BUILD_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}\r
248 BIN_DIR = $(BUILD_DIR)${separator}${architecture}\r
249 LIB_DIR = $(BIN_DIR)\r
250 MODULE_BUILD_DIR = $(BUILD_DIR)${separator}${architecture}${separator}${module_relative_directory}${separator}${module_file_base_name}\r
251 OUTPUT_DIR = $(MODULE_BUILD_DIR)${separator}OUTPUT\r
252 DEBUG_DIR = $(MODULE_BUILD_DIR)${separator}DEBUG\r
253 DEST_DIR_OUTPUT = $(OUTPUT_DIR)\r
254 DEST_DIR_DEBUG = $(DEBUG_DIR)\r
255 \r
256 #\r
257 # Default Tools Flags Macro Definition (from tools_def.txt by default)\r
258 #\r
259 ${BEGIN}DEFAULT_${tool_code}_FLAGS = ${default_tool_flags}\r
260 ${END}\r
261 \r
262 #\r
263 # Platform Tools Flags Macro Definition (from platform description file)\r
264 #\r
265 ${BEGIN}PLATFORM_${tool_code}_FLAGS = ${platform_tool_flags}\r
266 ${END}\r
267 \r
268 #\r
269 # Module Tools Flags Macro Definition (from platform/module description file)\r
270 #\r
271 ${BEGIN}MODULE_${tool_code}_FLAGS = ${module_tool_flags}\r
272 ${END}\r
273 \r
274 #\r
275 # Tools Flag Macro\r
276 #\r
277 ${BEGIN}${tool_code}_FLAGS = $(DEFAULT_${tool_code}_FLAGS) $(PLATFORM_${tool_code}_FLAGS) $(MODULE_${tool_code}_FLAGS)\r
278 ${END}\r
279 MAKE_FLAGS = /nologo\r
280 \r
281 #\r
282 # Tools Path Macro\r
283 #\r
284 ${BEGIN}${tool_code} = ${tool_path}\r
285 ${END}\r
286 \r
287 #\r
288 # Shell Command Macro\r
289 #\r
290 ${BEGIN}${shell_command_code} = ${shell_command}\r
291 ${END}\r
292 \r
293 #\r
294 # Build Macro\r
295 #\r
296 ${BEGIN}${source_file_macro}\r
297 ${END}\r
298 \r
299 ${BEGIN}${target_file_macro}\r
300 ${END}\r
301 \r
302 SOURCE_FILES = ${BEGIN}${source_file_macro_name} ${END}\r
303 \r
304 TARGET_FILES = ${BEGIN}${target_file_macro_name} ${END}\r
305 \r
306 INC = ${BEGIN}${include_path_prefix}$(WORKSPACE)${separator}${include_path} \\\r
307       ${END}\r
308 \r
309 #OBJECTS = ${BEGIN}$(OUTPUT_DIR)${separator}${object_file} \\\r
310 #          ${END}\r
311 \r
312 LIBS = ${BEGIN}$(BUILD_DIR)${separator}$(ARCH)${separator}${library_file} \\\r
313        ${END}${BEGIN}${system_library} \\\r
314        ${END}\r
315 \r
316 COMMON_DEPS = ${BEGIN}$(WORKSPACE)${separator}${common_dependency_file} \\\r
317               ${END}\r
318 \r
319 ENTRYPOINT = ${module_entry_point}\r
320 \r
321 #\r
322 # Overridable Target Macro Definitions\r
323 #\r
324 INIT_TARGET = init\r
325 PCH_TARGET =\r
326 CODA_TARGET = ${BEGIN}${remaining_build_target} \\\r
327               ${END}\r
328 \r
329 #\r
330 # Default target, which will build dependent libraries in addition to source files\r
331 #\r
332 \r
333 all: ${build_type}\r
334 \r
335 \r
336 #\r
337 # Target used when called from platform makefile, which will bypass the build of dependent libraries\r
338 #\r
339 \r
340 pbuild: $(INIT_TARGET) $(PCH_TARGET) $(CODA_TARGET)\r
341 \r
342 #\r
343 # ModuleTarget\r
344 #\r
345 \r
346 mbuild: $(INIT_TARGET) gen_libs $(PCH_TARGET) $(CODA_TARGET)\r
347 \r
348 \r
349 #\r
350 # Target to update the FD\r
351 #\r
352 \r
353 fds: mbuild gen_fds\r
354 \r
355 #\r
356 # Initialization target: print build information and create necessary directories\r
357 #\r
358 init:\r
359 \t-@echo Building ... $(MODULE_NAME) $(MODULE_VERSION) [$(ARCH)] in platform $(PLATFORM_NAME) $(PLATFORM_VERSION)\r
360 \t${BEGIN}@${create_directory_command}\r
361 \t${END}\r
362 \r
363 #\r
364 # GenLibsTarget\r
365 #\r
366 gen_libs:\r
367 \t${BEGIN}cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory}\r
368 \t$(MAKE) $(MAKE_FLAGS)\r
369 \t${END}cd $(MODULE_BUILD_DIR)\r
370 \r
371 #\r
372 # Build Flash Device Image\r
373 #\r
374 gen_fds:\r
375 \tcd $(BUILD_DIR)\r
376 \t$(MAKE) $(MAKE_FLAGS) fds\r
377 \tcd $(MODULE_BUILD_DIR)\r
378 \r
379 #\r
380 # Individual Object Build Targets\r
381 #\r
382 ${BEGIN}${file_build_target}\r
383 ${END}\r
384 \r
385 \r
386 #\r
387 # clean all intermediate files\r
388 #\r
389 \r
390 clean:\r
391 \t${BEGIN}${clean_command}\r
392 \t${END}\r
393 \r
394 #\r
395 # clean all generated files\r
396 #\r
397 \r
398 cleanall:\r
399 \t${BEGIN}${cleanall_command}\r
400 \t${END}${remove_file_command} *.pdb *.idb > NUL 2>&1\r
401 \r
402 #\r
403 # clean pre-compiled header files\r
404 #\r
405 \r
406 cleanpch:\r
407 \t${remove_file_command} $(OUTPUT_DIR)\*.pch > NUL 2>&1\r
408 \r
409 #\r
410 # clean all dependent libraries built\r
411 #\r
412 \r
413 cleanlib:\r
414 \t${BEGIN}cd $(BUILD_DIR)${separator}$(ARCH)${separator}${dependent_library_build_directory}\r
415 \t$(MAKE) $(MAKE_FLAGS) cleanall\r
416 \t${END}cd $(MODULE_BUILD_DIR)\r
417 \r
418 '''\r
419 \r
420 gPlatformMakefileTemplate = '''\r
421 ${makefile_header}\r
422 \r
423 #\r
424 # Platform Macro Definition\r
425 #\r
426 PLATFORM_NAME = ${platform_name}\r
427 PLATFORM_GUID = ${platform_guid}\r
428 PLATFORM_VERSION = ${platform_version}\r
429 PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
430 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
431 \r
432 #\r
433 # Build Configuration Macro Definition\r
434 #\r
435 TOOLCHAIN_TAG = ${toolchain_tag}\r
436 TARGET = ${build_target}\r
437 MAKE_FLAGS = /nologo\r
438 \r
439 #\r
440 # Build Directory Macro Definition\r
441 #\r
442 BUILD_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}\r
443 FV_DIR = ${platform_build_directory}${separator}${build_target}_${toolchain_tag}${separator}FV\r
444 \r
445 #\r
446 # Default target\r
447 #\r
448 all: init build_libraries build_modules build_fds\r
449 \r
450 #\r
451 # Initialization target: print build information and create necessary directories\r
452 #\r
453 init:\r
454 \t-@echo Building ... $(PLATFORM_NAME) $(PLATFORM_VERSION) [${build_architecture_list}]\r
455 \t${BEGIN}@${create_directory_command}\r
456 \t${END}\r
457 #\r
458 # library build target\r
459 #\r
460 libraries: init build_libraries\r
461 \r
462 #\r
463 # module build target\r
464 #\r
465 modules: init build_libraries build_modules\r
466 \r
467 #\r
468 # Flash Device Image Target\r
469 #\r
470 fds: init build_fds\r
471 \r
472 #\r
473 # Build all libraries:\r
474 #\r
475 build_libraries:\r
476 \t${BEGIN}cd $(WORKSPACE)${separator}${library_build_directory}\r
477 \t$(MAKE) $(MAKE_FLAGS) pbuild\r
478 \t${END}cd $(BUILD_DIR)\r
479 \r
480 #\r
481 # Build all modules:\r
482 #\r
483 build_modules:\r
484 \t${BEGIN}cd $(WORKSPACE)${separator}${module_build_directory}\r
485 \t$(MAKE) $(MAKE_FLAGS) pbuild\r
486 \t${END}cd $(BUILD_DIR)\r
487 \r
488 #\r
489 # Build Flash Device Image\r
490 #\r
491 build_fds:\r
492 \t-@echo Generating flash image, if any ...\r
493 ${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -p ${active_platform} -a ${build_architecture_list}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}\r
494 \r
495 #\r
496 # run command for emulator platform only\r
497 #\r
498 run:\r
499 \tcd $(BUILD_DIR)${separator}IA32\r
500 \tSecMain\r
501 \tcd $(BUILD_DIR)\r
502 \r
503 #\r
504 # Clean intermediate files\r
505 #\r
506 clean:\r
507 \t${BEGIN}cd $(WORKSPACE)${separator}${library_build_directory}\r
508 \t$(MAKE) $(MAKE_FLAGS) clean\r
509 \t${END}${BEGIN}cd $(WORKSPACE)${separator}${module_build_directory}\r
510 \t$(MAKE) $(MAKE_FLAGS) clean\r
511 \t${END}cd $(BUILD_DIR)\r
512 \r
513 #\r
514 # Clean all generated files except to makefile\r
515 #\r
516 cleanall:\r
517 \t${BEGIN}${cleanall_command}\r
518 \t${END}\r
519 \r
520 #\r
521 # Clean all library files\r
522 #\r
523 cleanlib:\r
524 \t${BEGIN}cd $(WORKSPACE)${separator}${library_build_directory}\r
525 \t$(MAKE) $(MAKE_FLAGS) cleanall\r
526 \t${END}cd $(BUILD_DIR)\r
527 \r
528 '''\r
529 \r
530 class Makefile(object):\r
531     def __init__(self, Info, Option=None):\r
532         if isinstance(Info, ModuleBuildInfo):\r
533             if Info == None or Info == "":\r
534                 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No valid module found! Please check your build configuration!\n")\r
535             self.ModuleInfo = Info\r
536             self.PlatformInfo = Info.PlatformInfo\r
537             self.ModuleBuild = True\r
538 \r
539             self.BuildType = "mbuild"\r
540             self.BuildFileList = []\r
541             self.TargetFileList = []\r
542             self.ObjectFileList = []\r
543             self.ObjectBuildTargetList = []\r
544 \r
545             self.FileDependency = []\r
546             self.LibraryBuildCommandList = []\r
547             self.LibraryFileList = []\r
548             self.LibraryMakefileList = []\r
549             self.LibraryBuildDirectoryList = []\r
550             self.SystemLibraryList = []\r
551 \r
552         elif type(Info) == type({}):    # and isinstance(info, PlatformBuildInfo):\r
553             if len(Info) <= 0:\r
554                 EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No buildable platform found! Please check your build configuration!\n")\r
555             self.PlatformInfo = Info\r
556             self.ModuleBuild = False\r
557             self.ModuleBuildCommandList = []\r
558             self.ModuleMakefileList = []\r
559             self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()\r
560             self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()\r
561         else:\r
562             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Non-buildable item:%s" % str(Info))\r
563 \r
564         #self.Opt = Option\r
565         #self.BuildWithPch = Option["ENABLE_PCH"]\r
566         #self.BuildWithLocalLib = Option["ENABLE_LOCAL_LIB"]\r
567         self.IntermediateDirectoryList = []\r
568 \r
569     def PrepareDirectory(self):\r
570         if self.ModuleBuild:\r
571             CreateDirectory(path.join(self.ModuleInfo.WorkspaceDir, self.PlatformInfo.BuildDir))\r
572             CreateDirectory(path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.BuildDir))\r
573             CreateDirectory(path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.DebugDir))\r
574 \r
575     def Generate(self, File=None, MakeType=gMakeType):\r
576         if self.ModuleBuild:\r
577             return self.GenerateModuleMakefile(File, MakeType)\r
578         else:\r
579             return self.GeneratePlatformMakefile(File, MakeType)\r
580 \r
581     def GeneratePlatformMakefile(self, File=None, MakeType=gMakeType):\r
582         Separator = gDirectorySeparator[MakeType]\r
583 \r
584         ArchList = self.PlatformInfo.keys()\r
585         PlatformInfo = self.PlatformInfo.values()[0]\r
586         ActivePlatform = PlatformInfo.Platform\r
587 \r
588         OutputDir = PlatformInfo.OutputDir\r
589         if os.path.isabs(OutputDir):\r
590             self.PlatformBuildDirectory = OutputDir\r
591             CreateDirectory(self.PlatformBuildDirectory)\r
592         else:\r
593             self.PlatformBuildDirectory = "$(WORKSPACE)" + Separator + OutputDir\r
594             CreateDirectory(os.path.join(PlatformInfo.WorkspaceDir, OutputDir))\r
595 \r
596 \r
597         self.IntermediateDirectoryList = ["$(BUILD_DIR)%s%s" % (Separator, Arch) for Arch in self.PlatformInfo]\r
598         self.IntermediateDirectoryList.append("$(FV_DIR)")\r
599 \r
600         # TRICK: for not generating GenFds call in makefile if no FDF file\r
601         if PlatformInfo.FdfFile != None and PlatformInfo.FdfFile != "":\r
602             FdfFileList = [PlatformInfo.FdfFile]\r
603         else:\r
604             FdfFileList = []\r
605 \r
606         MakefileName = gMakefileName[MakeType]\r
607         MakefileTemplateDict = {\r
608             "makefile_header"           : gMakefileHeader % MakefileName,\r
609             "platform_name"             : PlatformInfo.Name,\r
610             "platform_guid"             : PlatformInfo.Guid,\r
611             "platform_version"          : PlatformInfo.Version,\r
612             "platform_relative_directory": PlatformInfo.SourceDir,\r
613             "platform_output_directory" : PlatformInfo.OutputDir,\r
614             "platform_build_directory"  : self.PlatformBuildDirectory,\r
615 \r
616             "toolchain_tag"             : PlatformInfo.ToolChain,\r
617             "build_target"              : PlatformInfo.BuildTarget,\r
618             "build_architecture_list"   : ",".join(ArchList),\r
619             "architecture"              : self.PlatformInfo.keys(),\r
620             "separator"                 : Separator,\r
621             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
622             "remove_directory_command"  : gRemoveDirectoryCommand[MakeType],\r
623             "remove_file_command"       : gRemoveFileCommand[MakeType],\r
624             "cleanall_command"          : self.GetRemoveDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
625             "library_build_directory"   : self.LibraryBuildDirectoryList,\r
626             "module_build_directory"    : self.ModuleBuildDirectoryList,\r
627             "fdf_file"                  : FdfFileList,\r
628             "active_platform"           : PlatformInfo.WorkspaceDir + Separator + ActivePlatform.DescFilePath,\r
629             "fd"                        : PlatformInfo.FdTargetList,\r
630             "fv"                        : PlatformInfo.FvTargetList\r
631         }\r
632 \r
633         self.PrepareDirectory()\r
634 \r
635         AutoGenMakefile = TemplateString()\r
636         AutoGenMakefile.Append(gPlatformMakefileTemplate, MakefileTemplateDict)\r
637 \r
638         FilePath = ""\r
639         if File == None:\r
640             FilePath = path.join(PlatformInfo.WorkspaceDir, PlatformInfo.MakeFileDir, MakefileName)\r
641         else:\r
642             FilePath = File\r
643 \r
644         return SaveFileOnChange(FilePath, str(AutoGenMakefile))\r
645 \r
646     def GenerateModuleMakefile(self, File=None, MakeType=gMakeType):\r
647         if MakeType in self.ModuleInfo.CustomMakefile and self.ModuleInfo.CustomMakefile[MakeType] != "":\r
648             return self.GenerateCustomBuildMakefile(File, MakeType)\r
649 \r
650         Separator = gDirectorySeparator[MakeType]\r
651         PlatformInfo = self.PlatformInfo\r
652 \r
653         if os.path.isabs(PlatformInfo.OutputDir):\r
654             self.PlatformBuildDirectory = PlatformInfo.OutputDir\r
655         else:\r
656             self.PlatformBuildDirectory = "$(WORKSPACE)" + Separator + PlatformInfo.OutputDir\r
657 \r
658         self.ProcessSourceFileList(MakeType)\r
659         self.ProcessDependentLibrary(MakeType)\r
660 \r
661         if "DLINK" in PlatformInfo.ToolStaticLib:\r
662             EdkLogger.debug(EdkLogger.DEBUG_5, "Static library: " + PlatformInfo.ToolStaticLib["DLINK"])\r
663             self.SystemLibraryList.append(PlatformInfo.ToolStaticLib["DLINK"])\r
664 \r
665         EntryPoint = "_ModuleEntryPoint"\r
666         if self.ModuleInfo.Arch == "EBC":\r
667             EntryPoint = "EfiStart"\r
668 \r
669         DefaultToolFlag = PlatformInfo.ToolOption.values()\r
670         if self.ModuleInfo.ModuleType == "USER_DEFINED":\r
671             DefaultToolFlag = ["" for p in DefaultToolFlag]\r
672 \r
673         if "CC" not in PlatformInfo.ToolChainFamily:\r
674             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not supported [%s, %s, %s]" % (self.ModuleInfo.BuildTarget,\r
675                                     self.ModuleInfo.ToolChain, self.ModuleInfo.Arch))\r
676         if  "DLINK" not in PlatformInfo.ToolChainFamily:\r
677             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [DLINK] is not supported [%s, %s, %s]" % (self.ModuleInfo.BuildTarget,\r
678                                     self.ModuleInfo.ToolChain, self.ModuleInfo.Arch))\r
679 \r
680         if self.ModuleInfo.IsLibrary:\r
681             self.ResultFileList = self.DestFileDatabase["Static-Library-File"]\r
682         #elif self.BuildType == "obj":\r
683         #    ResultFile = ""\r
684         elif self.ModuleInfo.ModuleType == "USER_DEFINED":\r
685             self.ResultFileList = self.DestFileDatabase["Dynamic-Library-File"]\r
686             #ResultFile = "$(LLIB_FILE) $(DLL_FILE)"\r
687         #else:\r
688         #    ResultFile = "$(LLIB_FILE) $(DLL_FILE) $(EFI_FILE)"\r
689 \r
690         SourceFileMacroNameList = []\r
691         SourceFileMacroList = [] # macro name = file list\r
692         for FileType in self.SourceFileDatabase:\r
693             Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
694             SourceFileMacroNameList.append("$(%s)" % Macro)\r
695             Template = TemplateString()\r
696             Template.Append("%s = ${BEGIN}${source_file} \\\n\t${END}" % Macro,\r
697                             {"source_file" : self.SourceFileDatabase[FileType]})\r
698             SourceFileMacroList.append(str(Template))\r
699         TargetFileMacroList = []\r
700         TargetFileMacroNameList = []\r
701         for FileType in self.DestFileDatabase:\r
702             Macro = "%s_LIST" % FileType.replace("-", "_").upper()\r
703             TargetFileMacroNameList.append("$(%s)" % Macro)\r
704             Template = TemplateString()\r
705             Template.Append("%s = ${BEGIN}${target_file} \\\n\t${END}" % Macro,\r
706                             {"target_file" : self.DestFileDatabase[FileType]})\r
707             TargetFileMacroList.append(str(Template))\r
708 \r
709         MakefileName = gMakefileName[MakeType]\r
710         MakefileTemplateDict = {\r
711             "makefile_header"           : gMakefileHeader % MakefileName,\r
712             "platform_name"             : PlatformInfo.Name,\r
713             "platform_guid"             : PlatformInfo.Guid,\r
714             "platform_version"          : PlatformInfo.Version,\r
715             "platform_relative_directory": PlatformInfo.SourceDir,\r
716             "platform_output_directory" : PlatformInfo.OutputDir,\r
717 \r
718             "module_name"               : self.ModuleInfo.Name,\r
719             "module_guid"               : self.ModuleInfo.Guid,\r
720             "module_version"            : self.ModuleInfo.Version,\r
721             "module_type"               : self.ModuleInfo.ModuleType,\r
722             "module_file_base_name"     : self.ModuleInfo.FileBase,\r
723             "module_relative_directory" : self.ModuleInfo.SourceDir,\r
724 \r
725             "architecture"              : self.ModuleInfo.Arch,\r
726             "toolchain_tag"             : self.ModuleInfo.ToolChain,\r
727             "build_target"              : self.ModuleInfo.BuildTarget,\r
728 \r
729             "platform_build_directory"  : self.PlatformBuildDirectory,\r
730 \r
731             "separator"                 : Separator,\r
732             "default_tool_flags"        : DefaultToolFlag,\r
733             "platform_tool_flags"       : [PlatformInfo.BuildOption[tool] for tool in PlatformInfo.ToolPath],\r
734             "module_tool_flags"         : [self.ModuleInfo.BuildOption[tool] for tool in PlatformInfo.ToolPath],\r
735 \r
736             "tool_code"                 : PlatformInfo.ToolPath.keys(),\r
737             "tool_path"                 : PlatformInfo.ToolPath.values(),\r
738 \r
739             "shell_command_code"        : gShellCommand[MakeType].keys(),\r
740             "shell_command"             : gShellCommand[MakeType].values(),\r
741 \r
742             "module_entry_point"        : EntryPoint,\r
743             #"auto_generated_file"       : self.AutoGenBuildFileList,\r
744             "include_path_prefix"       : gIncludeFlag[PlatformInfo.ToolChainFamily["CC"]],\r
745             "dlink_output_flag"         : PlatformInfo.OutputFlag["DLINK"],\r
746             "slink_output_flag"         : PlatformInfo.OutputFlag["SLINK"],\r
747             "start_group_flag"          : gStartGroupFlag[PlatformInfo.ToolChainFamily["DLINK"]],\r
748             "end_group_flag"            : gEndGroupFlag[PlatformInfo.ToolChainFamily["DLINK"]],\r
749             "include_path"              : self.ModuleInfo.IncludePathList,\r
750             "target_file"               : self.TargetFileList,\r
751             "object_file"               : self.ObjectFileList,\r
752             "library_file"              : self.LibraryFileList,\r
753             "remaining_build_target"    : self.ResultFileList,\r
754             "system_library"            : self.SystemLibraryList,\r
755             "common_dependency_file"    : self.CommonFileDependency,\r
756             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
757             "remove_directory_command"  : gRemoveDirectoryCommand[MakeType],\r
758             "remove_file_command"       : gRemoveFileCommand[MakeType],\r
759             "copy_file_command"         : gCopyFileCommand[MakeType],\r
760             "clean_command"             : self.GetRemoveDirectoryCommand(["$(OUTPUT_DIR)"], MakeType),\r
761             "cleanall_command"          : self.GetRemoveDirectoryCommand(["$(DEBUG_DIR)", "$(OUTPUT_DIR)"], MakeType),\r
762             "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
763             #"file_build_target"               : self.BuildTargetList,\r
764             "build_type"                        : self.BuildType,\r
765             "source_file_macro"         : SourceFileMacroList,\r
766             "target_file_macro"         : TargetFileMacroList,\r
767             "source_file_macro_name"    : SourceFileMacroNameList,\r
768             "target_file_macro_name"    : TargetFileMacroNameList,\r
769             "file_build_target"         : self.BuildTargetList,\r
770         }\r
771 \r
772         self.PrepareDirectory()\r
773 \r
774         AutoGenMakefile = TemplateString()\r
775         AutoGenMakefile.Append(gModuleMakefileTemplate, MakefileTemplateDict)\r
776 \r
777         FilePath = ""\r
778         if File == None:\r
779             FilePath = path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.MakeFileDir, MakefileName)\r
780         else:\r
781             FilePath = File\r
782 \r
783         return SaveFileOnChange(FilePath, str(AutoGenMakefile))\r
784 \r
785     def GenerateCustomBuildMakefile(self, File=None, MakeType=gMakeType):\r
786         Separator = gDirectorySeparator[MakeType]\r
787 \r
788         if os.path.isabs(self.PlatformInfo.OutputDir):\r
789             self.PlatformBuildDirectory = self.PlatformInfo.OutputDir\r
790         else:\r
791             self.PlatformBuildDirectory = "$(WORKSPACE)" + Separator + self.PlatformInfo.OutputDir\r
792 \r
793         CustomMakefile = open(os.path.join(self.ModuleInfo.WorkspaceDir, self .ModuleInfo.CustomMakefile[MakeType]), 'r').read()\r
794 \r
795         MakefileName = gMakefileName[MakeType]\r
796         MakefileTemplateDict = {\r
797             "makefile_header"           : gMakefileHeader % MakefileName,\r
798             "platform_name"             : self.PlatformInfo.Name,\r
799             "platform_guid"             : self.PlatformInfo.Guid,\r
800             "platform_version"          : self.PlatformInfo.Version,\r
801             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
802             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
803 \r
804             "module_name"               : self.ModuleInfo.Name,\r
805             "module_guid"               : self.ModuleInfo.Guid,\r
806             "module_version"            : self.ModuleInfo.Version,\r
807             "module_type"               : self.ModuleInfo.ModuleType,\r
808             "module_file_base_name"     : self.ModuleInfo.FileBase,\r
809             "module_relative_directory" : self.ModuleInfo.SourceDir,\r
810 \r
811             "architecture"              : self.ModuleInfo.Arch,\r
812             "toolchain_tag"             : self.ModuleInfo.ToolChain,\r
813             "build_target"              : self.ModuleInfo.BuildTarget,\r
814 \r
815             "platform_build_directory"  : self.PlatformBuildDirectory,\r
816 \r
817             "separator"                 : Separator,\r
818             "default_tool_flags"        : self.PlatformInfo.ToolOption.values(),\r
819             "platform_tool_flags"       : self.PlatformInfo.BuildOption.values(),\r
820             "module_tool_flags"         : self.ModuleInfo.BuildOption.values(),\r
821 \r
822             "tool_code"                 : self.PlatformInfo.ToolPath.keys(),\r
823             "tool_path"                 : self.PlatformInfo.ToolPath.values(),\r
824 \r
825             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList, MakeType),\r
826             "directory_to_be_created"   : self.IntermediateDirectoryList,\r
827             "dependent_library_build_directory" : self.LibraryBuildDirectoryList,\r
828             "custom_makefile_content"   : CustomMakefile\r
829         }\r
830 \r
831         self.PrepareDirectory()\r
832 \r
833         AutoGenMakefile = TemplateString()\r
834         AutoGenMakefile.Append(gCustomMakefileTemplate, MakefileTemplateDict)\r
835 \r
836         FilePath = ""\r
837         if File == None:\r
838             FilePath = path.join(self.ModuleInfo.WorkspaceDir, self.ModuleInfo.MakeFileDir, MakefileName)\r
839         else:\r
840             FilePath = File\r
841 \r
842         return SaveFileOnChange(FilePath, str(AutoGenMakefile))\r
843 \r
844     def ProcessSourceFileList(self, MakeType=gMakeType):\r
845         Separator = gDirectorySeparator[MakeType]\r
846 \r
847         Family = self.PlatformInfo.ToolChainFamily["CC"]\r
848         BuildRule = self.PlatformInfo.BuildRule\r
849 \r
850         self.ResultFileList = []\r
851         #self.ObjectFileList = []\r
852         #self.ObjectBuildTargetList = []\r
853         #self.AutoGenBuildFileList = []\r
854         self.IntermediateDirectoryList = ["$(DEBUG_DIR)", "$(OUTPUT_DIR)"]\r
855 \r
856         self.SourceFileDatabase = {}  # {file type : file path}\r
857         self.DestFileDatabase = {}  # {file type : file path}\r
858         self.FileBuildTargetList = [] # [(src, target string)]\r
859         self.BuildTargetList = [] # [target string]\r
860         self.PendingBuildTargetList = [] # [FileBuildRule objects]\r
861 \r
862         ForceIncludedFile = []\r
863         SourceFileList = []\r
864 \r
865         FileList = self.ModuleInfo.SourceFileList\r
866         if len(FileList) == 0:\r
867             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "No files to be built in module [%s, %s, %s]"\r
868                             % (self.ModuleInfo.BuildTarget, self.ModuleInfo.ToolChain, self.ModuleInfo.Arch),\r
869                             ExtraData=str(self.ModuleInfo.Module))\r
870 \r
871         CCodeFlag = False\r
872         for FileInfo in FileList:\r
873             F, SrcFileType, SrcFileBuildRule = FileInfo\r
874             if SrcFileType == "C-Code-File":\r
875                 CCodeFlag = True\r
876             SrcFileName = path.basename(F)\r
877             SrcFileBase, SrcFileExt = path.splitext(SrcFileName)\r
878             SrcFileDir = path.dirname(F)\r
879             if SrcFileDir == "":\r
880                 SrcFileDir = "."\r
881             else:\r
882                 P = "$(OUTPUT_DIR)" + Separator + SrcFileDir\r
883                 if P not in self.IntermediateDirectoryList:\r
884                     self.IntermediateDirectoryList.append(P)\r
885             SrcFileRelativePath = os.path.join(self.ModuleInfo.SourceDir, F)\r
886 \r
887             SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self.ModuleInfo.SourceDir, Separator)\r
888 \r
889             if SrcFileType not in self.SourceFileDatabase:\r
890                 self.SourceFileDatabase[SrcFileType] = []\r
891             self.SourceFileDatabase[SrcFileType].append(SrcFile)\r
892             SourceFileList.append(SrcFileRelativePath)\r
893 \r
894             BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\\r
895                                   "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))\r
896             self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))\r
897 \r
898             while True:\r
899                 # next target\r
900                 DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)\r
901                 if DstFileType == None:\r
902                     DstFileType = "Unknown-Type-File"\r
903 \r
904                 if DstFileType  in self.SourceFileDatabase:\r
905                     self.SourceFileDatabase[DstFileType].append(DstFile)\r
906                 else:\r
907                     if DstFileType not in self.DestFileDatabase:\r
908                         self.DestFileDatabase[DstFileType] = []\r
909                     self.DestFileDatabase[DstFileType].append(DstFile)\r
910 \r
911                 if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:\r
912                     if DstFileBuildRule not in self.PendingBuildTargetList:\r
913                         self.PendingBuildTargetList.append(DstFileBuildRule)\r
914                     break\r
915                 elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:\r
916                     self.ResultFileList.append(DstFile)\r
917                     break\r
918 \r
919                 SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)\r
920                 BuildTargetString = "%s : %s %s\n"\\r
921                                     "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
922                 self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
923                 SrcFileBuildRule = DstFileBuildRule\r
924 \r
925         # handle pending targets\r
926         TempBuildTargetList = []\r
927         while True:\r
928             while len(self.PendingBuildTargetList) > 0:\r
929                 SrcFileBuildRule = self.PendingBuildTargetList.pop()\r
930                 SrcFileList = []\r
931                 for FileType in SrcFileBuildRule.SourceFileType:\r
932                     if FileType not in self.SourceFileDatabase:\r
933                         if FileType not in self.DestFileDatabase:\r
934                             continue\r
935                         else:\r
936                             SrcFileList.extend(self.DestFileDatabase[FileType])\r
937                     else:\r
938                         SrcFileList.extend(self.SourceFileDatabase[FileType])\r
939                 SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(SrcFileList, None, Separator)\r
940                 BuildTargetString = "%s : %s %s\n"\\r
941                                     "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
942                 self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
943 \r
944                 # try to find next target\r
945                 while True:\r
946                     DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)\r
947                     if DstFileType == None:\r
948                         DstFileType = "Unknown-Type-File"\r
949 \r
950                     if DstFileType  in self.SourceFileDatabase:\r
951                         self.SourceFileDatabase[DstFileType].append(DstFile)\r
952                     else:\r
953                         if DstFileType not in self.DestFileDatabase:\r
954                             self.DestFileDatabase[DstFileType] = []\r
955                         self.DestFileDatabase[DstFileType].append(DstFile)\r
956 \r
957                     if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:\r
958                         TempBuildTargetList.append(DstFileBuildRule)\r
959                         break\r
960                     elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:\r
961                         self.ResultFileList.append(DstFile)\r
962                         break\r
963 \r
964                     SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)\r
965                     BuildTargetString = "%s : %s %s\n"\\r
966                                         "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
967                     self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
968                     SrcFileBuildRule = DstFileBuildRule\r
969             if len(TempBuildTargetList) == 0:\r
970                 break\r
971             self.PendingBuildTargetList = TempBuildTargetList\r
972 \r
973         if CCodeFlag == True:\r
974             for F in self.ModuleInfo.AutoGenFileList:\r
975                 SrcFileName = path.basename(F)\r
976                 SrcFileBase, SrcFileExt = path.splitext(SrcFileName)\r
977                 SrcFileDir = path.dirname(F)\r
978                 if SrcFileDir == "":\r
979                     SrcFileDir = "."\r
980                 else:\r
981                     P = "$(DEBUG_DIR)" + Separator + SrcFileDir\r
982                     if P not in self.IntermediateDirectoryList:\r
983                         self.IntermediateDirectoryList.append(P)\r
984 \r
985                 SrcFileRelativePath = os.path.join(self.ModuleInfo.DebugDir, F)\r
986 \r
987                 SrcFileType, SrcFileBuildRule = BuildRule.Get(SrcFileExt, Family)\r
988                 if SrcFileType != None and SrcFileType == "C-Header-File":\r
989                     ForceIncludedFile.append(SrcFileRelativePath)\r
990                 if SrcFileBuildRule == None or SrcFileBuildRule.CommandList == []:\r
991                     continue\r
992 \r
993                 SrcFile, ExtraSrcFileList, DstFile, CommandList = SrcFileBuildRule.Apply(F, self.ModuleInfo.DebugDir, Separator)\r
994 \r
995                 if SrcFileType not in self.SourceFileDatabase:\r
996                     self.SourceFileDatabase[SrcFileType] = []\r
997                 self.SourceFileDatabase[SrcFileType].append(SrcFile)\r
998                 SourceFileList.append(SrcFileRelativePath)\r
999 \r
1000                 BuildTargetTemplate = "${BEGIN}%s : ${deps}\n"\\r
1001                                       "${END}\t%s\n" % (DstFile, "\n\t".join(CommandList))\r
1002                 self.FileBuildTargetList.append((SrcFileRelativePath, BuildTargetTemplate))\r
1003 \r
1004                 while True:\r
1005                     # next target\r
1006                     DstFileType, DstFileBuildRule = BuildRule.Get(SrcFileBuildRule.DestFileExt, Family)\r
1007                     if DstFileType == None:\r
1008                         DstFileType = "Unknown-Type-File"\r
1009 \r
1010                     if DstFileType  in self.SourceFileDatabase:\r
1011                         self.SourceFileDatabase[DstFileType].append(DstFile)\r
1012                     else:\r
1013                         if DstFileType not in self.DestFileDatabase:\r
1014                             self.DestFileDatabase[DstFileType] = []\r
1015                         self.DestFileDatabase[DstFileType].append(DstFile)\r
1016 \r
1017                     if DstFileBuildRule != None and DstFileBuildRule.IsMultipleInput:\r
1018                         if DstFileBuildRule not in self.PendingBuildTargetList:\r
1019                             self.PendingBuildTargetList.append(DstFileBuildRule)\r
1020                         break\r
1021                     elif DstFileBuildRule == None or DstFileBuildRule.CommandList == []:\r
1022                         self.ResultFileList.append(DstFile)\r
1023                         break\r
1024 \r
1025                     SrcFile, ExtraSrcFileList, DstFile, CommandList = DstFileBuildRule.Apply(DstFile, None, Separator)\r
1026                     BuildTargetString = "%s : %s %s\n"\\r
1027                                         "\t%s\n" % (DstFile, SrcFile, " ".join(ExtraSrcFileList), "\n\t".join(CommandList))\r
1028                     self.FileBuildTargetList.append((SrcFile, BuildTargetString))\r
1029                     SrcFileBuildRule = DstFileBuildRule\r
1030 \r
1031         #\r
1032         # Search dependency file list for each source file\r
1033         #\r
1034         self.FileDependency = self.GetFileDependency(SourceFileList, ForceIncludedFile, self.ModuleInfo.IncludePathList)\r
1035         DepSet = None\r
1036         for File in self.FileDependency:\r
1037             # skipt AutoGen.c\r
1038             if File.endswith("AutoGen.c") or not File.endswith(".c"):\r
1039                 continue\r
1040             elif DepSet == None:\r
1041                 DepSet = set(self.FileDependency[File])\r
1042             else:\r
1043                 DepSet &= set(self.FileDependency[File])\r
1044         # in case nothing in SourceFileList\r
1045         if DepSet == None:\r
1046             DepSet = set()\r
1047         #\r
1048         # Extract comman files list in the dependency files\r
1049         #\r
1050         self.CommonFileDependency = list(DepSet)\r
1051         for F in self.FileDependency:\r
1052             NewDepSet = set(self.FileDependency[F])\r
1053             NewDepSet -= DepSet\r
1054             if F.endswith("AutoGen.c") or not F.endswith(".c"):\r
1055                 self.FileDependency[F] = [Separator.join(["$(WORKSPACE)", dep]) for dep in self.FileDependency[F]]\r
1056             else:\r
1057                 self.FileDependency[F] = ["$(COMMON_DEPS)"] + [Separator.join(["$(WORKSPACE)", dep]) for dep in NewDepSet]\r
1058 \r
1059         for File, TargetTemplate in self.FileBuildTargetList:\r
1060             if File not in self.FileDependency:\r
1061                 self.BuildTargetList.append(TargetTemplate)\r
1062                 continue\r
1063             Template = TemplateString()\r
1064             Template.Append(TargetTemplate, {"deps" : self.FileDependency[File]})\r
1065             self.BuildTargetList.append(str(Template))\r
1066 \r
1067     def ProcessDependentLibrary(self, MakeType=gMakeType):\r
1068         for LibraryModule in self.ModuleInfo.DependentLibraryList:\r
1069             LibraryFile = str(LibraryModule)\r
1070             FileBase = path.basename(LibraryFile).split(".")[0]\r
1071             LibraryBuildPath = path.dirname(LibraryFile) + gDirectorySeparator[MakeType] + FileBase\r
1072             self.LibraryBuildDirectoryList.append(LibraryBuildPath)\r
1073             self.LibraryFileList.append(gDirectorySeparator[MakeType].join([LibraryBuildPath, "OUTPUT", LibraryModule.BaseName + ".lib"]))\r
1074 \r
1075     def GetPlatformBuildDirectory(self):\r
1076         if os.path.isabs(self.PlatformInfo.OutputDir):\r
1077             return self.PlatformInfo.OutputDir\r
1078         else:\r
1079             return os.path.join("$(WORKSPACE)", self.PlatformInfo.OutputDir)\r
1080 \r
1081     def GetFileDependency(self, FileList, ForceInculeList, SearchPathList):\r
1082         WorkingDir = os.getcwd()\r
1083         os.chdir(self.ModuleInfo.WorkspaceDir)\r
1084         Dependency = {}\r
1085         for F in FileList:\r
1086             Dependency[F] = self.GetDependencyList(F, ForceInculeList, SearchPathList)\r
1087         os.chdir(WorkingDir)\r
1088         return Dependency\r
1089 \r
1090     def GetDependencyList(self, File, ForceList, SearchPathList):\r
1091         WorkingDir = os.getcwd()\r
1092         os.chdir(self.ModuleInfo.WorkspaceDir)\r
1093 \r
1094         EdkLogger.debug(EdkLogger.DEBUG_3, "Try to get dependency files for %s" % File)\r
1095         EdkLogger.debug(EdkLogger.DEBUG_2, "Including %s" % " ".join(ForceList))\r
1096         FileStack = [File] + ForceList\r
1097         DependencySet = set()\r
1098         MacroUsedByIncludedFile = False\r
1099 \r
1100         while len(FileStack) > 0:\r
1101             EdkLogger.debug(EdkLogger.DEBUG_2, "Stack %s" % "\n\t".join(FileStack))\r
1102             F = FileStack.pop()\r
1103 \r
1104             CurrentFileDependencyList = []\r
1105             if F in gDependencyDatabase and not IsChanged(F):\r
1106                 CurrentFileDependencyList = gDependencyDatabase[F]\r
1107                 for Dep in CurrentFileDependencyList:\r
1108                     if Dep not in FileStack and Dep not in DependencySet:\r
1109                         FileStack.append(Dep)\r
1110             else:\r
1111                 try:\r
1112                     Fd = open(F, 'r')\r
1113                 except:\r
1114                     EdkLogger.error("AutoGen", FILE_OPEN_FAILURE, ExtraData=F)\r
1115 \r
1116                 FileContent = Fd.read()\r
1117                 Fd.close()\r
1118                 if len(FileContent) == 0:\r
1119                     continue\r
1120 \r
1121                 if FileContent[0] == 0xff or FileContent[0] == 0xfe:\r
1122                     FileContent = unicode(FileContent, "utf-16")\r
1123                 IncludedFileList = gIncludePattern.findall(FileContent)\r
1124 \r
1125                 CurrentFilePath = os.path.dirname(F)\r
1126                 for Inc in IncludedFileList:\r
1127                     Inc = os.path.normpath(Inc)\r
1128                     for SearchPath in [CurrentFilePath] + SearchPathList:\r
1129                         FilePath = os.path.join(SearchPath, Inc)\r
1130                         if not os.path.exists(FilePath) or FilePath in CurrentFileDependencyList:\r
1131                             continue\r
1132                         CurrentFileDependencyList.append(FilePath)\r
1133                         if FilePath not in FileStack and FilePath not in DependencySet:\r
1134                             FileStack.append(FilePath)\r
1135                         break\r
1136                     else:\r
1137                         if gMacroPattern.match(Inc) != None:\r
1138                             MacroUsedByIncludedFile = True\r
1139                         EdkLogger.verbose("%s included by %s was not found in any given path:\n\t%s" % (Inc, F, "\n\t".join(SearchPathList)))\r
1140                 if not MacroUsedByIncludedFile:\r
1141                     if F == File:\r
1142                         CurrentFileDependencyList += ForceList\r
1143                     #\r
1144                     # Don't keep the file in cache if it uses macro in included file.\r
1145                     # So it will be scanned again if another file includes this file.\r
1146                     #\r
1147                     gDependencyDatabase[F] = CurrentFileDependencyList\r
1148             DependencySet.update(CurrentFileDependencyList)\r
1149 \r
1150         #\r
1151         # If there's macro used in included file, always build the file by\r
1152         # returning a empty dependency\r
1153         #\r
1154         if MacroUsedByIncludedFile:\r
1155             DependencyList = []\r
1156         else:\r
1157             DependencyList = list(DependencySet)  # remove duplicate ones\r
1158             DependencyList.append(File)\r
1159 \r
1160         os.chdir(WorkingDir)\r
1161         return DependencyList\r
1162 \r
1163     def GetModuleBuildDirectoryList(self):\r
1164         DirList = []\r
1165         for Arch in self.PlatformInfo:\r
1166             for ModuleAutoGen in self.PlatformInfo[Arch].ModuleAutoGenList:\r
1167                 DirList.append(ModuleAutoGen.BuildInfo.BuildDir)\r
1168         return DirList\r
1169 \r
1170     def GetLibraryBuildDirectoryList(self):\r
1171         DirList = []\r
1172         for Arch in self.PlatformInfo:\r
1173             for LibraryAutoGen in self.PlatformInfo[Arch].LibraryAutoGenList:\r
1174                 DirList.append(LibraryAutoGen.BuildInfo.BuildDir)\r
1175         return DirList\r
1176 \r
1177     def GetCreateDirectoryCommand(self, DirList, MakeType=gMakeType):\r
1178         return [gCreateDirectoryCommandTemplate[MakeType] % {'dir':Dir} for Dir in DirList]\r
1179 \r
1180     def GetRemoveDirectoryCommand(self, DirList, MakeType=gMakeType):\r
1181         return [gRemoveDirectoryCommandTemplate[MakeType] % {'dir':Dir} for Dir in DirList]\r
1182 \r
1183 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
1184 if __name__ == '__main__':\r
1185     pass\r