首页 > 编程语言 >使用cmake构建C/C++项目和动态库

使用cmake构建C/C++项目和动态库

时间:2022-11-22 19:22:56浏览次数:42  
标签:cmake MakeFile library 编译 add 构建 C++ debug

编译C/C++文件时,很多时候都是直接使用像 gcc main.c 或者 g++ main.cpp 这样的命令编译的。但是代码文件多了后,这样编译就很困难了。这时候 就出现了MakeFile 这个工具。

MakeFile 解决了多个文件编译难的问题,有了MakeFile,只需要在MakeFile的目录中 运行一下make 命令, 编译就会自动完成。但是编写MakeFile又很啰嗦,于是聪明的程序员们有开发了一个工具,自动生成MakeFile 文件,cmake 的作用就是自动生成MakeFile。毕竟写cmake要比写MakeFile要简单很多

也许你会说,现在都是用IDE写代码,IDE都会自动自动编译和运行,我还学这些干啥。但是有时候需要服务器上编译项目,或者在没有IDE的机器上编译项目,这时候MakeFile就很有用了。其实很多IDE也是使用cmake完成编译的,比如 clion

cmake 安装

在linux上可以使用源码安装和包管理安装,一般直接用包管理安装就好了
Ubuntu和Debian
sudo apt-get install cmake

CentOS
sudo yum install cmake

因为cmake只是生成MakeFile,最终组织编译的还是MakeFile,所以还有安装make

make 一般都会预装,为了保险,还是装一下

Ubuntu和Debian
sudo apt-get install make

CentOS
sudo yum install make

cmake基本规则

cmake 也没啥神秘的,本质上也是根据一定的规则自动生成MakeFile的,也是有语法的

# 是注释符号

预定义变量

PROJECT_NAME项目名称
PROJECT_SOURCE_DIR工程的根目录
PROJECT_BINARY_DIR 执行cmake命令的目录
PROJECT_BINARY_DIR 执行cmake命令的目录
CMAKE_CURRENT_SOURCE_DIR当前CMakeLists.txt文件所在目录
CMAKE_C_FLAGS设置C编译选项
CMAKE_CXX_FLAGS设置C++编译选项
CMAKE_C_COMPILER设置C编译器
CMAKE_CXX_COMPILER设置C++编译器
EXECUTABLE_OUTPUT_PATH设置编译后可执行文件目录
LIBRARY_OUTPUT_PATH设置生成的库文件目录

常用规则

cmake_minimum_required(VERSION 3.16) 指令cmake 版本
project(hello_world) 设置工程名
include_directories(${PROJECT_SOURCE_DIR}/include) 添加头文件路径
link_directories(${PROJECT_SOURCE_DIR}/lib) 添加链接库的路径
add_subdirectory(module)添加 module 子目录, 此目录下也要有CMakeLists.txt文件
add_executable(project1 main.c)指定编译的可执行文件
add_library(lib1 SHARED library.c library.h)指定生成的库文件,SHARED是生成动态库,STATIC后生成静态库
add_compile_options() 添加编译选项
target_link_libraries()指定动态链接库
install()指定make install的目录

set(XXXX YYYYYY)用于设置和修改变量
${XXXX} 使用变量

构建一个简单的项目

只有一个 main.c 文件

CMakeList.txt

cmake_minimum_required(VERSION 3.15)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_executable(project1 main.c)

main.c

#include <stdio.h>

int main() {
    printf("Hello, CMakeList!\n");
    return 0;
}
编译一个debug版本
  1. mkdir debug 新建debug目录
  2. cd debug 进入debug目录
  3. cmake -DCMAKE_BUILD_TYPR=debug .. 指定编译模式为debug
  4. make 生成可执行文件

此时会生成project1文件

步骤 3 中 cmake -DCMAKE_BUILD_TYPE=release .. 指定编译模式为release

构建一个生成动态库的项目

有两个文件library.hlibrary.c
CMakeList.txt

cmake_minimum_required(VERSION 3.15)
project(shared C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.c library.h)

library.h

int add(int a, int b);

library.c

int add(int a, int b) {
    return a + b;
}
生成动态库
  1. mkdir lib 新建lib目录
  2. cd lib 进入lib目录
  3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定编译模式为debug
  4. make 生成可执行文件
    此时会生成 libshared.so文件

在第一个项目中使用动态库

首先把 libshared.so文件和library.h文件复制到第一个项目中

修改 CMakeList.txt

cmake_minimum_required(VERSION 3.15)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_executable(project1 main.c)

target_link_libraries(project1 ${PROJECT_SOURCE_DIR}/libshared.so)#指定动态库文件
  1. mkdir debug 新建debug目录
  2. cd debug 进入debug目录
  3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定编译模式为debug
  4. make 生成可执行文件

最终目录如图


 

把两个项目合成一个

能不能在一个项目中生成动态库并在这个项目中使用呢,当然是可以的。

也就是在这个项目中部分文件编译成动态库 .so 文件, 部分文件编译成 可执行文件

修改 CMakeList.txt

cmake_minimum_required(VERSION 3.13.3)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.h library.c)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)#设置动态库输出目录

add_executable(project1 main.c)

target_link_libraries(project1 shared)
  1. mkdir debug 新建debug目录
  2. cd debug 进入debug目录
  3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定编译模式为debug
  4. make 生成可执行文件

最终目录如图

 

最后

通过几个简单的例子,介绍了一下cmake的基本使用,文中是使用cmake构建的C项目,换成C++基本没什么区别,就不展示了

标签:cmake,MakeFile,library,编译,add,构建,C++,debug
From: https://www.cnblogs.com/lidabo/p/16916177.html

相关文章

  • C++ Builder使用FMX多平台框架(FireMonkey)开发安卓APP应用,底层是基于什么?
    【DelphiGuy】:底层是基于AndroidNDK的,JDK也可以调用。Delphi、C++Builder目前编译生成的安卓应用是基于ARM机器码的共享库.so(相当于DLL,在.APK中有一个java写的启动代码......
  • C++——map
      Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作!1.map最基本的构造函数;  map<s......
  • (C++) atomic_flag的使用
    使用示例#include<atomic>#include<iostream>#include<thread>#include<vector>intmain(intargc,char**argv){constexprsize_tkLoopNum=10;std::......
  • C++初阶(stack+queue)
    stackstack介绍stack是一种先进后出的数据结构,只有一个出口,类似于栈。stack容器哦允许新增元素,移除元素,取得栈顶元素,但是除了最顶端之后,没有任何其他办法可以存取stack的......
  • ROS_C++_第三方库Eigen
    Eigen提供了快速的矩阵线性代数运算,矩阵、向量、旋转矩阵、变换矩阵。Eigen是纯头文件搭建成的库,使用时只需引入Eigen的头文件即可,不需要链接库文件target_link安装......
  • Java工具库Guava的区间(范围Range)的构建、区间运算、查询运算、关系运算(包含、相连
    场景Java核心工具库Guava介绍以及Optional和Preconditions使用进行非空和数据校验:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127683387Java工具库Gua......
  • 广州华锐互动|构建智慧城市数字化三维实景建模平台
    在技术日新月异的时代,智慧城市建设发展也在不断推进,从物理世界到虚拟世界,人们对于未来城市的构想正在智慧城市中逐步实现。智慧城市的构建离不开物联网、人工智能、虚拟现......
  • Jenkins+Maven+Gitlab+Tomcat 自动化构建打包、部署
    Jenkins+Maven+Gitlab+Tomcat自动化构建打包、部署笔记版本控制概念记录开发文件的时间机器更好的开发,挽回代码错误带来的损失分类本地版本控制系统集中......
  • c++ bitse用法
    c++bitse用法bitset类似于数组结构,但是它的每一个元素之能是0或1,每个元素仅用1bit空间。应用是须加入​​​#include<bitset>​​0.引子Determineifallcharactersof......
  • C++11创建线程的三种方式
    1.通过函数thread:标准库的类join:阻塞主线程并等待//MultiThread.cpp:Definestheentrypointfortheconsoleapplication.#include"stdafx.h"#include<iostream>#i......