Makefile实战指南:从核心语法到自动化构建的完整模板
1. 为什么Makefile至今仍是Linux项目管理的首选1.1 从全量重编手工编译说起如果你在Linux下管理代码项目Makefile估计是你绕不开的一个工具。它语法不算复杂但用得好的项目一进目录就能敲一个make搞定编译用不好的改一个源文件都要全量重编甚至编译出来的东西对不对都不敢保证。我印象很深的一次经历是在一个多文件的C语言项目里。当时头文件里改了函数接口我手工把主文件重新编译了一遍但其他依赖同一个头文件的源文件没有重编。链接出来的程序一开始跑得还挺正常等执行到某个功能时行为和预期完全不一致。我查了半天最后发现是一部分目标文件还在用旧的头文件内容。那一刻我才真正理解靠人脑记录文件依赖关系就是在赌运气。Makefile解决的就是这个问题它记录目标文件、依赖文件和生成命令之间的关系并且通过文件时间戳来决定哪些目标需要重建。如果某个依赖比目标新make就执行对应命令更新目标如果依赖没有变化目标就不会被重新编译。这套机制天然支持增量构建改一个文件往往只需要编译几个相关文件而不是从头再来。你可能会问现在有那么多现代构建系统为什么还要学Makefile答案是它足够轻量、足够底层几乎所有Linux发行版都自带make工具不需要额外安装。无论你写C、C还是用make去处理文档、数据流水线只要存在输入文件生成输出文件这样的关系它都能派上用场。这篇文章我就从最核心的语法讲起再带你看我踩过的坑最后给出一个可以直接参考和改写的完整模板。1.2 Makefile与Shell脚本、CMake的真实分工很多人会把Makefile当成一种编译脚本这其实是个误会。Shell脚本确实能编译但它是一条一条命令顺序执行脚本本身并不知道哪些文件变了、哪些目标需要重建。Makefile不一样它更像是一张依赖关系图先构建哪个文件依赖什么用什么命令生成都会根据文件状态自动判断。CMake则属于更高一层的工具它负责处理跨平台、大型复杂项目的配置问题最终还是要生成Makefile或者Ninja这样的构建文件。在我的实际经验里中小项目、Linux下的工具链项目、嵌入式固件直接用Makefile反而更清爽。它没有额外一层抽象出问题的时候你能看到完整的规则和命令排查起来非常直接。Makefile还有一个容易被忽略的好处它可以随时用make target来执行某个具体目标。比如make clean、make install、make test本质上它成了一个项目管理入口而不仅是编译工具。后面我会专门讲怎么把Makefile当命令入口来用。2. 从零拆解Makefile核心语法规则、变量、伪目标2.1 规则三要素目标、依赖、命令Makefile的基本单元是规则一行规则的骨架如下目标: 依赖1 依赖2 ... 命令要注意的是命令前面不是普通空格而是一个Tab字符。这是新手最容易踩的坑后面我会单独展开。看一个最简单的例子app: main.o utils.o gcc -o app main.o utils.o main.o: main.c utils.h gcc -c main.c -o main.o utils.o: utils.c utils.h gcc -c utils.c -o utils.o这段规则表达了三件事app这个目标依赖main.o和utils.o。如果这两个文件不存在或者它们比app新就执行gcc -o app ...重新链接。main.o依赖main.c和utils.h。如果头文件、源文件发生变化就重新编译这个目标文件。utils.o同理。make执行时的默认行为是找第一个目标然后递归检查它的依赖。依赖不存在就先生成依赖依赖更新了最终目标也会跟着重建。你可以把make想象成一个会看时间的快递分拣员哪个包裹上的时间戳更晚说明它更新就得重新处理一遍。理解了这层逻辑你就知道Makefile为什么能实现增量编译了。它不是每次从零开始而是只做最小必要的工作。2.2 变量展开方式、:、?、 的差异变量是让Makefile脱离复制粘贴的关键。先看变量定义和引用的样子CC gcc CFLAGS -Wall -g main.o: main.c utils.h $(CC) $(CFLAGS) -c main.c -o main.o定义变量用引用变量用$(变量名)。看起来简单但变量赋值有四种方式差别很大赋值符含义常见场景递归展开定义时不立即求值使用时才逐层展开旧式写法灵活但容易产生循环引用:简单展开定义时立即求值推荐优先使用行为更可预测?如果变量未定义才赋值给用户提供默认值在原有值后面追加内容分阶段追加编译选项举个例子下面这段代码A hello B $(A) world A hi C : hello D : $(C) world C : hi最后B的值是hi world因为是使用时才展开这时A已经变成hi。而D的值是hello world因为:在定义时就把C当时的hello展开了。如果你不熟悉这些行为建议一律用:排查问题会容易很多。?最常见的使用场景是给构建模式一个默认值BUILD ? release这样用户可以在命令行用make BUILDdebug覆盖但如果直接敲make它就用默认的release。这个技巧在后面实战部分会用到。2.3 自动变量与模式规则写规则时不想每次重复目标名和依赖列表自动变量就是为此设计的。最常用的三个$当前目标名$当前规则中的第一个依赖$^当前规则中的所有依赖比如编译utils.o: utils.c utils.h $(CC) $(CFLAGS) -c $ -o $这里$是utils.c$是utils.o即使以后改了文件名命令这一行基本不用动。自动变量配合模式规则能让同类的规则合并成一条。模式规则用%作为通配符%.o: %.c $(CC) $(CFLAGS) -c $ -o $这条规则表示任何.c文件都能生成对应的.o文件。只要源文件比目标文件新或者目标文件不存在make就会套用这条规则来编译。这是Makefile里效率最高的写法比逐文件手写规则省太多事。2.4 伪目标和默认目标的正确打开方式如果一个目标并不对应真实文件只是代表一个动作比如clean、install它就叫伪目标。问题是如果当前目录下恰好有一个叫clean的文件make会认为这个目标已经是最新的直接跳过命令导致make clean没反应。解决办法是用.PHONY显式声明.PHONY: clean clean: rm -rf *.o app声明之后make就不管同名文件是否存在每次都会执行clean对应的命令。默认目标的概念也很重要make会从第一个目标开始执行所以通常把all或主要产物放在文件最前面.PHONY: all all: app这样直接敲make等价于make app。如果后面还有别的目标比如docs、test它们之间不会互相干扰。设计合理的默认目标才能让使用者不看说明也能直接编译。3. 进阶语法函数、条件判断与头文件搜索3.1 三个高频函数的用途和组合Makefile自带一批文本处理函数它们不是用来炫技的而是解决一个痛点让规则自动适配目录里的文件而不是每次新增源文件都去改Makefile。最常用的三个函数wildcard查找符合通配符的文件列表patsubst做模式替换foreach遍历列表并拼接内容比如把src目录下的所有.c文件找出来再全部替换成.o文件SRC_DIR : src OBJ_DIR : obj SRCS : $(wildcard $(SRC_DIR)/*.c) OBJS : $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS))这段代码最后得到的OBJS类似于obj/main.o obj/utils.o。以后往src目录里新增源文件Makefile自动就能感知完全不用改规则。foreach的典型场景是处理多目录。比如你有src和test两个目录都要找文件MODULES : src test SRCS : $(foreach dir,$(MODULES),$(wildcard $(dir)/*.c))它的逻辑是遍历MODULES中的每个值分别执行wildcard再把结果拼接在一起。遇到更复杂的生成逻辑时foreach比逐个写wildcard直观得多。这里还想分享一个小技巧写复杂函数组合时先用$(info ...)把变量打印出来确认内容再继续。很多莫名其妙的错误其实都是因为变量值和你想象的不一样。3.2 条件判断实现Debug/Release切换条件判断语法是ifeq、else、endif这一组。它的作用范围是Makefile解析阶段而不是运行时。所以它很适合根据参数切换编译选项。看个完整的切换例子BUILD ? release ifeq ($(BUILD),debug) CFLAGS : -Wall -Wextra -g -O0 else CFLAGS : -Wall -Wextra -O2 endif命令行这样用make BUILDdebug make BUILDrelease如果不传参数默认进入release分支。这个写法我几乎每个项目都在用简单、可控不会让编译选项散落在各处。除了ifeq还有ifneq、ifdef、ifndef。ifdef判断变量是否被定义即使变量值是空字符串只要被定义过也会返回真这个细节要注意。如果需要判断变量非空最好用ifneq ($(VAR),)这也是我在一个项目里排查了半小时才发现的坑值时明明感觉是空但ifdef始终为真。3.3 VPATH与vpath让目录结构更干净默认情况下make只会在当前目录查找目标和依赖。如果源文件放在src子目录头文件放在include子目录光写规则还不够make需要知道去哪里找文件。最简单的做法是设置VPATHVPATH : src include这样make在找不到文件时会去src和include目录里找。如果希望更精细地控制比如只让make在src里搜索.c文件在include里搜索.h文件可以用vpath指令vpath %.c src vpath %.h include两者的区别在于VPATH是无差别搜索vpath是带模式匹配的搜索。项目规模变大后我更推荐用vpath规则清晰也避免不同目录同名文件被错误匹配。需要注意的是如果源文件不在当前目录而规则里写的是相对路径比如%.o: %.cmake会通过vpath找到源文件但生成的目标文件仍然在当前目录。所以我在实战模板里会刻意让目标文件和源文件分目录存放而不是src和obj混在一起。4. 我在Makefile里踩过的坑Tab、隐式规则与Shell执行4.1 Tab和空格第一个拦路虎新手刚写Makefile十个里有八个会碰到这个报错Makefile:3: *** missing separator. Stop.原因只有一个命令行前面用的不是Tab字符而是空格。make规定规则中的命令必须以Tab开头普通空格一律不认。很多编辑器会把Tab显示成一条横线或者自动转成空格这就导致问题非常隐蔽。建议在编辑器里打开空白字符显示强制让Tab可见。我自己习惯在项目根目录放一个编辑器配置让Makefile永不自动展开Tab。如果发现报错先用cat -A Makefile查看Tab在输出里会显示成^I空格则是普通空白一眼就能分辨。后来我发现GNU make支持一个扩展特性可以改变命令前缀字符.RECIPEPREFIX 定义之后命令行前缀就可以用而不用Tab。这个功能在Linux自带的GNU make里基本都能用。我下面实战示例里就用了这个写法主要是为了排版更清楚你复制到本地时如果make不支持再把换回Tab即可。4.2 被隐式规则反咬一口的经历make内置了很多隐式规则比如看到.c文件就自动知道可以用cc编译成.o文件。这表面上很方便但有时候会带来意外。有次我定义了一个目标名字恰好和某个.o文件有关规则里又没写完整命令。make没有试图执行我的规则而是调用了它自己内置的.c - .o规则硬生生去编译了另一个源文件。我当时盯着输出看了很久才明白原来是隐式规则在起作用。如果你不需要这些内置规则可以在文件开头清空后缀列表.SUFFIXES:这样大部分隐式规则就会失效所有构建行为都由你显式定义。在调试复杂问题时还可以用make -R效果是禁用内置变量和隐式规则能帮助你判断问题是否出自隐式规则。4.3 每条命令都在独立Shell里执行Makefile规则里的每一条命令都是在一个独立的Shell进程中执行的。这意味着你写下面这种写法是无效的test: cd /tmp pwd第二行pwd打印的还是当前目录而不是/tmp因为第一条命令的cd影响不了第二个Shell进程。解决办法有三种在一条命令里用连接用反斜杠\把多行拼接成一行使用GNU make的.ONESHELL告诉make所有命令在同一个Shell里执行实际项目中我更推荐用第一条方案显式串联能让你看清每个步骤之间的关系。另外两个常用的命令前缀也在这里一起说命令不显示命令本身只显示输出-命令忽略这条命令的返回值即使报错也继续执行我用得最多的是比如echo build done输出干净很多。-要慎用因为它会把错误吞掉建议只在确实知道命令可能失败、但又不能让它中断构建的场景里用。4.4 其它容易被忽略的小陷阱变量赋值时行尾的空格可能会悄悄混进值里。比如CFLAGS -Wall -g最后一个空格会被当成变量值的一部分有时命令行里会多出奇怪参数。遇到这种问题可以用strip函数清理。另一个坑是目标名称和目录名一致。比如你有一个目录叫docs同时又想定义一个目标docs如果不用.PHONY声明make会认为目录已经存在、目标是最新的规则永远不执行。还有如果Makefile里出现空行空行前不能有Tab字符否则make会把它当成一条命令。这些问题单独看都很小但组合起来就非常消耗时间。我的排查习惯是先用make -n看make打算执行哪些命令再用make -d看详细决策过程基本能定位大多数问题。5. 实战一个多目录、双模式、自动依赖的完整Makefile5.1 目录结构和目标设计说了这么多不如直接上一份可以复用的完整模板。假设项目结构如下project/ ├── Makefile ├── include/ │ └── utils.h ├── src/ │ ├── main.c │ └── utils.c ├── obj/ └── bin/目标很简单生成bin/app可执行文件支持make BUILDdebug切换调试模式和发布模式源文件在src头文件在include目标文件放在obj自动创建obj和bin目录自动生成头文件依赖改头文件后相关源文件会重新编译make clean一键清理核心设计思路是源文件目录和生成文件目录分离构建过程不会污染源码目录。这也是我建议每个项目都采用的结构尤其当项目需要打包发布时直接清掉obj和bin两个目录就能得到干净的源码包。5.2 逐段拆解完整Makefile下面是完整内容我用GNU make的.RECIPEPREFIX把命令前缀改成方便阅读.RECIPEPREFIX TARGET : bin/app SRC_DIR : src INC_DIR : include OBJ_DIR : obj SRCS : $(wildcard $(SRC_DIR)/*.c) OBJS : $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS)) CC : gcc CFLAGS : -I$(INC_DIR) -Wall -Wextra LDFLAGS : BUILD ? release ifeq ($(BUILD),debug) CFLAGS -g -O0 else CFLAGS -O2 endif .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJS) | $(BIN_DIR) $(CC) $(LDFLAGS) -o $ $(OBJS) $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR) $(CC) $(CFLAGS) -MMD -MP -c $ -o $ $(OBJ_DIR): mkdir -p $(OBJ_DIR) $(BIN_DIR): mkdir -p $(BIN_DIR) clean: rm -rf $(OBJ_DIR) $(BIN_DIR) $(TARGET) -include $(OBJS:.o.d)这段代码看起来不长但它把前面提到的语法点和坑基本都用上了。5.3 关键细节order-only依赖、自动生成.d依赖文件先看这一行$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)竖线|后面的依赖叫做order-only依赖。它的意思是$(OBJ_DIR)目录只负责先存在这个条件不会因为目录里的文件变化触发目标重建。如果不用order-only而是写成普通依赖那么obj目录里任何文件变化都会导致所有目标重新编译那增量构建就废了。在普通依赖那一侧$(SRC_DIR)/%.c是实际的源文件。只要源文件时间戳大于目标文件就会重新编译。-MMD -MP这两个参数很关键。-MMD让GCC在编译时顺便生成.d文件这个文件记录了源文件对头文件的依赖关系。比如编译src/utils.c后会得到obj/utils.d里面写的是obj/utils.o: src/utils.c include/utils.h。文件末尾的-include $(OBJS:.o.d)就是把所有.d文件包含进Makefile这样make就能感知到头文件的变化改一次utils.h所有包含它的.o都会重新编。-MP的作用是生成针对伪目标的依赖防止头文件被删除后make报错说找不到目标。这也是自动依赖方案里的重要一环建议不要省略。5.4 如何验证和扩展这个模板模板写完先跑一遍make make BUILDdebug make clean第一次执行时obj和bin目录会由mkdir -p自动创建然后逐个编译源文件最后链接。再执行一次make你会看到make什么都不做因为所有目标都已经是最新的。这时用touch include/utils.h再执行make会看到相关源文件被重新编译这就是自动依赖在起作用。如果要扩展可以考虑在SRCS的基础上增加多个目录使用前面说的foreach函数。大型项目如果目录层次很深也可以在子目录里放各自的Makefile再在主Makefile里用$(MAKE) -C subdir调用。不过我的建议是除非目录真的复杂到单文件无法维护否则先尽量保持一个顶层Makefile结构越简单排查问题越容易。6. 提升日常使用体验的Makefile细节6.1 -j并行编译的正确姿势Makefile的依赖关系是天然支持并行的。只要两个目标没有依赖关系理论上它们可以同时构建。比如多个.o文件互相独立就可以并行编译。执行时加-j参数make -j$(nproc)nproc会返回当前机器的CPU核心数。对于大型项目这个加速效果非常明显。并行编译的前提是Makefile里的规则必须正确。如果你用了一些顺序依赖的写法比如整个项目只有一条规则命令里自己去编译多个文件并行就可能导致冲突。另一个需要注意的问题是同一时刻不要有多个规则往同一个文件里写比如两个规则都试图生成temp.txt就会出乱子。我的原则是每个目标只由一个规则负责生成别的规则只依赖它。如果有时候不想并行也可以用make -j1回到单线程模式。调试莫名其妙的构建问题时我经常先-j1再看输出。6.2 把Makefile当命令入口来用Makefile不仅能管编译还可以把项目常用的维护命令都集中起来。比如.PHONY: format test run clean format: clang-format -i $(SRCS) $(wildcard $(INC_DIR)/*.h) test: $(TARGET) --test run: $(TARGET)这样团队里的同事不需要记一堆命令只要看Makefile就知道项目有哪些常规操作。这也是很多开源项目使用Makefile的原因之一。需要提醒的是format、test这类目标最好都声明为.PHONY否则万一目录里出现同名文件会莫名失效。我还习惯在all目标里只放构建任务把测试、格式化等动作单独拆出目标避免默认执行太多事情影响构建速度。6.3 调试Makefile的实用手段Makefile出错时最怕像黑盒一样瞎猜。只要掌握下面几个手段大部分问题都能快速定位。make -n只打印需要执行的命令但不真正执行。适合检查规则和变量是否按预期工作。make -d输出make的详细决策过程包括依赖检查、时间戳对比。信息量很大适合定位为什么没重新编译这类问题。make -p打印整个Makefile的变量、规则、内置信息。在Makefile内部用$(info ...)、$(warning ...)输出调试信息。我经常用的组合是make -n BUILDdebug先看调试模式下make想干什么再决定要不要真跑。如果觉得变量值不对就在怀疑位置加一行$(info OBJS$(OBJS))这样做比在Shell命令里打印更直接因为它能看到make解析阶段的真实内容。最后分享一个我养成很久的习惯每次修改Makefile先执行make -n确认命令列表符合预期再执行真实构建。如果你刚接触Makefile建议先从这份模板开始不要急着写复杂的函数和规则。把核心规则、变量、伪目标、自动依赖这几个点吃透再逐步加入自己的需要你的Linux项目管理体验会轻松很多。

相关新闻

API在信贷风控与反欺诈中的实战:从数据接入到稳定治理

API在信贷风控与反欺诈中的实战:从数据接入到稳定治理

1. 为什么要聊挖数据这件事做信贷风控的朋友应该都有同感:互联网信贷看似比拼的是流量和产品体验,到了后期拼的全是数据。我一开始做风控建模的时候,最头疼的不是模型选型,而是特征工程之前那一大堆脏活累活——数据从哪来、怎么取…

2026/10/15 22:03:21 阅读更多 →
人脸识别实战:从检测到部署的全链路调优指南

人脸识别实战:从检测到部署的全链路调优指南

1. 为什么从“记录一次人脸识别的学习”开始,而不是直接抄个现成模型很多人看到“人脸识别”四个字,第一反应是去GitHub搜一个star数过万的项目,改两行配置,跑通demo就发朋友圈:“搞定!AI已入门”。我试过三…

2026/10/15 22:03:21 阅读更多 →
打造高效算法刷题本:从设计模板到知识体系

打造高效算法刷题本:从设计模板到知识体系

算法刷题本这三个字,拆开看不像什么新鲜事,不就是题目、讲解、代码三段式吗?但真能把这三块同时做扎实的人,我身边并不多见。大部分人的刷题记录,要么是一堆来不及看的题解链接,要么是粘贴板上贴了一整页代…

2026/10/15 22:03:21 阅读更多 →

最新新闻

喂文件、写代码、聊天:三个开源工具打造本地化AI工作流

喂文件、写代码、聊天:三个开源工具打造本地化AI工作流

1. 项目概述:为什么“喂文件、写代码、聊天”这三件事,才是AI真正落地的临界点最近在几个技术社区和产品团队内部做AI工具链调研时,反复听到一句话:“模型能力早就够了,卡在怎么用上。”不是模型不够聪明,而…

2026/10/15 22:55:22 阅读更多 →
AI全链路开发微信小游戏:火山AgentPlan + Cocos + MCP自动化流水线实战(TaoToken统一Key接入版)

AI全链路开发微信小游戏:火山AgentPlan + Cocos + MCP自动化流水线实战(TaoToken统一Key接入版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 22:55:22 阅读更多 →
膀胱癌机器学习论文复现全解析:从传统模型到图神经网络

膀胱癌机器学习论文复现全解析:从传统模型到图神经网络

前阵子一位学弟跟我吐槽,他拿某公开肿瘤数据仓库的膀胱癌转录组数据跑了一圈随机森林,训练集AUC超过0.95,换到外部验证集立刻掉到0.6出头,论文投出去直接被秒拒。我听完一点不意外。这几年顶着“机器学习”帽子的肿瘤预后文章越来…

2026/10/15 22:55:22 阅读更多 →
嵌入式GPS解析C程序:NMEA状态机设计与抗丢帧实战

嵌入式GPS解析C程序:NMEA状态机设计与抗丢帧实战

简介:本资源是一套面向嵌入式开发初学者与单片机爱好者的GPS数据解析实战代码,聚焦NMEA协议报文(如GPGGA、GPGLL)的C语言解析与12864液晶屏实时显示,解决GPS模块串口数据读取、坐标提取、浮点转换及硬件驱动集成等典型…

2026/10/15 22:55:22 阅读更多 →
CLI+SKILL:零代码基础也能搭建自动化流程的新范式

CLI+SKILL:零代码基础也能搭建自动化流程的新范式

1. 这个标题到底在说什么先把话说直白一点:这个标题讲的不是“程序员要失业了”,而是开发这件事的门槛正在被重新定义。过去我们讲全栈,默认你得会前端三件套、后端一门语言、数据库、部署、运维,少说也得啃个一两年。但现在冒出来…

2026/10/15 22:55:22 阅读更多 →
2026桌面Agent工具对比:OpenClaw龙虾替代品与TaoToken统一接入实践

2026桌面Agent工具对比:OpenClaw龙虾替代品与TaoToken统一接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 22:54:21 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →