• VScode环境下使用CMake构建工程


    VS code环境下使用CMake构建工程

    本文主要介绍vscode环境下使用CMake构建工程的详细用法,包含多文件工程的构建,静态链接库/动态链接库文件的生成,外部库文件的使用。

    1. C/C++多文件工程构建

    工程目录结构如下,将头文件放在include中,.c文件放在src目录下,每一个包含源文件(.c/.cpp)的文件夹如果工程需要使用,则都需要通过add_subdirectory的方式添加到工程中。项目的根目录下需要有一个CMakeLists.txt,用来配置工程信息,建立和子目录的联系,每一个包含源码的子目录也都需要一个CMakeLists.txt

    D:.
    │  CMakeLists.txt
    │  main.c
    ├─build
    ├─include
    │      hello.h
    └─src
            CMakeLists.txt
            hello.c
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在工程目录下mian.c文件中调用src文件下的hello.c文件中的函数

    hello.h文件放在include 文件夹中

    工程中的CMakeLists.txt文件如下

    cmake_minimum_required(VERSION 3.0.0)
    project(multiFileTest VERSION 0.1.0)
    
    include(CTest)
    enable_testing()
    
    #包含头文件
    include_directories(include)
    
    #工程目录下的原文件,命名为ROOT_SOURCE
    aux_source_directory(. ROOT_SOURCE)
    
    #指定一个子目录src,制定了src,cmake才回去src中找CMakeList
    add_subdirectory(src)
    
    #添加可执行文件,生成一个目标文件,取名为hello
    add_executable(hello ${ROOT_SOURCE} ${HELLO_SRC})
    
    set(CPACK_PROJECT_NAME ${PROJECT_NAME})
    set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
    include(CPack)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

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

    #子目录下的源文件,取名为HELLO_SRC,让父级目录可见
    aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} HELLO_SRC)
    set(HELLO_SRC ${HELLO_SRC} PARENT_SCOPE)
    
    • 1
    • 2
    • 3

    2. 制作静态/动态链接库文件

    工程目录结构如下

    D:.
    │  CMakeLists.txt
    ├─build
    └─lib
            CMakeLists.txt
            myhello.c
            myhello.h
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    hello.chello.h编译成静态和动态链接库文件,供外部使用

    工程目录下的CMakeLists.txt内容如下,只用包含注释的两句话是必要的,后面的install可安装也可不安装:

    cmake_minimum_required(VERSION 3.0.0)
    #工程设置
    project(myhello VERSION 0.1.0)
    
    include(CTest)
    enable_testing()
    
    #包含源文件,生成的可执行文件放在bin文件中
    add_subdirectory(lib bin)
    
    set(CPACK_PROJECT_NAME ${PROJECT_NAME})
    set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
    include(CPack)
    
    install(FILES hello.h DESTINATION include/hello)
    install(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    lib目录下的CMakeLists.txt内容如下,同时生成动态库和静态库:

    set(LIB_SRC  myhello.c)
    
    add_library(hello_static  STATIC ${LIB_SRC})
    
    set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello" )
    set_target_properties( hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1 )
    
    add_library(hello SHARED ${LIB_SRC})
    set_target_properties(hello PROPERTIES OUTPUT_NAME "hello")
    set_target_properties( hello PROPERTIES CLEAN_DIRECT_OUTPUT 1 )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这个实例是使用C文件做的库,在C++中调用,.c和.h文件内容如下

    //.c文件如下
    #include  "myhello.h"
    #include  
    
    void  helloFun()
    {
        printf("helloWorld!");
    }
    
    //.h文件如下
    #ifndef  _MYHELLO_H
    #define  _MYHELLO_H
    
    #ifdef  __cplusplus
    extern "C"{
     #endif
    
    extern  void  helloFun(void);
    
    #ifdef  __cplusplus
    }
    #endif
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    编译链接之后生成了libhello.alibhello.dll

    3. 使用外部库文件构建工程

    工程目录结构如下:

    D:.
    │  CMakeLists.txt
    │  main.cpp
    ├─build
    ├─include
    │      myhello.h
    └─lib
            libhello.a
            libhello.dll
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    工程目录下的main.cpp内容如下:

    #include 
    #include "myhello.h"
    
    int main(int, char**) {
        helloFun();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    工程目录下的CMakeLists.txt内容如下:

    cmake_minimum_required(VERSION 3.0.0)
    project(mytest VERSION 0.1.0)
    
    include(CTest)
    enable_testing()
    
    include_directories(include)
    
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
    
    LINK_DIRECTORIES(lib)
    
    add_executable(mytest main.cpp)
    
    target_link_libraries(mytest libhello.dll)
    
    set(CPACK_PROJECT_NAME ${PROJECT_NAME})
    set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
    include(CPack)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4. CMake常用指令

    #设置最低cmake版本
    cmake_minimum_required(VERSION 3.0.0)
    
    #配置项目信息
    project(mytest VERSION 0.1.0)
    
    #搜索当前目录下所有源文件
    aux_source_directory(. ROOT_SOURCE)
    
    #包含头文件
    include_directories(include)
    
    #包含链接库目录
    LINK_DIRECTORIES(lib)
    
    #包含工程子目录
    add_subdirectory(src)
    
    #生成可执行文件
    add_executable(mytest main.cpp)
    
    #生成静态链接库
    add_library(hello_static  STATIC ${LIB_SRC})
    
    #生成动态链接库
    add_library(hello SHARED ${LIB_SRC})
    
    #链接库文件,注意链接库文件必须在生成可执行文件之后
    target_link_libraries(mytest libhello.dll)
    
    #配置编译类型
    set(CMAKE_BUILD_TYPE Debug)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    5. 填坑

    在vscode下使用CMake构建工程,使用cmake quick start之后,自动生成了main.cpp文件,CMakeLists.txt文件和build文件夹,在构建工程的过程中不要删除build文件夹,如果删除之后重新建build文件夹,然后cmake…,则会出现错误:

    The CMAKE_C_COMPILER:
        cl
    is not a full path and was not found in the PATH.
    
    • 1
    • 2
    • 3

    编译器找不到了,这是则需要重新配置cmake工程,右键CMakeLists.txt,清除项目重新配置即可

    调试过程中,在build文件下编译链接,不要删除build文件夹的内容

    使用外部链接库文件时,如果提示使用的函数未定义,检查目标文件是否链接库target_link_libraries

    undefined reference to .......
    
    • 1

    如果提示找不到库,检查库文件路径是否包含,LINK_DIRECTORIES

    cannot find -lhello ......
    
    • 1

    找不到头文件,检查头文件是否包含

    No such file or directory
     #include "myhello.h"
              ^~~~~~~~~~~
    
    • 1
    • 2
    • 3

    _link_libraries`

    undefined reference to .......
    
    • 1

    如果提示找不到库,检查库文件路径是否包含,LINK_DIRECTORIES

    cannot find -lhello ......
    
    • 1

    找不到头文件,检查头文件是否包含

    No such file or directory
     #include "myhello.h"
              ^~~~~~~~~~~
    
    • 1
    • 2
    • 3
  • 相关阅读:
    Kotlin
    前端js获取key值方法
    ReactNative 网络库
    Attention Transformer
    清算、结算、南北卡支付行业概念一次说清
    [附源码]Python计算机毕业设计Django高血压分析平台
    前端拿到url地址拼接的参数
    PTE整体考试结构
    图像处理学习笔记-07-小波和多分辨率处理02
    Android Runtime (ART) 和 Dalvik
  • 原文地址:https://blog.csdn.net/aoyousihaiqiuqihuang/article/details/127953688