网罗开发小红书、快手、视频号同名大家好我是展菲目前在上市企业从事人工智能项目研发管理工作平时热衷于分享各种编程领域的软硬技能知识以及前沿技术包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。图书作者《ESP32-C3 物联网工程开发实战》图书作者《SwiftUI 入门进阶与实战》超级个体COC上海社区主理人特约讲师大学讲师谷歌亚马逊分享嘉宾科技博主华为HDE/HDG我的博客内容涵盖广泛主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告同时也会提供产品优缺点分析、横向对比并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。展菲您的前沿技术领航员 大家好我是展菲 全网搜索“展菲”即可纵览我在各大平台的知识足迹。每周定时推送干货满满的技术长文从新兴框架的剖析到运维实战的复盘助您技术进阶之路畅通无阻。文章目录0. Vcpkg是什么1. Port 是什么2. 执行时可依赖的上下文变量3. 声明依赖与特性vcpkg.json4. 获取源码4.1 vcpkg_from_github最常见4.2 额外下载与解压libpng 的 apng5. 特性映射vcpkg_check_features6. CMake 端口的标准流水线7. 非 CMake 或拆分式 portfileopenssl8. 平台与链接类型分支9. 安装后修补vcpkg_replace_string 与路径重写10. 链接方式约束与工具依赖11. 调试与质量检查建议12. 实战新增 mediainfo CLI 端口依赖 libmediainfo12.1 目标与设计12.2 新建目录结构12.3 vcpkg.json 示例CLI 端口12.4 portfile.cmake 示例重点12.5 usage 示例12.6 验证流程建议按顺序12.7 常见坑位与处理13. 从本仓库四个端口可归纳的「检查清单」14. 小结本文面向鸿蒙三方库移植适配需要在 vcpkg 中维护或新增端口的开发者结合通用约定与本仓库中ports/libpng、ports/curl、ports/openssl、ports/libmediainfo等portfile.cmake里的常见写法说明如何组织端口脚本、与vcpkg.json配合以及处理特性、平台差异与安装收尾工作。vcpkg鸿蒙仓地址https://gitcode.com/OpenHarmonyPCDeveloper/ohos_vcpkg0. Vcpkg是什么vcpkg是微软开源的C/C 包管理器面向原生库与工具链生态核心能力包括统一入口用同一套命令与元数据port描述大量开源库的获取、配置、编译与安装。跨平台与交叉编译除 Windows、Linux、macOS 等主机平台外社区与官方长期维护对Android、iOS等目标的交叉编译支持各类 fork 也会为新兴平台补充 toolchain 与 triplet。依赖解析自动处理依赖树、版本约束与构建顺序减少“手工拼 Makefile / 逐个改 CMake 交叉参数”的成本。与 CMake 深度集成通过scripts/buildsystems/vcpkg.cmake等机制让业务工程以标准 CMake 方式消费已安装的库与配置文件。它已经能够处理 Android、iOS 和其他嵌入式目标的交叉编译。将 HarmonyOS 添加为一级平台意味着 OHOS 开发人员无需对每个库的构建系统进行修改即可使用整个 vcpkg 移植目录。QT官方2026年4月10号分享和贡献了支持HarmonyOS系统的vcpkg这意味着海量的三方库上千个鸿蒙化移植从此变得简单了借助QT官方修改后的 vcpkg 分支只需一条命令即可完成三方库的安装。且vcpkg本身是跨平台的跟windows下的使用习惯一致。对鸿蒙而言vcpkg 可以把“每个库一套脚本、一套坑”收敛为“平台 triplet 少量 port 补丁 一条安装命令”。鸿蒙的vcpkg已经通过了上游合并请求合入了微软的 vcpkg主分支。详情参见这个pr: https://github.com/microsoft/vcpkg/pull/514701. Port 是什么一个port描述「如何从上游源码构建并安装某个库/工具到 vcpkg 的安装树」。每个端口通常包含文件作用vcpkg.json端口元数据名称、版本、描述、依赖、可选features、平台约束等portfile.cmake构建脚本下载源码、打补丁、调用构建系统、把产物放到CURRENT_PACKAGES_DIR补丁、辅助.cmake、usage等与端口同目录由portfile.cmake引用portfile.cmake在CMake 脚本模式下由 vcpkg 执行可使用 CMake 语法以及 vcpkg 提供的函数如vcpkg_from_github、vcpkg_cmake_configure等。2. 执行时可依赖的上下文变量编写portfile.cmake时最常接触的内置变量包括PORT当前端口名与vcpkg.json中name一致。VERSION当前要构建的版本字符串来自vcpkg.json的version/version-date等。FEATURES用户启用的特性列表可用foo IN_LIST FEATURES判断。VCPKG_LIBRARY_LINKAGEstatic或dynamic与 triplet 一致。VCPKG_TARGET_IS_WINDOWS、VCPKG_TARGET_IS_UWP、VCPKG_TARGET_IS_ANDROID、VCPKG_TARGET_IS_OHOS等目标平台布尔变量用于分支逻辑。VCPKG_TARGET_ARCHITECTURE如x64、arm64、arm。CURRENT_PACKAGES_DIR本端口本次安装的目标根目录installed/triplet/下对应包目录。CURRENT_BUILDTREES_DIR构建树路径适合放下载的补丁解压物等中间文件。CMAKE_CURRENT_LIST_DIR/CURRENT_PORT_DIR当前portfile.cmake所在端口目录用于file(INSTALL ...)引用同目录下的补丁、usage、vcpkg-cmake-wrapper.cmake等。在libpng中会根据VCPKG_LIBRARY_LINKAGE设置PNG_STATIC/PNG_SHARED在curl中会根据FEATURES与 Windows 条件追加 Schannel 等选项——这些都是典型的上下文用法。3. 声明依赖与特性vcpkg.json脚本里的逻辑应与vcpkg.json一致普通依赖列在dependencies需要「仅在宿主机上参与配置」的工具链端口可加host: true例如vcpkg-cmake。可选能力放在features里portfile里用vcpkg_check_features或IN_LIST FEATURES与 CMake 选项对齐。libpng的apng、tools与curl的大量 SSL/协议相关 features 都是范例JSON 声明依赖与描述portfile.cmake把 feature 名映射到上游的-D...开关。4. 获取源码4.1vcpkg_from_github最常见本仓库中libpng、curl、openssl、libmediainfo均使用vcpkg_from_githubOUT_SOURCE_PATH SOURCE_PATH输出源码根路径变量名惯例写SOURCE_PATH。REPO/REF/SHA512仓库与固定提交/标签及校验和保证可复现构建。HEAD_REF供--head模式使用。PATCHES相对于端口目录的补丁列表.patch/.diff。版本字符串处理上游标签与VERSION不完全一致时在portfile里用string(REGEX REPLACE ...)等先算出REF再传给vcpkg_from_github。libmediainfo将VERSION规整为MEDIAINFO_VERSION再拼v${MEDIAINFO_VERSION}curl用string(REPLACE . _ ...)生成curl-${VERSION}形式的 ref。4.2 额外下载与解压libpng的 apng当某个 feature 需要额外资源时可使用vcpkg_download_distfile下载文件并校验SHA512用vcpkg_execute_required_process调用外部命令如gzip -d解压到CURRENT_BUILDTREES_DIR在vcpkg_from_github的PATCHES里加入该补丁路径可为空字符串时需注意条件本仓库通过变量在 feature 关闭时为空补丁路径的处理方式依端口而定。若 Windows 上需要 Unix 工具链可配合vcpkg_acquire_msys与vcpkg_add_to_pathlibpng的 apng 流程。5. 特性映射vcpkg_check_features将vcpkg.json中的 feature 名映射为 CMake 配置选项推荐统一使用vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES http2 USE_NGHTTP2 openssl CURL_USE_OPENSSL openssl CURL_CA_FALLBACK INVERTED_FEATURES ldap CURL_DISABLE_LDAP )FEATURES启用某 feature 时向列表追加-DOPTIONON或等价行为依实现而定。INVERTED_FEATURES未启用某 feature 时追加对应选项如禁用 LDAP。在OPTIONS里展开${FEATURE_OPTIONS}传给vcpkg_cmake_configure见curl。互斥与组合校验复杂端口用if(...)message(FATAL_ERROR ...)明确禁止不支持的组合。curl对http3与部分 TLS backend 的组合即如此openssl在开头检测已安装的libressl/boringssl并直接失败避免链接冲突。6. CMake 端口的标准流水线以libmediainfo、curl、libpng为代表典型顺序为vcpkg_find_acquire_program如PKGCONFIG必要时set(ENV{PKG_CONFIG} ...)。vcpkg_cmake_configureSOURCE_PATH指向上游含顶层或子目录CMakeLists.txt的路径libmediainfo使用${SOURCE_PATH}/Project/CMake。OPTIONS/OPTIONS_DEBUG/OPTIONS_RELEASE传入-D变量可加入MAYBE_UNUSED_VARIABLES避免上游未使用某变量时产生警告libpng。vcpkg_cmake_installvcpkg_cmake_config_fixup修正*Config.cmake安装路径或包名PACKAGE_NAME、CONFIG_PATH。vcpkg_fixup_pkgconfig修正.pc文件中的前缀等。按需vcpkg_copy_pdbsMSVC、vcpkg_copy_tools安装可执行文件到tools/port。file(REMOVE_RECURSE ...)删除不需要安装的目录如重复的debug/include、debug/share。vcpkg_install_copyright安装许可证文件到share/port/copyright。可选安装usage、vcpkg-cmake-wrapper.cmake以改善find_package体验curl、libpng。注入额外 CMake 逻辑curl通过-DCMAKE_PROJECT_INCLUDE...在工程配置阶段包含自定义片段用于与 vcpkg 环境对齐。7. 非 CMake 或拆分式portfileopensslopenssl说明了一种常见模式顶层portfile.cmake只做共性逻辑vcpkg_from_github、组装CONFIGURE_OPTIONS、按 feature 追加 OpenSSL 的Configure参数再通过include(${CMAKE_CURRENT_LIST_DIR}/windows/portfile.cmake) # 或 include(${CMAKE_CURRENT_LIST_DIR}/unix/portfile.cmake)把平台相关的大段步骤拆到子文件便于维护。此类端口还会使用vcpkg_cmake_get_varsinclude(${cmake_vars_file})读取探测到的编译器信息如VCPKG_DETECTED_CMAKE_C_COMPILER_ID用于决定是否启用某些优化或 OpenSSL 目标三元组见openssl与libpng中 ARM/编译器相关分支。8. 平台与链接类型分支典型模式静态库使用方式curl在VCPKG_LIBRARY_LINKAGE STREQUAL static时改写curl.h中的宏使消费者默认按静态链接语义包含头文件。Windows 与.pc/ 库名libpng、curl在 Windows 上对pkgconfig中的-l名称做vcpkg_replace_string区分debug与release、以及是否定义VCPKG_BUILD_TYPE单一构建类型 triplet。UWP / Android / OHOS通过VCPKG_TARGET_IS_*关闭不支持的选项或调整编译参数libpng在 OHOS 上为VCPKG_C_FLAGS追加--target...以配合交叉 sysroot这是「工具链绕过 CMake 的execute_process调用编译器」类问题的典型处理思路。9. 安装后修补vcpkg_replace_string与路径重写上游生成的脚本或.pc常带有绝对路径不利于包可移植性。curl对curl-config的替换与移动到tools/${PORT}/bin是范例把安装目录占位符改为${prefix}或基于脚本位置的相对推导区分debug与release两套文件用IGNORE_UNCHANGED避免在路径已替换时失败。10. 链接方式约束与工具依赖vcpkg_check_linkage(ONLY_STATIC_LIBRARY)在无法支持动态库的平台上强制静态库openssl对 Emscripten。vcpkg_find_acquire_program(PERL)、NASM、PKGCONFIG等声明构建期可执行文件由 vcpkg 获取或定位必要时vcpkg_add_to_path。11. 调试与质量检查建议先最小化默认关闭非必要features保证基线vcpkg install port可通过。对齐vcpkg.jsonfeatures的dependencies、supports与portfile中的FATAL_ERROR条件应一致否则用户会在解析阶段或构建阶段才看到错误。补丁尽量小、注释清楚 issue/upstream 链接命名放在端口目录在vcpkg_from_github或等价获取函数中列出。版权始终vcpkg_install_copyright若项目多许可证如curl额外写入从源文件提取的声明可组合多个FILE_LIST条目。12. 实战新增mediainfoCLI 端口依赖libmediainfo你当前仓库已经有libmediainfo库但没有mediainfo命令行工具。这类“CLI 与库分仓、CLI 依赖库”是 vcpkg 中很常见的建模场景推荐单独新建一个mediainfoport。12.1 目标与设计端口拆分原则libmediainfo负责 SDK/链接库mediainfo负责最终可执行程序。依赖关系mediainfo的vcpkg.json依赖libmediainfo以及其上游链条如libzen。安装形态CLI 可执行文件应安装到tools/mediainfo由vcpkg_copy_tools或上游安装路径配合移动完成。链接策略通常允许 triplet 决定静/动态不在端口里硬编码若上游对纯静态有问题再用vcpkg_check_linkage限制。12.2 新建目录结构在ports下创建ports/ mediainfo/ vcpkg.json portfile.cmake usage如果后续需要修补上游构建逻辑再补充*.patch/*.diff文件。12.3vcpkg.json示例CLI 端口下面是一个可作为起点的声明示例版本号与哈希需按你实际选用的上游 release 调整{name:mediainfo,version:24.12,description:Unified display of technical and tag data for video and audio files,homepage:https://mediaarea.net/en/MediaInfo,license:BSD-2-Clause,dependencies:[{name:vcpkg-cmake,host:true},{name:vcpkg-cmake-config,host:true},libmediainfo]}编写要点mediainfo不直接重复声明libzen因为它已在libmediainfo依赖链里。若 CLI 仅支持部分平台可在supports字段提前约束例如排除uwp。12.4portfile.cmake示例重点mediainfoCLI 的上游仓库是MediaArea/MediaInfo与libmediainfo的MediaInfoLib不同。可采用和现有端口一致的 CMake 流水线vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO MediaArea/MediaInfo REF v${MEDIAINFO_VERSION} SHA512 填写实际SHA512 HEAD_REF master PATCHES find-mediainfolib-names.patch ) vcpkg_cmake_configure( SOURCE_PATH ${SOURCE_PATH}/Project/CMake/CLI OPTIONS -DMEDIAINFO_CLI_STATICOFF ) vcpkg_cmake_install() vcpkg_copy_pdbs() vcpkg_copy_tools(TOOL_NAMES mediainfo AUTO_CLEAN) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share) file(INSTALL ${CMAKE_CURRENT_LIST_DIR}/usage DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT}) vcpkg_install_copyright(FILE_LIST ${SOURCE_PATH}/LICENSE)这段示例体现了几个关键点分仓拉取REPO必须指向 CLI 仓库而不是MediaInfoLib。入口目录正确MediaInfoCLI 的 CMake 入口是Project/CMake/CLI不是Project/CMake。关闭“源码子工程”静态路径-DMEDIAINFO_CLI_STATICOFF否则会要求MediaInfoLib与MediaInfo在同一父目录下并排克隆触发add_subdirectory ... MediaInfoLib/Project/CMake不存在。CMake 包名与文件名不一致上游安装的是MediaInfoLibConfig.cmake而 CLI 里写的是find_package(mediainfolib)在区分大小写系统上 CONFIG 查找会失败。本仓库find-mediainfolib-names.patch将其改为find_package(mediainfolib NAMES MediaInfoLib REQUIRED)。不要对ZenLib使用NAMES zenliblibzen安装目录里仍是ZenLibConfig.cmakevcpkg_cmake_config_fixup(PACKAGE_NAME zenlib)主要修正路径与合并 debug/release并不等于生成zenlib-config.cmake写成NAMES zenlib反而会找不到包。ZenLib保持上游的find_package(ZenLib REQUIRED)即可。不要在mediainfo的portfile里向CURRENT_PACKAGES_DIR复制libmediainfo的 CMake 文件配置mediainfo时CURRENT_PACKAGES_DIR指向packages/mediainfo_*此时还没有、也不应去写libmediainfo的share/mediainfolib/把复制逻辑放在ports/libmediainfo/portfile.cmake或仅用上述补丁才对。慎加CMAKE_REQUIRE_FIND_PACKAGE_mediainfolib若与上游find_package(... REQUIRED)叠加vcpkg 会提示 “already called with REQUIRED, thus … has no effect”且对解决 “找不到 Config” 无帮助。CLI 安装规范vcpkg_copy_tools(TOOL_NAMES mediainfo …)把可执行文件收敛到tools/${PORT}。纯工具端口一般不需要vcpkg_cmake_config_fixup()除非上游安装了需修正的 CMake package。许可证文件名以仓库为准常见为根目录LICENSE或License.html。12.5usage示例ports/mediainfo/usage可以写成The package mediainfo provides the command line tool: mediainfo media-file Example: mediainfo sample.mp412.6 验证流程建议按顺序安装并构建端口vcpkg install mediainfo验证可执行文件位置检查installed/triplet/tools/mediainfo/mediainfo(.exe)是否存在运行命令验证installed/triplet/tools/mediainfo/mediainfo --Version验证依赖解析如果配置失败先看 CMake 日志是否在find_package(MediaInfoLib)处报错再检查vcpkg.json依赖声明12.7 常见坑位与处理add_subdirectory ... MediaInfoLib ... not an existing directory几乎总是MEDIAINFO_CLI_STATIC仍为默认 ON。在vcpkg_cmake_configure里加上-DMEDIAINFO_CLI_STATICOFF让工程使用find_package(mediainfolib)vcpkg 安装的libmediainfo而不是在 buildtree 旁再克隆一份MediaInfoLib。CMAKE_REQUIRE_FIND_PACKAGE_*与 “already called with REQUIRED”**对已在find_package(… REQUIRED)的包再写CMAKE_REQUIRE_FIND_PACKAGE_*往往只会报警、不能修复缺失的 Config优先用补丁或 **NAMES修正查找名。Could not find a package configuration file provided by mediainfolibMediaInfoLib工程安装的是MediaInfoLibConfig.cmake与 CLI 里find_package(mediainfolib)在大小写敏感系统上不匹配。处理(A)libmediainfo端口用configure_file(... COPYONLY)生成mediainfolib-config.cmake本仓库ports/libmediainfo/portfile.cmake(B)mediainfo补丁find_package(mediainfolib NAMES MediaInfoLib REQUIRED)本仓库ports/mediainfo/find-mediainfolib-names.patch。切勿在mediainfo的portfile里向packages/mediainfo_*下的share/mediainfolib复制——那是错误目录配置阶段永远找不到libmediainfo已安装的文件。Could not find … zenlibConfig.cmake包名却写 ZenLib多为把find_package(ZenLib …)改成了NAMES zenlib。libzen仍提供ZenLibConfig.cmake应保留上游find_package(ZenLib REQUIRED)只对mediainfolib使用NAMES MediaInfoLib。MediaInfoDLL.h中unknown type name size_tOHOS / musl动态链接路径下会包含该头文件在部分 libc 上dlfcn.h不保证已间接定义size_t。本仓库在libmediainfo中通过补丁mediainfodll-include-stddef.patch在extern C前加入#include stddef.h。版本标签不匹配若上游 tag 不是v${VERSION}参考curl/libmediainfo的做法先做字符串变换再传REF。二进制名差异某些平台产物可能不是mediainfo需按实际产物名修改vcpkg_copy_tools(TOOL_NAMES ...)。Windows 调试后缀若上游生成mediainfo_d.exe等命名建议在安装后统一命名减少下游脚本复杂度。仅工具端口场景若端口只提供 CLI不提供库可不强制vcpkg_cmake_config_fixup()但保留也通常无害取决于是否安装了 config 文件。OHOS SDK 的 CMake Deprecation Warning来自ohos.toolchain.cmake里偏旧的cmake_minimum_required与mediainfo本身无关升级 Harmony/OpenHarmony NDK/SDK 中的 toolchain 或本地忽略该警告即可。13. 从本仓库四个端口可归纳的「检查清单」步骤libpngcurlopenssllibmediainfo获取源码GitHub 条件额外下载GitHubGitHubGitHub版本/ref 变换直接使用v${VERSION}下划线替换openssl-${VERSION}正则修正次版本号特性vcpkg_check_featuresIN_LIST大量 feature 冲突检测fips/tools等少量 FIND_PACKAGE锁定构建系统CMakeCMakeConfigure/NMake 等分平台CMake子目录收尾pkgconfig、PDB、可选 toolscurl-config、静态头宏拆分子 portfile wrapper 模板pkgconfig debug 后缀版权LICENSECOPYING 额外片段LICENSE.txtLICENSE14. 小结编写 vcpkg 端口脚本的核心是在vcpkg.json中诚实声明元数据与特性在portfile.cmake中把「版本/平台/特性」翻译成上游构建系统能理解的选项并在安装阶段修正 CMake 配置、pkg-config、脚本路径与版权文件使安装树对下游 CMake/pkg-config 用户一致且可维护。遇到复杂平台或互斥依赖时尽早message(FATAL_ERROR)、拆分include()子文件、用vcpkg_cmake_get_vars读取探测结果与本仓库中成熟端口的写法保持一致可显著降低维护成本。最后欢迎加入开源鸿蒙开发者社区交流https://harmonypc.csdn.net/