cmake 教程

cmake 教程


1. 创建CMakeLists.txt

在工程中,需要创建很多的CMakeLists.txt,在运行 cmake 时,cmake会根据这些文件,对我们构建的依赖关系创建makefile。
这里以一个最小的工程为例,来实现cmake编译管理工程。

常用的工程目录结构如下:

[duapple@duapple-pc test]$ tree -N -L 3 -I 'build|bin'
.
├── CMakeLists.txt
├── include
│   └── play.h
├── lib
│   ├── CMakeLists.txt
│   └── mylib
│       ├── CMakeLists.txt
│       ├── mylib.c
│       └── mylib.h
└── src
    ├── CMakeLists.txt
    ├── main.c
    └── play.c

4 directories, 9 files
[duapple@duapple-pc test]$ 

一般将 .c 文件放到src中,.h 文件放到include中,然后lib目录存放我们自己的库。main.c可以放顶层目录,也可以放src中。

这里有两个思路构建CMakeLists.txt。一种是:由于工程比较简单,在顶层目录下编写CMakeLists.txt即可,通过这一个文件来生成makefile。第二种是:在每一个目录下都编写CMakeLists.txt,没一个目录下的文件只负责自己目录下的文件依赖关系。

这里我采用第二种方式。

  • 先主目录编写CMakeLists.txt。
# CMake 最低版本号要求
cmake_minimum_required(VERSION 3.1)

# 项目信息
project(test_project)

# 添加  子目录
add_subdirectory(lib)
add_subdirectory(src)
  • lib中编写CMakeLists.txt。(按理来说这里,应该也是可以跳过这个目录在lib/mylib 中直接编写一个就行了,在顶层路径下指定子目录为lib/mylib)
add_subdirectory(mylib)
  • lib/mylib中编写CMakeLists.txt。
aux_source_directory(. SRC_LIST)

include_directories(../include ../lib/mylib)

add_library(mylib STATIC ${SRC_LIST})
  • src中编写CMakeLists.txt。
aux_source_directory(. SRC_LIST)

# 添加头文件搜索路径
include_directories(../include ../lib/mylib)

add_executable(test ${SRC_LIST})

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# 链接库的搜索路径
link_directories("../lib/mylib")

# 添加链接库
target_link_libraries(test m mylib)

至此,CMakeLists.txt文件编写完成,非常的简单明了。如果是在顶层路径下编写一个CMakeLists.txt,那么将更加的简单。cmake的语法是易读的,看一些例子就知道这些语句的作用是什么了。

2. 编译

开始生成makefile。

$ mkdir build & cd build
$ cmake ../

编译。(这里可能会遇到链接先后的顺序的问题,链接顺序不对导致出现函数未定义的情况。将需要的库先链接即可。还有可能出现库的相互依赖问题。暂时没有遇到。)

[duapple@duapple-pc build]$ make 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/duapple/work/cmake/test/build
[ 20%] Building C object lib/mylib/CMakeFiles/mylib.dir/mylib.c.o
[ 40%] Linking C static library libmylib.a
[ 40%] Built target mylib
[ 60%] Building C object src/CMakeFiles/test.dir/main.c.o
[ 80%] Building C object src/CMakeFiles/test.dir/play.c.o
[100%] Linking C executable ../../bin/test
[100%] Built target test

运行。

[duapple@duapple-pc build]$ ../bin/test 
play_1 called.
mylib_1 called.
3^4 = 81.000000

3. 快捷生成

每次都需要自己手动编写CMakeLists.txt,比较麻烦。写一个脚本来快捷生成模板。

  • 编写模板文件gen_cmake.conf.
# 支持的最低版本
cmake_minimum_required(VERSION 3.0)

# 项目名称
project(project_name)

# 可执行文件名称
set(OUT_EXEC "out")

# 源文件目录
aux_source_directory(. SRC_LIST)

# 头文件路径
include_directories(./)

# 添加编译参数
add_compile_options(-Os -g -std=gnu99)

# 设置可执行文件输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})

# 链接库的路径
link_directories(./)

# 生成可执行文件
add_executable(${OUT_EXEC} ${SRC_LIST})

# 添加链接库
target_link_libraries(${OUT_EXEC} )

  • 编写生成脚本gen_make.sh
#!/bin/bash

cp /usr/local/sbin/gen_cmake.conf ./CMakeLists.txt
  • 设置权限,并放到可执行系统路径下。
$ sudo chmod 777 gen_cmake.sh
$ sudo chmod 777 gen_cmake.conf
$ sudo chmod +x gen_cmake.sh
$ sudo cp gen_cmake.sh gen_cmake.conf /bin/
$ gen_cmake.sh

效果如下:
请添加图片描述

交叉编译模板 gen_cross_cmake.conf

# 支持的最低版本
cmake_minimum_required(VERSION 3.0)

# 项目名称
project(project_name)

# 可执行文件名称
set(OUT_EXEC "main")

# 指定交叉编译器路径
set(TOOLSCHAIN_PATH "/opt/arm-2014.05/")
set(TOOLCHAIN_HOST "${TOOLSCHAIN_PATH}/bin/arm-none-linux-gnueabi")

# 设置工具链编译器
set(TOOLCHAIN_CC "${TOOLCHAIN_HOST}-gcc")
set(TOOLCHAIN_CXX "${TOOLCHAIN_HOST}-g++")

#告诉cmake是进行交叉编译
set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSTEM_NAME "Linux")

# Define the compiler
set(CMAKE_C_COMPILER ${TOOLCHAIN_CC})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_CXX})

# 源文件目录
aux_source_directory(. SRC_LIST)

# 头文件路径
include_directories(./)

# 添加编译参数
add_compile_options(-Os -g -std=gnu99)

# 设置可执行文件输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})

# 链接库的路径
link_directories(./)

# 生成可执行文件
add_executable(${OUT_EXEC} ${SRC_LIST})

# 添加链接库
target_link_libraries(${OUT_EXEC} )

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值