CMake 教程

作者: LGmark | 来源:发表于2017-07-02 21:34 被阅读2192次

1. 编译单目录工程

1.创建工程文件夹

mkdir hello #工程目录
cd hello
mkdir src   # 存放源代码的目录
mkdir build # 存放编译中间代码和目标代码的目录

2.进入src目录,编写一个main.c文件

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello world\n");
    return 0;
}

3.编写工程顶层目录的CMakeLists.txt

cmake_minumum_required(VERSION 2.6)

#指定项目名
project(hello)

#指定子目录
add_subdirectory(src)

4.编写子目录srcCMakeLists.txt

aux_source_directory(. SRC_LIST)

add_executable(hello ${SRC_LIST})

5.编译工程

1.进入build 目录
2.执行命令cmake ..创建Makefile
3.执行命令make编译工程
4.在build的子目录src生成了执行文件

2. 编译多目录工程

1.创建工程目录

mkdir hello # 工程目录
cd hello
mkdir src   # 存放源码目录
mkdir build # 存放编译产生的中间文件
cd src      
mkdir hello # 存放hello 模块
mkdir world # 存放world 模块

2.编写hello模块

  • 进入hello目录
  • 编写hello.h文件
#ifndef  HELLO_H
#define  HELLO_H

void Hello_Print(void);

#endif
  • 编写hello.c文件
#include "hello.h"

#include <stdio.h>

void Hello_Print(void)
{
    printf("hello ");
}

  • 编写CMakeLists.txt 文件
aux_source_directory(. DIR_HELLO_SRC)

add_library(hello_lib ${DIR_HELLO_SRC})

3.编写world模块

  • 进入world目录
  • 编写world.h文件
#ifndef  WORLD_H
#define  WORLD_H

void World_Print(void);

#endif
  • 编写world.c文件
#include "world.h"

#include <stdio.h>

void World_Print(void)
{
    printf("world");
}

  • 编写CMakeLists.txt 文件
aux_source_directory(. DIR_WORLD_SRC)

add_library(world_lib ${DIR_WORLD_SRC})

4.编写主模块

  • 进入src目录
  • 编写main.c 文件
#include "hello/hello.h"
#include "world/world.h"

int main(int argc, char **argv)
{
    Hello_Print();
    World_Print();

    return 0
}
  • 编写CMakeLists.txt 文件
add_source_directory(. DIR_SRC)

# 添加子目录
add_subdirectory(hello)
add_subdirectory(world)

# 执行文件
add_executable(hello_prj ${DIR_SRC})
target_link_libraries(hello_prj ello_lib world_lib)

5.编写顶层目录的CMakeLists.txt文件

cmake_minumum_required(VERSION 2.6)

project(hello_prj)

add_subdirectory(src)

3. 动态库和静态库的构建和使用

1.使用一个hello world工程来展开说明
项目结构

|-- CMakeLists.txt
|-- build
|-- include
|   |-- hello
|   |   `-- hello.h
|   `-- world
|       `-- world.h
|-- src
|   |-- CMakeLists.txt
|   |-- hello
|   |   `-- hello.c
|   `-- world
|       `-- world.c
`-- test
    |-- CMakeLists.txt
        `-- mytest.c

2.顶层目录CMakeLists.txt

 cmake_minimum_required(VERSION 2.6)
 
 project(helloworld)
 
 #设置库文件存放路径
 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/lib)
 
 #设置执行文件存放路径
 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/bin)
 
 #获取当前目录及子目录(递归获取),添加到头文件搜索路径
 function(include_sub_directories_recursively root_dir)
     if (IS_DIRECTORY ${root_dir})               # 当前路径是一个目录吗,是的话就加入到包含目录
         message("include dir: " ${root_dir})
         include_directories(${root_dir})
     endif()
 
     file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*) # 获得当前目录下的所有文件,让如ALL_SUB列表中
     foreach(sub ${ALL_SUB})
         if (IS_DIRECTORY ${root_dir}/${sub})
             include_sub_directories_recursively(${root_dir}/${sub}) # 对子目录递归调用,包含
         endif()
     endforeach()
 endfunction()
 
 #项目的所有目录都为头文件搜索路径
 include_sub_directories_recursively(${PROJECT_SOURCE_DIR})
 
 #添加库文件搜索路径
 link_directories(
     ${PROJECT_SOURCE_DIR}/build/lib
     )

 #添加子目录
 add_subdirectory(src)
 add_subdirectory(test)

 #设置安装目录
 set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)


3.helloworld库的源代码
hello.h文件

#ifndef  HELLO_H
#define  HELLO_H

void Hello_Print(void);

#endif

hello.c文件

#include "hello/hello.h"

#include <stdio.h>

void Hello_Print(void)
{
    printf("hello ");
}

world.h文件

#ifndef  WORLD_H
#define  WORLD_H

void World_Print(void);

#endif

world.c文件

#include "world/world.h"

#include <stdio.h>

void World_Print(void)
{
    printf("world");
}

4.子目录src下的CMakeLists.txt

 #递归获取当前目录及子目录下的所有c文件
 file(GLOB_RECURSE c_files "*.c")
 
 #生成动态库和静态库
 add_library(helloworld_lib_shared  SHARED ${c_files})
 add_library(helloworld_lib_static STATIC ${c_files})
 
 #将动态库和静态库的名字设置为一致
 set_target_properties(helloworld_lib_shared PROPERTIES OUTPUT_NAME "helloworld")
 set_target_properties(helloworld_lib_static PROPERTIES OUTPUT_NAME "helloworld")
 
 #设置动态库版本
 set_target_properties(helloworld_lib_shared PROPERTIES VERSION 1.2 SOVERSION 1)
 
 #安装动态库和静态库
 INSTALL(TARGETS helloworld_lib_shared helloworld_lib_static
     LIBRARY DESTINATION lib
     ARCHIVE DESTINATION lib)
 
 #安装头文件
 INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)

5.mytest.c文件测试生成的库文件
mytest.c文件

#include "hello/hello.h"
#include "world/world.h"

#include <stdio.h>

int main(int argc, char **argv)
{
    Hello_Print();
    World_Print();

    printf("\n");
    return 0;
}

CMakeLists.txt文件

#递归获取所有当前目录及子目录下的C文件
file(GLOB_RECURSE c_files ./*.c)
  
#生成执行文件
add_executable(mytest ${c_files})
     
#链接外部库
target_link_libraries(mytest libhelloworld.so)

6.构建工程

1.进入目录build
2.执行命令: cmake ..
3.执行命令: make
4.执行命令: make install

4. 指定编译器和编译选项

1.CMAKE_C_COMPILER: 指定C编译器
2.CMAKE_CXX_COMPILTER:指定C++编译器
3.CMAKE_C_FLAGS: 指定C编译选项
4.CMAKE_CXX_FLAGS:指定C++编译选项
5.EXECUTABLE_OUTPUT_PATH: 指定执行文件存放目录
6.LIBRARY_OUTPUT_PATH: 指定库文件存放目录
7.CMAKE_BUILD_TYPE:指定build类型[Debug|Release]
8.BUILD_SHARED_LIBS: 指定默认库编译方式[OFF|ON]

上述内部变量使用说明:
1.CMakeLists.txt文件上使用set命令
2.cmake 命令中指定,如: cmake -DCMAKE_C_COMPILER=gcc

add_definitions:添加编译参数

5. 配置编译模块

6. CMake 常用变量和语句

1.include_directories:指定头文件搜索路径
2.link_directories:指定库文件搜索路径
3.add_subdirectory:添加子目录
4.target_link_libraries:指定文件链接库文件

相关文章

  • C/C++项目开发编译

    vscode + 插件 C/C++ Cmake : cmake教程 Cmake Tools Remote Deve...

  • ios cmake

    参考cmake 官方教程[https://cmake.org/cmake/help/latest/guide/tu...

  • CMake学习小结--变量

    CMake学习小结 参考资料 CGold的Cmake教程 -- 这个教程很新: https://cgold.rea...

  • CMake官方文档翻译(1) CMake教程 Step by S

    CMake 教程 Step by Step 本教程涉及的源码可在CMake源码的Help/guide/tutori...

  • CMake官方教程

    CMake官方教程 CMake教程提供了逐步指南,涵盖了CMake可以解决的常见构建系统问题。了解示例项目中各个主...

  • CMake教程 (一)

    本文所有示例来源于CMake官方教程:https://cmake.org/cmake-tutorial/ CMak...

  • Android cmake使用外部动态共享库

    官方文档分享: CMake的基本用法参考Android官方文档上的CMake教程: https://develop...

  • cmake教程

    cmake只是生层,能够生层.o之类文件语句的程序,而最终生成.o的还是make 爽一爽 (下面我将cmake生成...

  • CMake 教程

    1. 编译单目录工程 1.创建工程文件夹 2.进入src目录,编写一个main.c文件 3.编写工程顶层目录的CM...

  • CMake教程

    什么是CMake? 你或许听过好几种 Make 工具,例如GNU的Make,QT 的qmake,,微软的MS nm...

网友评论

  • rainzhang:首先感谢你的这么清晰明了的教程。
    我测试的时候发现一个问题
    编译多目录工程 --> 4.编写主模块 --> 编写CMakeLists.txt 文件
    add_source_directory(. DIR_SRC) 应该是 aux_source_directory(. DIR_SRC)

本文标题:CMake 教程

本文链接:https://www.haomeiwen.com/subject/rvupcxtx.html