【聲明】本博客所有內容均為個人業余時間創作,所述技術案例均來自公開開源項目(如Github,Apache基金會),不涉及任何企業機密或未公開技術,如有侵權請聯系刪除
背景
接之前 blog
【OS】【Nuttx】【構建】cmake 支持構建的目標
之前分析了怎么查看 cmake 支持構建的目標,里面著重分析了 menuconfig 這個目標,這個也是這篇 blog 的主題,下面就來看 menuconfig 這個目標的細節
menuconfig 目標
上篇 blog 分析的是一些準備環境,接下來分析的,是 cmake 配置工程的關鍵,menuconfig.cmake 腳本中,menuconfig 目標的構建規則如下
有幾個關鍵點講下:
- add_custom_target:創建一個自定義構建目標,這里名字叫 menuconfig,執行這個目標并不會編譯代碼,而是執行一系列命令
- 下面來詳細分析這個目標會執行的命令,42 行第一條:啟動配置界面。這里簡單講下里面幾個關鍵字:
${CMAKE_COMMAND}:cmake 的可執行文件路徑,比如 /usr/bin/cmake
-E:啟用 cmake 的命令行模式
env:子命令,設置環境變量并運行程序
${KCONFIG_ENV}:之前定義的環境變量列表,上篇 blog 【OS】【Nuttx】【構建】cmake 支持構建的目標 分析過
${MENUCONFIG}:要運行的命令,比如 menuconfig(Linux),guiconfig(Windows)
所以最后等價于在終端執行如下命令,命令執行完后,會彈出一個菜單界面,和 make menuconfig 一樣,可以選擇內核功能
/usr/bin/cmake -E env KCONFIG_CONFIG=~/nuttx_pdt/nuttx/build/.config EXTERNALDIR=dummy APPSDIR=~/nuttx_pdt/nuttx-apps DRIVERS_PLATFORM_DIR=dummy APPSBINDIR=~/nuttx_pdt/nuttx/build/nuttx-apps BINDIR=~/nuttx_pdt/nuttx/build ~/nuttx_pdt/nuttx/menuconfig
- 43 ~ 44 行是第二條命令:刪除舊的配置頭文件。這里有兩個關鍵字:
remove -f:強制刪除文件(類似 rm -f)
${CMAKE_BINARY_DIR}/include/nuttx/config.h:由 .config 轉換而來的關鍵頭文件,直接參與 Nuttx 編譯
config.h 是由 .config 文件自動生成的,包含所有配置宏信息,如果不刪除,即使改了 .config,cmake 在構建時也會認為它沒變,影響到重新生成,而導致配置沒生效;刪除是為了強制下一次構建時重新生成 config.h,確保配置生效;這是一種構建時失效緩存的常見策略:主動刪除舊結果,強制重新生成 - 46 行是第三條命令:觸發 CMake 重新配置,這里也有幾個關鍵點:
touch:更新文件的時間戳(類似 Linux 的 touch 命令,如果文件不存在,就創建一個,如果文件存在,就更新下時間戳)
${CMAKE_PARENT_LIST_FILE}: 包含當前文件的 cmake 文件完整路徑,該 menuconfig.cmake 文件是在 Nuttx 項目的根目錄 CMakeLists.txt 被展開的,所以其實也就是 Nuttx 根目錄下的 CMakeLists.txt 文件,更新下這個文件的時間戳
這里 touch 下 Nuttx 根目錄下的 CMakeLists.txt 文件,是因為 cmake 構建依賴文件時間戳,來判斷是否需要重新運行配置;當修改 .config 后,源碼文件本身沒變,cmake 判斷沒有文件改變,就不會自動重新生成 Makefile,此時通過 touch 關鍵的 CMakeLists.txt,來欺騙 cmake 說這里有個文件被修改了,要重新運行 cmake 構建,確保修改配置后,整個構建系統能感知到變化,重新生成配置后的構建產物 - 47 行:設置命令執行時的工作目錄為 NUTTXDIR,{NUTTX_DIR},NUTTXD?IR,{NUTTX_DIR} 是 Nuttx 項目根目錄(這里有總構建入口 CMakeLists.txt 和內核配置 Kconfig 文件)
- 48 行:USES_TERMINAL 告訴構建系統(比如 make),這個 menuconfig 目標需要交互式終端,此時構建系統會使用終端資源,來給用戶顯示 curses 圖形界面
ok,先分析到這里,下篇 blog 分析構建目標時遇到的問題