cmake使用

tags: 嵌入式
categories: 開發

cmake 總結

交叉編譯

  • 設置編譯器
    CMAKE_FORCE_C_COMPILER($ENV{CROSS}gcc GNU)
  • 設置pkg-config執行的位置
    set(PKG_CONFIG_EXECUTABLE $ENV{PKG_CONFIG})
  • 設置工程名
    project(suma_middleware)
  • 設置工程的相關變量
    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR mips)

基本功能

  • 使用系統變量
    增加$ENV{xxx},使用系統變量xxx,因為目前使用的交叉編譯的方法是使用source xxx.sh文件的方法將相關的變量增加到當前終端的系統變量中。所以需要大量的變量都是這種形式的。
  • 設置相關代碼子目錄
    按照分層的結構,比如在下一層的src中有代碼,使用如下的方式增加:
    add_subdirectory(xxx)
    以上方法需要確保xxx目錄中有CMakcLists.txt文件。
  • 設置頭文件查找位置
    cmake文檔中使用
    include_directories(xxx)
    目前我的方法是使用:
    set(dir)
    list(APPEND dir ${dir1})
    include_directories(${dir})
    以上的方式來添加編譯的選項

  • 設置庫搜索的位置
    link_directories(xxx)
    查找xxx位置有無制定的庫。
    可以按照頭文件設置的方法進行管理,這樣便于管理

  • 設置鏈接庫的名字
    在生成對應的可執行程序(或者庫)后面執行
    target_link_libraries(xxx ${libname})
    小坑:注意此處增加libname cmake會自動腦補成lib${libname}.so (或者a)的文件名。

  • 使用pkg-config機制查找庫

    • 配置package
      find_package(PkgConfig)

    • 定義宏

      macro(detectpkgconfig lib LIBNAME)  
      
      pkg_check_modules(${LIBNAME} REQUIRED ${lib} )  
      message(STATUS 'lib is' ${lib}^^^ "${LIBNAME}_INCLUDE_DIRS is " ${${LIBNAME}_INCLUDE_DIRS})  
      message(STATUS ${lib}^^^ "${LIBNAME}_CFLAGS is " ${${LIBNAME}_CFLAGS})  
      set(${LIBNAME}_INCLUDE_DIRS)  
      
      endmacro(detectpkgconfig)  
      
    • 調用宏
      detectpkgconfig(directfb DIRECTFB)

    • 增加庫相關頭文件位置
      include_directories(${DIRECTFB_INCLUDE_DIRS})

    • 增加庫位置
      link_directories(${DIRECTFB__LIBRARY_DIRS})

  • 生成可執行文件
    add_executable(demo main.c)

  • 生成庫文件
    add_library(xxx ${SRC_LIST}) (有變量可以定義生成的為靜態庫或者是動態庫)

  • 鏈接順序
    編寫makefile的時候就容易踩得坑。現在也需要注意庫的依賴順序和添加順序有關系。

  • 查找特定名稱的庫
    因為之前項目中歷史遺留問題生成的庫沒有按照標準的libxx.a或者libxx.so寫法,需要手動制定特定的位置以及文件名。

    find_library(KERNEL_DRV NAMES xxx.a PATHS ${PROJECT_LIB_PATH})  
    
    在指定的 PROJECT_LIB_PATH路徑下尋找xxx.a文件。生成變量保存在KERNEL_DRV_NAMES變量中。
    
  • 編譯的不同時期執行特定的腳本
    部分項目,因為屬于不同項目組,沒有統一編譯的環境,而且他們也不準備花時間統一,所以用他們的最新的庫,需要使用腳本來進行編譯... ...
    到此處,我用cmake改寫的過程中深深的體會到了,隊友的重要性。
    add_custom_command(TARGET demo PRE_BUILD
    COMMAND echo ARGS "##### build xxx start ###### "
    WORKING_DIRECTORY $ENV{xxxxx})
    在WORKING_DIRECTORY 目錄xxxxx中執行腳本。對象為demo,也就是說在編譯demo之前執行以上腳本。但是cmake的文檔中好像提到PRE_BUILD只在特定的編譯環境有效果,所以在一般情況下,表示鏈接階段。

總結

  • cmake 語法的特點,使用大寫變量表示變量類型
  • prefix機制,不少地方定義一個變量xxx以后.實際是定義了一個${prefix},會有 cmake中,類似全局變量的${prefix}_xxx存在,可以直接調用。比如前面說的pkg-config

疑問

  • 變量的作用域。
  • 變量的初始化,在改寫工程過程中,初始化已經定義的list,不再有效。(類型設置有問題???)
  • 函數和marco的區別聯系初看文檔說是主要變量作用域的區別,暫時沒來得及細看,目前使用的是marco

主要參考資料

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.安裝 $sudo apt-get install cmake 2.示例:簡單的文件目錄 sample |—...
    荷包蛋醬閱讀 29,707評論 0 15
  • 注:首發地址 1. 前言 當在做 Android NDK 開發時,如果不熟悉用 CMake 來構建,讀不懂 CMa...
    cfanr閱讀 24,556評論 1 53
  • 剛才認真的聽完了楊亮老師的講話,大師就是大師。身份定位:我是誰?喚醒者:支持者,陪伴者,引領者。每個人都圓潤俱足。...
    自我探索閱讀 104評論 0 0
  • 晚飯后,一個人在樓區散步。 好久沒這么漫無目的地走了,因為總控制不住向前奔。生命似乎是一段一段的,過了一段平靜期,...
    方佳水閱讀 141評論 2 4
  • 今夕是何夕,往日如流水般一樣,匆匆而過,時時感嘆時間過得飛快,而我們正在時間里充當著過客,我們所走的路,都是暫借的...
    盧小碩閱讀 312評論 0 1