cmake 构建linux工程学习记录

本文介绍了如何使用CMake在Linux环境下构建动态库和可执行程序。首先,展示了如何通过CMakeLists.txt文件在prj_lib目录下创建动态库,接着说明如何在prj_linux目录中编写CMakeLists.txt来链接库并生成目标程序。整个过程详细解释了CMake的配置步骤,并与传统的Makefile进行了对比,强调了CMake的跨平台优势和简洁性。
摘要由CSDN通过智能技术生成

以前在Linux上通过一套格式化的Makefile来构建Linux工程,生成库和可执行文件。
今天看了一下cmake这种跨平台构建方式来构建Linux下工程一样方便,可之前格式化的Makefile没有什么不一样。下面进行展示:
我在虚拟机中的工作目录如图所示:
在这里插入图片描述
本文首先在prj_lib工程中生成动态库,然后再在prj_linux中生成目标程序时链接该动态库,这样比较符合日常实际开发。当然也可以生成静态库给可执行程序编进去~
放心这里的实例不会比别人从单文件到多文件再到链接库来得困难。

生成动态库:

进入到prj_lib的目录下,有3个文件夹和一个txt文本文件:
在这里插入图片描述
在include文件夹中就是我们需要生成库的头文件,在source中就是库的源文件,build文件夹等会儿说,CMakeLists.txt就是cmake所需要的文件。(对了,要进行下面的内容,你得先安装make和cmake,怎么装在网上很多)
简单看看这个库干了什么吧(其实也没必要看,因为写的很丑 命名也不规范)
在这里插入图片描述
在这里插入图片描述
这个库实现的功能就是:基类提供打印一下当前函数所在文件,名字的能力,子类来完善一下功能,增加一个耗时的打印。

注意我在源文件中第二行写的#include “…/include/common.h”,这里直接去找到并展开上级目录中的include目录,因此我在之后介绍的CMakeList.txt中就没有添加子目录去增加访问include目录的功能。

然后来看prj_lib下面的CMakeList.txt:
在这里插入图片描述
看注释!

# 指定cmake最低版本要求  版本低了有些功能没有
#version require
cmake_minimum_required(VERSION 3.1)

# 工程名
#project
project(comprt)

# 将./source/目录下的所有源文件 一并赋值给LIB_SRC, 当然你可以任意指定一个变量名,比如SRC_LIST之类的
#source cpp path
aux_source_directory(source LIB_SRC)

# 生成库总得给个名字吧  第二个参数SHARED如果不写的话,就是默认是静态库
#target
add_library(comprt SHARED ${LIB_SRC})

就此CMakeLists.txt写完了,我是把它放在顶级目录下的,然后呢进入到build/里面去,当然你可以试试就在CMakeLists.txt所在目录执行以下cmake . 意思是cmake + 路径,你会看到生成一对东西,这样是内部构建,它不好看,所以还是选择外部构建的方式
在build/中 cmake .. 会生成以下东西

看到生成了一个Makefile了没,这下子就可以编译你的库啦。
tip:我一般喜欢make clean all
在这里插入图片描述

看,生成动态库了吧
大功告成,这样这个库就可以丢给别人使用了。

生成可执行程序

假如我作为一个用户要使用这个libcomprt.so,我肯定要去包库的头文件,找到库在哪,然后链接它,接下来就开整:
我这个用户很简单,不包含其他的头文件,源文件,只有一个有main函数的cpp,但是呢接下来要写在这个工程里面的CMakeLists.txt包罗万象,把g++指令完全体现出来了:
先看看我文件结构吧:
在这里插入图片描述
再看看main.cpp干了啥,(其实也没必要)
在这里插入图片描述
主函数包含iostream , string 以及 我们libcomprt的头文件common.h ,一般来说,使用者在代码里不用理会这个库头文件在哪(所以这个地方补足之前编库的时候说的#include里写路径的问题)
主函数干了什么呢,他用库提供的morePrint类型,来做一个函数进出和耗时的打印,你可以把这个类型放在任意函数中,他自己的生命周期就和函数进出栈的时机是一致的。
然后呀,主函数就打印一个hello world,用到了一个c++17的新类型std::string_view,这个不懂可以去我之前写的一个博客看看,或者找别人的来看看,蛮有用的(打给自己打个广告:string_view

会makefile以及gcc/g++指令的同学,我们在编译这个程序是会执行类似于下面这串指令的吧(之前编库忘了写。。。)
默认你在main.cpp同级目录:

g++ -std=c++17 -Wall -O2 main.cpp -I../prj_lib/include -L../prj_lib/build -lcomprt -o demo

我将g++的参数拆分为以下几段:

# C++标准
-std=c++17
# g++ 参数 当然还有诸如-g -shared, 生成中间文件的-E  -s -c等等
-Wall -O2
# 源文件们,本文就一个main.cpp,在其他目录记得带上路径哦

main.cpp
# 头文件们
-I path
# 库在哪
-L path
# 库叫啥
-l 库名(不加lib和.a/.so)
# 输出(不加的话给你一个a.out)
-o target

好了。让我们来看看cmake怎样实现以上各段参数吧:
在这里插入图片描述

# 不用多说了,无视图里这版本不一样
cmake_minimum_required(VERSION 3.1)

project(DEMO)

#源文件们
# main.cpp
set(FILE_MAIN main.cpp)

# C++标准,这个代码里面用到17的东西,所以要加17
# param
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 给CMAKE_CXX_FLAG追加一堆参数
set(CMAKE_CXX_FLAG ${CMAKE_CXX_FLAG} "-O2 -Wall -g")

# 头文件们,此处工程简单,没有除了库以外的头文件,你可是想上一行那样使用set追加
# -I
set(LIB_INCLUDE ../prj_lib/include)
include_directories(${LIB_INCLUDE})

# 库在哪
# -L
set(LIB_DIR ../prj_lib/build)
link_directories(${LIB_DIR})

# 输出目标文件名字和依赖上面的源文件们
# -o
add_executable(test ${FILE_MAIN})

#库的名字
# -l
set(LIB_NAME comprt)
target_link_libraries(test ${LIB_NAME})

然后我们在build里构建:
在这里插入图片描述
看到了没,生成test了,执行下看个效果吧,这里还不需要添加环境变量,牛哔了
在这里插入图片描述
好就这样吧,文章用词很粗糙,后面来改

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

歪锅锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值