BaseTools: Sometime write file not immediate to disk

BZ: https://bugzilla.tianocore.org/process_bug.cgi

On Windows OS, sometime the generated file is not immediate saved to disk.
When run nmake, prompt AutoGen.h not found, and stop build.
Below blog shows Write-Replace to fix it. This patch uses this way to write
temp file, then rename the temp file to the real file.
https://blog.gocept.com/2013/07/15/reliable-file-updates-with-python/

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
This commit is contained in:
Yunhua Feng 2019-04-11 12:57:15 +08:00 committed by Liming Gao
parent e72920ec61
commit 0b836855fb
1 changed files with 13 additions and 4 deletions

View File

@ -22,6 +22,7 @@ from random import sample
from struct import pack from struct import pack
import uuid import uuid
import subprocess import subprocess
import tempfile
from collections import OrderedDict from collections import OrderedDict
import Common.LongFilePathOs as os import Common.LongFilePathOs as os
@ -476,15 +477,23 @@ def SaveFileOnChange(File, Content, IsBinaryFile=True):
if not os.access(DirName, os.W_OK): if not os.access(DirName, os.W_OK):
EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName) EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)
OpenMode = "w"
if IsBinaryFile: if IsBinaryFile:
OpenMode = "wb"
if GlobalData.gIsWindows and not os.path.exists(File):
# write temp file, then rename the temp file to the real file
# to make sure the file be immediate saved to disk
with tempfile.NamedTemporaryFile(OpenMode, dir=os.path.dirname(File), delete=False) as tf:
tf.write(Content)
tempname = tf.name
try: try:
with open(File, "wb") as Fd: os.rename(tempname, File)
Fd.write(Content) except:
except IOError as X:
EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X) EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)
else: else:
try: try:
with open(File, 'w') as Fd: with open(File, OpenMode) as Fd:
Fd.write(Content) Fd.write(Content)
except IOError as X: except IOError as X:
EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X) EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)