一、环境安装
-  win10安装wsl ubuntu2004 #windows c盘工程目录建立软链ln-s/mnt/c/home/vrviu/
- 安装cmake、c++编译工具 aptinstall-y cmake g++
二、CMakeLists.txt讲解
- 准备工作 首先,在/home/vrviu 目录建立一个 cmake 目录 以后我们所有的 cmake 练习都会放在cmake 的子目录下 然后在 cmake 建立第一个练习目录 t1 cd cmake mkdir t1 cd t1 在 t1 目录建立 main.c 和 CMakeLists.txt(注意文件名大小写): main.c 文件内容: //main.c#include <stdio.h>intmain(){printf(“Hello World from t1 Main!\n”);return0;}CmakeLists.txt 文件内容: PROJECT (HELLO)SET(SRC_LIST main.c)MESSAGE(STATUS"This is BINARY dir "${HELLO_BINARY_DIR})MESSAGE(STATUS"This is SOURCE dir "${HELLO_SOURCE_DIR})ADD_EXECUTABLE(hello SRC_LIST)
-  开始构建 指令: cmake . 
 成功建立如下: 包括:CMakeCache.txt、CMakeFiles、cmake_install.cmake、Makefile等中间文件。 
 指令:make PS:可以使用make VERBOSE=1来查看make构建的详细过程。 
 这个时候已经生成了hello.
 指令:./hello 以上是cmake构建的全部过程。 
- 详细解释 CMakeLists.txt,是cmake 的构建定义文件,文件名 是大小写相关的,如果工程存在多个目录,需要确保每个要管理的目录都存在一个 CMakeLists.txt。 PROJECT 指令的语法是: PROJECT(projectname [CXX] [C] [Java]) 同时 cmake 系统也帮助我们预定义了 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR 变量,他们的值分别跟 HELLO_BINARY_DIR 与 HELLO_SOURCE_DIR 一致。 建议以后直接使用 PROJECT_BINARY_DIR,PROJECT_SOURCE_DIR,即 使修改了工程名称,也不会影响这两个变量。如果使用了 <projectname>_SOURCE_DIR,修改工程名称后,需要同时修改这些变量。 SET 指令的语法是: SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) 现阶段,你只需要了解 SET 指令可以用来显式的定义变量即可。 比如我们用到的是 SET(SRC_LIST main.c),如果有多个源文件,也可以定义成: SET(SRC_LIST main.c) MESSAGE 指令的语法是: MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...) 这个指令用于向终端输出用户定义的信息,包含了三种类型: SEND_ERROR,产生错误,生成过程被跳过。 SATUS,输出前缀为—的信息。FATAL_ERROR,立即终止所有 cmake 过程. 我们在这里使用的是 STATUS 信息输出,演示了由 PROJECT 指令定义的两个隐式变量 HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR。 ADD_EXECUTABLE(hello ${SRC_LIST}) 定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中 定义的源文件列表 指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。 上面的 MESSAGE 指令我们已经用到了这条规则: MESSAGE(STATUS “This is BINARY dir” ${HELLO_BINARY_DIR}) 这里需要特别解释的是作为工程名的 HELLO 和生成的可执行文件 hello 是没有任何关系的。 hello 定义了可执行文件的文件名,你完全可以写成: ADD_EXECUTABLE(t1 main.c)编译后会生成一个 t1 可执行文件。 
-  清理工程 
 可以使用make clean清理makefile产生的中间的文件,但是,不能使用make distclean清除cmake产生的中间件。如果需要删除cmake的中间件,可以采用rm -rf ***来删除中间件。
- 外部构建
 在目录下建立一个build文件用来存储cmake产生的中间件,不过需要使用cmake …来运行。其中外部编译,PROJECT_SOURCE_DIR仍然指代工程路径,即/vrviu/cmake/t1,而PROJECT_BINARY_DIR指代编译路径,即/vrviu/cmake/t1/build。
三、动态库、静态库编译,安装
本节建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc向终端输出Hello World字符串。安装头文件和共享库。
- 准备工作
 在/vrviu/cmake中建立t3,用于存放工程文件。
- 建立共享库
 指令:
 cd /cmake/t3
 mkdir lib
 在t2目录下建立CMakeLists.txt,内容如下:PROJECT(HELLOLIB)ADD_SUBDIRECTORY(lib)在lib目录下建立两个两个源文件hello.c和hello.h, hello.c的内容如下: #include "hello.h"voidHelloFunc(){printf("Hello World\n");}hello.h的内容如下: #ifndef HELLO_H#define HELLO_H#include <stdio.h>voidHelloFunc();#endif在lib的目录下建立CMakeLists.txt,内容如下: SET(LIBHELLO_SRC hello.c)SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME"hello")SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)INSTALL(FILES hello.h DESTINATION include/hello)
- 外部构建
 在build目录下:
 cmake ..
 make
 编译成功后,在build文件下的lib文件下可以发现存在一个libhello.so的动态链接库
 ADD_LIBRARY(libname [SHARED|STATIC|MODULE][EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
 不需要在全libhello.so,只需要填写hello即可,cmake系统会自动为你生成libhello.X
 类型有三种:
 SHARED,动态库
 STATIC,静态库
 MODULE,在使用dyld的系统有效,如果不支持dyld,则被当做SHARED对待。
 EXCLUDE_FROM_ALL参数的意思是这个不会被默认构建,除非有其他的组件依赖或者手工构建。
- 添加静态库 在以上的基础上再添加一个静态库,按照一般的习惯,则这个静态库的名字的后缀为.a。 
 我们往lib/CMakeLists.txt中添加一条:SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") 
 这样就可以同时得到libhello.so/libhello.a两个库了。ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC}) 
 使用语句,hello作为target是不能重名的。所以会造成静态库的构建指令无效。SET_TARGET_PROPERTIES(target1 target2 ...PROPERTIES prop1 value1 prop2 value2 ...) 
 这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库的版本和API版本。与他对应的指令是: GET_TARGET_PROPERTY(VAR target property) 
 举例:向lib/CMakeLists.txt中添加:GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME) 
 MESSAGE(STATUS "This is the hello_static OUTPUT_NAME:"${OUTPUT_VALUE})
 如果没有这个属性则会返回NOTFOUND.而使用以上的例子会出现一个问题,那就是会发现libhello.a存在,但是libhello.so会消失,因为cmake在构建一个新的target时,会尝试清理掉其他使用这个名字的库。解决方案如下:
 向lib/CMakeLists.txt中添加SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_PUTPUT 1) 
 SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
 这个时候再进行构建,会发现build/lib目录中同时生成了libhello.so和libhello.a。
- 增加动态库的版本号 SET_TARGET_PROPERTIES(hello PROPERTIES VERION 1.2 SOVERSION 1) 
 VERSION指代动态库版本,SOVERSION指代API版本。此时,会生成三个文件,其中,libhello.so.1.2为动态库的文件名(realname),libhello.so.1为动态库的别名(soname),libhello.so为动态库的链接名(linkname)。  在makefile中-lthello时,makefile会寻找libhello.so,然后将libhello.so.1写入到可执行文件的链接信息中 
-  安装共享库和头文件 
 以上面的例子,将libhello.a、libhello.so以及hello.h安装到系统目录,才能真正让其他人开发使用。例如将共享库安装到/usr/local/lib目录,将hello.h安装到/usr/local/include/hello目录。在lib/CMakeLists.txt中添加指令: INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) 
 INSTALL(FILES hello.h DESTINATION include/hello)
 编译指令:cmake .. 
 make
 make install
 这样就可以将头文件和共享库安装到系统目录/usr/lib和/usr/local/include/hello中了 
四、SDK集成
- 准备工作
 在cmake中创建t4用来存储这一节的资源,在t4目录下创建src目录
- 编码
 在src目录下编写源文件main.c如下:
 t4下的CMakeLists.txt如下:#include <hello.h>intmain(){HelloFunc();return0;}
 t4下的src下的CMakeLists.txt如下:PROJECT(NEWHELLO)ADD_SUBDIRECTORY(src bin)INCLUDE_DIRECTORIES(/usr/local/include/hello)ADD_EXECUTABLE(main main.c)#TARGET_LINK_LIBRARIES(main hello)TARGET_LINK_LIBRARIES(main libhello.a)
- 引入头文件搜索路径
 在src/CMakeLists.txt添加一个头文件搜索路径,如下:INCLUDE_DIRECTORIES(/usr/local/include/hello)
- 配置共享库目录 echo“/usr/local/lib” >>/etc/ld.so.conf#更新/etc/ld.so.cache文件ldconfig
- 编译执行
 在build目录下:
 cmake ..
 make 
- 判断链接sdk
 指令:
 ldd src/main(在目录build下)
 静态库: 
 动态库: