Article
Windows下编译VLC完整指南:MinGW/MSYS2交叉编译与踩坑记录
mhpn.cn 原创整理 · 三门峡/驻马店本地视角 · 阅读约 3 分钟 · 看完可电话咨询
TEMPLATE PREVIEW · 文章页模板示意 · 正文由后台文章数据自动填充 · 配图自动生成

简介这是VLC 2.0.4在Windows平台下的编译操作手册专为需要从源码自行构建VLC播放器/流媒体服务器的开发者、运维人员及开源软件研究爱好者编写。手册按步骤梳理了完整编译环境搭建包括MSYS、MSYS-DTK、MinGW等基础工具链安装AutoTools、Glib、pkg-config等依赖组件的更新配置以及lua库编译、VLC源码修改、contrib初始化等关键环节并对Windows 7权限设置、安装目录一致性等易错点给出明确提示。资源包为单个doc文档大小267KB结构紧凑步骤带有下载地址便于边读边操作。已有322人学习/下载对于初涉Windows下开源项目编译的读者来说是一份兼具操作性与排错参考价值的实用笔记。1. 为什么在 Windows 上自己编译 VLC官方二进制装不下的三个需求官方 Windows 版 vlc.exe 用久了总会冒出几个坐不住的理由想在播放器里嵌进自研的 RTSP 认证逻辑想裁掉一堆用不上的协议模块让安装包小一半或者要给视频渲染管线加一个私有滤镜。按官方安装包这些需求完全无从下手因为你拿到的是编译好的二进制黑匣子。这时候就需要在 Windows 上自己编译 VLC。常见做法是以 mingw-w64 工具链为主线拉源码、编 contrib 第三方依赖、跑 configure、make最后用打包目标得到一套自包含的 vlc.exe 与插件目录。这条路径适合定制播放器功能、维护私有分支或者被官方包版本卡住需要锁定某个 commit 的开发者。只是换个皮肤、换个默认设置不建议受这个罪官方二进制足够用。2. 编译前必读三条路线、依赖清单与工具链选型2.1 三条路线MinGW 交叉编译、MSYS2 原生编译与 MSVC 的差距Windows 上编 VLC主流工具链是 MinGW-w64也就是 GCC 移植到 Windows 的那套编译器加运行时。围绕它有两种落地方案一是在 Windows 里装 MSYS2 原生编译二是在 Linux 机器上交叉编译出 Windows 可执行文件。前者适合需要边编边在 Windows 环境调试模块行为的场景后者胜在环境干净、依赖可控、路径问题少。官方 CI 的 Windows 产物基本走交叉编译这也是我个人的默认选择。一年里我大概有 80% 的 VLC 构建是在 Ubuntu 上完成的只有排查 Windows 特有 bug 时才回 MSYS2 重编。至于 MSVC也就是 Visual Studio 那条路建议直接绕开。VLC 的构建体系整个建立在 autotools 上contrib 里有几百个 C 库的 Makefile 是为 unix 风格 shell 和 GCC 标志写的。网上偶尔有人晒出用 MSVC 编 ffmpeg 的教程那只是单个库级别的工程和 VLC 这种全链集成不是一个量级。更深一层的问题是线程模型VLC 核心代码大量使用 pthread 语义MinGW 用 winpthreads 提供兼容层MSVC 只有 Windows API 线程移植等于重写核心。所以碰到类似用 msvc 编译 ffmpeg libx265的心得看看就好别冲动搬到 VLC 上。2.2 Ubuntu 与 MSYS2 的依赖清单装一次就够的命令在 Debian 系 Linux 上交叉编译我一般先把这些工具一次装齐# 安装在 Ubuntu / Debian 上交叉编译 VLC for Windows 的工具链 sudo apt-get update sudo apt-get install -y build-essential git autoconf automake libtool \ gettext autopoint pkg-config yasm flex bison gperf lua5.3 python3 \ gcc-mingw-w64-x86-64 g-mingw-w64-x86-64 \ pkg-config-mingw-w64-x86-64autoconf、automake、libtool 负责从 configure.ac 生成 configure 和 Makefile.inVLC 的 bootstrap 脚本会直接调用它们缺一个就报 missing。gettext 和 autopoint 管多语言翻译宏少了会在 autoreconf 阶段报错。flex 和 bison 是词法语法解析器VLC 的 demux 模块有部分语法分析逻辑依赖它们。gperf 用来生成完美哈希模块查找表靠它。yasm 提供 x86 汇编器编 dav1d、x265 时要用。带 x86_64-w64-mingw32 前缀的 gcc 才是真正产出 Windows exe 的编译器。最后的 pkg-config-mingw-w64-x86-64 很关键它提供交叉版 pkg-config避免 configure 拿宿主机的 pkg-config 去查 Linux 库路径。如果非要在 Windows 本机做MSYS2 的 MSYS shell 里对应安装# MSYS2 下安装原生编译 VLC 的工具 pacman -S base-devel git autoconf automake libtool \ gettext-devel pkg-config yasm flex bison gperf lua python \ mingw-w64-x86_64-toolchainMSYS2 分 MSYS 和 MinGW-x64 两种 shell别混。上面这条在 MSYS shell 里执行装完的 mingw 工具落在 /mingw64/bin跑 configure 前要把这个目录加进 PATH。装完后先验证编译器是否可见x86_64-w64-mingw32-gcc --version。看不到就说明 PATH 有问题后面所有步骤都会白忙。2.3 host 字符串、PATH 与 pkg-config环境变量错位是第一个坑configure 脚本里 --host 参数决定产物的运行平台。mingw-w64 工具链中x86_64-w64-mingw32 对应 64 位 Windowsi686-w64-mingw32 对应 32 位 Windows。--build 通常省略configure 会自己探测当前机器。需要注意不要在 configure 前手动 export CC 或 CXX除非明确知道在干什么。VLC 的 configure 会从 --host 自动推导编译器前缀但如果你在 Ubuntu 上先 export CCgcc宿主机 GCC 可能被混进交叉编译链编出来的 exe 在 Windows 上要么启动即崩要么缺一堆运行时 DLL。这个坑我早期翻车过一次configure 一路绿灯最后产出的文件行为完全不对查了半小时才意识到是环境变量污染。pkg-config 同样要小心。宿主机上的 pkg-config 查的是 /usr/lib/pkgconfig而交叉编译需要查 /usr/x86_64-w64-mingw32/lib/pkgconfig。configure 会优先找带 host 前缀的 x86_64-w64-mingw32-pkg-config前提是你装了对应该包。configure 阶段大量 checking for Qt... no 和 checking for freetype... no 其实不是真没有而是 pkg-config 找错了目录。在 Windows 原生编译时开工前还要先开 git 的 longpathsgit config --system core.longpaths true否则后面拉源码或 checkout 时会栽在路径长度上原因后面细说。3. 拉源码到 configurecontrib 依赖系统与最小验证3.1 拉取 VLC 源码与目录结构先跑 bootstrap源码从 VideoLAN 的 Git 仓库拉稳定分支比 master 适合入门git clone https://code.videolan.org/videolan/vlc.git cd vlc git checkout 3.0.xclone 完成后先认清目录src 是 libvlc 核心modules 是几百个功能插件的源码contrib 放第三方依赖的下载与编译逻辑po 目录是翻译文件。真正编译时 contrib 会在自己的 win64 子目录里产出 include 和 lib供 configure 检测依赖是否齐备。接下来跑 bootstrap./bootstrapbootstrap 会调用 autoconf 工具链生成 configure、Makefile.in 等一堆构建文件。缺工具时会直接提示比如 autopoint: not found 就去补装 gettext。这一步与平台无关Linux 和 MSYS2 都能跑。如果 git clone 时网络不稳定导致仓库不完整后面编译会出现诡异的文件不存在先git status确认工作区干净再继续。3.2 contrib 依赖链make prebuilt 与单独编译指定库VLC 为避免宿主机库污染产物几乎把所有第三方依赖都收进 contrib 统一管理下载源码、各自编译、安装到 contrib/win64 里。两种拉法make prebuilt 下载 VideoLAN 服务器上打好的预编译包省时但依赖网络直接 make 表示全部源码本地编译耗时但可重试。cd contrib mkdir -p win64 cd win64 ../bootstrap --buildx86_64-w64-mingw32 make prebuilt--build 参数告诉 contrib 的 Makefile 目标平台是 Windows。如果 prebuilt 下载失败不要急着整体重来先确定是哪个依赖的包没下来。常见做法是进 contrib/win64 里单独编对应目标cd contrib/win64 make freetype make qt5这种单个目标可以反复跑失败时会打印具体库的 configure 日志。prebuilt 失败的下一级症状是 configure 阶段一大堆库检测不过因为 contrib/win64/lib/pkgconfig 里没有对应 .pc 文件。排查顺序先看这个目录里有什么、缺什么再决定补哪个依赖。另外注意prebuilt 包跟你当前 commit 的 contrib 版本可能不完全匹配第三方 API 变化会导致编译报错。如果错误集中在 contrib 头文件层面优先清掉那个库重编而不是去改 VLC 源码。3.3 configure 参数清单六个开关控制编译范围回到源码根目录执行 bootstrap 后的下一步cd ../.. ./configure \ --hostx86_64-w64-mingw32 \ --disable-lua \ --disable-nls \ --disable-srt \ --disable-upnp \ --enable-qtconfigure 开关含义使用建议--hostx86_64-w64-mingw32指定产出 64 位 Windows 程序必填--disable-lua关闭 Lua 扩展系统新手先关减少依赖链--disable-nls关闭多语言只保留英文要中文界面就留着--disable-srt关闭 SRT 协议支持用不到就关省 mbedtls 依赖--disable-upnp关闭 UPnP 网络发现避免 libupnp 编译问题--enable-qt强制开启 Qt 图形界面要现代界面必须开--disable-lua 是减少新手痛苦最有效的一项。Lua 扩展链长contrib 里容易成为失败源不需要脚本扩展时尽早关。--disable-nls 会省下 po 文件的编译时间代价是界面只剩英文。--enable-qt 很关键如果不写configure 检测到 Qt 不可用时会自动退化到 skins2 老界面功能都在但观感落后一个时代。configure 结束时最后几行会列出哪些模块被启用花一分钟核对freetype 是否 yesqt 是否 yesavcodec 是否 yes。如果 contrib 里明明编过 qtconfigure 仍显示 no检查 contrib/win64/lib/pkgconfig 下 Qt5Core.pc 是否存在不存在就回去补 contrib不用怀疑 configure 本身。4. make 与打包并行度、package-win-common 与启动验证4.1 make -jN并行数、中途失败与内存控制configure 通过后进入正式编译make -j8不加 -j 默认单线程全量编译以小时计。并行数按 CPU 线程数取我习惯先 -j4 起步观察内存占用因为 VLC 的 C 模块和 big 库单步编译非常吃内存编到一半 OOM 被 kill 反而浪费时间。8 核 16G 的机器-j8 可以跑但如果听到内存吃紧、swap 开始活动就降回 -j4。Windows 原生编译场景下还要注意杀毒软件实时扫描编译目录一大扫描带来的卡顿肉眼可见。中途失败直接重跑同样的 make 命令即可make 的增量机制会跳过已完成的模块。第一个错误之后的产物通常正常不要一看到 error 就 clean 全部。想收集更多错误可以用make -k8但我不建议第一次就开 -k因为你会面对几十条相互关联的报错定位反而困难。时间量级上走 prebuilt 的前提下8 核机器从 bootstrap 到打包完成大约 20 到 40 分钟如果 contrib 全走本地源码编译按小时算中间吃顿午饭很正常。4.2 make package-win-common谁才是能发布的产物编译完成后源码树里的 bin/vlc.exe 确实能跑但依赖旁边一堆构建产物直接拷走必挂。正确做法是走打包目标make package-win-common这个目标把所有运行期需要的 exe、DLL、plugins、locale、数据文件收集到一个类似 vlc-版本-win64 的目录里同时执行 vlc-cache-gen 生成插件缓存。它不依赖 NSIS 安装器是 CI 里最稳的产物目标也是我平时调试用的目标。想要压缩包再跑make package-win-zip它基于 common 的成果打成 zip。想要带安装向导的 exe 则用make package-win但要求机器装了 NSIS 且 makensis 在 PATH 里。NSIS 版本和脚本兼容性会带来额外变量所以我的习惯是日常只用 common发布时才碰 package-win。4.3 启动验证-vvv 日志与 --list-plugins打包完成后别急着双击。Windows 下控制台日志经常被 GUI 子系统吞掉写文件更可靠。我用这样的方式做首次冒烟./vlc-版本-win64/vlc.exe -vvv --no-qt --file-logging --logfilevlc-run.log-vvv 把日志级别拉到 debug--no-qt 强制不启动图形界面避免桌面环境干扰模块加载判断。跑完看 vlc-run.log 里有没有 fatal error。接着验证插件目录是否被发现./vlc-版本-win64/vlc.exe --list-plugins | head输出里应能看到 qt、freetype、avcodec 等关键模块登记。如果列表里没有 freetype字幕问题早晚会找上门。这一步三分钟能做完但能省掉后面在界面上反复点按的排查时间。5. Windows 编译高频踩坑5 条从现象到解法的记录5.1 路径太长Filename too long 与删不掉的目录在 Windows 原生编译时经常出现git checkout 报 Filename too long 无法继续或者编译中途某个文件创建失败错误信息里带一长串路径。原因很直接Windows 的 MAX_PATH 限制是 260 字符VLC 源码树嵌套深加上 contrib 里某些依赖的目录结构很容易撞上限。解决分两层。git 层面执行git config --system core.longpaths true系统层面把注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled设为 1 并重启。如果已经产生删不掉的目录用robocopy /MIR配一个空目录去镜像覆盖或者用\\?\前缀访问绝对路径再删。这套问题在 Linux 交叉编译下几乎不存在也是我推荐交叉编译的直接原因。5.2 QScintilla 编不出来Qt 界面黑匣子的常见源头表现很典型make 到 qt 模块时报错找不到 QScintilla 相关符号或者 configure 阶段直接判定 qt disabled最后界面退化到 skins2。原因集中在 contrib 里 qt5 和 qscintilla 的编译链。Qt 依赖大contrib 下载 qt 源码包失败、并发过高导致 moc 工具没生成都会让 qscintilla 跟着崩。解决思路是单独编目标把错误看得更清楚cd contrib/win64 make qt5 make qscintilla单独编译会打印具体库的 configure 输出看是哪一层依赖缺了。常见缺的是 libpng 或 zlib 链补完再回到根目录重新 configure。临时缓解方案是--enable-skins2 --disable-qt界面会难看但能继续干活根治还是得把 Qt 链路补齐。网上搜 qscintilla 下载与编译的经验多半也是在单独处理这条链。5.3 undefined referencecontrib 依赖链断裂的定位方法make 接近尾声时出现大量 undefined reference指向 libvlc 核心符号这是最让人头大的错误之一。常见原因不是 VLC 代码问题而是某个 contrib 静态库没编出来configure 却以为可用另一个高危操作是中途切换 host比如先编 32 位再改 64 位旧 .a 残留和新目标混在一起。定位方法先确认缺失符号属于哪个库用 nm 在候选静态库里查x86_64-w64-mingw32-nm contrib/win64/lib/libavcodec.a | grep 缺失符号如果对应 .a 文件整个不存在直接回 contrib 单独编那个库。更省事的做法是发现架构切换后立刻清掉整个 contrib/win64 目录重来rm -rf contrib/win64。代价是几十几分钟但比在混合产物里挑残渣省心这个坑我踩过之后长了记性。5.4 只拷 vlc.exe 必闪退缺 DLL 与自包含目录编译完成后只把 bin/vlc.exe 拷到另一台机器双击报缺少 libvlc.dll 或 libvlccore.dll。原因不复杂VLC 不是单文件程序运行时按相对路径找同目录的 DLL 和 plugins 子目录。源码树里的 bin 目录只是构建产物的一部分手动拷全几乎不可能。正确姿势是回到打包那一节使用make package-win-common产出自包含目录。如果你确实需要手动发布至少要把构建产生的全部 exe、DLL、plugins、share 树一起拷走同时保证 plugins.dat 缓存存在。但最稳的永远是打包命令不要手挑文件这不是偷懒是 Windows 下 VLC 的运行时结构决定的。5.5 字幕变成方块和 Xfreetype 链路的连锁反应播放本地视频正常外挂字幕却渲染成方块或 X换官方版一切正常。这个现象在 Windows 编译版里非常常见别想当然归给字幕文件编码。根因是 contrib 里 freetype 或 harfbuzz 没编出来configure 自动把字幕渲染降级到 fallback文字形状数据根本出不来。解决cd contrib/win64 make freetype make harfbuzz看失败原因多半是 zlib/png 链没闭环。补完后重新 configure确认输出里有 freetype support yes再 make。还有一个排查辅助直接在 config.h 里搜 FREETYPE 相关宏没定义就说明 configure 阶段已经悄悄禁用了。字幕字体链路是最容易默默失败的依赖之一因为 configure 不会硬报错它只会悄悄降级。6. 编译产物的进阶玩法免安装包、插件缓存与版本标记6.1 把打包目录变成免安装便携版make package-win-common生成的那个完整目录其实就是一个天然的绿色免安装包。把整个 vlc-版本-win64 目录拷到 U 盘或移动硬盘在别的 Windows 机器上直接运行目录里的 vlc.exe 就能用不需要安装动作。关键约束只有一个目录结构不能拆散。VLC 根目录下的 libvlc.dll 和 plugins 子目录必须保持在 exe 同级否则插件加载器找不到目标。便携版有个细节容易被忽略首次运行时会扫描全部插件生成 plugins.dat 缓存在机械硬盘上可能要等十几秒。提前生成缓存的方法是进入打包目录执行./vlc-cache-gen.exe plugins跑完后把生成的 plugins.dat 一起带走目标机器上首次启动就能秒开。这一步做没做决定了用户拿到手的便携版是双击就开还是双击转圈半天属于做产品时值得花十几秒处理的细节。6.2 交付前用三分钟冒烟验证我每次出包前固定跑一遍冒烟vlc.exe --version确认版本与 commit--list-plugins确认 qt、freetype、avcodec 都在放一段本地 H.264 文件确认解码链路再挂一个带字幕的片段确认字体渲染。这套检查下来三分钟左右能挡掉大部分低级发布事故。VLC 的 --version 输出里带有 git 描述信息对维护私有分支尤其有用——测试人员报 bug 时版本号能直接映射回源码 commit省去无头绪排查。最后说个我自己吃过亏的习惯编译成功不等于发布包可用。曾经把源码树 bin 里的 vlc.exe 直接发给同事结果对方反馈少了十几个 DLL那是一次很尴尬的交付。现在每次构建完都强制自己走一遍 package-win-common plugins.dat 校验这个流程不再省略。希望这次整理的编译手册能让你第一次就在 Windows 上拿到能发布的 VLC 产物。本文还有配套的精品资源点击获取
看完文章还有疑问?直接问顾问
三门峡、驻马店特种作业考证问题:报名条件、考试批次、材料整理、证书复审,电话或邮箱都能找到我们,当天回复,企业团报另对接 HR 专人。
预约咨询 18236992212