<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C++ on Lishengxie</title><link>https://lishengxie.top/tags/c++/</link><description>Recent content in C++ on Lishengxie</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Wed, 16 Aug 2023 10:42:01 +0800</lastBuildDate><atom:link href="https://lishengxie.top/tags/c++/index.xml" rel="self" type="application/rss+xml"/><item><title>LJson</title><link>https://lishengxie.top/post/ljson/</link><pubDate>Wed, 16 Aug 2023 10:42:01 +0800</pubDate><guid>https://lishengxie.top/post/ljson/</guid><description>&lt;h1 id="ljson"&gt;LJSon&lt;/h1&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;A C++ library for json parse/creation/update&lt;/li&gt;&#10;&lt;li&gt;package地址：&lt;a href="https://github.com/lishengxie/LJson"&gt;https://github.com/lishengxie/LJson&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="开发原因"&gt;开发原因&lt;/h2&gt;&#10;&lt;p&gt;最近在复习C++相关的知识，想要通过一个项目来巩固C++和算法的一些相关知识，但是网上推荐的相关C++项目大多比较复杂，很难下手。刚好最近实验室项目中频繁使用json文件，想到是否可以使用C++来实现一个json的解析库，在github上搜索后看到了一些现有的json仓库，初步了解后开始进行实现。&lt;/p&gt;&#10;&lt;h2 id="参考仓库"&gt;参考仓库&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/510850111/cJSON/tree/master"&gt;https://github.com/510850111/cJSON/tree/master&lt;/a&gt;，在这个项目中学习了json对象的表示以及如何操作json对象；&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/ACking-you/MyUtil/tree/master/json-parser"&gt;https://github.com/ACking-you/MyUtil/tree/master/json-parser&lt;/a&gt;，在这个项目中学习了如何从json字符串中解析数据，服用了部分解析json字符串的代码；&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://github.com/nlohmann/json"&gt;https://github.com/nlohmann/json&lt;/a&gt;，著名的json处理库，从中学习了如何使用初始化列表来实现类Python的方式创建和更新json对象。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="json文件格式"&gt;json文件格式&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;这里只做简单介绍，具体的格式可以参考json官网&lt;a href="http://www.json.org"&gt;http://www.json.org&lt;/a&gt;。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;json主要基于两种结构，分别是“键值对集合”和“值的有序列表”，前者可以看做字典或哈希表，后者可以看做数组。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;对象是无序的键值对集合，一个对象被包含在&lt;code&gt;{}&lt;/code&gt;中，每个键值对的格式为&lt;code&gt;key:value&lt;/code&gt;，其中&lt;code&gt;key&lt;/code&gt;是字符串，value可以是字符串、布尔类型(&lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt;)、&lt;code&gt;null&lt;/code&gt;、数值(整数或浮点数)、对象、数组；键值对之间使用&lt;code&gt;,&lt;/code&gt;分隔，对象应该使用key索引对应的值；&lt;/li&gt;&#10;&lt;li&gt;数组是值的有序集合，包含在&lt;code&gt;[]&lt;/code&gt;中，值可以是前面提到的字符串、布尔类型(&lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt;)、&lt;code&gt;null&lt;/code&gt;、数值(整数或浮点数)、对象、数组，值之间使用&lt;code&gt;,&lt;/code&gt;分隔；&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;通过使用对象、数组以及支持两者之间的嵌套，json可以支持复杂的数据格式定义和传递。&lt;/p&gt;&#10;&lt;h2 id="使用数据结构表示json对象"&gt;使用数据结构表示json对象&lt;/h2&gt;&#10;&lt;p&gt;前面提到了json文件的格式，一种很自然的表示json对象的方式应该是使用字典表示对象，字典的值本身也可以是一个json对象，有一些json解析库中使用了这种方式，可以参考Python中&lt;code&gt;json&lt;/code&gt;库对json文件的读写。我们使用了另外一种方式，即使用树形结构来表示整个json对象，如下图所示：&#10;&lt;a href="https://lishengxie.top/uploads/2023/08/json-node-fig.png"&gt;&lt;img src="https://lishengxie.top/uploads/2023/08/json-node-fig.png" alt=""&gt;&lt;/a&gt;&#10;对应的C++定义如下，对象中的每个键值对以及数组中的每个值都使用一个JsonObject对象来表示，整个对象/数组的键值对/值使用双向链表进行表示，遍历整个双向链表即可以遍历整个json对象或数组。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;enum&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JsonType&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; T_FALSE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, T_TRUE, T_NULL, T_INT, T_FLOAT, T_STRING, T_ARRAY, T_OBJECT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JsonObject&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* next和prev分别指向前一个对象和后一个对象 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JsonObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;next, &lt;span style="color:#f92672"&gt;*&lt;/span&gt;prev;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* Object和Array类型对象需要设置child指针 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JsonObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;child;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* Object的类型 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; JsonType type;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* String对象的值 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;valueString;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 整数对象的值 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; valueInt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 浮点数的值 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; valueDouble;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* 键值对的键 */&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;key;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上图为例，假设有如下的json对象&lt;/p&gt;</description></item><item><title>Gdb调试学习</title><link>https://lishengxie.top/post/gdb-study/</link><pubDate>Sun, 30 Apr 2023 08:40:25 +0800</pubDate><guid>https://lishengxie.top/post/gdb-study/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;&#10;&lt;p&gt;使用linux进行systemc的开发时经常出现core dump的文件，对于较大的项目vscode无法很快地进行debug，clion对makefile的支持不是很好，此时想到使用gdb进行调试并学习了一些基本的操作。以下的内容主要参考这篇博客和gdb debug的参考文档。&lt;/p&gt;&#10;&lt;p&gt;参考资料：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;a href="https://www.yanbinghu.com/2019/04/20/41283.html"&gt;https://www.yanbinghu.com/2019/04/20/41283.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.eecs.umich.edu/courses/eecs373/readings/Debugger.pdf"&gt;Debugging with GDB&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="启动调试"&gt;启动调试&lt;/h2&gt;&#10;&lt;p&gt;GDB需要一个带有调试信息的可执行文件进行调试，因此编译过程中出现的错误无法使用GDB进行排除。通常对于C或者C++程序来说，在编译时加上&lt;code&gt;-g&lt;/code&gt;参数可以保留调试信息，否则不能使用GDB进行调试。使用cmake时，可以在&lt;code&gt;CMakeLists.txt&lt;/code&gt;文件中添加以下指令以支持GDB调试。&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SET(&lt;span style="color:#e6db74"&gt;CMAKE_BUILD_TYPE&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Debug&amp;#34;&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SET(&lt;span style="color:#e6db74"&gt;CMAKE_CXX_FLAGS_DEBUG&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb&amp;#34;&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SET(&lt;span style="color:#e6db74"&gt;CMAKE_CXX_FLAGS_RELEASE&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;$ENV{CXXFLAGS} -O3 -Wall&amp;#34;&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果程序不是自己编译的，那么如何判断文件中是否带有调试信息呢，这篇&lt;a href="https://www.yanbinghu.com/2019/04/20/41283.html"&gt;博客&lt;/a&gt;中给出了几种调试的方法。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;使用gdb&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ gdb main&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Reading symbols from main...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果提示no debugging symbols found, 那么不可以使用gdb调试该可执行文件。&#10;2. readelf&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# main是可执行文件名称&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ readelf -S main | grep debug&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;&#10;&lt;li&gt;file查看strip状况&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ file main&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果输出内容为xxx stripped, 那么说明该文件的调试信息已经被去除，不能使用gdb调试。但是not stripped的情况不能说明该文件可以被调试。&lt;/p&gt;&#10;&lt;h2 id="启动调试-1"&gt;启动调试&lt;/h2&gt;&#10;&lt;h3 id="无参数程序"&gt;无参数程序&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ gdb main&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;gdb&lt;span style="color:#f92672"&gt;)&lt;/span&gt; run&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输入run命令即可运行程序。&lt;/p&gt;</description></item><item><title>Makefile使用学习</title><link>https://lishengxie.top/post/makefile-study/</link><pubDate>Sun, 30 Apr 2023 08:37:37 +0800</pubDate><guid>https://lishengxie.top/post/makefile-study/</guid><description>&lt;h2 id="参考教程"&gt;参考教程&lt;/h2&gt;&#10;&lt;p&gt;原文：&lt;a href="https://makefiletutorial.com/"&gt;https://makefiletutorial.com/&lt;/a&gt;&#10;中文翻译：&lt;a href="https://makefiletutorial.vercel.app"&gt;https://makefiletutorial.vercel.app&lt;/a&gt;&lt;/p&gt;&#10;&lt;h2 id="makefile常用内容"&gt;Makefile常用内容&lt;/h2&gt;&#10;&lt;p&gt;本文主要基于以上教程记录一些平时阅读&lt;code&gt;Makefile&lt;/code&gt;可能会用到的信息。&lt;/p&gt;&#10;&lt;h3 id="makefile基础使用"&gt;Makefile基础使用&lt;/h3&gt;&#10;&lt;p&gt;首先，Makefile用于帮助决定一个大型程序的哪些部分需要重新编译，如果有任何文件的依赖项发生改变，那么该文件将会重新编译。Makefile通常由一组规则组成，规则通常如下所示：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;target&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; prerequisites&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;command&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;command&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;command&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;target&lt;/code&gt;是文件名，以空格分隔，通常每个规则只有一个。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;command&lt;/code&gt;通常是用于制作目标的一系列步骤，需要以制表符&lt;code&gt;Tab&lt;/code&gt;而不是空格开头。&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;prerequisites&lt;/code&gt;也是文件名，称为依赖项，以空格分隔，在运行针对目标的命令之前，这些文件需要存在。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;下面是一个&lt;code&gt;Makefile&lt;/code&gt;的实例：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-makefile" data-lang="makefile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;blah&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; blah.o&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;gcc blah.o -o blah &lt;span style="color:#75715e"&gt;# Runs third&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;blah.o&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; blah.c&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;gcc -c blah.c -o blah.o &lt;span style="color:#75715e"&gt;# Runs second&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Typically blah.c would already exist, but I want to limit any additional required files&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;blah.c&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;echo &lt;span style="color:#e6db74"&gt;&amp;#34;int main() { return 0; }&amp;#34;&lt;/span&gt; &amp;gt; blah.c &lt;span style="color:#75715e"&gt;# Runs first&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;使用&lt;code&gt;make&lt;/code&gt;时默认会执行第一个目标&lt;code&gt;blah&lt;/code&gt;，或者可以指定目标进行生成&lt;code&gt;make blah&lt;/code&gt;。上面的Makefile在执行&lt;code&gt;make&lt;/code&gt;指令后按照一系列步骤进行调用：&lt;/p&gt;</description></item><item><title>Cmake 常用指令学习</title><link>https://lishengxie.top/post/cmake-study/</link><pubDate>Sun, 30 Apr 2023 08:36:41 +0800</pubDate><guid>https://lishengxie.top/post/cmake-study/</guid><description>&lt;h2 id="参考教程"&gt;参考教程&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Cmake Cookbook:&lt;a href="https://www.bookstack.cn/read/CMake-Cookbook/README.md"&gt;https://www.bookstack.cn/read/CMake-Cookbook/README.md&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Cmake官方文档:&lt;a href="https://cmake.org/cmake/help/latest/guide/tutorial/index.html"&gt;https://cmake.org/cmake/help/latest/guide/tutorial/index.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Cmake入门实战: &lt;a href="https://www.hahack.com/codes/cmake/"&gt;https://www.hahack.com/codes/cmake/&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;CMake 生成静态库与动态库：&lt;a href="https://blog.csdn.net/zhiyuan2021/article/details/129032343"&gt;https://blog.csdn.net/zhiyuan2021/article/details/129032343&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="cmake介绍"&gt;Cmake介绍&lt;/h2&gt;&#10;&lt;p&gt;Cmake是一种支持跨平台编译的工具，允许通过配置独立的配置文件&lt;code&gt;CMakeList.txt&lt;/code&gt;来定制编译流程，随后在不同的平台上进一步生成本地的&lt;code&gt;Makefile&lt;/code&gt;和工程文件(Linux平台的&lt;code&gt;Makefile&lt;/code&gt;和Windows平台的&lt;code&gt;Visual Studio&lt;/code&gt;工程等)。在linux平台下使用Cmake编译程序的主要流程是：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;编写CMakeLists.txt；&lt;/li&gt;&#10;&lt;li&gt;执行&lt;code&gt;cmake PATH&lt;/code&gt;生成&lt;code&gt;Makefile&lt;/code&gt;；&lt;/li&gt;&#10;&lt;li&gt;执行&lt;code&gt;make&lt;/code&gt;编译生成可执行程序或动态/静态链接库。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="cmake使用"&gt;Cmake使用&lt;/h2&gt;&#10;&lt;h3 id="基础案例"&gt;基础案例&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# CMake 最低版本号要求&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cmake_minimum_required (&lt;span style="color:#e6db74"&gt;VERSION&lt;/span&gt; &lt;span style="color:#e6db74"&gt;2.8&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 项目信息&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;project (&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 指定生成目标&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_executable(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;main.cc&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;CMakeLists.txt&lt;/code&gt;的语法由命令、注释和空格组成，命令不区分大小写，&lt;code&gt;#&lt;/code&gt;后面的内容是注释。命令由命令名称、小括号和参数组成，参数之间使用空格进行间隔。上面的示例中&lt;code&gt;CmakeLists.txt&lt;/code&gt;中使用了几个常用的命令，依次是&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;cmake_minimum_required&lt;/code&gt;：指定运行当前配置文件需要的最低的Cmake版本；&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;project&lt;/code&gt;：指定项目名称&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;add_executable&lt;/code&gt;：将&lt;code&gt;main.cc&lt;/code&gt;源文件编译成名为&lt;code&gt;project_name&lt;/code&gt;的可执行文件。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;实际使用中可能有多个源文件，逐个添加源文件是一件非常麻烦的事情，可以使用&lt;code&gt;aux_source_directory&lt;/code&gt;命令来获取指定目录下的所有源文件，并将结果存到指定变量名中，使用示例如下：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 查找当前目录下的所有源文件&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 并将名称保存到 DIR_SRCS 变量&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aux_source_directory(&lt;span style="color:#e6db74"&gt;.&lt;/span&gt; &lt;span style="color:#e6db74"&gt;DIR_SRCS&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 指定生成目标&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_executable(&lt;span style="color:#e6db74"&gt;Demo&lt;/span&gt; &lt;span style="color:#f92672"&gt;${&lt;/span&gt;DIR_SRCS&lt;span style="color:#f92672"&gt;}&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cmake生成动态和静态链接库"&gt;Cmake生成动态和静态链接库&lt;/h3&gt;&#10;&lt;p&gt;静态和动态链接库的主要目的是为了提供接口供其他程序调用，两者的主要区别在于：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;静态链接库的拓展名通常为&lt;code&gt;.a&lt;/code&gt;或&lt;code&gt;.lib&lt;/code&gt;，在编译时会直接整合到目标程序中，编译成功的可执行文件可以独立运行（不再需要静态库）；&lt;/li&gt;&#10;&lt;li&gt;动态链接库的拓展名通常为&lt;code&gt;.so&lt;/code&gt;或&lt;code&gt;.dll&lt;/code&gt;，在编译时不会放到目标程序中，可执行文件无法离开动态链接库单独执行。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Cmake用于生成动态和静态链接库的命令为&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 动态链接库&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_library(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;SHARED&lt;/span&gt; &lt;span style="color:#f92672"&gt;${&lt;/span&gt;SRC_FILE&lt;span style="color:#f92672"&gt;}&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 静态链接库&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;add_library(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;STATIC&lt;/span&gt; &lt;span style="color:#f92672"&gt;${&lt;/span&gt;SRC_FILE&lt;span style="color:#f92672"&gt;}&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="cmake引用外部库文件"&gt;Cmake引用外部库文件&lt;/h3&gt;&#10;&lt;p&gt;Cmake中另外一个常用的使用场景是使用外部库，对于外部库，我们通常需要进行两步操作，即引入头文件和添加链接库，具体示例如下所示：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 引入头文件所在路径&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;include_directories{include_path}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 添加链接库&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;target_link_libraries(&lt;span style="color:#e6db74"&gt;project_name&lt;/span&gt; &lt;span style="color:#e6db74"&gt;lib_name&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="其他常见的cmkae命令"&gt;其他常见的Cmkae命令&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cmake" data-lang="cmake"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 设置C++标准为C++14&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;set(&lt;span style="color:#e6db74"&gt;CMAKE_CXX_STANDARD&lt;/span&gt; &lt;span style="color:#e6db74"&gt;14&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item></channel></rss>