cmake 工程构建

一:CMakeLists.txt 基本框架

工程目录结构:
在这里插入图片描述
根目录./CMakeLists.txt:

# 指定cmake版本,只需要指定大版本和小版本即可
cmake_minimum_required(VERSION 3.10)

# 指定项目名称,项目版本号,主要实现语言
project(cmake-demo VERSION 1.0.0 LANGUAGES C CXX)

# 定义cmake配置文件。cmake配置文件以.in结尾,编译会生成.h文件
# 文件中定义了源码可以访问的变量,宏
configure_file(CmakeDemoConfig.h.in CmakeDemoConfig.h)

# 添加子目录
add_subdirectory(AddFunction)

# 设置c++ 版本
set(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED TRUE)

# 指定可执行文件名称
add_executable(demo src/main.cpp)

# 链接库文件
target_link_libraries(demo PUBLIC AddFunction)

# 指定项目编译需要include的文件路径
target_include_directories(demo PUBLIC 
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/AddFunction"
)

AddFunction/CMakeLists.txt

add_library(AddFunction AddFunction.cpp)
# 添加此语句,顶层cmakelists.txt不需要在include AddFunction下的头文件
target_include_directories(AddFunction INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

./CMakeDemoConfig.h.in

// #define CMAKE_VERSION_MAJOR @CMAKE_VERSION_MAJOR@
// #define CMAKE_VERSION_MINOR @CMAKE_VERSION_MINOR@
#define CMAKE_VERSION_MAJOR 1
#define CMAKE_VERSION_MINOR 2
#define USE_MYMATCH 3

./src/main.cpp

#include <iostream>
#include "CmakeDemoConfig.h"

int main()
{
    std::cout << "hello world" << std::endl;
    return 0;
}

二:编译静态库或者动态库

AddFunction/CMakeLists.txt

add_library(AddFunction AddFunction.cpp)
# 添加此语句,顶层cmakelists.txt不需要在include AddFunction下的头文件
target_include_directories(AddFunction INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

./CMakeLists.txt

# 添加子目录
add_subdirectory(AddFunction)

# 链接库文件
target_link_libraries(demo PUBLIC AddFunction)

# 指定项目编译需要include的文件路径
target_include_directories(demo PUBLIC 
"${PROJECT_BINARY_DIR}"
# "${PROJECT_SOURCE_DIR}/AddFunction" 删除AddFunction的头文件路径
)

说明
AddFunction.h头文件的引入不需要带路径

#include <iostream>
#include "CmakeDemoConfig.h"

#ifdef USE_MYMATCH
#include "AddFunction.h"//#include "AddFunction/AddFunction.h"是错误的
#endif

int main()
{
    std::cout << "hello world" << std::endl;
#ifdef USE_MYMATCH
    std::cout << "add function:" << add(1, 2) << std::endl;
#endif

    return 0;
}

三:find_package()

为了方便我们在项目引入外部依赖,cmake为我们预定义了许内置依赖包Module,存储位置/usr/share/cmake-3.16/Modules。每个以Find.cmake命名的文件都可以帮我们找到一个包。
以CURL为例进行说明:

find_package(CURL)#此函数会查调用FindCURL.cmake文件,找到curl库和头文件,加入到工程
add_executable(curltest curltest.cc)
if(CURL_FOUND)
    target_include_directories(clib PRIVATE ${CURL_INCLUDE_DIR})
    target_link_libraries(curltest ${CURL_LIBRARY})
else(CURL_FOUND)
    message(FATAL_ERROR ”CURL library not found”)
endif(CURL_FOUND)

每一个模块都会定义以下几个变量:

  1. LibaryName_FOUND
    可以通过LibaryName_FOUND 来判断模块是否被找到。
    TRUE:LibaryName找到
    FALSE:LibartName未找到
  2. LibaryName_INCLUDE_DIR or LibaryName_INCLUDES
  3. LibaryName_LIBRARY or LibaryName_LIBRARIES

四:module和config模式

  1. module
    cmake 自带依赖包
  2. config
    用户自定义库文件

五:引入第三方库文件

六:编译选项指定

add_compile_options命令和add_definitions添加的编译选项是针对所有编译器的(包括c和c++编译器),而set命令设置CMAKE_C_FLAGS或CMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器的。

  1. CMAKE_C_COMPILER:指定C编译器
add_compile_options(-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes)
  1. CMAKE_CXX_COMPILER:指定C++编译器

  2. CMAKE_C_FLAGS,CMAKE_CXX_FLAGS:指定编译C/C++文件时编译选项

set(CMAKE_C_FLAGS "-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes)
set(CMAKE_CXX_FLAGS "-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes)
  1. add_definitions
ADD_DEFINITIONS("-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes)
  1. add_compile_options
add_compile_options(-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes)
  1. debug 和 release 设置
# debug和release设置,default is debug
set(CMAKE_BUILD_TYPE "release")
if(!CMAKE_BUILD_TYPE STREQUAL "release")
  add_definitions("-g")
endif(!CMAKE)
  1. 启用Makefile详细输出
# set this to see the compilation commands
set(CMAKE_VERBOSE_MAKEFILE 1)
  1. 根据cmake debug和release设置编译选项
IF("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
    message(STATUS "building for: debugging")
    ## unfortunately these produce errors
    #include(CheckCXXCompilerFlag)
    # CHECK_CXX_COMPILER_FLAG("-Wformat-signedness" CXX_FORMAT_SIGNEDNESS)
    # CHECK_CXX_COMPILER_FLAG("-Werror=format-security" CXX_FORMAT_SECURITY)
    # CHECK_CXX_COMPILER_FLAG("-fstack-protector-all" CXX_STACK_PROTECTOR)
    set(CXX_FORMAT_SIGNEDNESS "-Wformat-signedness")
    set(CXX_FORMAT_SECURITY "-Werror=format-security")
    set(CXX_STACK_PROTECTOR "-fstack-protector-all")
    set(CXX_FLAGS_DEBUG "-O0")
    set(CMAKE_C_STANDARD 99)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -ggdb -Wall -Wextra -DNETDATA_INTERNAL_CHECKS=1 -DNETDATA_VERIFY_LOCKS=1 ${CXX_FORMAT_SIGNEDNESS} ${CXX_FORMAT_SECURITY} ${CXX_STACK_PROTECTOR} ${CXX_FLAGS_DEBUG}")
ELSE()
    message(STATUS "building for: release")
    cmake_policy(SET CMP0069 "NEW")
    include(CheckIPOSupported)
    check_ipo_supported(RESULT ipo_supported OUTPUT error)
    IF(${ipo_supported})
        message(STATUS "link time optimization: supported")
        set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
    ELSE()
        message(STATUS "link time optimization: not supported")
    ENDIF()
ENDIF()

七:交叉编译配置

八:配置option可选选项

修改配置文件CMakeDemoConfig.h.in

// #define CMAKE_VERSION_MAJOR @CMAKE_VERSION_MAJOR@
// #define CMAKE_VERSION_MINOR @CMAKE_VERSION_MINOR@
#define CMAKE_VERSION_MAJOR 1
#define CMAKE_VERSION_MINOR 2
#define USE_MYMATCH 1 //代码中使用的配置宏

根目录./CMakeLists.txt:

# 增加option选项
# 定义USE_MYMATCH变量
# ON:定义USE_MYMATCH OFF:删除USE_MYMATCH选项
option(USE_MYMATCH "Use tutorial provided math implementation" ON)
# option(USE_MYMATCH "Use tutorial provided math implementation" OFF)

# 添加子目录
# add_subdirectory(AddFunction)
if(USE_MYMATH) 
  add_subdirectory(AddFunction) 
  list(APPEND EXTRA_LIBS AddFunction) 
endif() 

# 链接库文件
# target_link_libraries(demo PUBLIC AddFunction)
target_link_libraries(demo PUBLIC ${EXTRA_LIBS})

./src/main.cpp

#include <iostream>
#include "CmakeDemoConfig.h"

#ifdef USE_MYMATCH
#include "AddFunction.h"//#include "AddFunction/AddFunction.h"是错误的
#endif

int main()
{
    std::cout << "hello world" << std::endl;
#ifdef USE_MYMATCH
    std::cout << "add function:" << add(1, 2) << std::endl;
#endif

    return 0;
}

九:安装

./AddFunction/CMakeLists.txt

# 安装
install(TARGETS AddFunction DESTINATION /home/sws/test/lib)
install(FILES AddFunction.h DESTINATION /home/sws/test/include)

./CMakeLists.txt

# 安装
install(TARGETS demo DESTINATION /home/sws/test/bin)
install(FILES "${PROJECT_BINARY_DIR}/CmakeDemoConfig.h" DESTINATION /home/sws/test/include)

说明
TARGETS:编译生成的目标文件
FILES:需要拷贝的文件

十:

参考资料

链接:知乎cmake
链接:cmake使用教程
链接:csdn教程
链接:官网
链接:编译选项
链接:module&config

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值