cmake 工具链

一、什么是Cmake

CMake是一种跨平台编译工具。CMake主要是编写CMakeLists.txt文件

通过cmake命令将CMakeLists.txt文件转化为make所需要的Makefile文件,最后用make命令编译源码生成可执行程序或者库文件。

二、一个简单的例子 演示CMake工作原理

1、项目一:生成共享库

ADD_LIBRARY(libname,SHARED,SOURCELIST)

目录结构如下:

| ---- src

| |----customprint.cpp

| ----include

| |----customprint.h

| ----lib

| ----build

| |----CmakeLists.txt

include目录放置头文件,src目录下放置的是.c/.cpp源文件,biuld目录是用来构建的项目,lib目录用来放置我们生成库文件

myprint.h

#include
#include

void feifei_print(char* str);

myprint.cpp

#include "/Users/feifei/Desktop/TM/Github/cmake_test/test/include/myprint.h"

void feifei_print(char* str) {

        printf("%s",str);

}


CMakeLists.txt

#指定CMake编译最低要求版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.10.2)
#给项目命名
PROJECT(customprint)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")

#收集c/c++文件并赋值给变量SRC_LIST_CPP  ${PROJECT_SOURCE_DIR}代表区当前项目录
FILE(GLOB SRC_LIST_CPP ${PROJECT_SOURCE_DIR}/src/*.cpp)
FILE(GLOB SRC_LIST_C ${PROJECT_SOURCE_DIR}/src/*.c)

#指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)

#指定生成库文件的目录
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#去变量SRC_LIST_CPP 与SRC_LIST_C 指定生成libmyprint 动态库   默认生成静态库  SHARED指定生成库类型为动态库
ADD_LIBRARY(customprint SHARED ${SRC_LIST_CPP} ${SRC_LIST_C})


  • cd到项目build目录执行cmake命令 将会在biuld目录下生成Makefile文件

cmake 指令用法:

cmake + CMakeLists.txt的路径

执行cmake指令后会生成中间文件,为了不污染源文件区,所有我们在build目录来执行cmake指令。CmakeLists.txt 位于相对路径 ../中

feifeideMacBook-Pro:build feifei$ cmake  ../
-- The C compiler identification is AppleClang 11.0.0.11000033
-- The CXX compiler identification is AppleClang 11.0.0.11000033
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/feifei/Desktop/TM/Github/cmake_test/test/build

生成makefile文件如下:

feifeideMacBook-Pro:build feifei$ ls
CMakeCache.txt      CMakeFiles      Makefile        cmake_install.cmake
  • 执行make命令项目就会开始编译,在项目lib目录下生成libcustomprint.so文件
feifeideMacBook-Pro:build feifei$ make 
Scanning dependencies of target customprint
[ 50%] Building CXX object CMakeFiles/customprint.dir/src/customprint.cpp.o
[100%] Linking CXX shared library ../lib/libcustomprint.dylib
[100%] Built target customprint

因为我是mac系统,所以生成的是libcustomprint.dylib
而非libcustomprint.so

2、使用生成的so共享库

//将libB.so 连接到A上
TARGET_LINK_LIBRARIES(A,B)

新建项目二:

| ---- src

| ----include

| |----customprint.h

| ----lib

| |----libcustomprint.so

| ----build

| |----CmakeLists.txt

  • 在src目录下 新建 hello.cpp,里面调用myprint()方法
#include 
#include "/Users/feifei/Desktop/TM/Github/cmake_test/test/include/myprint.h"
int main() {
        myprint("hello World\n");
        return 0;
}
  • 将生成的myprint.so 拷贝到lib目录

  • 将myprint.h 头文件 拷贝到include 目录

  • 新建 CmakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.14)
#指定项目名称
PROJECT(HELLO)

#将hello.cpp 赋值给SOURCE 变量
SET(SOURCE ${PROJECT_SOURCE_DIR}/src/hello.cpp)

#指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#指定链接库文件目录
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)

#将hello.cpp生成可执行文件hello 
ADD_EXECUTABLE(hello ${SOURCE})

#指定hello 链接库myprint
TARGET_LINK_LIBRARIES(hello myprint)
feifeideMacBook-Pro:build feifei$ cmake ../
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/feifei/Desktop/TM/Github/cmake_test/test/build
feifeideMacBook-Pro:build feifei$ make 
[ 50%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o
/Users/feifei/Desktop/TM/Github/cmake_test/test/src/hello.cpp:4:22: warning: conversion from string literal to 'char *' is deprecated
      [-Wc++11-compat-deprecated-writable-strings]
        feifei_print("hello World\n");
                     ^
1 warning generated.
[100%] Linking CXX executable hello
[100%] Built target hello
feifeideMacBook-Pro:build feifei$ ./hello 
hello World

三、多CMakeLists.txt 组织结构

一个工程可能会多个模块(多个CMakeLists.txt),多个子模块工程生成一个可执行程序,一般如下组织:

  • 最外层一个CMakeLists.txt,利用用add_subdirectory来进入各个子目录

  • 每个子目录一个单独的CMakeLists.txt 。负责生成各个模块的静态库(.a)或者动态链接库(.so)

如以下结构:

├── CMakeLists.txt
├── build
├── customcalculate
│   ├── CMakeLists.txt
│   ├── include
│   │   └── calculate.h
│   ├── lib
│   └── src
│       └── calculate.cpp
├── customprint
│   ├── CMakeLists.txt
│   ├── include
│   │   └── customprint.h
│   ├── lib
│   └── src
│       └── customprint.cpp
└── main.cpp

最外层CmkaeLists.txt

#指定CMake编译最低要求版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.10.2)

#指定项目名称
PROJECT(main)

#将main.cpp 赋值给SOURCE 变量
SET(SOURCE ${PROJECT_SOURCE_DIR}/main.cpp)

#将子模块 添加子模块路径
add_subdirectory(customprint)

#add_subdirectory(customcalculate)


#将main.cpp生成可执行文件main
ADD_EXECUTABLE(main ${SOURCE})

#将custom链接库 链接到main
TARGET_LINK_LIBRARIES(main customprint)

四、参考:

几个典型的概念:
https://www.jianshu.com/p/6332418b12b1

https://blog.csdn.net/pix_csdn/article/details/90384155

https://www.jianshu.com/p/33efb7b67acc

你可能感兴趣的:(cmake 工具链)