poky:單個任務是如何被執行的

來源:互聯網
上載者:User

* 範圍

本文忽略了任務的依賴及其他處理,僅討論單個任務是如何被執行的。

* 簡介:
任務是定義在bb檔案中的python/shell函數,代表了軟體包build過程中的一個步驟。Bitbake約定,任務名必須以’do_‘開
始,bitbake提供任務的分析和處理機制,具體的任務由bbclass/bbfile提供。

* 前情提要:
Bitbake以Server/UI的方式運行,Server端負責等待並執行命令,UI端負責提交命令並回顯結果,二者通過一個雙向命令管道
和一個狀態隊列進行互動。Server決定何時執行什麼命令,而命令的具體執行由Cooker負責,這種機制通過回呼函數實現。

以bzip2為例,執行以下命令時:
 
$ bitbake bzip2

1)Bitbake分析命令列得到:cmdline={'action': ['buildTargets', ['bzip2'], 'build'], 'msg': None};
2)UI調用server.runCommand(cmdline['action']),把命令傳遞給Server;
3)Server交給cooker處理,cooker.buildTargets()被執行,它把自己定義的方法buildTargetsIdle()註冊到Server的_idlefunctions列表;
4)Server輪詢並執行非同步命令,控制權交還給buildTargetsIdle(),故事從這裡開始了...

* 任務執行:
Bitbake中任務是一個對象,任務的表現形式是TaskData執行個體。TaskData可以添加,刪除任務,處理任務的各種依賴,但是不能執行任務。

任務的執行依靠RunQueue實現, RunQueue是一個狀態機器,根據當前所處狀態執行相應的操作,RunQueue初始化時狀態為”runQueueSceneInit“。

從buildTargetsIdle()開始分析, '->'表示函數/方法的調用關係:
-> rq.execute_runqueue():

該方法執行runqueue隊列中的任務,在初始狀態下,它調用的是RunQueueExecuteScenequeue執行個體的execute()方法:

945    self.rqexe = RunQueueExecuteScenequeue(self)
948    retval = self.rqexe.execute()

-> RunQueueExecuteScenequeue.execute()

運行隊列中的任務,每一個任務都不是單獨存在的,若干任務構成了一條任務鏈,每個可執行任務最終要通過以下方式被執行:

1602    pid, pipein, pipeout = self.fork_off_task(fn, realtask, taskname)

-> RunQueueExecuteScenequeue.fork_off_task(): 這是一個Wrapper,下面才是真正的fork_off_task()
-> RunQueueExecute.fork_off_task():

先檢查和設定任務執行的環境和相關變數,任務的Flag:[umask/fakeroot]就是在這裡處理的; 執行任務調用如下方法:

1160    bb.build.exec_task

-> bb.build._exec_task(): 執行任務要比單獨執行一個函數複雜一些,仍然需要處理任務相關的環境變數和資料;然後剝去任務的外衣,把它當做函數處理:

321    exec_func(task, localdata)

-> bb.build.exec_func(): 處理任務的其他Flags,根據任務類型(python/shell)分而治之;

170    if ispython:
171        exec_func_python(func, d, runfile, cwd=adir)
172    else:
173        exec_func_shell(func, d, runfile, cwd=adir)

a. -> bb.build.exec_func_python(): 如果任務是python函數:

   200    utils.better_exec(comp, {"d": d}, code, bbfile)

   -> bb.utils.better_exec(): python類型的任務最終由python內建函數exec執行:

   343    exec(code, _context, context)

b. -> bb.build.exec_func_shell():如果任務是shell函數:

   243    bb.process.run(cmd, shell=False, stdin=NULL, log=logfile)

   -> bb.process.run():把函數轉換成命令並返回命令的輸出:

   95    pipe = Popen(cmd, **options) # subprocess.Popen(), 有關Popen()詳細使用請參考subprocess模組的help資訊。

至此一個任務執行完畢。

* 總結:
Bitbake中用TakeDate,RunQueueData組織任務資料,而且任務處理過程中還涉及到了資料緩衝,日誌和事件資訊的處理,它們
在BB中被抽象成了不同的類型和對象,希望以後能逐步分析,最終形成一個完整的BB物件類型系統說明。

* 參考:

$ bitbake bzip2 # 部分輸出
NOTE: Resolving any missing task queue dependencies
NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Running setscene task 97 of 277 (/home/wenzong/sdb2/poky/meta/recipes-extended/bzip2/bzip2_1.0.6.bb:do_populate_sysroot_setscene)
NOTE: package bzip2-1.0.6-r3: task do_populate_sysroot_setscene: Started
NOTE: package bzip2-1.0.6-r3: task do_populate_sysroot_setscene: Succeeded
....

* Task Flags:
[dirs]: 任務運行前建立的目錄;
[cleandirs]: 任務運行前建立,並且是空目錄;
[noexec]: 不需要執行的任務;
[nostamp]: 不產生stamp檔案,任務總是被重新執行;
[fakeroot]: 任務需要在fakeroot環境下執行;
[umask]: 任務運行時的umask
[depends/deptask/rdeptask/recdeptask/recrdeptask]: 依賴的任務必須完成才能執行此任務

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.