cmake入门实践

cmake

make/scons类似,cmake也用来管理工程。

cmake是kitware公司及开源开发者在开发工具套件时的衍生品,目前是一个独立的开源项目,诞生于2001年,访问官网获取更多信息:www.cmake.org 。

cmake的优缺点:

  • 跨平台,并可生成native编译配置文件。支持在Linux平台生成Makefile,在Apple平台生成xcode,在Windows平台生成MSVC工程文件
  • 能够管理大型项目,如KDE4
  • 编译构建简单,只需要cmake + make
  • 高效、可扩展,可以为cmake编写特定功能的模块
  • 需要学习cmake语法
  • 与已有体系的配合不是特别理想,如pkgconfig

建议:

  • 在实践中学习才有效
  • 对于只有几个文件的小项目,直接写Makefile更简单
  • 只适用于c/c++/java
  • 如果已经具备构建体系,如java的ant,则不需要学习

以下内容,需要cmake的支持,请自行安装。

开始编译Hello World

以下2步,完成cmake对Hello World程序的管理:

  • 建立main.c文件,编写经典代码:
#include <stdio.h>

int main()
{
    printf("Hello, world\n");
    return 0;
}
  • 建立 CMakeLists.txt 文件,注意不要漏写最后的s,内容如下:
PROJECT (HELLO)
ADD_EXECUTABLE(hello main.c)

ok,现在可以开始构建和编译了:

  • 执行 cmake .,后面的点号表示当前目录

会出现cmake的一系列输出,执行完成后,当前目录下会生成一些文件,如 CMakeFiles, CMakeCache.txt, cmake_install.cmake 等,当然,还有Makefile。

  • 执行 make,完成编译。使用make VERBOSE=1查看make的详细过程。

至此,当前目录下已经生成可执行文件 hello,运行即可。

说明:

  • PROJECT 指令指定工程名称,可以任意填写,也可以指定支持的语言,默认支持所有语言。语法为:PROJECT(projectname [CXX] [C] [Java])
  • ADD_EXECUTABLE 指定该工程生成文件名为hello的可执行文件,依赖于main.c源文件,多个文件使用空格或者分号分开

注意:以上过程是内部构建,即在工程目录下直接运行命令,这样生成的临时文件无法自动清理,会影响项目管理。后面会说外部构建。

语法规则

  • CMakeLists.txt 的内容不区分大小写,建议内置命令全部使用大写。文件名区别大小写。
  • 如果工程中有多个目录,每个要管理的目录都要有一个CMakeLists.txt文件
  • 变量使用${}取值,注意在IF控制语句中直接使用变量名
  • 建议使用外部构建,不要使用内部构建,即不要直接在工程目录运行命令,建议在新建的build目录下执行指令
多目录管理

目前的目录如下所示:

.
COPYRIGHT
README
CMakeLists.txt
runhello.sh
src/CMakeLists.txt
src/main.c
doc/
doc/hello.txt

主目录下的CMakeLists.txt内容如下:

% cat CMakeLists.txt 
PROJECT (HELLO)
ADD_SUBDIRECTORY(src bin)
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t2)
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t2)

src目录下的CMakeLists.txt内容如下:

ADD_EXECUTABLE(hello main.c)

在主目录下,建立build目录,进入该目录,运行 cmake .. && make,开始构建和编译,完成后hello位于build/bin下。

其中,

  • ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 指令用于向当前工程添加源文件子目录、二进制文件目录及不参与编译的目录。
  • 上述指令可以使用 SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 替换
  • 执行 make install进行安装。可以指定 cmake -DCMAKE_INSTALL_PREFIX=/tmp/t2/usr .. 安装路径前缀
构建动态库和静态库

主目录下的CMakeLists.txt内容如下:

PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)

lib目录下有hello.c和hello.h,内容如下:

// hello.c
#include <stdio.h>

void HelloFunc()
{
    printf("hello world\n");
}

// hello.h
#ifndef HELLO_H_
#define HELLO_H_

#include <stdio.h>
void HelloFunc();

#endif

lib目录下CMakeLists.txt内容如下:

% cat lib/CMakeLists.txt 
SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) # 以源文件生成共享库
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) # 以源文件生成静态库,目标名字与动态库区分
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") # 静态库的输出名字依然使用hello
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1) # 不要清除我
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) # 不要清除我
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1) # 为动态库设置版本号

构建方法如下,在build/lib/下分别生成如下库文件:

在这里插入图片描述

使用共享库

主目录CMakeLists.txt内容如下:

PROJECT(NEWHELLO)
ADD_SUBDIRECTORY(src)

src目录下的main.c文件:

#include <hello.h>

int main()
{
    HelloFunc();
    return 0;
}

src目录下的CMakeLists.txt内容如下:

ADD_EXECUTABLE(main main.c)
INCLUDE_DIRECTORIES(/home/demo/cmake/t3/lib) # 依赖的h文件路径
LINK_DIRECTORIES(/home/demo/cmake/t3/build/lib) # 依赖的库文件路径
TARGET_LINK_LIBRARIES(main hello) # 链接时依赖的库

外部构建即可。

总结

cmake为跨平台的应用提供了一种简便的管理方式,值得学习。

它的强实践性就像make和scons,在使用中才能学的更多。

我只是入门,更多内容继续学习。

参考资料

《Cmake实践》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值