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