[cococos 2 dx---ツール編を再認識]setup.py
15070 ワード
エンジンのソースコードを取得してsetupを実行します.pyは必要ですが、
このツールはエンジンの環境変数の構成を構成し、path変数に追加します.
設定された変数は次のとおりです.
COCOS_CONSOLE_ROOT COCOS_TEMPLATES_ROOT NDK_ROOT ANDROID_SDK_ROOT ANT_ROOT
重中の重------プログラムの入り口を見つけます:
コードは4つの部分に分けて分析することができます
1.準備段階---判断バージョン
Python 2.7.3を例に、sys.version_infoにはバージョン番号情報が以下のように含まれています.
2.コマンドラインパラメータ設定
3.本体部---システムパラメータの設定
関数set_environment_variables()の重要な部分は次の5行です.
まずcocosコマンドの設定経路を見てみましょう
いくつかの重要なカスタム関数があります
環境変数の値を最初に取得します.関数のレジストリに対する操作はこのツールの核心ステップであり、osを補助する.Environはこのツールでよく見られるコーディネートです
2つ目:Path変数に変数を追加
3つ目:異なるプラットフォームに基づいて、それぞれ環境変数を追加する
4つ目:Pathの変数を削除するには、文字列の操作に注意する必要があります.
5つ目:環境変数の更新
2つ目は、新規工事時のテンプレートのパスを設定することです.
コードは最初のステップと同じで、省略します.
3つ目はandroid関連のパスを設定し、3つは同じです.
小結:この部分の構造はとてもはっきりしていて、カプセル化の関数はちょうど利益があって、クラスSetEnvVarは大部分の操作をカプセル化しました
4.終了部分
すべての最上位ウィンドウに通知し、アプリケーションがシステムパラメータを変更しました.
まとめ:pythonの使い方:(仕方なく長すぎて、別に開くしかありません)
[python補足]optparser
os.path
このツールはエンジンの環境変数の構成を構成し、path変数に追加します.
設定された変数は次のとおりです.
COCOS_CONSOLE_ROOT COCOS_TEMPLATES_ROOT NDK_ROOT ANDROID_SDK_ROOT ANT_ROOT
重中の重------プログラムの入り口を見つけます:
if __name__ == '__main__':
コードは4つの部分に分けて分析することができます
1.準備段階---判断バージョン
if not _check_python_version():
exit()
/**************************/
def _check_python_version():
major_ver = sys.version_info[0]
if major_ver > 2:
print ("The python version is %d.%d. But python 2.x is required. (Version 2.7 is well tested)
"
"Download it here: https://www.python.org/" % (major_ver, sys.version_info[1]))
return False
return True
カスタム_を呼び出すcheck_python_version関数はpythonのバージョン番号をpython 2ではないと判断する.Xはpython 2で終了します.Xとpython 3.Xコードは互換性がなく、バージョン番号を判断する必要がありますPython 2.7.3を例に、sys.version_infoにはバージョン番号情報が以下のように含まれています.
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=3, releaselevel='final', serial=0)
2.コマンドラインパラメータ設定
parser = OptionParser()
parser.add_option(
'-n', '--ndkroot', dest='ndk_root', help='directory of ndk root')
parser.add_option('-a', '--androidsdkroot',
dest='android_sdk_root', help='directory of android sdk root')
parser.add_option(
'-t', '--antroot', dest='ant_root', help='directory that contains ant/ant.bat')
opts, args = parser.parse_args()
3.本体部---システムパラメータの設定
env = SetEnvVar()
env.set_environment_variables(
opts.ndk_root, opts.android_sdk_root, opts.ant_root)
関数set_environment_variables()の重要な部分は次の5行です.
self.set_console_root()
self.set_templates_root()
ndk_ret = self.set_variable(NDK_ROOT, ndk_root)
sdk_ret = self.set_variable(ANDROID_SDK_ROOT, android_sdk_root)
ant_ret = self.set_variable(ANT_ROOT, ant_root)
まずcocosコマンドの設定経路を見てみましょう
def set_console_root(self):
print("->Check environment variable %s" % COCOS_CONSOLE_ROOT)
#
cocos_consle_root = os.path.join(
self.current_absolute_path, 'tools', 'cocos2d-console', 'bin')
#
old_dir = self._find_environment_variable(COCOS_CONSOLE_ROOT)
if old_dir is None:
#
if self._isWindows():
self.set_windows_path(cocos_consle_root)
self._set_environment_variable(
COCOS_CONSOLE_ROOT, cocos_consle_root)
else:
if old_dir == cocos_consle_root:
# is same with before, nothing to do
return
#
if self._isWindows():
self.remove_dir_from_win_path(old_dir)
self.set_windows_path(cocos_consle_root)
self._force_update_env(COCOS_CONSOLE_ROOT, cocos_consle_root)
いくつかの重要なカスタム関数があります
環境変数の値を最初に取得します.関数のレジストリに対する操作はこのツールの核心ステップであり、osを補助する.Environはこのツールでよく見られるコーディネートです
def _find_environment_variable(self, var):
'''
var , None
'''
print(" ->Search for environment variable %s..." % var)
ret = None
try:
# os.environ
# python
ret = os.environ[var]
except Exception:
if not self._isWindows():
file_list = self._get_unix_file_list()
if file_list is not None:
home = os.path.expanduser('~')
for name in file_list:
path = os.path.join(home, name)
ret = self._search_unix_variable(var, path)
if ret is not None:
break
else:
'''
_winreg windows
_winreg.OpenKeyEx() , key
_winreg.QueryValueEx()
_winreg.CloseKey()
'''
import _winreg
try:
env = None
#
env = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER,
'Environment',
0,
_winreg.KEY_READ)
#
ret = _winreg.QueryValueEx(env, var)[0]
_winreg.CloseKey(env)
except Exception:
if env:
_winreg.CloseKey(env)
ret = None
if ret is None:
print(" ->%s not found
" % var)
else:
print(" ->%s is found : %s
" % (var, ret))
return ret
2つ目:Path変数に変数を追加
def set_windows_path(self, add_dir):
'''
add_dir Path
'''
ret = False
import _winreg
try:
env = None
path = None
env = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER,
'Environment',
0,
_winreg.KEY_SET_VALUE | _winreg.KEY_READ)
path = _winreg.QueryValueEx(env, 'Path')[0]
# add variable if can't find it in PATH
# _winreg.SetValueEx()
# _winreg.FlushKey()
path_lower = path.lower()
add_dir_lower = add_dir.lower()
if (path_lower.find(add_dir_lower) == -1):
path = add_dir + ';' + path
_winreg.SetValueEx(env, 'Path', 0, _winreg.REG_SZ, path)
_winreg.FlushKey(env)
_winreg.CloseKey(env)
ret = True
except Exception:
if not path:
path = add_dir
_winreg.SetValueEx(env, 'Path', 0, _winreg.REG_SZ, path)
_winreg.FlushKey(env)
ret = True
else:
_winreg.SetValueEx(env, 'Path', 0, _winreg.REG_SZ, path)
_winreg.FlushKey(env)
ret = False
if env:
_winreg.CloseKey(env)
if ret:
print(" ->Add directory \"%s\" into PATH succeed!
" % add_dir)
else:
print(" ->Add directory \"%s\" into PATH failed!
" % add_dir)
3つ目:異なるプラットフォームに基づいて、それぞれ環境変数を追加する
def _set_environment_variable(self, key, value):
'''
key,value
'''
print(" -> Add %s environment variable..." % key)
ret = False
if self._isWindows():
ret = self._set_environment_variable_win32(key, value)
else:
ret = self._set_environment_variable_unix(key, value)
if ret:
print(" ->Added %s=%s
" % (key, value))
else:
print(" ->Add failed
")
return ret
# modify registry table to add an environment variable on windows
def _set_environment_variable_win32(self, key, value):
'''
win32 key,value
'''
ret = False
import _winreg
try:
env = None
env = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER,
'Environment',
0,
_winreg.KEY_SET_VALUE | _winreg.KEY_READ)
_winreg.SetValueEx(env, key, 0, _winreg.REG_SZ, value)
_winreg.FlushKey(env)
_winreg.CloseKey(env)
ret = True
except Exception:
if env:
_winreg.CloseKey(env)
ret = False
return ret
4つ目:Pathの変数を削除するには、文字列の操作に注意する必要があります.
def remove_dir_from_win_path(self, remove_dir):
'''
Path remove_dir
'''
import _winreg
try:
env = None
path = None
env = _winreg.OpenKeyEx(_winreg.HKEY_CURRENT_USER,
'Environment',
0,
_winreg.KEY_SET_VALUE | _winreg.KEY_READ)
path = _winreg.QueryValueEx(env, 'Path')[0]
path_lower = path.lower()
remove_dir = remove_dir.replace('/', '\\')
remove_dir_lower = remove_dir.lower()
start_pos = path_lower.find(remove_dir_lower)
if (start_pos >= 0):
length = len(remove_dir_lower)
need_remove = path[start_pos:(start_pos + length)]
path = path.replace(need_remove, '')
path = path.replace(';;', ';')
_winreg.SetValueEx(env, 'Path', 0, _winreg.REG_SZ, path)
_winreg.FlushKey(env)
_winreg.CloseKey(env)
print(' ->Remove directory \"%s\" from PATH!
' % remove_dir)
except Exception:
print(' ->Remove directory \"%s\" from PATH failed!
' %
remove_dir)
5つ目:環境変数の更新
def _force_update_env(self, var_name, value):
ret = False
if self._isWindows():
print(" ->Force update environment variable %s" % var_name)
ret = self._set_environment_variable_win32(var_name, value)
if not ret:
print(" ->Failed!")
else:
print(" ->Succeed : %s=%s" % (var_name, value))
else:
ret = self._force_update_unix_env(var_name, value)
return ret
def _force_update_unix_env(self, var_name, value):
'''
'''
import re
home = os.path.expanduser('~')
str_re = SetEnvVar.RE_FORMAT % var_name
patten = re.compile(str_re)
replace_str = 'export %s=%s
' % (var_name, value)
file_list = SetEnvVar.MAC_CHECK_FILES
if self._isLinux():
file_list = SetEnvVar.LINUX_CHECK_FILES
print(" ->Update variable %s in files %s" %
(var_name, str(file_list)))
variable_updated = False
for file_name in file_list:
path = os.path.join(home, file_name)
if os.path.isfile(path):
lines = []
# read files
need_over_write = False
file_obj = open(path, 'r')
for line in file_obj:
str_temp = line.lstrip(' \t')
match = patten.match(str_temp)
if match is not None:
variable_updated = True
need_over_write = True
lines.append(replace_str)
else:
lines.append(line)
file_obj.close()
# rewrite file
if need_over_write:
file_obj = open(path, 'w')
file_obj.writelines(lines)
file_obj.close()
print(" ->File %s updated!" % path)
# nothing updated, should add variable
if not variable_updated:
print("
->No files updated, add variable %s instead!" %
var_name)
ret = self._set_environment_variable(var_name, value)
else:
ret = True
return ret
2つ目は、新規工事時のテンプレートのパスを設定することです.
コードは最初のステップと同じで、省略します.
3つ目はandroid関連のパスを設定し、3つは同じです.
def set_variable(self, var_name, value):
'''
var_name, value
'''
print("->Check environment variable %s" % var_name)
find_value = self._find_environment_variable(var_name)
var_found = (find_value is not None)
action_none = 0
action_add = 1
action_update = 2
# : , ,
need_action = action_none
if var_found:
if value and self._check_valid(var_name, value):
# should update
need_action = action_update
else:
# do nothing
need_action = action_none
else:
if not value:
# find the command path in system
value = self._find_value_from_sys(var_name)
if not value:
value = self._get_input_value(var_name)
if value and self._check_valid(var_name, value):
# should add variable
need_action = action_add
else:
# do nothing
need_action = action_none
#
if need_action == action_none:
# do nothing
return SetEnvVar.RESULT_DO_NOTHING
elif need_action == action_add:
# add variable
if self._set_environment_variable(var_name, value):
return SetEnvVar.RESULT_ADDED
else:
return SetEnvVar.RESULT_ADD_FAILED
elif need_action == action_update:
# update variable
if self._force_update_env(var_name, value):
# update succeed
return SetEnvVar.RESULT_UPDATED
else:
# update failed
return SetEnvVar.RESULT_UPDATE_FAILED
else:
return SetEnvVar.RESULT_DO_NOTHING
小結:この部分の構造はとてもはっきりしていて、カプセル化の関数はちょうど利益があって、クラスSetEnvVarは大部分の操作をカプセル化しました
4.終了部分
すべての最上位ウィンドウに通知し、アプリケーションがシステムパラメータを変更しました.
if env._isWindows():
import ctypes
HWND_BROADCAST = 0xFFFF
WM_SETTINGCHANGE = 0x1A
SMTO_ABORTIFHUNG = 0x0002
result = ctypes.c_long()
SendMessageTimeoutW = ctypes.windll.user32.SendMessageTimeoutW
SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
u'Environment', SMTO_ABORTIFHUNG, 5000, ctypes.byref(result))
まとめ:pythonの使い方:(仕方なく長すぎて、別に開くしかありません)
[python補足]optparser
os.path