Masimaro's blog - 软件与环境配置
type: channel
link: https://www.masimaro.top/category/software_and_enviroment/
description: 主要记录相关软件和环境配置过程的问题以及解决方案
items: wsl 迁移
items: Emacs折腾日记(三十六)——打造个人笔记系统
items: lazygit 规范提交记录
items: Emacs 折腾日记(三十四)—— org todo
items: Emacs折腾日记(三十三)——org capture
items: Emacs折腾日记(三十二)——org mode的基本美化
items: Emacs折腾日记(三十一)——org mode入门
items: Emacs 折腾日记(三十)——打造C++ IDE 续
items: Ubuntu 20.04 安装gcc5.4 与 cmake3.16 编译环境
items: wsl 启动报错：Wsl/0x80080005

wsl 迁移
type: item
date: 2026-04-26T11:36:13+08:00
description: 之前我使用Linux的方式主要是在wsl 中。WSL 中的Linux系统默认放在了C盘，随着使用频率的增加，里面会充斥各种环境、代码、以及其他的内容，最终导致占用磁盘飙升。因为最近我发现我C盘已经飘红了，所以我需要将其中Linux系统从C盘移动到其他盘，目前我就D盘还有大量的空间所以这里我将它移动到了D盘。迁移在移动之前我们先要确保系统处于关闭状态。这里使用如下命令确认它们的状态wsl --list --verbose这条命令会输出当前系统中所有的Linux子系统的名称和对应的状态，我们需要保证对应的系统状态为 Stopped如果处于运行状态，我们可以使用wsl --terminate Arch其中最后的 Arch 就是上一步看到的系统名称停止之后，我们可以使用命令wsl --export Arch D:\WSL_Storage\Arch.tar后面两个参数分别是前面显示的系统名称，和需要备份保存的位置之后我们需要删除原先位于C盘的子系统，使用命令wsl --unregister Arch最后我们从之前备份的位置导入并生成一个新的子系统wsl --import Arch D:\WSL_Storage\Arch D:\WSL_Storage\Arch.tar这条第一个参数Arch代表的是新系统的名称。第二个参数表示系统内容存放的目录。第三个参数是从哪里导入系统数据。再次打开wsl的子系统我们会发现它采用的是root账户登录我们需要默认采用之前配置的普通用户。我们可以使用命令Arch.exe config --default-user archArch.exe 是之前子系统的名称，后面是设置该系统默认的登录用户，这里我仍然使用之前的用户名进入系统之后，我发现终端上之前配置的一些Unicode emoji 符号失效了显示乱码。这是因为我们相当于重新建立了一个子系统，在Windows Terminal 中为这个新系统配置的字体是默认的字体，我们需要在Windows Termianl中为这个新系统选择一个Unicode 字体。之后我们会看到一切恢复如初了

Emacs折腾日记(三十六)——打造个人笔记系统
type: item
date: 2026-02-01T11:31:00+08:00
description: 在前面我介绍了如何使用 org mode 来实践 gtd 的理念。其实org mode 和其他工具的结合可以打造一个强大的个人笔记系统嵌入 plantuml作为程序员，对 uml 自然不会陌生，虽然时至今日可能有些显老，但是对我来说它仍然是我不可或缺的工具。而 plantuml 是一种将文本转化为图片的工具。我们可以在 plantuml 入门 找到对应的安装步骤。对于archlinux 来说，我需要首先保证java 安装sudo pacman -S jdk21-openjdk根据 plantuml 的官方介绍，只需要jdk8就可以运行，但是我比较喜欢安装最新的版本。plantuml 中某些图需要依赖 graphviz 来生成，所以这里需要再安装一个 graphvizsudo pacman -S graphviz完成了这些基础组件的安装，下面我们就可以下载 程序这个 jar 包放在哪里都可以，既然是Emacs配合，那么我打算将它放置到 ~/.emacs.d/lib 中作为功能的依赖库我们可以使用官网的测试用例来测试一下是否正常@startuml Alice -> Bob: test @enduml将上述文本保存为 test.txt。然后执行 plantuml.jar -jar test.txt。默认在当前目录中生成同名的png图片。如果显示正常，那么我们就可以进行Emacs的改造工作了根据 官方 的文档，针对Emacs，它提供了名为 plantuml-mode 的扩展插件。我们可以通过以下简单的配置来进行org和plantuml 的联动(use-package plantuml-mode :ensure t :mode ("\\.puml\\'" "\\.plantuml\\'") :config (setq plantuml-default-exec-mode 'jar) (setq plantuml-jar-path (expand-file-name "~/.emacs.d/lib/plantuml.jar")) ;; 设置plantuml jar包的位置 ;; 让org代码块能识别plantuml语法 (add-to-list 'org-src-lang-modes '("plantuml" . "plantuml")) (org-babel-do-load-languages 'org-babel-load-languages '((plantuml . t))) (setq org-plantuml-jar-path plantuml-jar-path) )我们还是可以用官方给的示例来看看具体的效果#+begin_src plantuml :file demo.png @startuml Alice -> Bob: test @enduml #+end_src这里必须通过 :file 来指定生成图片的链接这里可以为 plantuml 做一个代码片段以便快速进行进入画图的流程。具体细节就不再深入介绍了。各位读者有兴趣可以自行探索。另外关于画图的一些其他技巧和配置，可以参考 面向产品经理的Emacs教程：15. 在Org mode里用纯文本画图构建笔记系统我个人习惯使用双链笔记，简单来说它就像wiki一样随意插入链接，各种知识结构是一个网状的。传统的笔记是树状结构（这里主要是指马克飞象那样的笔记软件对笔记的组织形式），某一条笔记输入某个单元，而这个单元又属于某个父级单元中，就像一本书一样。但我们在学习的过程中，很难在一开始就把知识整理成体系，而是先零散学习，之后随着知识面的增加逐渐形成体系。另外有些跨学科的知识可能会在多个地方被提及到，就像芒格说的跨学科思维。我们无法将某条知识仅仅归于一个大类里面。而当前双链笔记它是没有层级的，它是一个网络结构，任何知识都可以随意引用其他知识。更符合我们的认知习惯，学到新知识了先记下来，未来知识成体系了可以通过链接随意将它放置到任何体系下。在Emacs中可以使用 org-roam 插件来实现(use-package org-roam :ensure t :after org :init (setq org-oram-v2-ack t) :config (org-roam-setup) :custom (org-roam-directory "~/org/roam/") :bind (("C-c n f" . org-roam-node-find) (:map (("C-c n i" . org-roam-node-insert) ("C-c n o" . org-id-get-create) ("C-c n t" . org-roam-tag-add) ("C-c n a" . org-…

lazygit 规范提交记录
type: item
date: 2026-01-29T17:51:00+08:00
description: 背景随着项目的进程，我们经常面临一个问题：发现之前的代码有bug，但是我不知道当初为什么这么写，如果改了会影响哪些？会不会把原来改好的bug又改出来了。我们可以通过 git 的提交记录来查看当初为什么改的。但是 git 提交记录的增长，一个文件提交记录可能有成千上万，要是从头到尾找一遍不知道要找到什么时候。更糟糕的是，好不容易找到了结果提交记录就一条 update at 2026/01/29。这种情况着实令人抓狂。要防止这种情况，我们可以从两个方面着手：要求整个团队规范git 的提交记录在IDE中能快速找到每行代码对应的提交记录规范提交记录git 原版的提交信息模板提交记录我们可以采取国际通用的 Conventional Commits (约定式提交)。它的格式如下:<类型>(影响范围): 一句话总结 <空行> [正文：详细解释为什么这么做，解决了什么痛点] <空行> [脚注：关联的任务单号 ID]正文部分我希望用 Why、How 这两个关键词，也就是为什么要改，如何改。git本身支持自定义 commit 信息的格式，我们可以将一个模板添加到 ~/.gitmessage。然后通过命令git config --global commit.template ~/.gitmessage来指定使用定义的模板，这里我定义的模板如下:<type>(scope): <subject> # --- 为什么修改 (Why) --- # 描述导致问题的现象，或为什么要增加这个功能 # --- 解决方案 (How) --- # 简述核心算法或处理逻辑 # --- 关联单号 --- # Fixes: #这里的 <type> 可以是修改的类型，这个部分是必须的，我一般喜欢定义这么几种类型bugfix (修改bug)feature (添加新功能)doc (更新文档或者注释)forspell (拼写修改)scope 代表的是影响范围，可以根据项目情况灵活的定义，例如在一个前后端分离的项目中，可以定义范围为UI、数据传输、权限等等模块最后的 subject 就是一句话总结，例如"修改普通用户可以访问其他用户隐私文件的bug"后面我可以通过 git commit 来触发模板，后续通过git 默认的编辑器(一般是vi 或者 nano)。lazygit 的配置lazygit 本身也支持自定义配置，它主要通过 config.yml 文件配置，默认的配置文件位置如下:Windows: %LOCALAPPDATA%\lazygit\config.ymlMacOs: ~/Library/Application Support/lazygit/config.ymlLinux: ~/.config/lazygit/config.yml我们可以通过一个命令快捷键触发一个规范化提交的功能。用户自定义命令的模板可以在这里找到。它以 customCommands 作为根节点。后面接 key，command 和 prompts。各个部分的含义如下:key: 用来触发命令的快捷键command: 真实触发的命令prompts: 触发时的行为prompts 是另一个根节点，用于定义详细的行为。它的子元素如下:type: 输入项的类型，有 menu 表示下拉列表框；input代表输入框；menuFromCommand根据用户提供的外部shell命令来生成一个下拉列表框title: 输入框的标题，提示我们这个框用来输入什么信息key: 在command中，需要填入一些数据，我们暂时利用占位符来表示，key代表的是某个具体占位符，需要与占位符对应如果我们的类型是 menu 的话，还需要利用 options 标签来表示具体的选项。最终我的配置如下:customCommands: - key: 'X' command: "git commit -m '{{.Form.Type}}{{.Form.Scope}}: {{.Form.Subject}}' -m 'Why: {{.Form.Why}}' -m 'How: {{.Form.How}}' -m '用例文档或者jira单: {{.Form.TestCase}}'" context: 'files' description: '规范化提交 (Gitmoji + Scope)' prompts: - type: 'menu' title: '选择提交类型 (Type)' key: 'Type' options: - name: '✨ feat (新功能)' value: '✨' - name: '🐛 fix (修复Bug)' value: '🐛' - name: '🚀 更新流水线或者部署脚本' value: '🚀' - name: '📝 docs (…

Emacs 折腾日记(三十四)—— org todo
type: item
date: 2026-01-11T19:12:00+08:00
description: 在上一篇文章中，我们简单介绍了 gtd 的一些理念，并且也通过org capture 完成了 gtd 中收集的操作。gtd分为收集任务、整理、执行、回顾。本篇我想通过org todo 来聚焦整理和执行这两个步骤整理上一篇文章中，我们通过org capture 收集到了一些任务，针对这些任务我们还需要给每个任务安排优先级并且根据优先级来确定开始执行的时间。显示待办事项我们在前面的模板中，待办任务前面都是以 TODO 开头，这里的TODO就是org 中待办事项的一个标识。我们可以通过 org-agenda 来查看相关的任务。打开该页面之后，它列举出了所有的支持的一些快捷键。例如使用 t 显示所有的待办事项，使用 m 来根据 PROP、TODO、TAGS 来查找任务。但是第一次使用时会发现自己兴冲冲的咔咔一顿添加任务，结果到头来通过 org-ageda 的 t 来列举之前添加的待办任务毛都没看到，顿时好奇兴奋的心情一下跌倒谷底。别着急这是因为我们没有告诉 org-agenda 该去哪里找这些待办事项。我们可以通过 org-agenda-files 来告诉org-agenda 这个信息就像名称显示的那样 org-agenda-files 是一个列表成员，我们指定它去这些文件中查找待办事项； (use-package org-agenda :ensure nil :custom (org-agenda-files (list "~/org/reading.org" "~/org/blog.org" "~/org/working.org")))这里我设置了三个 org 文档，这三个文档分别记录待读书目、需要完成的博客以及工作任务。需要注意的是我们需要这几个文件真实存在否则就会报错。设置好了这个变量之后效果如下:设定优先级列举出所有任务之后，针对每个任务我们可以考虑如何安排这些任务，首先需要的就是考虑给它从那四个维度安排一个优先级。上面说到我们可以使用A、B、C、D 做一个标识，这里我规定优先级的顺序是:A > B > C > D为了达到这个需求，首先我们要解决的是优先级的定义问题，因为Emacs默认只支持A/B/C这三种优先级，我需要它能支持4种。Emacs种有两个变量分别控制优先级最大值和优先级最小值，它们是 org-highest-priority 和 org-lowest-priority。另外还有一个变量可以设置默认的优先级 org-default-priority。理论上它可以设置优先级从A到Z，但是过多的优先级并不适合。我们可以在上面的 :custom 下使用下列的语句进行设置 (org-highest-priority ?A) (org-lowest-priority ?D) (org-default-priority ?D)设置完成之后可以使用 S-UP (Shift + 上箭头)或者 S-Down(Shift+下箭头)来调整优先级设置计划执行时间和结束时间安排好了优先级，我们就需要为每个任务安排时间了，这里可以安排计划开始时间和结束时间。开始时间和结束时间在 org agenda 中分别是命令 org-agenda-schedule 和 org-agenda-deadline。它们被绑定到了快捷键 C-c C-s 和 C-c C-d上面。当我们通过快捷键或者 M-x 调用这两个命令的时候，Emacs会弹出日历菜单供我们选择日期，默认提供了三个月的日期可供选择。如果不够的化，日历下方两个各有一个箭头可以向上或者向下再显示一个月。另外可以在下方 mini-buffer 处输入 +1d 这样的字符表示在当前时间的1天以后，根据这个规律我们可以输入 + 后面跟任意的数字，然后后面加 d/w/m/y 来表示天、周、月、年。设置任务属性和标签有些任务，特别是工作中的任务我们自己可能无法单独完成，例如某个bug需要前端或者后端一起完成又或者这个bug不光前端要改后端也需要改，这个时候我们修改完了自己的部分，这个时候可以显示我们将任务派发给了其他同事。又或者这个bug牵扯到其他bug，又或者有时候需要开会或者整理需求文档，这个时候我们需要记录该任务的场地例如对于会议可以记录一下在 D-01 会议室。这些可以通过设置属性和标签来描述这些信息。我个人认为它们二者在记录任务的额外信息时没有什么大的区别。主要区别在显示方面，标签一般于TODO 信息展示在一行，而属性默认是被折叠起来的，所以对于一些简要的信息，例如任务目前是谁在处理、开会的地点这类信息我习惯放置到标签上、而属性放置一些不那么重要的信息。对于标签，我们可以在设置任务时，在任务后面使用 :TAG1:TAG2: 这种方式添加多个标签。在前面介绍 org-capture 的文章中我给出了…

Emacs折腾日记(三十三)——org capture
type: item
date: 2025-12-14T20:02:03+08:00
description: 在日常的工作生活中有各种各样的琐事，如果不及时记录下来很可能后面就忘了。或者在日常软件开发中有很多想法想要实现但是时间一长自己就忘了。这种情况下我们需要一个系统来记录收集想法并且后续需要追踪甚至回顾。我们需要一套适合的管理系统让大脑摆脱待办事项的纠缠，让大脑专注于当前要做的事物。目前我采取的方式是GTD+ 番茄工作法。GTD 简介GTD（Getting Things Done），是由戴维·艾伦于2002年提出的时间管理方法。其核心在于通过收集、整理、组织、回顾、执行五个步骤，将任务从大脑中移出，减轻心理压力以提升效率，强调两分钟内可完成事项立即处理的原则。用我的理解，我们需要事先准备几个速记的笔记本，一旦脑海中出现了想法就将它记录下来，这步叫做收集。在一天中的空闲时间例如下班前或者睡觉前打开看看之前记录的内容，将内容按照一定的规则重新组织例如分为工作、生活、学习之类的想法，将它们转化成可以执行的任务。并且为每个事项定一个紧急程度，这个就是整理、组织。在每天开始的时候或者结束的时候可以根据上面的分类安排一下当前或者明天的任务，这个是执行任务。在每周或者每天的时候回忆一下当前的任务看看哪些完成了、哪些未完成、从任务中有何感想，有哪些可以记录下来作为重要的日志或者日后博客的灵感来源，这个就是最后的回顾总结过程。番茄工作法再完美的系统，如果不执行或者不认真执行也是白搭的。对我来说GTD主要解决的是要做哪些事，如何安排时间的问题。至于如何高效的执行任务专注到任务上，我采用的番茄工作法。番茄工作法的简单理解就是将任务的时间拆分成几个不可分割的最小单元，在这个时间片单元内一心一意、专心到任务上。一旦分心就需要终止当前番茄钟，并记录分心的原因，如果是有新来的新任务就需要采用记录的方式记录，如果是紧急且重要的任务可能还要修改当前的任务计划。当然番茄工作法有一整套的收集、整理、执行、归纳总结的流程，但是对我来说我喜欢GTD的流程和番茄工作法的时间管理方式，所以我采用的是它们二者的结合。但是主要用在工作中，日常生活中的场景都是一些简单的琐事，例如收拾卫生、做饭、对我来说不合适这种形式。org capture目前来说市面上没有完全符合我心目中最佳时间管理理论的工具，但是Emacs中的org 是十分强大的，完全可以稍加改造成符合自己心意的时间管理系统。首先要解决的就是如何收集想法的问题。这个功能可以使用 org-capture，顾名思义它就是使用org的格式来快速记录当前的想法。我们使用 org-capture 命令可以看到下面的界面下方提示我们可以使用前面的字母符号来选择一个模板，默认只提供了一个名为 Task 的模板。我们可以使用 org-capture 中 来实现GTD中的分类记录的功能。在我们选定需要使用的模板之后，Emacs会调用 org-capture-select-template 函数来选中模板并且根据模板来创建默认的org 模板。默认的Task 模板如下：("t" "Task" entry (file+headline "" "Tasks") "* TODO %?\n %u\n %a")它们的含义如下t 标识选择模板时的快捷键。Task 模板的描述，让用户了解当前模板作用的说明文字。后面一个部分就是新增的内容新增的内容比较复杂，我们一个个的说。第一个部分是新增模板的type。type 可以是下面的内容type描述entry带有 headline 的一个 Org mode 节点item一个列表项checkitem一个 checkbox 列表项table-line一个表格行plain普通文本type 的不同，后面跟的内容也不一样。例如如果当前是 entry 的话，后面需要添加 "* headline" 作为标题行的形式，如果是 item 后面需要跟上 - item 作为一个项。如果是 checkitem 需要跟 [ ] item 作为一个checkbox项。如果使用 table-line，需要跟 | colum 1 | colum 2 | colum3 | 作为一个表格项目。如果是 plain 则没有特殊要求。接下来看看 (file+headline "" "Tasks") 中各个部分的含义，前面的 file+headline 表示将记录的内容保存到哪个位置。除了这两个标识还有其他的一些常用标识标识含义file文件id某个特定id的headlinefile+headline某个文件中的某个headlinefile+olp文件中某个headline的路径file+regexp文件以及被正则匹配的headlinefile+datetree文件中当日所在的datetreefile+datetree+prompt文件中的datetree 会弹出日…

Emacs折腾日记(三十二)——org mode的基本美化
type: item
date: 2025-10-12T20:27:17+08:00
description: 在上一篇，已经介绍了org mode的基础知识，它与markdown非常相似，并且也十分容易上手，但是它的可扩展性比markdown要强很多。如果将来打算重度使用org mode，那么此时可以对它进行一些基本的配置和美化基本配置org mode 的配置可以通过Emacs自带的org 包来进行管理，可以配置一些标签显示的图形以及一些特殊语句块的高亮(use-package org :ensure nil :mode ("\\.org\\'" . org-mode) :hook ((org-mode . visual-line-mode) (org-mode . my/org-prettify-symbols)) :commands (org-find-exact-headline-in-buffer org-set-tags) :custom-face ;; 设置org mode标题以及美级标题行的大小 (org-document-title ((t (:height 1.75 :weight bold)))) (org-level-1 ((t (:height 1.4 :weight bold)))) (org-level-2 ((t (:height 1.35 :weight bold)))) (org-level-3 ((t (:height 1.3 :weight bold)))) (org-level-4 ((t (:height 1.25 :weight bold)))) (org-level-5 ((t (:height 1.2 :weight bold)))) (org-level-6 ((t (:height 1.15 :weight bold)))) (org-level-7 ((t (:height 1.1 :weight bold)))) (org-level-8 ((t (:height 1.05 :weight bold)))) (org-level-9 ((t (:height 1.0 :weight bold)))) ;; 设置代码块用上下边线包裹 (org-block-begin-line ((t (:underline t :background unspecified)))) (org-block-end-line ((t (:overline t :underline nil :background unspecified)))) :config ;; 设置org mode中某些标签的显示字符 (defun my/org-prettify-symbols() (setq prettify-symbols-alist '(("[ ]" . 9744) ;; ☐ ("[x]" . 9745) ;; ☑ ("[-]" . 8863) ;; ⊟ ("#+begin_src" . 9998) ;; ✎ ("#+end_src" . 9633) ;; □ ("#+results:" . 9776) ;; ☰ ("#+attr_latex:" . "🄛") ("#+attr_html:" . "🄗") ("#+attr_org:" . "🄞") ("#+name:" . "🄝") ("#+caption:" . "🄒") ("#+date:" . 128197) ;; 📅 ("#+author:" . 128100) ;; 💁 ("#+setupfile:" . 128221) ;;📝 ("#+email:" . 128231) ;;📧 ("#+startup" . 10034) ;; ✲ ("#+options:" . 9965) ;; ⛭ ("#+title:" . 10162) ;; ➲ ("#+subtitle:" . 11146) ;; ⮊ ("#+downloaded" . 8650) ;; ⇊ ("#+language:" . 128441) ;;🖹 ("#+begin_quote" . 187) ;; » ("#+end_quote" . 171) ;; « ("#+begin_results" . 8943) ;; ⋯ ("#+end_results" . 8943) ;; ⋯ )) (setq prettify-symbols-unprettify-at-point t) (prettify-symbols-mode 1)) :custom (org-fontify-whole-heading-line t) ;; 设置折叠符号 (org-ellipsis " ▾") ) 上述配置比较简单，核心部分就是我们使用 prettify-symbols-alist 来使将这些特定的 prop…

Emacs折腾日记(三十一)——org mode入门
type: item
date: 2025-09-25T22:04:00+08:00
description: 之前我介绍了Emacs相关配置以及对应的知识，主要包括：vim模式、编辑的优化、补全、代码跳转、调试等等，旨在将它打造成另一个vscode、也许是我技术能力有限，不仅在使用体验上赶不上vscode，在配置的简便化以及开箱即用的程度上都比不上。如果是使用Emacs仅仅因为它复杂一般人不那么容易学会，那么就有点装x的嫌疑了。我使用Emacs的原因主要有三点：高度自由、elisp语言的魅力以及org mode。可以说没有org mode我可能不会考虑Emacs。我认为 org mode是Emacs的灵魂也是目前市面上没有任何一款软件能替代的。什么是org mode、它与markdown相比有什么优势呢？本文将对org mode做一个入门的介绍什么是org mode实际上 Org mode 是一种轻量级标记语言，它与markdown、RST类似，但是功能上要比它们强得多，不仅可以用来完成日常的文章编写，还可以进行任务管理、项目规划、笔记收集整理等各种操作。并且配合elisp编程可以千变万化。作为一门标记语言org mode实际是十分容易的，它保存的文档以 .org 作为扩展名基本使用大纲大纲可以理解为多级的标题，了解markdown的肯定知道这个意思。一个 * 代表一级大纲，两个代表二级大纲，然后依次类推。对于大纲我们可以手动输入 *，可以使用Emacs提供的快捷键快捷键功能备注在后面创建一个与光标所在位置同级的大纲如果没有大纲则默认创建一个新的一级大纲M-降低当前大纲的等级 M-升高当前大纲的等级 M-将当前大纲及其内容整体向上移动 M-将当前大纲以及内容整体向下移动 大纲这部分有点像思维导图，我们可以将某些知识点以这种大纲的形式组织起来。有些思维导图软件可以点击某个模块将它的子模块隐藏起来，与这类似的，org mode也可以在大纲上按tab键来显示或者隐藏大纲底下的内容。我们可以定义和切换整个org 文档的大纲显示样式，它主要有三种Folded: 对于当前的大纲只显示大纲本身不显示其子大纲以及内容children: 只显示当前大纲的子大纲，不显示更下一级的内容subtree: 完全展开整个大纲代码块代码块放在 #+BEGIN_SRC 和 #+END_SRC 之间，在Emacs中有一个快捷键 <s <TAB> 来快速输入这个标识. 另外也可以在 后面接上 语言类型，例如下面是一段对应的c++代码#+BEGIN_SRC c++ int main(int argc, char* argv[]) { return 0; } #+END_SRC当我们进入到代码块中编写代码时它会开启对应语言的major mode，前面我们配置了c++ lsp 补全相关的内容也可以在编辑代码块时使用超链接超链接我们可以采用 [[ ][<text>]] 的语法，例如 [[https://www.baidu.com][百度一下，你就知道]]图片本地图片可以使用 file:/path/to/image.png 的形式来写上本地图片的位置，然后开启 iimage-mode 显示图片字体样式字体样式主要有:粗体：我们可以使用 ** 来包裹文字以便显示为粗体斜体: 可以使用 // 来包裹文字显示斜体下划线: 可以使用 一前一后两个 _ _来包裹文字将它显示为带下划线的样式删除线: 可以使用 + 前后包裹来显示为删除线其实org mode 与markdown一样都非常简单，日常写博客或者写文档的话，我觉得这些基本知识差不多就够用了。

Emacs 折腾日记(三十)——打造C++ IDE 续
type: item
date: 2025-09-18T21:23:25+08:00
description: 上一篇博客中，我完成了C++ IDE初步工作，包括代码的高亮、折叠、跳转以及补全等工作。但是作为IDE来说功能还有点不够，就我个人而言作为IDE来说它还需要具备一键编译运行和调试功能。这篇文章就来记录我是如何实现上述功能的编译运行我使用的演示项目比较简单，它的文件结构如下:. ├── include │ └── head.h └── src ├── add.cpp ├── div.cpp ├── main.cpp ├── mult.cpp └── sub.cpp它分为两个目录分别保存头文件和源文件。其中头文件只有一个定义各个接口函数，而接口函数的实现就放到各自定义的cpp文件中。这里使用加减乘除的四则运算的实现来作为演示。这里我分别演示一下Make文件和CMake构建的项目是如何实现一键编译运行的。Make构建的项目针对上前面介绍的简单项目，我们可以写出如下的Makefile# 编译器设置 # 定义项目根目录 ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) CXX := g++ CXXFLAGS := -Iinclude -Wall -Wextra -pedantic -std=c++11 -MMD -MP LDFLAGS := EXE_OUTPUT := $(ROOT_DIR)bin TARGET := $(EXE_OUTPUT)/app $(info TARGET = $(TARGET)) # 源文件和对象文件设置 SRC_DIR := src SRCS := $(wildcard $(SRC_DIR)/*.cpp) OBJ_DIR := $(ROOT_DIR)build/obj OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS)) DEPS := $(OBJS:.o=.d) # 默认目标（第一个目标） all: $(TARGET) # 链接生成可执行文件 $(TARGET): $(OBJS) @mkdir -p $(@D) $(CXX) $(LDFLAGS) $^ -o $@ # 编译源文件并生成依赖 $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR) $(CXX) $(CXXFLAGS) -c $< -o $@ # 创建对象文件目录 $(OBJ_DIR): mkdir -p $@ # 包含自动生成的依赖关系 -include $(DEPS) # 清理生成的文件 clean: rm -rf $(TARGET) build .PHONY: all clean 上面我们定义了头文件路径为include 目录，并且规定了中间文件生成在 build/obj 中，最后定义了生成可执行程序在 bin/app 中对于编译来说，Emacs内置了 compile 命令，它会自动执行 make -k 命令，但是如果我在使用Emacs的过程中切换到了其他目录的话，还需要特别指定Makefile 所在的路径，对我来说我希望能在尽可能少输入参数的情况下完成同样的操作，不太希望每次都指定项目根目录，好在之前配置的projectile 插件帮助我们识别出来了项目的根目录。所以这里可以使用 projectile-compile-project 来自动指定根目录并编译。从上面的截图可以看到，flycheck 提示了几个错误，这是因为项目没有生成 compile_commands.json文件，所以lsp服务器无法跨文件分析，导致找不到头文件。原始的make 命令并不支持生成 compile_commands.json 文件，我们可以通过 bear 命令来完成这个工作，它的用法比较简单，只需要使用 bear -- <your-build-command> 即可, 对于使用make编译的项目来说 <your-build-command> 代表的就是 make 命令。我们需要考虑的一个问题是，如何将bear加入到编译命令中，也就是将它自动生成的 make -k 给替换掉，第二个问题是如果当前目录在其他目录下，如何保证 compile_commands.json 永远生成在根目录下Emacs中有一个变量 compile-command 保存了编译的命令，如果我们使用Emacs自带的compile来编译可以通过修改它来实现，而 projectile-compile-project 则是通过变量 projectile-project-compilation-cmd 来保存编译命令，默认是nil，对于使用 projectile 我们通过修改这个变量的值从而修改编译时使用的命令。另外既然 proj…

Ubuntu 20.04 安装gcc5.4 与 cmake3.16 编译环境
type: item
date: 2025-09-03T10:36:00+08:00
description: 因为公司的编译环境使用的是Ubuntu 20.04 搭配 gcc5.4 和 cmake3.16。所以我也在自己的开发机上安装了配套的环境Ubuntu 就使用 WSL2 直接安装就行，编译环境因为Ubuntu 20.04 默认使用的是gcc 9的版本，所以配置起来还是需要稍微费点功夫的。这里记录一下有效的步骤防止后续又需要配置这套环境的时候满世界找因为gcc5.4 相对来说比较老了，这一版Ubuntu 的官方软件源仓库中没有，需要添加额外的软件源仓库我们可以选择先备份原始的软件源，然后将下列源添加到 /etc/apt/sources.list 文件的末尾deb http://archive.ubuntu.com/ubuntu xenial main universe然后执行sudo apt update && sudo apt upgrade更新软件源接着安装gcc 5.4 以及对应的32位环境支持sudo apt install -y gcc-5 g++-5 gcc-5-multilib g++-5-multilib sudo apt install -y libc6-dev-i386 lib32stdc++6 lib32gcc1默认情况下，ubuntu 20.04 中安装的gcc版本是9.0，如果我们自行安装了 gcc5.4，系统中会有多个gcc版本有时候会导致冲突，我们可以使用下面的命令来管理多个gcc版本# 配置备选版本 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 50 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 50 # 切换版本（选 5.4 对应的编号） sudo update-alternatives --config gcc sudo update-alternatives --config g++此时使用 gcc --version 将会看到当前gcc的版本是5.4Ubuntu 20.04 官方的软件源中cmake的版本就是 3.16，所以对于cmake直接使用sudo apt install cmake

wsl 启动报错：Wsl/0x80080005
type: item
date: 2025-08-11T10:44:53+08:00
description: 周末结束过来上班的时候发现公司电脑上安装的wsl2 中的arch和Ubuntu 都无法打开了，表现出来的现象是通过终端打开系统时长时间无法进入系统，等待大概半小时左右会出现提示：Wsl/0x80080005通过网络上查找，这种一般是系统坏了，或者是服务没启动，又或者是网络协议栈出现问题。对应的办法就是重置Linux系统(这种是最坏的情况，一般留到最后实在没办法了再尝试)、启动 LxxManager 服务，重置网络协议。通过尝试我发现我的属于网络协议栈问题，通过powershell 命令(需要管理员权限)netsh winsock reset # 重置网络套接字 netsh int ip reset # 重置 IP 协议然后重启电脑问题就解决啦!