ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Sequel-Ace 自带 MySQL 客户端库的通用二进制构建配方:libmysqlclient 与 OpenSSL 的源码级自建方案

Sequel-Ace 自带 MySQL 客户端库的通用二进制构建配方:libmysqlclient 与 OpenSSL 的源码级自建方案 数据库桌面应用开发工具【免费下载链接】Sequel-AceMySQL/MariaDB database management for macOS项目地址https://gitcode.com/gh_mirrors/se/Sequel-Ace点击查看免费下载导读本文深入剖析 Sequel-Ace 仓库中 Frameworks/libmysqlclient/README.md 所定义的“捆绑 MySQL 客户端构建配方”两个完全自包含的 Shell 脚本如何从 OpenSSL 与 MySQL 官方源码包构建出与 macOS 13.5 部署目标严格对齐的arm64 x86_64 通用二进制libmysqlclient.24.dylib、libssl.3.dylib、libcrypto.3.dylib、客户端认证插件与头文件并解答三个核心问题为什么不能直接使用 Homebrew 的瓶子bottle构建产物如何在SPMySQL.framework内部通过loader_path相互引用以及如何在开发机上安全地增量重建、并发发布这些 dylib。读完本文你将掌握这套配方背后的依赖策略、校验与验证机制、可复现构建原理以及其在 Xcode 工程中的挂接方式。一、为什么 Sequel-Ace 要自建 MySQL 客户端库而不是用 HomebrewSequel-Ace 的底层连接层由 SPMySQLFramework 实现它依赖三份关键的第三方动态库MySQL 客户端库libmysqlclient.24.dylib以及加密栈libssl.3.dylib/libcrypto.3.dylib。这些库必须作为应用的一部分随 App 分发因此它们的构建方式直接决定应用的兼容边界。Homebrew 瓶子的两个致命问题README 与 build-openssl.sh 的注释相互印证最低系统版本由宿主决定Homebrew 的瓶子是针对“宿主 macOS 版本”编译的。文档给出了一个真实案例历史上随仓库分发的 OpenSSL 3.4.1 对arm64 片的 minos最低系统版本是 15.0、x86_64 片是 14.0而应用自身的目标是 macOS 13.5。这直接导致构建期出现 “building for macOS-13.5, but linking with dylib libssl.3.dylib which was built for newer version 15.0” 的链接器警告——在 13.5 上运行这样的二进制是危险且不合规的。绝对路径引用Homebrew 的库之间通过/opt/homebrew/...arm64或/usr/local/...x86_64的绝对路径互相引用这些路径在用户机器上根本不存在运行时要么加载失败要么更糟悄悄捡起用户机器上真实安装的 Homebrew 副本造成行为漂移。因此这套配方从一开始就明确构建产物只能链接loader_path、/usr/lib或/System/Library之内的内容。两个脚本在发布前都会执行这条规则的自动化校验见下文“验证关卡”任何指向 Homebrew 前缀的引用都会导致构建失败并停止复制。二、产物清单两个脚本各产出什么README 用一张表界定了分工仓库中的实际目录结构与之一一对应产物位于SPMySQLFramework/MySQL Client Libraries下由谁构建原料来源lib/libssl.3.dylib、lib/libcrypto.3.dylibbuild-openssl.shOpenSSL 官方 release 源码包lib/libmysqlclient.24.dylib、include/、lib/mysqlplugins/认证插件 WebAuthn 插件加载的捆绑 libfido2build-libmysqlclient.shMySQL 官方源码包当前仓库中 MySQL Client Libraries 的实际内容为lib/libcrypto.3.dylib、lib/libssl.3.dylib、lib/libmysqlclient.24.dyliblib/mysqlplugins/下的三个客户端认证插件authentication_ldap_sasl_client.so、authentication_oci_client.so、authentication_webauthn_client.so以及 WebAuthn 插件运行时加载的libfido2.1.dylibinclude/下与源码包同步的头文件包括mysql.h、mysql_version.h、errmsg.h、mysql_com.h等 13 个头文件。注意插件目录中的命名细节libfido2.1.dylib是真实文件构建脚本中另有其他 libfido2 名字的符号链接但被打包时只复制真实文件本身WebAuthn 插件通过loader_path/libfido2.1.dylib加载它。三、运行方式两步命令与自动依赖重建README 给出最直接的运行方式Frameworks/libmysqlclient/build-openssl.sh # 构建 OpenSSL 对 Frameworks/libmysqlclient/build-libmysqlclient.sh # 构建客户端库、头文件与插件两个脚本都要求先存在目标目录SPMySQLFramework/MySQL Client Libraries/lib否则直接报错退出❌ Library directory not found。关键设计第二个命令可以单独完成全部重建。build-libmysqlclient.sh会检查 OpenSSL 树是否“过时”它以 stamp 文件.sequel-ace-recipe记录 OpenSSL 版本与构建时的部署目标下限并读取build-openssl.sh当前钉死的OPENSSL_VERSION对比只有当两个架构的 OpenSSL 树都存在、stamp 匹配、且libcrypto.3.dylib每片架构的 minos 等于DEPLOYMENT_TARGET时才复用已有树否则自动调用build-openssl.sh重建见 build-libmysqlclient.sh。Rosetta 2 前置条件在 Apple silicon 上构建 x86_64 片时MySQL 构建期编译出的 helper 程序以目标架构运行必须通过 Rosetta 转译因此脚本在开始时就检查arch -x86_64 /usr/bin/true是否可执行失败则提示softwareupdate --install-rosetta --agree-to-license两个脚本默认把中间产物写入脚本同级的build/目录该目录已被 git 忽略且只有全部检查通过后才会把最终产物复制进SPMySQLFramework/MySQL Client Libraries。可用环境变量覆盖工作目录OPENSSL_BUILD_DIROpenSSL 的 scratch 目录默认脚本目录/build/opensslMYSQL_BUILD_DIRMySQL 的 scratch 目录默认脚本目录/build/mysqlMYSQL_INCREMENTAL1复用各架构的构建目录跳过重新 configure默认每次从头配置此外CMAKE可覆盖 CMake 可执行文件路径默认使用脚本下载的 Kitware 官方通用二进制。Xcode 挂接方式libmysqlclient.xcodeproj中的 target 是一个包装器——其构建脚本只有一行${PROJECT_DIR}/build-libmysqlclient.sh见 project.pbxproj也就是说你可以在 Xcode 里直接跑这个 target 来触发同一份配方。四、版本与校验和钉死以及可复现构建版本、校验和全部硬编码在脚本顶部升级版本时必须同时升级校验和README 明确要求 “bump the version and the checksum together”build-openssl.shOPENSSL_VERSION3.5.8、OPENSSL_SHA256与 OpenSSL release 页发布的 SHA-256 一致、DEPLOYMENT_TARGET13.5、ARCHS(arm64 x86_64)build-libmysqlclient.shMYSQL_VERSION8.4.11、MYSQL_SHA256、MYSQL_MD5Oracle 在 dev.mysql.com 上发布 MD5用于与 SHA-256 双重匹配下载、CMAKE_VERSION4.4.3、CMAKE_SHA256同样钉死 13.5 与双架构。可复现性设计OpenSSL 构建导出SOURCE_DATE_EPOCH0压掉 libcrypto 中内嵌的构建时间戳build-openssl.sh。这样在同一工具链上重跑脚本产出的 dylib 字节完全一致不会在 git 中产生虚假的二进制变更。双校验策略curl -fsSL下载后OpenSSL 走shasum -a 256MySQL 包同时走 SHA-256verify_sha256与md5 -q双重校验前者防篡改、后者与官方下载页公布值互相印证。五、依赖策略零 Homebrew全部自给自足README 明确两个脚本完全自包含不使用 Homebrew 的任何东西。依赖按来源分三类MySQL 源码包自带通过 CMake 的-DWITH_*bundled开启zlib、zstd、lz4、ICU、protobuf、libfido2、editline、libeventmacOS SDK 自带SASL用于 LDAP 插件WITH_AUTHENTICATION_LDAPON且WITH_KERBEROSnone因为捆绑从未分发过 Kerberos 插件脚本自行下载并校验MySQL 与 OpenSSL 源码包、以及 Kitware 官方发布的 CMake 通用universal二进制。此外Bison 不需要解析器属于 server 侧纯客户端构建WITHOUT_SERVERON永远不会执行它。为了彻底隔离 Homebrewconfigure 时显式传入-DCMAKE_IGNORE_PREFIX_PATH/opt/homebrew;/usr/local即使/opt/homebrew/bin在 PATH 中也不会被find_*找到build-libmysqlclient.sh。OpenSSL 的 Homebrew 形状保留但绝不落盘build-openssl.sh的 configure 参数刻意镜像 Homebrew openssl3 配方no-ssl3 no-ssl3-method no-zlib --libdirlib以及逐架构的--prefix/--openssldir如 arm64 对应/opt/homebrew/opt/openssl3、x86_64 对应/usr/local/opt/openssl3目的是让 OPENSSLDIRlibcrypto 中内嵌的默认证书与配置查找路径与旧二进制完全一致、行为不变但这些 Homebrew 形状的路径只作为 DESTDIR 下的“虚拟安装前缀”通过make install_sw DESTDIR$dest安装进 scratch 目录从不写入真实文件系统。构建完成后还会用install_name_tool把这些路径改写为指向本构建树的绝对路径供 MySQL 链接其 helper 程序最终发布前再统一改写为loader_path。六、框架内部的布局与 loader_path 引用约定README 的 “Layout inside the framework” 一节描述了最终运行时布局SPMySQL.framework/Versions/A中并排放置SPMySQL可执行体与三个 dylib彼此以loader_path/name相互引用。插件目录的关键一跳SPMySQLConnection在建立连接时把插件搜索路径指向框架的PlugIns目录——SPMySQLConnection.m 中的源码为// Point libmysqlclient at this frameworks PlugIns directory for client-side auth plugins. NSString *pluginDirectory [[NSBundle bundleForClass:[self class]] builtInPlugInsPath]; if (pluginDirectory) { mysql_options(theConnection, MYSQL_PLUGIN_DIR, [pluginDirectory fileSystemRepresentation]); }MYSQL_PLUGIN_DIR正是 include/mysql.h 中声明的客户端选项。代码注释解释了它的必要性若不设置libmysqlclient 会回退到“编译期烧入的插件路径”——那是构建机上才存在的目录在用户系统上必然 dlopen 失败历史 issue 即 MariaDB ed25519 认证的故障场景。由此产生了一个几何关系插件位于Versions/A/PlugIns比Versions/A中的 dylib 低一级因此插件对 OpenSSL 对的引用写作loader_path/../lib*.dylib而libmysqlclient.24.dylib对 OpenSSL 的引用写作loader_path/lib*.dylib。构建脚本中的retarget_openssl辅助函数正是按这个约定把所有绝对/相对形式的 OpenSSL 引用统一改写为对应前缀build-libmysqlclient.sh。尚未完成的接线README 明确指出把插件打包进PlugIns目录这件事目前还没有接上线对应 GitHub issue #2590因此构建出的插件暂存在lib/mysqlplugins/中待命。七、开发期工作树中被修改的 dylib 与并发发布README 最后一个章节处理一个易踩的坑当你为了调试直接改动了MySQL Client Libraries/lib下的某个 dylib例如用install_name_tool改 install nameSPMySQL.framework的 post-build 脚本会在每次构建时把“从已构建框架里拷出的 dylib”重新复制回MySQL Client Libraries/lib覆盖你的改动——条件是git diff报告该文件已被修改否则保持原样。发布一致性无论是 post-build 脚本还是两个配方脚本所有发布者都遵循“先写入唯一临时文件再 rename 到位”的协议例如mktemp $lib_dir/.$lib.XXXXXX后mv -fdylib 与头文件均如此因此并发读取者永远不会看到写了一半的文件。剩下的语义是最后写入者胜出last-writer-wins如果两个构建同时发布树中留下的将是最后完成的那份拷贝——所以在这种状态下如果在意最终树中是哪个构建的产物应当让xcodebuild调用一个一个地跑。八、从源码看构建细节配置旗标与验证关卡8.1 OpenSSL 的 configure 与通用化build-openssl.sh对每个架构分别 configure 与编译perl ./Configure darwin64-$arch-cc \ --prefix$prefix --openssldir$openssldir --libdirlib \ shared no-ssl3 no-ssl3-method no-zlib no-tests \ -mmacosx-version-min$DEPLOYMENT_TARGET \ -Wl,-headerpad_max_install_names随后make build_swmake install_sw DESTDIR...只装库、头文件与 openssl 程序不装文档、engines 和 providers——这些捆绑不携带安装出的 dylib 是只读的install_name_tool无法直接改写因此提前用-Wl,-headerpad_max_install_names预留 headerpad 空间再chmod uw后改写 install name。最后对 arm64 片ad-hoc 重签名——install_name_tool会作废链接器的 ad-hoc 签名而 dyld 拒绝接受无签名的 arm64 dylib这会影响CODE_SIGNING_ALLOWEDNO的单元测试 scheme。两个架构的 dylib 经lipo -create合并为通用二进制install name 统一设为loader_path/libcrypto.3.dylib/loader_path/libssl.3.dylib并留下一棵sdk-arch符号链接树供 MySQL 侧WITH_SSL链接。8.2 MySQL 客户端的 CMake 配置要点build-libmysqlclient.sh的核心 configure节选关键旗标$cmake_bin -S $src -B $build -G Unix Makefiles \ -DCMAKE_OSX_ARCHITECTURES$arch -DCMAKE_SYSTEM_PROCESSOR$arch \ -DCMAKE_OSX_DEPLOYMENT_TARGET$DEPLOYMENT_TARGET -DCMAKE_OSX_SYSROOT$sysroot \ -DINSTALL_LAYOUTSTANDALONE \ -DCMAKE_IGNORE_PREFIX_PATH/opt/homebrew;/usr/local \ -DBUILD_CONFIGmysql_release -DWITHOUT_SERVERON -DWITH_UNIT_TESTSOFF \ -DWITH_SSL$openssl_dir/sdk-$arch \ -DWITH_ZLIBbundled -DWITH_ZSTDbundled -DWITH_LZ4bundled -DWITH_ICUbundled \ -DWITH_PROTOBUFbundled -DWITH_FIDObundled -DWITH_EDITLINEbundled -DWITH_LIBEVENTbundled \ -DWITH_KERBEROSnone \ -DWITH_AUTHENTICATION_CLIENT_PLUGINSON -DWITH_AUTHENTICATION_LDAPON \ -DWITH_AUTHENTICATION_WEBAUTHNON \ -DENABLED_LOCAL_INFILEON -DWITH_EXTRA_CHARSETSall值得注意的细节跨编译的 zstd 陷阱在 Apple silicon 上交叉编译 x86_64 时CMake 会从宿主推导CMAKE_SYSTEM_PROCESSOR导致 MySQL 自身的APPLE_ARM开关保持开启捆绑的 zstd 因而省略了 x86_64 汇编却又从 C 代码引用它。脚本为此在 x86_64/arm64 宿主组合下追加-DZSTD_DISABLE_ASM强制走 C 回退路径该开关仅影响服务端 InnoDB 读取的路径。头文件一致性证明头文件“按构造”应是架构无关的但脚本不假设而是证明——构建后对两架构的include/做diff -r不一致即失败。插件集合完整性以 arm64 的插件集合为基准逐一lipo合并再反向遍历 x86_64 集合确保“某架构多出了插件”不会静默丢失。8.3 发布前的验证关卡两个脚本共有任何产物只有通过全部检查才会被复制进框架目录主要检查项包括lipo -archs确认每个文件都包含 arm64 与 x86_64 两片otool逐片读取LC_BUILD_VERSION的 minos必须精确等于13.5install nameotool -D必须等于预期的loader_path/nameotool -L的依赖列表tab 缩进行中不允许出现loader_path/、/usr/lib/、/System/Library/之外的任何路径——这一条直接落实了“绝不链接 Homebrew 路径”的承诺codesign --verify确认 ad-hoc 签名有效版本字符串抽查strings必须在 libcrypto 中找到OpenSSL 3.5.8版本横幅、在 libmysqlclient 中找到8.4.11且mysql_version.h声明了同一版本。8.4 与 SPMySQLFramework 的联动SPMySQLFramework.xcodeproj中的MySQL Client Libraries文件组引用这三份 dylibproject.pbxproj工程的MACOSX_DEPLOYMENT_TARGET 13.5与脚本中的DEPLOYMENT_TARGET保持同步脚本注释也要求三者——Xcode 工程、OpenSSL 脚本、MySQL 脚本——共同钉死同一值其 post-build 脚本会对链接进SPMySQL的 dylib 执行install_name_tool把引用改写为loader_path/libcrypto.3.dylib等project.pbxproj。这就是“框架内部loader_path约定”的工程落地。九、何时需要重建适用前提与限制这套配方面向的是“随 Sequel-Ace 分发”的客户端库理解其适用前提有助于避免误用需要macOS 13.5 及以后的最低系统版本承诺——如果你想抬高或降低部署目标必须同时修改两个脚本的DEPLOYMENT_TARGET、Xcode 工程的MACOSX_DEPLOYMENT_TARGET以及 OpenSSL 树的 stamp 校验并全部重建需要Rosetta 2仅 Apple silicon 主机交叉编译 x86_64 片时需要联网下载并校验三个来源的 tarballOpenSSL、MySQL、CMake离线环境无法首次构建产物当前仍以“头文件 lib/三个 dylib lib/mysqlplugins/插件”的形式驻留在 MySQL Client Libraries 目录中插件最终迁移进框架PlugIns目录的接线尚未完成issue #2590因此当前实际运行路径是SPMySQLConnection在运行时显式设置MYSQL_PLUGIN_DIR指向builtInPlugInsPath。十、扩展阅读配方脚本本体build-openssl.sh、build-libmysqlclient.sh包装 targetlibmysqlclient.xcodeproj运行时插件目录设置SPMySQLConnection.m产物布局MySQL Client Libraries、插件目录 lib/mysqlpluginsSPMySQL 框架总览SPMySQLFramework/README.md。赞分享数据库桌面应用开发工具【免费下载链接】Sequel-AceMySQL/MariaDB database management for macOS项目地址https://gitcode.com/gh_mirrors/se/Sequel-Ace点击查看免费下载相关推荐Sequel Ace vs NavicatMacOS上MySQL客户端终极性能对比测试Sequel Ace vs NavicatMacOS上MySQL客户端终极性能对比测试 作为一名数据库管理员或开发者选择一款高效的MySQL客户端工具对工作数据库桌面应用开发工具10分钟彻底改变你的工作方式UI-TARS桌面版零代码实现智能GUI自动化完整指南10分钟彻底改变你的工作方式UI TARS桌面版零代码实现智能GUI自动化完整指南 痛点洞察篇你的时间正在被这些重复性任务消耗 每天面对计算机你是否经历过人工智能大模型AI Agent桌面应用GUI 自动化浏览器控制MCP 服务MCP Clients企业级部署every-chatgpt-gui自建ChatGPT客户端的架构方案企业级部署every chatgpt gui自建ChatGPT客户端的架构方案 随着AI在企业应用中的普及自建ChatGPT客户端已成为企业提升工作效率和数上一篇【免费下载】 探索未来互动新体验Live2D AI 项目详解下一篇agent-orchestrator 项目注册的等价路径去重机制PR 4928 回归验证解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表