如果你跟我一样日常开发机是一台 Windows x86 机器但最终要交付的程序却要跑在一块 arm64 的 Linux 板子上那你大概率经历过这种混乱本地编译得好好的程序拷到板子上直接告诉你 Exec format error想打个 deb 包交给部署的人发现 Windows 上连 dpkg 命令都没有。我后来把整个交叉编译和打包流程统一放到 WSL 里才结束这种两头折腾的日子。这篇文章就把这条链路完整记下来从 WSL 环境搭建、aarch64 交叉编译到用 dpkg-deb 手工打出 arm64 的 deb 包最后传到板子上用一条 dpkg -i 完成安装。整个过程我实际跑了很多遍踩过的坑也一并写出来供同样在搞嵌入式、板级开发或者软件交付的朋友参考。1. 为什么非要在 WSL 里交叉编译先把环境问题想明白1.1 开发机和目标板之间隔的不止是 CPU 指令集很多人第一次遇到这个问题时的反应是换个编译器编译一下不就行了实际上远没有这么简单。x86 和 arm64 的差异只是第一个层次更麻烦的是你的开发机跑的是 Windows而目标板跑的是 Linux。这两者之间至少隔了三层鸿沟。第一层是 CPU 指令集。x86_64 和 ARM aarch64 是完全不同的指令集源码必须专门针对 aarch64 重新编译这一点大家都有共识。第二层是二进制格式。Windows 可执行文件是 PE 格式Linux 可执行文件是 ELF 格式。就算换了编译器链接器、动态加载器、系统调用约定也必须全部按 Linux 体系来否则产物在板子上根本跑不起来。第三层是包管理生态。deb 是 Debian 系 Linux 发行版的软件包格式安装工具是 dpkg/dpkg-deb控制脚本是 shell 脚本。在 Windows 原生环境里你连 dpkg 都找不到更别说模拟 postinst 脚本在安装时的真实行为。这也是我最初觉得最别扭的地方代码可以跨平台写但打包成 deb这件事天然是 Linux 用户的活。所以第一步不是忙着敲编译命令而是先给自己准备一个 Linux 用户态环境。1.2 WSL 补齐了Linux 用户态这块拼图而且它自己可以是 x86WSLWindows Subsystem for Linux是 Windows 提供的 Linux 兼容环境。对我来说它的价值不是跑个终端而是提供了一个完整的 Linux 用户态bash、apt、gcc、dpkg、dpkg-deb这些东西全部齐全。相比双系统或者虚拟机WSL 的启动开销小文件系统能和 Windows 互通路径也能互相访问天然适合做这种跨平台构建工作。这里有个关键点很多人一开始没转过弯WSL 装好之后本身是 x86 架构除非你用的是 ARM Windows 设备。那它还能打出 arm64 的包吗能。因为交叉编译这个动作核心在于编译器的两个维度编译器在什么架构上运行host编译器生成的代码跑在什么架构上target。gcc-aarch64-linux-gnu 这样的交叉编译器它是在 x86 上运行的程序但它生成的代码目标是 aarch64。host 和 target 被解耦了这就是交叉编译的本质。在 x86 的 WSL 里产出 arm64 的 deb平台层面完全行得通用来验证这个结论的就是后面你会看到的 file 命令输出。补充一个 WSL 使用习惯WSL 的发行版文件默认放在 C 盘用户目录下但交叉编译加打包动辄十几个 GB 的依赖。我习惯装完系统后立刻把虚拟磁盘迁移到 D 盘用wsl --export和wsl --import就能做。这不是必须的但如果你 C 盘常年吃紧这个操作能救回不少空间。2. 交叉编译工具链选型系统自带还是厂商提供2.1 Debian/Ubuntu 仓库里的 aarch64 交叉工具链工具链不是只有一种选择。对大部分场景首选的是发行版仓库里的 GNU 交叉工具链。以 Ubuntu/Debian 的 WSL 环境为例安装命令很简单sudo apt update sudo apt install -y gcc-aarch64-linux-gnu g-aarch64-linux-gnu binutils-aarch64-linux-gnu装完后会得到一系列aarch64-linux-gnu-前缀的工具比如aarch64-linux-gnu-gcc、aarch64-linux-gnu-g、aarch64-linux-gnu-ld、aarch64-linux-gnu-objdump。前缀的含义就是目标是 aarch64 Linux。如果准备编译 C/C 程序建议再补一个包libc6-dev-arm64-cross。它提供的是目标平台的 glibc 开发文件头文件和库交叉编译器在链接阶段要用它对最终产物做 glibc 相关的处理。缺少它最常见的报错是找不到 stdio.h 一类的头文件或者链接时找不到 crt1.o。这个细节值得单独拿出来说因为新手往往只装了 gcc、没装 libc 开发文件然后花大量时间怀疑是工具链坏了。这里其实涉及一个原理交叉编译器本身跑在 x86 上但它编译的代码要跑在 aarch64 上所以编译时用到的标准头文件、启动文件、运行库都必须来自 aarch64 目标体系的 sysroot而不是本机 x86 的 /usr/include。libc6-dev-arm64-cross装进去的正是这一整套 target 侧的系统库这也是交叉这两个字的真正含义。2.2 板卡厂商的交叉编译工具链在什么时候用如果你用的是特定板卡厂商的开发板比如 RK3568 这类比较常见的瑞芯微平台厂商 SDK 里经常会额外附带一套预编译的交叉编译工具链。网上搜野火rk3568交叉编译工具链下载能很容易找到这类资源。这时候就产生一个选择到底用系统包管理器装 GNU 工具链还是用厂商提供的我的建议是分情况如果你的目标是给板子系统打一个干净的 deb 包优先用发行版自带的 GNU 工具链。它的版本更现代、依赖清晰、和板子上的 dpkg 生态是同一套体系排错时社区答案也最多。如果你的目标是配合厂商 SDK 编译内核模块、device tree、固件镜像这时候大概率只能用厂商工具链因为 SDK 的构建脚本会对路径和版本做硬编码。强行用系统工具链替换反而会遇到各种隐含的 ABI 或版本不匹配问题。如果目标板不是标准 Debian/Ubuntu而是被厂商深度裁剪过的 rootfs比如精简到只剩基础库的嵌入式系统那编译用户态程序时也要优先用厂商工具链配套的 sysroot避免链接出依赖高版本 glibc 的程序在板子上跑不起来。还要提醒一句厂商工具链的前缀往往五花八门有叫 arm-linux-gnueabihf- 的也有叫 aarch64-none-linux-gnu- 的。如果机器上同时装了系统自带工具链和厂商工具链操作时一定看清前缀别混用。2.3 装完之后的第一道验货流程工具链装完别急着打包先用最小程序验一下。我习惯写一个 hello.c做最小闭环#include stdio.h int main(void) { printf(hello from arm64\n); return 0; }编译和验货aarch64-linux-gnu-gcc -O2 -o hello-arm64 hello.c file hello-arm64正常情况下 file 会输出类似这样的一行hello-arm64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, ...看到ARM aarch64基本可以确认工具链工作正常。注意此时如果你直接./hello-arm64x86 的 WSL 会给出Exec format error。这是预期行为千万别以为编译失败了。后面我们在第 5 部分会用 qemu-user 让它在 x86 环境里也能跑起来做快速验证。3. deb 包的工作原理它不是压缩包改个名那么简单3.1 用一条命令拆开别人的 deb 看看动手做包之前我强烈建议先拆一个现成的 deb 看看。这比看任何文档都快。在 WSL 里找一个常见的小包或者去/var/cache/apt/archives里翻缓存然后用两条命令拆mkdir -p DEBIAN_CTRL data dpkg-deb -e 某个包.deb DEBIAN_CTRL dpkg-deb -x 某个包.deb data-e解出的是控制包内容里面会看到 control、md5sums、conffiles、postinst 等文件-x解出的是安装数据里面是 usr/bin、usr/lib、etc 这类目录。这才是 deb 的本来面貌一个 ar 归档容器里面装着一个控制包和一个数据包。理解到这个层面很多问题就能想明白了。比如为什么 dpkg -i 可以准确知道这个包会对系统做哪些改动因为数据包里的路径就是安装后映射到根目录/的路径为什么卸载时可以选择保留或删除配置因为 conffiles 文件单独登记了配置文件的路径为什么有的包安装时能自动启动服务因为维护脚本里写了 systemctl 命令。所以做 deb 包本质上是在准备两份东西一份是系统文件快照一份是安装状态机描述。3.2 control 文件的字段逐一扫盲control 是打包时最需要抠细节的地方。下面是字段清单照着填基本不会出错字段作用示例Package包名小写全局唯一hello-arm64Version版本号1.0.0Architecture目标架构dpkg 安装时会严格校验arm64Maintainer维护者信息Name youexample.comDepends运行时依赖包可带版本约束libc6 ( 2.31)Section分类方便包管理工具归类utilsPriority优先级一般写 optionaloptionalHomepage项目主页可选https://example.comDescription首行是短描述后面是长描述A tiny arm64 demo package built in WSL这里我想强调两个字段。第一个是 Architecture。dpkg 在安装时会拿它和系统架构做比对不一致就直接拒绝。所以我后来形成习惯打包完成先dpkg-deb --info看架构再 file 二进制确认两个信息对齐了才外发。第二个是 Depends。它声明的是运行时依赖。最典型的例子是 libc6。你可以用strings看编译产物实际引用了哪些 GLIBC 符号再反推版本要求而不是随手写一个大版本号。比如strings hello-arm64 | grep GLIBC_输出会显示GLIBC_2.17、GLIBC_2.34这样的符号。如果你编译环境的 glibc 很新产物可能引用到较新的符号那么 Depends 里至少写成libc6 ( 2.34)并且要确认目标板子上的 libc6 版本满足要求。这个细节是很多 deb 包装上去但跑不起来的根源。3.3 维护脚本postinst、prerm、postrm 分别管什么deb 的数据部分只是文件搬运真正让包变得智能的是维护脚本。常用脚本有这几个脚本执行时机常见用途preinst解压数据前停止旧版本的服务、备份配置postinst数据解压完成后创建用户、更新配置、启动或重启服务prerm卸载前停止服务、清理资源postrm卸载后删除配置、清理临时文件这些脚本的本质是 shell 脚本要求第一行是#!/bin/sh并且在 DEBIAN 目录里要有可执行权限。一个典型的 postinst 长这样#!/bin/sh # postinst set -e if command -v systemctl /dev/null 21; then systemctl daemon-reload /dev/null 21 || true systemctl enable my-service /dev/null 21 || true systemctl restart my-service /dev/null 21 || true fi exit 0set -e的意思是任何一条命令返回非零都立刻退出dpkg 会把这个包标记为配置失败。这个特性既可以帮我们尽早发现问题也会带来麻烦我见过很多 postinst 里因为systemctl restart一个不存在的服务导致整个包安装失败的情况。所以写维护脚本有两条经验一是明确哪些命令是必须成功的比如复制关键配置哪些是尽力而为的比如启动一个可能不存在的服务后者建议加|| true。二是脚本要面向精简目标板来写别默认系统里一定有 systemd、一定有某个工具先command -v判断一下再调。4. 手工制作 arm64 deb 包完整流水线实操4.1 先编译一个最小可用的 arm64 程序第 2 部分的 hello.c 已经编译出 hello-arm64 了这里直接用它。为了让流程更贴近实际我建议再验证一次产物aarch64-linux-gnu-gcc -O2 -o hello-arm64 hello.c file hello-arm64确认是 ARM aarch64 ELF 后把它收进包目录。如果你的真实项目是 CMake 工程交叉编译的配置通常是一份 toolchain.cmakeset(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g)然后cmake -DCMAKE_TOOLCHAIN_FILEtoolchain.cmake .. make。这样一套配置就能在 WSL 里持续产出 arm64 二进制后续打包只需要面向这个产物做文章。4.2 搭建包根目录并编写 control 文件现在开始搭包文件树。我们要准备两个部分控制目录 DEBIAN 和安装数据目录。以 hello-arm64 为例结构是hello-arm64-deb/ ├── DEBIAN/ │ ├── control │ └── postinst └── usr/ ├── bin/ │ └── hello-arm64 └── share/ └── doc/ └── hello-arm64/ └── copyright创建目录并拷贝程序mkdir -p hello-arm64-deb/DEBIAN mkdir -p hello-arm64-deb/usr/bin mkdir -p hello-arm64-deb/usr/share/doc/hello-arm64 cp hello-arm64 hello-arm64-deb/usr/bin/然后写 control内容如下Package: hello-arm64 Version: 1.0.0 Architecture: arm64 Maintainer: Your Name youexample.com Depends: libc6 ( 2.31) Section: utils Priority: optional Homepage: https://example.com Description: A tiny arm64 demo package built in WSL This package contains a hello-arm64 executable that demonstrates how to cross-compile and package an arm64 deb from Windows/WSL.这里的路径和字段都有讲究usr/bin/对应目标系统 PATH 里的/usr/bindpkg 安装时会原样解压到根目录所以最终程序会出现在/usr/bin/hello-arm64直接敲命令就能调用。usr/share/doc/hello-arm64/是 Debian 体系惯例的文档目录放 copyright、changelog 等文件不强制但很规范。注意control 示例里的libc6 ( 2.31)只是演示实际版本号要以你strings看到的最低 GLIBC 符号为准我一般会写成编译环境实际引用的最低版本而不是随意挑一个。4.3 用 dpkg-deb --build 打包并自检目录和 control 都就绪后执行打包dpkg-deb --build --root-owner-group hello-arm64-deb hello-arm64_1.0.0_arm64.deb这里要解释一下--root-owner-group的作用如果不加这个选项dpkg-deb 会把你当前用户的 uid/gid 写进包内文件的 owner。在 WSL 里你的用户通常是 1000 之类的普通 uid而目标板安装时这些文件会被解压成同样的 uid导致文件所有者不是预期的 root。这不是致命错误但后面排查权限问题时很容易让人一头雾水。加了这个参数包内文件统一变成 root:root和目标系统常规安装包保持一致。打包完成后立刻自检两件事dpkg-deb --info hello-arm64_1.0.0_arm64.deb dpkg-deb --contents hello-arm64_1.0.0_arm64.deb--info会显示 control 里的全部元数据重点看 Architecture 是不是 arm64--contents会列出数据文件树重点看文件是否都进了正确的路径、owner 是否是 root。我建议这两条命令成为每一次打包后的肌肉记忆五分钟内能避免大部分低级翻车。4.4 如果你要打包的是真实项目而不是 hello worldhello world 只是最小闭环真实项目会多出几个绕不开的问题。第一是动态库依赖。交叉编译完成后用 readelf 看 NEEDED 列表aarch64-linux-gnu-readelf -d hello-arm64 | grep NEEDED输出通常只有libc.so.6和ld-linux-aarch64.so.1说明依赖简单control 里写 libc6 就行。但如果你的程序依赖第三方库比如 libssl、libsqlite3那就有两条路要么在 control 的 Depends 里声明对应的系统包名前提是目标系统仓库里有要么把库一起打包进 deb。第二种情况库文件一般放在/usr/lib/aarch64-linux-gnu/下这是 Debian 体系 multiarch 的标准路径如果你不想污染系统目录也可以放在私有目录比如/usr/lib/my-app/并给二进制设置$ORIGIN相对的 rpath让它在运行时找到自己的库。第二是静态链接的选择。如果目标板环境很精简或者你不想跟 glibc 版本纠缠可以静态链接aarch64-linux-gnu-gcc -static hello.c -o hello-arm64-static静态包的优点是拿来就跑缺点是体积大且某些依赖系统配置的功能比如 DNS 解析行为会和动态方式不同。嵌入式场景里 dropbear 这类工具经常静态编译就是图一个省心。第三是构建系统的收集方式。用 autotools 的项目比如网上很多人交叉编译 dropbear 的做法一般靠make install DESTDIR...把文件收集到一个临时根目录然后再手动整理成 deb 包目录。基本套路是./configure --hostaarch64-linux-gnu --prefix/usr make make install DESTDIR$PWD/pkgroot--host指定程序运行的目标平台是 aarch64configure 的很多检测都会按这个平台来跑DESTDIR则让 install 阶段把文件装到一个独立的模拟根目录里而不是真的装进当前系统。这个临时根目录经过整理后就是 deb 包的数据部分。理解了这个套路再看官方源码包的 debian/ 目录就会觉得那些打包规则不再神秘。5. 在板子上执行 dpkg -i安装背后的执行逻辑与常见报错5.1 把 deb 传到板子的几种方式包打好了接下来是把包送上板子。常见方式看你的网络和设备情况方式命令/操作适用场景scpscp hello-arm64_1.0.0_arm64.deb userboard:/tmp/板子开了 ssh最常见HTTPWSL 里执行python3 -m http.server 8000板子wget http://Windows IP:8000/包名.deb有网络但不想配 sshU盘拷贝到 U 盘挂载到板子后复制完全离线adb pushadb push 包名.deb /data/local/tmp/一些带 adb 的板子我用得最多的是 scp因为板子上通常跑着 dropbear 或者 openssh-server传完直接就能操作。如果只是临时传一个小包python3 -m http.server更轻WSL 和 Windows 共享网络板子只要访问开发机的局域网 IP 就能下载。5.2 dpkg -i 到底在后台做了哪些事在板子上执行sudo dpkg -i hello-arm64_1.0.0_arm64.debdpkg 有一套固定的安装流程先读 control 并检查架构执行 preinst如果有解压数据包到根目录更新 dpkg 数据库最后执行 postinst。任何一个环节失败dpkg 都会给出明确错误码并且把包留在半配置状态方便排查。如果想看得更细可以边安装边看日志tail -f /var/log/dpkg.log如果 postinst 出现奇怪错误最实用的手段是单独执行安装后脚本sudo /var/lib/dpkg/info/hello-arm64.postinst configure这条命令能把某个包的 postinst 再跑一遍过程中任何一种报错都会直接打在终端上比看 dpkg 的抽象提示直观得多。遇到装了但服务没起这类问题我基本都是靠这一招定位到具体命令的。5.3 常见安装失败的三种场景与修复把我在实际安装中遇到最多的失败场景整理一下。场景一架构不匹配dpkg: error processing package hello-arm64 (--install): package architecture (arm64) does not match system (amd64)这个报错多半是把 arm64 的包装到了 x86 系统或者反过来或者 control 里的 Architecture 写错了。修复方法在板子上执行dpkg --print-architecture看真实架构然后回到 WSL 改 control 里的 Architecture 重新打包。场景二依赖缺失或版本不足dpkg: dependency problems prevent configuration of hello-arm64: hello-arm64 depends on libc6 ( 2.34); however: Version of libc6 on system is 2.31.这个报错说明包里的程序在编译时引用了比你目标系统更新的 glibc 符号。板子系统如果联网可以先apt update apt install -f让 apt 尝试补齐依赖如果版本确实不满足就要回到编译侧解决用更老的构建环境、静态链接或者根据strings结果把 Depends 版本往低调到实际所需的最低值。场景三postinst 维护脚本执行失败dpkg: error processing package hello-arm64 (--configure): installed hello-arm64 package post-installation script subprocess returned error exit status 1这个报错基本锁定在维护脚本上。按第 3 节的做法手动执行一次 postinst 脚本看到具体的失败命令再在脚本里做防御性判断或加|| true。修改完重新打包先dpkg -r hello-arm64卸掉旧包再装新包。千万别在没定位到具体命令之前盲目重装那样只会得到同样的报错。5.4 qemu 模拟 vs 实机安装验证维度不要搞混在把包传到板子之前你可能会想先在 WSL 里快速验证一下。做法是安装 qemu-user-staticsudo apt install -y qemu-user-static装好后系统通常会通过 binfmt_misc 注册 aarch64 二进制格式这时候在 x86 的 WSL 里直接跑./hello-arm64会出现正常输出。如果还是Exec format error检查一下 binfmt_misc 是否挂载sudo mount -t binfmt_misc none /proc/sys/fs/binfmt_misc sudo update-binfmts --enable qemu-aarch64但我要强调一个维度问题qemu-user 只能验证这个二进制能在 arm64 系统调用被模拟的环境下运行它验证不了真实板子的内核模块、外设驱动、GPU、网络接口和 systemd 服务依赖。它的价值在于快速排除二进制坏了依赖缺了控制脚本语法错了这一类基础问题而不是替代真机验收。如果你连板子都不在手边又想比较完整地验证 deb 的安装行为可以配合 debootstrap 做一个最小 arm64 rootfs把 qemu-aarch64-static 放进去然后 chroot 进去执行 dpkg -i。这样 dpkg 的架构校验、依赖检查、postinst 都会在模拟的 arm64 系统里真实跑一遍。不过这类测试仍然不等于实机最终验收还是以板子为准。6. 这条链路里我踩过的坑以及现在固定下来的工作习惯6.1 架构字段写错dpkg 直接说 wrong architecture我第一次认真打包时control 里 Architecture 手滑写了 amd64内容却是 arm64 产物。dpkg-deb 完全不会拦你包照样打出来结果板子上一装直接报不匹配。这类错误 build 阶段根本查不出来只能靠自检。所以后来我固定要求自己打包完成后dpkg-deb --info看架构file看二进制两个信息对不上就绝不外发。这已经成了我自动化的第一步。6.2 postinst 没加执行权限导致安装流程一半失败维护脚本的权限问题也是高频坑。DEBIAN/postinst 写好了忘了chmod xdpkg-deb 打包时不会报错但板子上安装时 dpkg 会因为脚本没有执行权限拒绝执行然后整个包处于半安装状态。我现在每次建完 DEBIAN 目录会统一chmod 755 DEBIAN/*相当于一个固定动作。顺便再说一遍脚本第一行必须写#!/bin/sh没有 shebangdpkg 会当成格式错误处理。6.3 打包时把编译缓存和临时文件一并收进包用make install DESTDIR收集安装文件时DESTDIR 里经常混进 build 临时目录、符号链接甚至 .o 文件。这些东西一旦进包装到板子上就是一堆莫名其妙的残留垃圾。我现在会在打包前清理删除 .o、.tmp、.git 目录、编辑器临时文件然后再构建目录树。做得更讲究一点的话还可以用md5sums文件记录所有数据文件的校验和让 dpkg 在安装时校验完整性。命令很简单cd hello-arm64-deb find usr -type f -exec md5sum {} \; DEBIAN/md5sums cd ..6.4 依赖 glibc 版本与板子系统版本不匹配这是编译环境更新、部署环境更老带来的典型问题。新版 Ubuntu 的 gcc 默认链接出来的动态程序可能引用了比较新的 GLIBC 符号放到老系统的板子上一跑就报GLIBC_2.34 not found。问题不在打包而在编译基线和目标基线的错位。我的三个解决思路按优先级排一是尽量用和目标板子同版本或更老的发行版做编译基线从源头减少符号版本差二是特殊场景静态链接三是实在要动态链接就用strings hello-arm64 | grep GLIBC_看清实际引用的最高符号版本把 Depends 写准并在部署说明里写清楚目标系统的 libc6 要求。三者组合下来基本能把这类问题提前拦在打包阶段。6.5 我现在固定使用的自检清单最后分享我每次打包前固定过一遍的检查动作file 确认交叉编译产物是 ARM aarch64 ELF且是预期的链接方式动态或静态。readelf 查看 NEEDED把运行时依赖控制在视野内。control 里的 Architecture、Package、Version、Depends 与产物实际一致。维护脚本都有执行权限shebang 正确。打包目标目录干净没有混入编译缓存和临时文件。dpkg-deb --info 与 dpkg-deb --contents 检查包外壳。在板子上先执行 dpkg --print-architecture确认目标系统架构。安装后运行一次主程序验证不是装上了但跑不起来。这套清单不一定适合所有人但对我来说它确实把交叉编译加 deb 打包这条链路的翻车率压到了很低的水平。每个项目可以按自己的痛点增删关键是让打包前自查变成习惯而不是等到板子上报错再回头拆包。这串流程从最初的两小时折腾到现在稳定成流水线靠的就是把这些坑一个个记下来变成固定动作。希望这份记录能帮你少走同样的弯路。
企业数字化 ERP 产品动态
相关推荐
自动驾驶安全架构实战:威胁建模、纵深防御与传感器欺骗防护 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 1:05:44
定制化磁吸充电接口:重构电力连接的工程实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 1:04:44
ESP32+HX711智能包裹称重系统:从硬件到Android App全栈实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 1:04:44
没 iPhone 也能玩:DiPlay 热点模式白嫖 CarPlay 没 iPhone 也能玩:DiPlay 热点模式白嫖 CarPlay 【免费下载链接】DiPlay Independent CarPlay receiver for compatible Android head units. Wired and wireless public preview. 项目地址: https://gitcode.com/gh_mirrors/di/DiPlay
先说个扎心的帖子
车… · 2026/11/4 1:47:00
如何用Hermes Agent打造你的智能投资助手:从零到专业分析的完整指南 如何用Hermes Agent打造你的智能投资助手:从零到专业分析的完整指南
在AI技术快速发展的今天,拥有一个能理解市场动态、提供专业投资建议的智能助手已经成为现实。Hermes Agent作为一款自学习AI代理框架,为你提供了构建个性化金融分析系统的… · 2026/11/4 1:47:00
沁恒 RISC-V 蓝牙应用中常用蓝牙参数的设定和修改 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 1:47:00
KoboldCpp v1.98 使用指南:一个文件跑起本地 AI 模型,5 分钟见到第一条回复 KoboldCpp v1.98 使用指南:一个文件跑起本地 AI 模型,5 分钟见到第一条回复 【免费下载链接】koboldcpp KoboldCpp - Run GGUF AI models locally with a KoboldAI UI. One File. Zero Install. 项目地址: https://gitcode.com/gh_mirrors/ko/koboldcp… · 2026/11/4 1:47:00
用一局太空侵略者看懂 SQLAlchemy ORM:多态继承与 joinedload 预加载实战 用一局太空侵略者看懂 SQLAlchemy ORM:多态继承与 joinedload 预加载实战 【免费下载链接】sqlalchemy The Database Toolkit for Python 项目地址: https://gitcode.com/gh_mirrors/sq/sqlalchemy
SQLAlchemy ORM 常被当成 CRUD 脚手架,但仓库里… · 2026/11/4 1:47:00
深度揭秘:Hermes Agent如何构建企业级多智能体通信架构 深度揭秘:Hermes Agent如何构建企业级多智能体通信架构
在当今分布式AI系统日益复杂的背景下,多智能体协作的效率直接决定了系统的整体性能。Hermes Agent作为一款面向企业级应用的开源多智能体框架,通过创新的消息传递机制和智能协调协议&a… · 2026/11/4 1:46:00
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46