会检测依赖文件列表中的变动,如果有改动,就重新编译。否则直接使用编译后的Object文件。
举个例子:
//hellomake.c
#include
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表示冒号后边表示规则,可以认为是一种依赖关系,make会检测这些依赖关系的变化,只有有变化的文件才重新build,这个Makefile的缺陷是如果头文件改动,make并不会重新build
CC :=gcc
CXX :=gcc
CFLAGS :=--std=c++11 -fPIC -shared -O3 -NDEBUG
CXXFLAGS :=--std=c++11 -fPIC -shared -O3 -NDEBUG
INCLUDES := -I.
LIBS_PATH := -L. -L/usr/lib
LIBS := -lstdc++ -lpthread
SRCS :=./hellomake.c
#读依赖的源文件和头文件,生成object文件。%表示替换,即取所有xxx.o的"xxx"
%.o:%.c %.h
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
设置cmake工具最低版本
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
设置项目名,可以指定编译语言
project( [LANGUAGES] [...])
设置变量的值
set(
[[CACHE [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目录
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
常用于添加一个子目录用于编译。比如一个目录包含一个top-level的CMakeLists,该目录下有不同的子目录,包含不同模块的源码,子目录又包含自己的CMakeLists,这个时候top-level的CMakelists需要用add_subdirectory命令包含子目录。
ADD_SUBDIRECTORY
添加链接库目录
link_directories(directory1 directory2 ...)
为某个的target链接一个或多个库,target名在前,库名在后
target_link_libraries( [item1 [item2 [...]]]
[[debug|optimized|general] - ] ...)
例子:
##把target与libsystemc.a库链接
TARGET_LINK_LIBRARIS(${PROJECT_NAME} systemc)
添加可执行文件
add_executable( [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
例子
##从源文件生成helloworld的可执行文件
ADD_EXECUTABLE(helloworld helloworld.cpp)
使top-level的target依赖于其他的target,确保top-level的target编译前,其他target已经编译。
add_dependencies(aarch64_toplevel simplecpu)
这个target是通过add_executeable命令或add_library命令指定的。
查找文件的完整路径
find_file (
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
)
显示字符信息,变量和字符串之间要有空格,不然cmake会出warning
跟C中宏定义有点相似,注意括号的区别
if (FPGA_SUPPORT)
set(FPGA_CFLAS "-DFPGA_SUPPORT=1")
else ()
set(FPGA_CFLAS "-DFPGA_SUPPORT=0")
endif()
如果需要外部的包,需要cmake在编译时去找对应的头文件路径、库文件路径、库名。find_package命令语法入下:
FIND_PACKAGE( [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文件会设置搜索头文件和库文件的路径。找到包以后,会自动设置下面的变量。
_FOUND
_INCLUDE_DIRS or _INCLUDES
_LIBRARIES or _LIBRARIES or _LIBS
_DEFINITIONS