CMake 快速指南

CMake

CMake使用简单方便,可以跨平台,构建项目编译环境。尤其比直接写Makefile简单(在构建大型工程编译时,需要写大量的文件依赖关系),可以通过简单的CMake生成负责的Makefile文件。


CMake使用介绍

cmake命令会执行目录下的CMakeLists.txt配置文件里面的配置项,一个基本的CMakeLists.txt的配置 文件内容如下:

1    cmake_minimum_required (VERSION 2.8)    #要求cmake最低的版本号
2    project (demo) # 定义当前工程名字
3    set(CMAKE_BUILD_TYPE "Debug")#设置debug模式,如果没有这一行将不能调试设断点
4    set(CMAKE_CXX_FLAGS ${
    
    CMAKE_CXX_FLAGS} -g)
5    add_executable(main main.c)
6
7    #进入子目录下执行 CMakeLists.txt文件    这里的lib和tests里面都有可编译的代码文件
8    add_subdirectory(lib)
9    add_subdirectory(tests)

示例一

生成一个main.cpp源文件,输出"hello world",然后在同级目录创建一个CMakeLists.txt文件,内容
如下:

1    cmake_minimum_required (VERSION 2.8)    #要求cmake最低的版本号
2    project (demo) # 定义当前工程名字
3    set(CMAKE_BUILD_TYPE "Debug")#设置debug模式,如果没有这一行将不能调试设断点
4    add_executable(main main.cpp)

保存退出,执行cmake .命令
ls查看目录,可以发现除了CMake生成的一些中间文件,还生成好了Makefile文件

1    tony@tony-virtual-machine:~/code/cmake/rpc$ ls
2  //  CMakeCache.txt  CMakeFiles  cmake_install.cmake  CMakeLists.txt  main.cpp  Makefile

make开始编译,最终生成可执行文件main

1    tony@tony-virtual-machine:~/code/cmake/rpc$ make
2    Scanning dependencies of target main
3    [ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
4    [100%] Linking CXX executable main
5    [100%] Built target main

查看生成的可执行文件:

上面生成的Makefile里面实现了clean,所以make clean可以清除生成的文件,然后重新编译源码。


示例二

如果需要编译的有多个源文件,可以都添加到add_executable(main main.cpp test.cpp)列表当中, 但是如果源文件太多,一个个添加到add_executable的源文件列表中,就太麻烦了,此时可以用 aux_source_directory(dir var)来定义源文件列表,使用如下:

1    cmake_minimum_required (VERSION 2.8)
2    project (demo)
3    aux_source_directory(. SRC_LIST) # 定义变量,存储当前目录下的所有源文件
4    add_executable(main ${
    
    SRC_LIST})

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


1    cmake_minimum_required (VERSION 2.8)
2    project (demo)
3    set( SRC_LIST
4         ./main.cpp
5         ./test.cpp)
6    add_executable(main ${
    
    SRC_LIST})

CMake 常用预定义变量

PROJECT_NAME : 通过 project() 指定项目名称
PROJECT_SOURCE_DIR : 工程的根目录
PROJECT_BINARY_DIR : 执行 cmake 命令的目录
CMAKE_CURRENT_SOURCE_DIR : 当前 CMakeList.txt 文件所在的目录
CMAKE_CURRENT_BINARY_DIR : 编译目录,可使用 add subdirectory 来修改
EXECUTABLE_OUTPUT_PATH : 二进制可执行文件输出位置
LIBRARY_OUTPUT_PATH : 库文件输出位置
BUILD_SHARED_LIBS : 默认的库编译方式 ( shared 或 static ) ,默认为 static
CMAKE_C_FLAGS : 设置 C 编译选项
CMAKE_CXX_FLAGS : 设置 C++ 编译选项
CMAKE_CXX_FLAGS_DEBUG : 设置编译类型 Debug 时的编译选项
CMAKE_CXX_FLAGS_RELEASE : 设置编译类型 Release 时的编译选项
CMAKE_GENERATOR : 编译器名称
CMAKE_COMMAND : CMake 可执行文件本身的全路径
CMAKE_BUILD_TYPE : 工程编译生成的版本, Debug / Release



CMake构建项目

一个正式的工程构建

一个正式的源码工程应该有这几个目录:

-bin
-build
-include
     --sum.h
     --minor.h
-src
     --sum.cpp
     --minor.cpp
-main.cpp
-CMakeLists.txt

CMakeLists.txt如下:

1    cmake_minimum_required (VERSION 2.8)
2    project (math) 
4    # 设置cmake的全局变
5    set(EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/bin) 
7    #添加头文件路径,相当于makefile里面的-I
8    include_directories(${
    
    PROJECT_SOURCE_DIR}/include) 
10    aux_source_directory (src SRC_LIST) 
12    add_executable (main main.cpp ${
    
    SRC_LIST})

然后在build目录里面执行cmake … 命令,这样所有的编译中间文件都会在build目录下,最终的可执行 文件会在bin目录里面

26    tony@tony-virtual-machine:~/code/cmake/rpc$ cd bin/
27    tony@tony-virtual-machine:~/code/cmake/rpc/bin$ ls
28    main

静态库和动态库的编译控制

把上面的sum和minor源文件直接生成静态库或者动态库,让外部程序进行链接使用,代码结构如下:

-bin
-build
-include
     --sum.h
     --minor.h
-src
     --sum.cpp
     --minor.cpp
-test
     --main.cpp
     --CMakeLists.txt

最外层的CMakeLists.txt是总控制编译,内容如下:

1    cmake_minimum_required (VERSION 2.8)
2    project (math)
3
4    add_subdirectory (test)
5    add_subdirectory (src)

src里面的源代码要生成静态库或动态库,CMakeLists.txt内容如下:

1    set (LIBRARY_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/lib)     # 生成库,动态库是SHARED,静态库是STATIC
3    add_library (sum SHARED sum.cpp)
4    add_library (minor SHARED minor.cpp)     # 修改库的名字
6    #set_target_properties (sum PROPERTIES OUTPUT_NAME "libsum")
7    #set_target_properties (minor PROPERTIES OUTPUT_NAME "libminor")

test里面的CMakeLists.txt内容如下:

1    set (EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/bin) 
3    include_directories (../include) # 头文件搜索路径
4    link_directories (${
    
    PROJECT_SOURCE_DIR}/lib) # 库文件搜索路径 
6    add_executable (main main.cpp) # 指定生成的可执行文件
7    target_link_libraries (main sum minor) # 执行可执行文件需要依赖的库

在build目录下执行cmake …命令,然后执行make,如下

1    tony@tony-virtual-machine:~/code/cmake/rpc02/build$ make
2    [ 16%] Building CXX object src/CMakeFiles/minor.dir/minor.cpp.o
3    [ 33%] Linking CXX shared library ../../lib/libminor.so
4    [ 33%] Built target minor
5    [ 50%] Building CXX object src/CMakeFiles/sum.dir/sum.cpp.o
6    [ 66%] Linking CXX shared library ../../lib/libsum.so
7    [ 66%] Built target sum
8    Scanning dependencies of target main
9    [ 83%] Building CXX object test/CMakeFiles/main.dir/main.cpp.o
10    [100%] Linking CXX executable ../../bin/main
11    [100%] Built target main

查看生成的可执行文件,检验其链接的库有哪些

1 tony@tony-virtual-machine:~/code/cmake/rpc02/bin$ ls
2 main
3 tony@tony-virtual-machine:~/code/cmake/rpc02/bin$ ./main 4 20 + 10 = 30
5 20 - 10 = 10
6 tony@tony-virtual-machine:~/code/cmake/rpc02/bin$ readelf -d ./main 7
8 Dynamic section at offset 0x1d48 contains 31 entries:
9 标记 类型 名称/值
10 0x0000000000000001 (NEEDED) 共享库: [libsum.so]
11 0x0000000000000001 (NEEDED) 共享库: [libminor.so]
12 0x0000000000000001 (NEEDED) 共享库: [libstdc++.so.6]
13 0x0000000000000001 (NEEDED) 共享库: [libc.so.6]

猜你喜欢

转载自blog.csdn.net/juggte/article/details/125777285