Cmake学习笔记

  • Post author:
  • Post category:其他




1.安装Cmake

在ubuntu的终端下使用如下命令:

sudo apt-get install cmake



2.创建好自己的项目

例如项目组成如下:

|-bin

|-build

|-include

|- -程序头文件

|-src

|- -程序源文件

|-CMakeLists.txt


其中,bin文件夹存放项目最终输出的elf可执行文件,build文件夹存放生成的对象文件,include文件夹存放项目中程序的.h头文件,src文件夹存放项目中程序的.c源文件,CMakeLists.txt为下一步需要编写的cmake脚本文件



3.编写CMakeLists.txt文件

在项目中创建并编写CMakeLists.txt,命令如下:

touch CMakeLists.txt

编写信息如下:

cmake_minimum_required (VERSION 3.5)
project (demo)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory (src SRC_LIST)
include_directories (include)
add_executable (main ${SRC_LIST})

其中:


第一行意思是表示我们cmake的最低版本要求是2.8,我电脑安装的是3.5.1;

第二行是表示本工程信息,也就是工程名叫demo

第三行把存放elf文件的位置设置为工程根目录下的bin目录


note:

EXECUTABLE_OUTPUT_PATH为CMake自带的预定义变量,表示目标二进制可执行文件的存放位置

PROJECT_SOURCE_DIR一样,在cmake中表示工程的根目录

cmake中变量使用${}方式取值。


第四行使用aux_source_directory命令把指定目录下的源文件列表存放到变量SRC_LIST里


note:

aux_source_directory()会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件,如下:

set( SRC_LIST
	 ./main.c
	 ./func1.c
	 ./func2.c)


第五行使用include_directories命令向工程添加多个指定头文件的搜索路径

第六行比较关键,表示最终要生成的elf文件的名字叫main,使用的源文件是main.c



4.运行cmake生成Makefile文件

使用外部编译方式编译项目,项目终端输入命令:

cd build	//进入目录build
cmake ..	//运行cmake命令

第二行命令使cmake检测编译环境,并在bulid文件夹生成相应的Makefile文件和运行中产生的中间文件。“…”代表父目录,因为CMakeLists.txt文件存在于父目录。



5.使用make命令编译程序

输入命令:

make

运行命令make进行编译。编译后,生成的所有中间文件在build目录下。由于我们修改可执行文件的存放位置为项目的bin文件夹,因此make命令最终生成的elf文件在bin文件中。

如果要清除生成的elf文件,使用命令:

make clean



6.运行elf文件

使用命令:

./文件名



7.cmake中动态库和静态库的编译控制

在项目中当我们写好自己的程序且无需修改时,别人需要调用我们写好的程序,我们只需要把写好的程序编译出静态库或动态库。因为静态库只在链接的时候才进行,可以减少他人编译程序时的时间。

动态库文件扩展名常为 “.so”; 静态库文件扩展名常为 “.a”,我们通常希望静态库和动态库文件名保持一致,只是扩展名不同。



eg:文件树如下

在这里插入图片描述

CMakeLists.txt信息如下:

cmake_minimum_required (VERSION 3.5)

project (demo)

set(SRC_LIST ${PROJECT_SOURCE_DIR}/src/testFunc.c)

add_library(testFunc_shared SHARED ${SRC_LIST})

add_library(testFunc_static STATIC ${SRC_LIST})

set_target_properties(testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")

set_target_properties(testFunc_static PROPERTIES OUTPUT_NAME "testFunc")

include_directories(${PROJECT_SOURCE_DIR}/include)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

cmake中动态库和静态库的编译控制命令如下:

add_library (func_shared SHARED ${SRC_LIST})	//生成动态库
add_library (func_static STATIC ${SRC_LIST})	//生成静态库

add_library函数用以生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态库还是静态库,如果没有就默认为静态;第3个参数指定生成库的源文件)


注:


上面提到静态库和动态库文件名通常保持一致,但add_library函数中库的名字不能够和其他文件重名的。因此需要添加“_shared”或“_static”,然后使用set_target_properties函数设置库输出的名称。命令如下:

set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "func")
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "func")

这样,我们就可以同时得到 func.so和func.a 两个库了。

然后指定cmake编译后库的存放路径,命令如下:

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

LIBRARY_OUTPUT_PATH为库文件的默认输出路径,这里设置为工程目录下的lib目录。



8.cmake中库的链接



eg:文件树如下

在这里插入图片描述

CMakeLists.txt信息如下:

cmake_minimum_required (VERSION 3.5)

project (demo)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)

include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)

add_executable (main ${SRC_LIST})

target_link_libraries (main ${PROJECT_SOURCE_DIR}/testFunc/lib/libtestFunc.so)

target_link_libraries()函数把目标文件与库文件进行链接,这里采用了绝对路径方式。



版权声明:本文为qq_42784403原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。