CMake教程快速入门

一、CMake是什么?

    CMake是一个跨平台的安装(编译)工具,可以用简单的语句描述所有平台下的安装或编译过程。CMake是一种高级编译配置工具,多个人使用不同的语言或者编译器开发一个项目,最终要输出一可执行文件或者共享库(DLL,so等等),就可以通过CMake来完成。所有操作都通过编译CMakeLists.txt来完成(cmake本质是生成Makefile的工具)

二、CMake常用命令

通过在CMakeLists.txt中写入生成工程的CMake命令,随后执行相应的命令,即可生成工程的Makefile;
常用命令如下:
PROJECT:指定工程的名字和支持的语言,默认支持所有语言;

PROJECT(HELLO CXX):支持C++
PROJECT(HELLO C CXX):支持C和C++
该指定隐式定义了两个CMAKE变量
<projectname>_BINARY_DIR,上面写的即HELLO_BINARY_DIR
<projectname>_SOURCE_DIR,上面写的是HELLO_SOURCE_DIRCMAKE中,PROJECT_SOURCE_DIR为包含PROJECT()命令的CMakeLists.txt文件所在的文件夹路径,默认的,不需要定义;
CMAKE_CURRENT_SOURCE_DIR这是当前处理的CMakeLists.txt所在的目录;

SET用来指定变量,相当于变量定义并赋值:

SET(SRC_LIST,main.cpp) ,那么SRC_LIST变量就包含了main.cpp,也可以包含多个;
SET(SOURCE main.cpp test.cpp) #SOURCE代表了main.cpp和test.cpp,后续用${SOURCE}取变量

ADD_EXECUTABLE生成可执行文件

ADD_EXECUTABLE关键字:生成可执行文件
ADD_EXECUTABLE(hello $(SRC_LIST)) 通过变量SRC_LIST中的源文件生成可执行文件名是hello,源文件读取变量SRC_LIST中的内容;
file(GLOB_RECURES variableName 源文件),递归匹配路径下的文件,并存入变量名variable 中;
file(GLOB_RECURSE LEF_FILES ${PROJECT_SOURCE_DIR}/common/*.cpp)

add_library用户生成链接库,静态或动态;

add_library(动态库名,SHARED | STATIC  源文件)add_library(<name>  [STATIC | SHARED | MOUDLE]  [EXCLUDE_FROM_ALL] [SOURCE1] [SOURCE2] [...])
name:生成库的名字
MOUDLE:不会被连接到其他文件中的插件,但是可能会在一些地方被用到;

包含目录,链接目录等最好都放在ADD_EXECUTABLE()之前,以防出现找不到头文件的说法;
include_directories();将指定目录添加到 编译器的头文件搜索路径之下,提供搜索头文件路径;默认添加到搜索列表最后,可以通过before fater 参数设置先后;

link_directories()命令是用来 添加需要链接的库文件路经,指定第三方库的路径;链接时根据这个路径去找库;

SET(lib_DIR /usr/lib)#lib_DIR设置为依赖库目录
LINK_DIRECTORIES(${lib_DIR})#添加依赖库路径;

target_link_libraries():设置要链接的库文件的名称; 指定链接给定目标和/或其依赖项时要使用的库。命名的<目标>必须是由add_executable()或add_library()之类的命令创建的,并且不能是ALIAS目标。

TARGET_LINK_LIBRARIES(myProject hello),连接libhello.so库
TARGET_LINK_LIBRARIES(myProject libhello.a)
TARGET_LINK_LIBRARIES(myProject libhello.so)
TARGET_LINK_LIBRARIES(json libjson.so libjson.a)
TARGET_LINK_LIBRARIES(json common)

如果都指明生成的可执行文件的名称,那么此命令要在ADD_EXECUTABLE()之后;否则提示无法为未生成的可执行文件链接;

AUX_SOURCE_DIRECTORY(.DIR_SRCS)#查找指定目录下的所有源文件,然后将结果存进变量名;
ADD_SUBDIRECORY(source_dir [binary_dir] [EXECUTABLE]  [EXCLUDE_FROM_ALL])  
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/common) #把common路径添加到工程,PROJECT_SOURCE_DIR是PROJECT()语句出现的CMakeLists所在的目录;
向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置;

EXCLUDE_FROM_ALL函数是将写的目录从编译中排除,如程序中的example;

ADD_LIBRARY(hello SHARED $(LIBHELLO_SRC)) #生成动态链接库
hello:正常的库名,生成的名字前会加上lib,最终产生的文件时libhello.so
SHARED,动态库 STATIC,静态库
${LIBHELLO_SRC}:源文件

同时生成静态库和动态库
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})//对hello_static的重名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES  OUTPUT_NAME "hello")
//cmake 在构建一个新的target 时,会尝试清理掉其他使用这个名字的库,因为,在构建 libhello.so 时, 就会清理掉 libhello.a
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello PROPERTIES  OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)

添加头文件搜索路径:

INCLUDE_DIRECTORIES(/usr/include/hello)

TARGET_INCLUDE_DIRECTORIES() 指定目标包含的头文件路径;
TARGET_LINK_LIBRARIES():指定目标链接的库

MESSAGE关键字:向终端输出用户自定义信息主要包含三种信息:
SEND_ERROR:产生错误,生成过程被跳过;
STATUS,输出前缀为"–"的信息;
FATAL_ERROR,立即终止所有cmake过程;
举一个简单例子,部分函数放在common文件下,最终要编译json.cpp这个文件成可执行文件;
common中,利用该文件夹下的cpp编译成链接库,默认是静态的;在json.cpp目录下的CMakeLists.txt,需要包含子目录,另外用到第三方json库,动态链接存放在/usr/lib目录下,名字是libjson.so\linjson.a;还要链接上common目录生成的;
在这里插入图片描述
在这里插入图片描述

语法的基本原则
使用${变量名}读取变量,如果在IF控制语句中是直接使用变量名;
指令(参数1 参数2…)参数使用括弧括起,参数之间使用空格或分号分开;
指令是大小写无关的,参数合变量是大小写相关的,但,推荐全部使用大写指令;

内部构建:产生的临时文件特别多,不方便清理
外部构建:会把生成的临时文件放在build目录下,不会对源文件有任何影响,强烈推荐使用外部构建方式;

静态库和动态库的扩展:
静态库:扩展名以.a或者.lib结尾;动态库扩展名一般为".so"或者“.dll”
静态库在编译时会直接整合到目标程序中,编译成功的可执行文件可独立运行;
动态库在编译时不会放到连接的目标程序中(运行时链接),即可执行文件无法单独运行;


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部