恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Windows 上使用 MSYS2 交叉编译 XLSXIO 到 Linux 实战指南
首页
资讯中心
/
Windows 上使用 MSYS2 交叉编译 XLSXIO 到 Linux 实战指南
Windows 上使用 MSYS2 交叉编译 XLSXIO 到 Linux 实战指南
发布时间:2026/10/12 11:54:34
1. 为什么要在 Windows 上折腾交叉编译环境很多做 C/C 开发的朋友日常主力机是 Windows但项目最终要跑在 Linux 服务器或者嵌入式设备上。这时候就面临一个很现实的问题代码在 Windows 上写编译却得在 Linux 环境下完成。传统做法是开虚拟机、装双系统或者干脆远程连一台 Linux 机器。这些方案不是不行但都有各自的麻烦——虚拟机吃资源、双系统切换烦、远程机器依赖网络。交叉编译环境就是来解决这个痛点的。它的核心思路是在 Windows 上搭建一套能够生成 Linux 可执行文件的工具链让编译这件事直接在本地完成。MSYS2 是目前 Windows 平台上做这件事最成熟的方案之一它提供了一个类 Unix 的 shell 环境和包管理器可以安装 MinGW-w64 工具链也可以安装针对 Linux 目标的交叉编译器。这次要编译的目标是 XLSXIO。这是一个用于读写 Excel 文件.xlsx 格式的 C 语言库底层依赖 zlib、minizip 等库来处理 ZIP 压缩和 XML 解析。它的特点是轻量、无外部运行时依赖编译出来就是一个静态库或者动态库可以直接嵌入到自己的项目里用。对于需要在服务端批量处理 Excel 文件的场景比如数据导出、报表生成、批量导入XLSXIO 是一个很务实的选择。这篇文章适合谁看如果你是在 Windows 上做开发需要把 C 代码编译成 Linux 可执行文件或者库同时对 MSYS2 有一定了解但还没完整跑通过交叉编译流程那这篇内容就是写给你的。我会从环境搭建开始一步步走到 XLSXIO 编译成功把中间踩过的坑和关键参数都讲清楚。2. MSYS2 环境搭建与工具链选型2.1 MSYS2 的安装与基础配置MSYS2 的安装本身不复杂去官网下载安装包一路下一步就行。但有几个细节需要注意。安装路径不要有空格和中文这是老生常谈但每次都有人踩。我一般直接装在C:\msys64省事。安装完成后你会看到几个不同的启动快捷方式MSYS2 MSYS、MSYS2 MINGW64、MSYS2 MINGW32、MSYS2 UCRT64 等。这些的区别在于环境变量和默认工具链不同。MSYS 环境是模拟 Unix 的用的工具链是 MSYS 自己的MINGW64 环境是 64 位 Windows 原生工具链UCRT64 用的是 Universal C Runtime更新一些。对于交叉编译来说我们主要用 MSYS 环境来安装和管理交叉编译器因为交叉编译器本身是跑在 MSYS 环境下的。但如果你同时也要编译 Windows 原生的程序那 MINGW64 环境也要熟悉。第一次打开 MSYS2 MSYS 终端后先更新包数据库和基础包pacman -Syu这个命令会更新所有已安装的包。注意更新过程中可能会提示你关闭终端重新打开这是正常的因为 pacman 自身可能被更新了。重新打开后再执行一次pacman -Su确保所有包都更新到最新。这一步很重要因为旧的包数据库可能导致后续安装交叉编译器时找不到对应的包或者版本冲突。2.2 交叉编译工具链的选择与安装MSYS2 的包仓库里提供了多种交叉编译工具链常见的有工具链包名目标平台说明mingw-w64-x86_64-gccWindows x86_64原生 Windows 编译mingw-w64-x86_64-cross-gccLinux x86_64交叉编译到 Linuxmingw-w64-i686-gccWindows x8632 位 Windows 编译我们需要的交叉编译工具链是mingw-w64-x86_64-cross-gcc这一系。但注意这个包本身可能依赖一些其他的库和工具。安装命令pacman -S mingw-w64-x86_64-cross-gcc安装完成后你会得到x86_64-pc-linux-gnu-gcc这个编译器。可以用which命令确认一下which x86_64-pc-linux-gnu-gcc如果输出路径类似/mingw64/bin/x86_64-pc-linux-gnu-gcc说明安装成功。但光有编译器还不够。交叉编译 XLSXIO 还需要一些依赖库的 Linux 版本比如 zlib。MSYS2 仓库里也有对应的交叉编译版本pacman -S mingw-w64-x86_64-cross-zlib这个包会安装 Linux 版本的 zlib 头文件和库文件路径通常在/mingw64/x86_64-pc-linux-gnu/下面。注意交叉编译工具链的包名和原生工具链的包名容易混淆。mingw-w64-x86_64-gcc是编译 Windows 程序的mingw-w64-x86_64-cross-gcc才是编译 Linux 程序的。装错了就白忙活。2.3 环境变量与路径配置安装完工具链后需要确保 MSYS2 的 shell 能找到这些工具。通常情况下/mingw64/bin已经在 PATH 里了但交叉编译器的前缀路径可能需要手动确认。我习惯在~/.bashrc里加一行把交叉编译工具的路径显式加进去export PATH/mingw64/bin:$PATH然后source ~/.bashrc生效。这样做的目的是确保x86_64-pc-linux-gnu-gcc和相关的工具如x86_64-pc-linux-gnu-ld、x86_64-pc-linux-gnu-ar都能被找到。另外交叉编译时经常需要指定--host参数这个参数的值就是x86_64-pc-linux-gnu。这个三元组架构-厂商-系统是交叉编译的约定告诉构建系统目标平台是什么。3. XLSXIO 源码获取与依赖分析3.1 源码下载与目录结构XLSXIO 的源码可以从它的发布页面获取。下载下来是一个压缩包解压后目录结构大致如下xlsxio/ ├── include/ │ ├── xlsxio_read.h │ └── xlsxio_write.h ├── lib/ │ ├── xlsxio_read.c │ └── xlsxio_write.c ├── CMakeLists.txt └── README.md核心文件就两个xlsxio_read.c和xlsxio_write.c分别负责读和写。头文件在include目录下。构建系统用的是 CMake这也是目前 C/C 项目最主流的构建方式。XLSXIO 的依赖主要有两个zlib 和 minizip。zlib 负责 DEFLATE 压缩解压minizip 负责 ZIP 容器的读写。在 Linux 上这两个库通常都是现成的交叉编译工具链里也带了对应的版本。3.2 依赖库的交叉编译版本确认在 MSYS2 里交叉编译版本的 zlib 已经通过mingw-w64-x86_64-cross-zlib安装好了。但 minizip 可能没有单独的交叉编译包需要确认一下。可以用pacman -Ss搜索pacman -Ss minizip如果找到mingw-w64-x86_64-cross-minizip就装如果没有那就需要手动编译 minizip 的源码或者看看 XLSXIO 是否自带了 minizip 的源码。实际上XLSXIO 的源码包里通常包含了一个minizip子目录里面是 minizip 的源码。这样做的好处是减少外部依赖编译时直接把 minizip 的源码一起编进去。如果是这种情况那就不需要单独安装 minizip 的交叉编译版本了。提示在开始编译之前先看一眼 CMakeLists.txt 里是怎么处理依赖的。如果它用了find_package(ZLIB REQUIRED)那就需要确保交叉编译版本的 zlib 能被找到。如果它直接 include 了 minizip 的源码那就省事很多。3.3 CMake 交叉编译工具链文件的编写CMake 交叉编译的关键在于一个工具链文件toolchain file。这个文件告诉 CMake 用哪个编译器、目标系统是什么、库和头文件去哪里找。在项目根目录下新建一个文件比如叫linux-toolchain.cmake内容如下set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR x86_64) set(CMAKE_C_COMPILER x86_64-pc-linux-gnu-gcc) set(CMAKE_CXX_COMPILER x86_64-pc-linux-gnu-g) set(CMAKE_FIND_ROOT_PATH /mingw64/x86_64-pc-linux-gnu) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)逐行解释一下CMAKE_SYSTEM_NAME设为 Linux告诉 CMake 目标系统是 Linux。CMAKE_SYSTEM_PROCESSOR设为 x86_64目标架构是 64 位。CMAKE_C_COMPILER和CMAKE_CXX_COMPILER指定交叉编译器。CMAKE_FIND_ROOT_PATH是交叉编译工具链的根路径CMake 会在这个路径下找库和头文件。CMAKE_FIND_ROOT_PATH_MODE_*这几个变量控制查找行为。PROGRAM设为 NEVER 表示不在目标路径下找可执行程序因为交叉编译的工具是跑在宿主机的LIBRARY、INCLUDE、PACKAGE设为 ONLY 表示只在目标路径下找库、头文件和包配置。这个文件是交叉编译的核心配置写对了后面就顺了。4. 编译过程实操与参数详解4.1 创建构建目录与 CMake 配置交叉编译建议在单独的构建目录里进行不要污染源码目录。在 XLSXIO 源码根目录下执行mkdir build-linux cd build-linux然后运行 CMake 配置命令cmake .. \ -DCMAKE_TOOLCHAIN_FILE../linux-toolchain.cmake \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX../install-linux参数说明-DCMAKE_TOOLCHAIN_FILE指定刚才写的工具链文件。-DCMAKE_BUILD_TYPERelease表示编译优化版本去掉调试符号适合生产环境。-DCMAKE_INSTALL_PREFIX指定安装路径编译完成后make install会把库和头文件复制到这个目录。如果配置成功你会看到 CMake 输出一系列检查信息最后显示 Configuring done 和 Generating done。如果报错通常是找不到 zlib 或者编译器路径不对。4.2 常见配置错误与排查配置阶段最常见的错误是找不到 zlib。错误信息类似Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)这说明 CMake 没有在交叉编译工具链的路径下找到 zlib。排查步骤确认mingw-w64-x86_64-cross-zlib已经安装。用pacman -Q mingw-w64-x86_64-cross-zlib检查。确认 zlib 的头文件和库文件在/mingw64/x86_64-pc-linux-gnu/下面。用ls看一下ls /mingw64/x86_64-pc-linux-gnu/include/zlib.h ls /mingw64/x86_64-pc-linux-gnu/lib/libz.so如果文件存在但 CMake 还是找不到可能是CMAKE_FIND_ROOT_PATH设置不对。检查工具链文件里的路径是否和实际安装路径一致。另一个常见问题是编译器找不到。错误信息类似The C compiler identification is unknown这通常是因为x86_64-pc-linux-gnu-gcc不在 PATH 里或者工具链文件里的编译器名称写错了。用which x86_64-pc-linux-gnu-gcc确认一下。4.3 编译与安装配置成功后执行编译make -j$(nproc)-j$(nproc)表示用所有可用的 CPU 核心并行编译加快速度。MSYS2 环境下nproc命令是可用的会返回核心数。编译过程中如果报错通常是源码层面的问题比如某个头文件找不到、某个函数签名不匹配。XLSXIO 的代码比较干净交叉编译时一般不会出大问题。如果报错仔细看错误信息定位到具体的文件和行号。编译完成后执行安装make install这会把编译好的库文件和头文件复制到../install-linux目录下。目录结构大致是install-linux/ ├── include/ │ ├── xlsxio_read.h │ └── xlsxio_write.h └── lib/ ├── libxlsxio_read.a ├── libxlsxio_read.so ├── libxlsxio_write.a └── libxlsxio_write.so静态库.a和动态库.so都会生成。静态库适合嵌入到其他项目里动态库适合独立部署。4.4 验证编译结果编译出来的库是 Linux 格式的不能在 Windows 上直接运行。验证的方法有几种第一种用file命令查看文件类型file install-linux/lib/libxlsxio_read.so输出应该是类似ELF 64-bit LSB shared object, x86-64的信息。如果是PE32那就是 Windows 格式说明交叉编译没成功。第二种用x86_64-pc-linux-gnu-objdump查看符号表x86_64-pc-linux-gnu-objdump -T install-linux/lib/libxlsxio_read.so | head -20能看到导出的函数符号说明库文件是完整的。第三种把库文件复制到一台 Linux 机器上写一个简单的测试程序链接一下确认能正常调用。这是最彻底的验证方式。5. 实操心得与避坑指南5.1 路径与权限的坑MSYS2 的路径映射有时候会让人迷惑。/mingw64在 Windows 上实际对应的是C:\msys64\mingw64但在 MSYS2 shell 里你只能用 Unix 风格的路径。CMake 工具链文件里写的路径必须是 MSYS2 shell 能识别的路径不能写 Windows 路径。另外MSYS2 默认的 umask 可能导致生成的文件权限不对。如果编译出来的库文件在 Linux 上没法用检查一下文件权限chmod 755 install-linux/lib/*.so chmod 644 install-linux/lib/*.a5.2 静态库与动态库的选择XLSXIO 默认会同时生成静态库和动态库。如果你的目标环境是嵌入式 Linux可能只需要静态库这样可以减少部署时的依赖。可以在 CMake 配置时加参数控制cmake .. \ -DCMAKE_TOOLCHAIN_FILE../linux-toolchain.cmake \ -DBUILD_SHARED_LIBSOFFBUILD_SHARED_LIBSOFF表示只生成静态库。反过来设为 ON 就是只生成动态库。不设的话就看 CMakeLists.txt 里的默认值。经验静态库链接时需要注意依赖顺序。XLSXIO 依赖 zlib链接时要写成-lxlsxio_read -lzzlib 放在后面。如果顺序反了链接器会报未定义符号。5.3 交叉编译的调试技巧交叉编译最头疼的是出了问题不好调试。我的经验是第一先用一个最简单的 hello world 程序测试工具链是否正常工作。写一个test.c内容就是打印一行字然后用交叉编译器编译x86_64-pc-linux-gnu-gcc test.c -o test file test如果输出是 ELF 格式说明工具链没问题。如果这一步就失败了那后面的都不用试了先解决工具链的问题。第二CMake 配置时加-DCMAKE_VERBOSE_MAKEFILEON这样编译时会输出完整的编译命令方便定位问题。能看到实际用的编译器、头文件搜索路径、库搜索路径一目了然。第三如果链接时报未定义符号用nm命令查看库文件的符号表x86_64-pc-linux-gnu-nm -D install-linux/lib/libxlsxio_read.so | grep 函数名确认符号是否真的在库里。有时候是库没编进去有时候是符号被隐藏了。5.4 版本兼容性注意事项MSYS2 的包更新比较频繁交叉编译工具链的版本也会跟着更新。如果之前编译成功过段时间再编译却失败了很可能是工具链版本变了。这时候可以用pacman -Q查看当前安装的版本。如果新版本有问题可以回退到旧版本pacman -U /var/cache/pacman/pkg/包名-旧版本.pkg.tar.zst。或者干脆锁定版本在/etc/pacman.conf里加IgnorePkg配置。XLSXIO 本身对编译器版本要求不高GCC 7 以上应该都能编。但如果遇到奇怪的编译错误先检查工具链版本再检查源码版本最后检查依赖库版本。6. 常见问题速查与解决方案6.1 编译阶段问题排查表问题现象可能原因解决方案找不到 x86_64-pc-linux-gnu-gcc工具链未安装或 PATH 不对安装 mingw-w64-x86_64-cross-gcc检查 PATH找不到 zlib.h交叉编译版 zlib 未安装安装 mingw-w64-x86_64-cross-zlibCMake 报找不到 ZLIB工具链文件路径配置错误检查 CMAKE_FIND_ROOT_PATH 是否指向正确路径链接时报未定义符号库链接顺序不对调整链接顺序依赖库放在后面生成的库是 PE 格式用了原生编译器而非交叉编译器检查 CMAKE_C_COMPILER 是否指向交叉编译器make 报权限错误MSYS2 文件权限问题用 chmod 调整权限或以管理员身份运行6.2 链接时的符号冲突处理XLSXIO 内部使用了 minizip而你的项目可能也依赖 minizip。如果两边都链接了 minizip可能会出现符号冲突。解决方法是如果 XLSXIO 已经把 minizip 的符号隐藏了编译时加了-fvisibilityhidden那就没问题。如果没有隐藏可以在链接时用--allow-multiple-definition参数让链接器忽略重复定义。更好的做法是让 XLSXIO 使用外部的 minizip而不是内置的。这需要在 CMake 配置时指定-DUSE_SYSTEM_MINIZIPON如果 CMakeLists.txt 支持这个选项。6.3 运行时依赖检查编译出来的动态库在 Linux 上运行时需要确保依赖的库都能找到。用ldd命令检查x86_64-pc-linux-gnu-ldd install-linux/lib/libxlsxio_read.so如果显示libz.so.1 not found说明目标机器上没有 zlib或者 zlib 的路径不在默认搜索路径里。解决方法是在目标机器上安装 zlib或者把 zlib 一起打包部署运行时用LD_LIBRARY_PATH指定路径。提示如果不想处理动态库依赖问题直接用静态库。静态库把所有依赖都编进去了部署时只需要一个可执行文件省心很多。6.4 性能优化建议交叉编译出来的库性能主要取决于编译优化选项。默认的 Release 模式已经开了-O2如果追求极致性能可以改成-O3cmake .. \ -DCMAKE_TOOLCHAIN_FILE../linux-toolchain.cmake \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_C_FLAGS-O3 -marchx86-64-v2-marchx86-64-v2表示针对 x86-64-v2 指令集优化支持 SSE4.2、POPCNT 等指令。但要注意目标机器的 CPU 是否支持这些指令集否则会非法指令崩溃。保守一点就用默认的-marchx86-64。另外如果目标环境是多核 CPU可以在编译时加-fopenmp开启 OpenMP 支持XLSXIO 内部如果有并行处理的部分会自动利用多核。不过 XLSXIO 本身是单线程的这个优化对它的效果有限。7. 从编译到集成的完整链路7.1 在自己的项目中链接 XLSXIO编译好的库和头文件可以直接复制到你的项目里用。假设你的项目结构是myproject/ ├── src/ │ └── main.c ├── lib/ │ ├── include/ │ │ ├── xlsxio_read.h │ │ └── xlsxio_write.h │ └── lib/ │ ├── libxlsxio_read.a │ └── libxlsxio_write.a └── MakefileMakefile 里这样写CC x86_64-pc-linux-gnu-gcc CFLAGS -Ilib/include -O2 LDFLAGS -Llib/lib -lxlsxio_read -lxlsxio_write -lz -lpthread main: src/main.c $(CC) $(CFLAGS) -o main src/main.c $(LDFLAGS)注意链接顺序先链接 XLSXIO 的库再链接 zlib最后链接 pthread。顺序不对会报未定义符号。7.2 编写测试程序验证功能写一个简单的测试程序创建一个 Excel 文件并写入数据#include xlsxio_write.h #include stdio.h int main() { xlsxiowriter writer xlsxiowrite_open(test.xlsx, Sheet1); if (writer NULL) { printf(Failed to create xlsx file\n); return 1; } xlsxiowrite_add_column(writer, Name, 20); xlsxiowrite_add_column(writer, Age, 10); xlsxiowrite_add_row(writer); xlsxiowrite_add_cell_string(writer, Alice); xlsxiowrite_add_cell_int(writer, 30); xlsxiowrite_add_row(writer); xlsxiowrite_add_cell_string(writer, Bob); xlsxiowrite_add_cell_int(writer, 25); xlsxiowrite_close(writer); printf(Done\n); return 0; }用交叉编译器编译x86_64-pc-linux-gnu-gcc -Ilib/include -o test_xlsx test_xlsx.c -Llib/lib -lxlsxio_write -lz编译成功后把test_xlsx复制到 Linux 机器上运行看看能不能生成test.xlsx文件。如果能生成用 Excel 或者 LibreOffice 打开确认内容正确那就说明整个链路都通了。7.3 部署时的注意事项部署到 Linux 时如果用的是动态库需要把.so文件一起复制过去并且确保目标机器上有 zlib。如果用的是静态库只需要复制可执行文件。另外注意目标机器的 glibc 版本。交叉编译工具链链接的 glibc 版本可能比目标机器的新导致运行时找不到符号。用objdump -T查看可执行文件依赖的 glibc 版本x86_64-pc-linux-gnu-objdump -T test_xlsx | grep GLIBC如果显示的版本高于目标机器的 glibc 版本就需要用更旧的工具链重新编译或者在目标机器上升级 glibc。后者风险较大不建议在生产环境做。经验如果目标环境是 CentOS 7 这类老系统glibc 版本比较旧建议用对应版本的交叉编译工具链。MSYS2 仓库里可能没有这么旧的版本那就需要考虑用 Docker 容器来做编译环境或者手动编译一套工具链。这是另一个话题了这里不展开。8. 交叉编译环境的日常维护8.1 包管理与版本锁定MSYS2 的 pacman 用起来和 Arch Linux 的 pacman 一样。日常维护主要是定期更新pacman -Syu但交叉编译工具链不建议频繁更新因为新版本可能引入不兼容的变更。我的做法是在项目开发阶段锁定工具链版本等项目稳定了再考虑升级。锁定版本的方法是在/etc/pacman.conf里加IgnorePkg mingw-w64-x86_64-cross-gcc mingw-w64-x86_64-cross-zlib这样pacman -Syu就不会更新这两个包了。需要更新时手动指定pacman -S mingw-w64-x86_64-cross-gcc8.2 多项目环境隔离如果你同时维护多个项目每个项目依赖的库版本可能不同。这时候可以考虑用 MSYS2 的多个环境来隔离。MSYS2 支持安装多个独立的子系统比如C:\msys64是一个环境C:\msys64-dev是另一个环境。每个环境有独立的包数据库和安装路径互不干扰。创建新环境的方法很简单把C:\msys64整个复制一份改个名字然后修改etc\pacman.d\mirrorlist.mingw64里的路径配置。这样两个环境就独立了可以装不同版本的交叉编译工具链。8.3 备份与迁移交叉编译环境配置好之后建议做个备份。最简单的方法是打包整个 MSYS2 目录tar -czf msys64-backup.tar.gz /c/msys64恢复的时候解压到相同路径就行。注意备份前先关闭所有 MSYS2 终端避免文件被占用。如果要在另一台机器上复现同样的环境可以把备份复制过去然后修改etc\pacman.d\mirrorlist.*里的镜像地址如果网络环境不同的话。这样比从头安装配置快得多。8.4 持续集成中的交叉编译如果项目用 CI/CD 流水线可以把交叉编译环境容器化。虽然 MSYS2 本身是 Windows 程序但可以在 Windows 容器里跑。或者更常见的做法是在 Linux 容器里安装 MinGW-w64 交叉编译工具链直接编译 Windows 程序。反过来在 Windows 上编译 Linux 程序的需求相对少一些但如果确实需要MSYS2 是目前最顺手的方案。在 CI 里用 MSYS2 的话可以用 GitHub Actions 的msys2/setup-msys2action它会自动安装 MSYS2 并配置好环境。然后在里面执行 pacman 安装交叉编译工具链再跑编译脚本。整个流程可以完全自动化。9. 一些容易被忽略的细节9.1 换行符与文件编码Windows 和 Linux 的换行符不同Windows 是\r\nLinux 是\n。交叉编译时如果源码文件是在 Windows 上编辑的可能带有\r。GCC 通常能处理但某些情况下会导致奇怪的编译错误。可以用dos2unix命令转换dos2unix src/*.c include/*.hMSYS2 里默认没有dos2unix需要安装pacman -S dos2unix文件编码方面建议统一用 UTF-8 无 BOM。Windows 上的一些编辑器默认用 GBK 或者带 BOM 的 UTF-8交叉编译时可能报错。用 VS Code 的话右下角可以切换编码选 UTF-8 就行。9.2 时间戳与可重现构建交叉编译时生成的文件时间戳可能会影响构建的可重现性。如果做持续集成建议在编译时加-ffile-prefix-map参数把源码路径映射成固定值避免路径信息泄露到二进制里-DCMAKE_C_FLAGS-ffile-prefix-map$(pwd)/build这样编译出来的二进制文件里不会包含你本地的路径信息既安全又可重现。9.3 调试符号的处理Release 版本默认会去掉调试符号但如果需要调试可以保留一份带符号的版本cmake .. \ -DCMAKE_TOOLCHAIN_FILE../linux-toolchain.cmake \ -DCMAKE_BUILD_TYPERelWithDebInfoRelWithDebInfo会开优化但保留调试符号。生成的库文件会大一些但用 gdb 调试时能看到源码行号。发布时再用strip命令去掉符号x86_64-pc-linux-gnu-strip install-linux/lib/libxlsxio_read.so9.4 交叉编译的替代方案MSYS2 不是唯一的选择。如果只是偶尔编译一下 Linux 程序用 WSL 可能更方便。WSL 里直接就是 Linux 环境装个 gcc 就能编译不需要交叉编译。但 WSL 的缺点是文件系统性能和 Windows 有差异而且需要开启 Windows 的虚拟化功能。另一个方案是用 Docker Desktop在容器里编译。这样环境完全隔离可重现性最好。但 Docker 的资源占用比 MSYS2 大启动也慢一些。选择哪个方案取决于你的具体需求。如果只是编译 XLSXIO 这种小库MSYS2 足够用了。如果是大型项目需要频繁编译和调试WSL 或者 Docker 可能更合适。10. 最后分享几个实用技巧第一个技巧在 MSYS2 里用ccache加速重复编译。安装pacman -S ccache然后在 CMake 配置时加-DCMAKE_C_COMPILER_LAUNCHERccache。这样第二次编译同样的代码时ccache 会直接返回缓存结果速度飞快。对于反复调试的场景能省不少时间。第二个技巧用pkg-config管理交叉编译的库依赖。如果库提供了.pc文件可以用pkg-config --cflags --libs获取编译和链接参数。MSYS2 的交叉编译库通常会在/mingw64/x86_64-pc-linux-gnu/lib/pkgconfig/下放.pc文件。设置PKG_CONFIG_PATH指向这个目录就能用pkg-config了。第三个技巧如果编译时报错说某个函数找不到但头文件里明明有声明那可能是链接时没找到对应的库。用x86_64-pc-linux-gnu-nm查看库文件的符号表确认函数是否真的在库里。有时候库编译时用了-fvisibilityhidden符号被隐藏了需要加__attribute__((visibility(default)))才能导出。第四个技巧交叉编译时如果遇到undefined reference to __stack_chk_fail这类错误通常是链接时缺少了-fstack-protector相关的库。加-lssp或者-fno-stack-protector可以解决。但后者会降低安全性生产环境不建议用。这些技巧都是我在实际项目中踩过坑之后总结出来的希望能帮你少走弯路。交叉编译这件事第一次配置确实麻烦但配好之后就是一劳永逸的事。后面再编译其他库照着同样的流程走就行无非是换个源码包和依赖库。