OpenHarmony移植案例: build lite源碼分析之hb命令__entry__.py

摘要:本文介紹了build lite 輕量級編譯構建系統hb命令的源碼,主要分析了_\entry__.py文件。

本文分享自華為雲社區《移植案例與原理 – build lite源碼分析 之 hb命令__entry__.py》,作者:zhushy 。

hb命令可以通過python pip包管理器進行安裝,應該是OpenHarmony Build的縮寫,在python包名稱是ohos-build。hb作為編譯構建子系統提供的命令行,用於編譯構建產品、芯片廠商組件或者單個組件。我們來學習hb命令行工具的源碼,本文主要分析下文件openharmony/build/lite/hb/__entry__.py。

1、find_top()函數

find_top()函數用於獲取OpenHarmony源代碼根目錄,之前的系列文章分析過。代碼也較簡單,不再贅述。

def find_top():
 cur_dir = os.getcwd()
 while cur_dir != "/":
 hb_internal = os.path.join(cur_dir, 'build/lite/hb_internal')
 if os.path.exists(hb_internal):
 return cur_dir
 cur_dir = os.path.dirname(cur_dir)
 raise Exception("Please call hb utilities inside source root directory")

2、get_hb_commands()函數

get_hb_commands()函數用於返回hb命令行工具支持的命令集。hb支持的命令定義在文件』build/lite/hb_internal/hb_command_set.json』中,支持的命令主要為build、set、env、clean和tool。

def get_hb_commands(config_file):
 if not os.path.exists(config_file):
 raise Exception('Error: {} not exist, couldnot get hb command set'.format(config_file))
 with open(config_file, 'r') as file:
        config = json.load(file)
 return config

3、main()函數

在main()函數中,首先獲取OpenHarmony源代碼根目錄,然後把路徑’build/lite’插入到sys.path系統搜索路徑,為後續調用importlib.import_module接口進行動態加載做準備。⑴處定義hb命令行的支持的選項,使用和命令輸出hb -h結合起來學習源代碼。⑵處獲取hb命令行工具支持的命令集合,然後添加到命令行解析參數列表裡parser_list。⑶和⑷配置支持的positional arguments(見 hb -h的輸出),⑶處動態引入支持的模塊,這些對應文件build/lite/hb_internal/hb_internal/XXX/XXX.py,其中XXX的取值為build、set、clean、env和tool。在這幾個python文件中,都會有add_options()函數,用於提供具體命令的參數選項,還有個函數exec_command(),執行具體的命令時,會調用這些函數。⑷處的代碼會配置剛才描述的add_options()函數和函數exec_command()。

⑸處的語句獲取hb命令傳入的參數選項,接下來動態加載』hb_internal.common.utils』,獲得函數地址,分別用於控制台輸出日誌、異常處理等。接下來處理hb命令行傳入的選項,⑹處如果指定了』-root』|』–root_path』選項時,開發者主動提供OpenHarmony源代碼根目錄,會執行args[0].root_path = topdir把根目錄傳入到參數列表裡。⑺根據是hb tool還是其他命令,分別調用對應的函數exec_command(),命令行選項不一樣時,傳入的參數稍有差異,分別是args和args[0]。對於hb tool,args[1]會傳遞些要傳遞給gn命令行的參數gn_args。

def main():
 try:
 topdir = find_top()
 except Exception as ex:
 return print("hb_error: Please call hb utilities inside source root directory")
 sys.path.insert(0, os.path.join(topdir, 'build/lite'))
⑴  parser = argparse.ArgumentParser(description='OHOS Build System '
 f'version {VERSION}')
 parser.add_argument('-v',
 '--version',
                        action='version',
                        version=f'[OHOS INFO] hb version {VERSION}')
 subparsers = parser.add_subparsers()
 parser_list = []
⑵ command_set = get_hb_commands(os.path.join(topdir, 'build/lite/hb_internal/hb_command_set.json'))
 for key, val in command_set.items():
 parser_list.append({'name': key, 'help': val})
 for each in parser_list:
 module_parser = subparsers.add_parser(name=each.get('name'),
 help=each.get('help'))
⑶      module = importlib.import_module('hb_internal.{0}.{0}'.format(
 each.get('name')))
⑷ module.add_options(module_parser)
 module_parser.set_defaults(parser=module_parser,
                                  command=module.exec_command)
⑸ args = parser.parse_known_args()
    module = importlib.import_module('hb_internal.common.utils')
 hb_error = getattr(module, 'hb_error')
 hb_warning = getattr(module, 'hb_warning')
 ohos_exception = getattr(module, 'OHOSException')
 try:
⑹ if args[0].parser.prog == 'hb set' and 'root_path' in vars(args[0]):
 # Root_path is topdir.
 args[0].root_path = topdir
⑺ if "tool" in args[0].parser.prog:
            status = args[0].command(args)
 else:
            status = args[0].command(args[0])
 except KeyboardInterrupt:
 hb_warning('User Abort')
        status = -1
 except ohos_exception as exception:
 hb_error(exception.args[0])
        status = -1
 except Exception as exception:
 if not hasattr(args[0], 'command'):
 parser.print_help()
 else:
 hb_error(traceback.format_exc())
 hb_error(f'Unhandled error: {exception}')
        status = -1
 return status

4、參考站點

 

5、小結

本文介紹了build lite 輕量級編譯構建系統hb命令的源碼,主要分析了_\entry__.py文件。因為時間關係,倉促寫作,或能力限制,若有失誤之處,請各位讀者多多指正。遺漏之處,歡迎補充。感謝閱讀,有什麼問題,請留言。

 

點擊關注,第一時間了解華為雲新鮮技術~