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<stdio.h>
#include<stdlib.h>

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 <stdio.h>
#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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容