文章目錄
Makefile
會檢測依賴文件列表中的變動,如果有改動,就重新編譯。否則直接使用編譯後的Object文件。
舉個例子:
//hellomake.c
#include <hellomake.h>
int main(){
myPrintHelloMake();
return 0;
}
//hellomake.h
void myPrintHelloMake();
//hellofunc.c
void myPrintHelloMake(){
printf("Hello makefile\n")
}
##Makefile
CC=gcc
CFLAGS=-I.
hellomake:hellomake.o hellofunc.o
$(CC) -o hellomake hellomake.o hellofunc.o
hellomake表示冒號後邊表示規則,可以認爲是一種依賴關係,cmake會檢測這些依賴關係的變化,只有有變化的文件才重新build,這個Makefile的缺陷是如果頭文件改動,cmake並不會重新build
CMake
CMake默認變量
- CMAKE_SOURCE_DIR:cmake命令開始的目錄,也叫source tree 根目錄
- CMAKE_CURRENT_SOURCE_DIR:目前正在處理的CMakeLists.txt 所在位置。
版本要求命令
設置cmake工具最低版本
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT命令
設置項目名,可以指定編譯語言
project(<PROJECT-NAME> [LANGUAGES] [<language-name>...])
SET命令
設置變量的值
set(<variable> <value>
[[CACHE <type> <docstring> [FORCE]] | PARENT_SCOPE])
例子:
##設置源碼文件名
set(SRC_LIST helloworld.cpp)
##設置環境變量
set(ENV($PATH) /home/chifred/vcs/bin
#覆蓋Cmake默認編譯選項
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEBUG_LOG=1")
若要引用上面的源碼文件名,如下:
${SRC_LIST}
INCLUDE_DIRECTORIES命令
添加include目錄
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
ADD_SUBDIRECTORY命令
常用於添加一個子目錄用於編譯。比如一個目錄包含一個top-level的CMakeLists,該目錄下有不同的子目錄,包含不同模塊的源碼,子目錄又包含自己的CMakeLists,這個時候top-level的CMakelists需要用add_subdirectory命令包含子目錄。
ADD_SUBDIRECTORY
LINK_DIRECTORIES命令
添加鏈接庫目錄
link_directories(directory1 directory2 ...)
TARGET_LINK_LIBRARIES命令
爲某個的target鏈接一個或多個庫,target名在前,庫名在後
target_link_libraries(<target> [item1 [item2 [...]]]
[[debug|optimized|general] <item>] ...)
例子:
##把target與libsystemc.a庫鏈接
TARGET_LINK_LIBRARIS(${PROJECT_NAME} systemc)
ADD_EXECUTABLE命令
添加可執行文件
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
例子
##從源文件生成helloworld的可執行文件
ADD_EXECUTABLE(helloworld helloworld.cpp)
ADD_DEPENDENCIES命令
使top-level的target依賴於其他的target,確保top-level的target編譯前,其他target已經編譯。
add_dependencies(aarch64_toplevel simplecpu)
這個target是通過add_executeable命令或add_library命令指定的。
FIND_FILE命令
查找文件的完整路徑
find_file (
<VAR>
name | NAMES name1 [name2 ...]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
例子:
##搜索指定目錄和文件名的文件,返回完整文件路徑
FIND_FILE(FILE_NAME
helloworld.cpp
PATHS /home/chifred/c++/project
)
MESSAGE命令
顯示字符信息,變量和字符串之間要有空格,不然cmake會出warning
條件判斷語法
跟C中宏定義有點相似,注意括號的區別
if (FPGA_SUPPORT)
set(FPGA_CFLAS "-DFPGA_SUPPORT=1")
else ()
set(FPGA_CFLAS "-DFPGA_SUPPORT=0")
endif()
find_package命令
如果需要外部的包,需要cmake在編譯時去找對應的頭文件路徑、庫文件路徑、庫名。find_package命令語法入下:
FIND_PACKAGE( <name> [version] [EXACT] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets... ] ] )
find_package會去CMAKE_MODULE_PATH指定的目錄中尋找Findname.cmake並執行。所以要修改CMAKE_MODULE_PATH變量,並且自己寫Findename.cmake文件。例子如下
#添加存放.cmake文件的路徑
set(CMAKE_MODULE_PATH $CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake"
find_package(Lua)
if(LUA_FOUND)
include_directories(${LUA_INCLUDE_DIR})
else()
message(FATAL_ERROR "LUA library not found")
endif ()
上述會去cmake文件夾下搜索FindLua.cmake文件,並執行。這個.cmake文件會設置搜索頭文件和庫文件的路徑。找到包以後,會自動設置下面的變量。
<name>_FOUND
<name>_INCLUDE_DIRS or <NAME>_INCLUDES
<name>_LIBRARIES or <name>_LIBRARIES or <name>_LIBS
<name>_DEFINITIONS