Repository navigation
Releases: wangwanjie/NoCompile
Release list
NoCompile v0.2.13
NoCompile 0.2.13
修复
- pod install / update 后控制台一直刷头文件分析,只能重启 NoCompile 才恢复:依赖工具一次改写成千上万个文件时,引擎逐个分析每个头文件,期间打开的文件描述符没有及时释放,最终耗尽进程上限(默认 256)。之后重新打开工程时读不到目录、文件基线为空,被碰到的每个文件都被当成新增文件。现在:
- 一批改动超过 100 个文件时,在分析头文件之前就跳过并提示重新编译,不再堵住引擎
- 子进程调用不再滞留描述符,启动时把打开文件数上限提高到 10240
- 扫描工程目录失败时不再建立空基线,会自动重试
- 读不到工程目录时按实际原因提示,描述符耗尽时不再误导去开隐私授权
- 依赖工具原样重写的文件被当成改动:pod install / update、git checkout 等会把内容没变的文件重新写一遍。现在文件基线会记录内容摘要,内容没变的文件不再触发热重载。摘要缓存在
~/Library/Caches/NoCompile/FileDigests,再次启动时直接复用;首次启动在后台计算,十万个文件约 1 秒 - 菜单栏图标在引擎未启动时显示为黑色的问题
升级提示
- 升级后无需改动工程,已编译的 App 仍可正常热重载
下载
| 芯片 | 文件 | 大小 | SHA-256 |
|---|---|---|---|
| Apple 芯片(M 系列) | NoCompile_v0.2.13_arm64.dmg | 3.6M | 9c93b3050bd0adbb5b06a479f10bb1cfd8c1d1b4d5a040c652e673cfdb7e8987 |
| Intel | NoCompile_v0.2.13_x86_64.dmg | 3.7M | faa71a75ded3f31d14bf5541551595fc19cc129346bc69d110daa24b70256703 |
不确定芯片类型:点击屏幕左上角的苹果菜单 → 关于本机,「芯片」一栏显示 Apple M 系列即选 arm64,显示 Intel 即选 x86_64。
NoCompile v0.2.12
NoCompile 0.2.12
修复
- 「拷贝 bundle」方式接入后工程编译失败:
[NoCompile] Copy Bundle阶段报IDENTITY\357: unbound variable与Command PhaseScriptExecution failed with a nonzero exit code。Xcode 用系统自带的 bash 3.2 执行 Run Script,在 UTF-8 环境下它会把紧跟变量名的中文全角字符当成变量名的一部分,nocompile_copy_bundle.sh因此在签名完成后退出。已修复所有同类写法,并新增测试防止再次出现
升级提示
- 升级后直接重新编译即可,Run Script 调用的是 NoCompile.app 内的新脚本,工程无需改动
- 客户端修订号没有变化,已编译的 App 仍可正常热重载
下载
| 芯片 | 文件 | 大小 | SHA-256 |
|---|---|---|---|
| Apple 芯片(M 系列) | NoCompile_v0.2.12_arm64.dmg | 3.5M | 5f9bdc98326160746689d97777d5cd11972388e6f50ad52b399b9d57dca9ca61 |
| Intel | NoCompile_v0.2.12_x86_64.dmg | 3.7M | 209f66da7f0f7dee79903d71b6e36213be39aaa5c95b28554e0237f484ab7e68 |
不确定芯片类型:点击屏幕左上角的苹果菜单 → 关于本机,「芯片」一栏显示 Apple M 系列即选 arm64,显示 Intel 即选 x86_64。
NoCompile v0.2.11
NoCompile 0.2.11
修复
- Podfile 钩子接入后看不到链接参数和 Run Script:启用了
cocoapods-arm64-to-sim等会在post_integrate中保存工程的 CocoaPods 插件时,插件在 Podfile 钩子之后执行,用内存中的旧工程覆盖了nocompile_setup.py对project.pbxproj的修改,只剩 AppDelegate 里的加载代码。--install-pod-hook生成的钩子改为在pod install成功结束、所有钩子执行完后再接入
升级提示
- 用 0.2.10 生成或照抄了旧钩子的 Podfile,需要换成新钩子:删掉旧的
post_integrate钩子后重新运行
/Applications/NoCompile.app/Contents/Resources/nocompile_setup.py --uninstall-pod-hook # 去掉带标记的旧钩子;手动粘贴的需手动删除
/Applications/NoCompile.app/Contents/Resources/nocompile_setup.py --install-pod-hook- 客户端修订号没有变化,已编译的 App 仍可正常热重载,无需重新编译
详见 接入指南 · 一键接入脚本。
下载
| 芯片 | 文件 | 大小 | SHA-256 |
|---|---|---|---|
| Apple 芯片(M 系列) | NoCompile_v0.2.11_arm64.dmg | 3.5M | 538d2bb587b36d8c3b2566c17d3dbc99d731888962e2235246030692ca374b05 |
| Intel | NoCompile_v0.2.11_x86_64.dmg | 3.7M | 1661aa544d9935958524e1fa2f4a57a694d32d4f19ad4265a3e7bee58164218b |
不确定芯片类型:点击屏幕左上角的苹果菜单 → 关于本机,「芯片」一栏显示 Apple M 系列即选 arm64,显示 Intel 即选 x86_64。
NoCompile v0.2.10
NoCompile 0.2.10
本版本新增一键接入脚本,解决「接入改动不能提交、每次切换分支都要重新设置」的问题。
新功能
- 一键接入脚本
nocompile_setup.py(位于NoCompile.app/Contents/Resources):在工程目录运行即可完成「拷贝 bundle」方式的全部接入,只作用于 App 类型 target 的 Debug 配置- Other Linker Flags 追加
-Xlinker -interposable;清空EXPORTED_SYMBOLS_FILE(例如只导出_main的工程,可用--keep-exported-symbols保留);关闭ENABLE_USER_SCRIPT_SANDBOXING - Build Phases 末尾添加 Run Script「[NoCompile] Copy Bundle」
- 在
didFinishLaunchingWithOptions、applicationDidFinishLaunching或 SwiftUIApp的init()最前面插入加载代码,自动区分 Swift / Objective-C 与 iOS / tvOS / macOS、模拟器 / 真机 - 所有改动都带标记,
--remove原样撤销,不影响工程里的其他改动;重复运行会跳过已接入的部分
- Other Linker Flags 追加
- CocoaPods 钩子:
nocompile_setup.py --install-pod-hook在 Podfile 添加一个可以提交的post_integrate钩子。本机export IntegrateNoCompile=true后,pod install会自动接入;未设置时自动撤销;没装 NoCompile.app 的同事不受影响
/Applications/NoCompile.app/Contents/Resources/nocompile_setup.py # 在工程目录运行,接入
/Applications/NoCompile.app/Contents/Resources/nocompile_setup.py --remove # 切换分支前撤销升级提示
- 客户端修订号没有变化,已编译的 App 仍可正常热重载,无需重新编译
详见 接入指南 · 一键接入脚本。
下载
| 芯片 | 文件 | 大小 | SHA-256 |
|---|---|---|---|
| Apple 芯片(M 系列) | NoCompile_v0.2.10_arm64.dmg | 4.5M | dd397e18d3d373442a4dcffeb1fc34173a653d01f5f00822da4450f1da35b33c |
| Intel | NoCompile_v0.2.10_x86_64.dmg | 4.7M | 95c345a8342a84a23c9d7b0d6f4d2ae06f4bc7cfe3f09d73f1c2aac9152d104e |
不确定芯片类型:点击屏幕左上角的苹果菜单 → 关于本机,「芯片」一栏显示 Apple M 系列即选 arm64,显示 Intel 即选 x86_64。
NoCompile v0.2.9
NoCompile 0.2.9
本版本是一次全面的代码审查与加固:修复了连接、日志解析、资源热重载、注入中的多处缺陷,补齐了单元测试,并改进了按芯片分发的安装包。
修复
- 私有类的改动不生效:
private/fileprivate的 Swift 类,以及开启-fvisibility=hidden或EXPORTED_SYMBOLS_FILE的工程里的 ObjC 类,改了方法体后注入报「未替换任何实现」。现在改用符号表中的地址定位这些类 - 真机上修改颜色集(.colorset)必定失败,提示「资源包缺少文件」
- 名称带设备后缀的资源(如
icon@2x~ipad.png、Main~iphone.xib)保存后不触发热重载 - 颜色集以 0–255 整数填写分量时颜色错误
swiftc -###输出中单引号包裹的参数(如-Xcc '-DM=a\b')里的反斜杠被吞掉,宏值被改写- 推送途中连接断开时,改动被误记为「已应用」,同一进程重连后不再补推。现在收到 App 回报后才登记
- Wi-Fi 连接在 Mac 休眠或设备断网后变成半开连接,两端都不会重连。两端已开启 TCP 保活,约 1 分钟内判定断开并自动重连
- 模拟器 App 刚连上就崩溃等情况下,Mac 端停止接受所有新连接,之后的 App 都连不上
- 切换工程的瞬间连上的连接不会被关闭、一直占着设备
- 构建日志解析中途失败(超时、Xcode 正在写入)后被记为已解析,之后一直提示「请先完整构建」
- 偏好设置在主线程修改、在引擎线程读取的数据竞争,可能导致崩溃
- tvOS 真机的编译命令被归为未知平台,无法热重载
- 自定义了带连字符配置名(如
Debug-Staging)的 macOS 工程,资源找不到所属的 bundle - 消息中含无法序列化为 JSON 的内容时 App 或 Mac 端崩溃
- 在主线程发起注入时可能死锁;
+load中用method_setImplementation/class_replaceMethod写的 hook 在注入时被重复安装 - 方法实现的符号被剥离时,新实现可能被写到无关的方法上
- 真机写入 dylib 失败(存储空间不足)时给出误导性的错误
- 打开已被移动或删除的最近工程时没有任何提示;恢复默认设置后 DerivedData、排除规则不生效;「登录时自动启动」开关会重复注册 / 注销;系统睡眠唤醒后被误判为主线程卡顿
- 命令行工具静默忽略拼错的参数,现在报错退出;支持
nocompile <工程路径>、--version,Ctrl+C 时先停止引擎再退出
新功能
- 注入记录右键「在 Xcode 中打开」,编译失败时直接定位到第一条错误所在的行
- Mac Catalyst App(实验性):与 macOS App 一样连接本机 NoCompile
- 在 Apple 芯片的 Mac 上运行 Intel 版时给出提示,检查更新时自动换成 arm64 版本
- 最近工程菜单标出已不存在的工程,并可一键清空
- 偏好设置显示当前安装包的架构
分发
- 每个 Release 额外提供不带版本号的
NoCompile_arm64.dmg/NoCompile_x86_64.dmg,README 中的下载链接始终指向最新版,并附SHA256SUMS.txt - arm64 包中的 Sparkle 等依赖也精简为单一架构,打包时逐个校验所有二进制的架构、客户端 bundle 的完整性与版本
- Sparkle feed 保留全部历史版本,发布后自动校验下载地址
测试
- 新增单元测试(
swift test):构建日志解析、命令分词、协议帧编解码、构建清单、头文件改动分析、版本号一致性,以及客户端的帧收发、ObjC 方法替换、布局变化保护等
升级提示
- 客户端修订号没有变化,已编译的 App 仍可正常热重载。要用上客户端侧的修复(私有类、颜色集、Wi-Fi 保活等),请重新编译运行 App;用「拷贝 bundle」方式接入的,确认这次构建执行了
nocompile_copy_bundle.sh
详见 接入指南。
下载
| 芯片 | 文件 | 大小 | SHA-256 |
|---|---|---|---|
| Apple 芯片(M 系列) | NoCompile_v0.2.9_arm64.dmg | 3.5M | 94ba16555aa57ee48580b6470ed94a6448a3ae17dfd6f45182af347be750cca7 |
| Intel | NoCompile_v0.2.9_x86_64.dmg | 4.7M | 10a62a8db0d6f03cce6d24934028a66ad8c9bb0e18827577fc3eede59237065a |
不确定芯片类型:点击屏幕左上角的苹果菜单 → 关于本机,「芯片」一栏显示 Apple M 系列即选 arm64,显示 Intel 即选 x86_64。
NoCompile v0.2.8
NoCompile 0.2.8
修复
- 真机注入报「存在未解析符号」(symbol not found in flat namespace):工程在 Debug 下也设置了
EXPORTED_SYMBOLS_FILE(例如只导出_main)或-fvisibility=hidden时,App 里的类、函数、常量都不在导出表中,注入的 dylib 加载失败。现在 Mac 端会从 DerivedData 中与 App 相同 UUID 的二进制里找到这些符号,按 App 运行时的地址生成一个小的「符号桥接」dylib,先于注入 dylib 加载,日志中显示「桥接 N 个 App 未导出的符号」 - App 启动后很久才显示「已连接」:解析构建日志与构建清单改在后台进行,头文件依赖索引在后台重建、重建期间沿用旧索引,大型工程刚构建完时 App 也能立即完成握手
- 同一个 App 进程重新连接(网络抖动、重新插拔数据线)时不再把已推送过的改动再推一遍
- 同时运行两个 NoCompile 时,后启动的实例不再连接真机,避免两个实例互相顶掉设备上的连接
文档
- 接入指南「常见问题」新增「存在未解析符号」的说明
升级提示
- 客户端修订号没有变化,已编译的 App 仍可正常热重载。符号桥接需要新版客户端在握手时上报镜像信息,App 未导出符号的工程请重新编译运行 App;用「拷贝 bundle」方式接入的,确认这次构建执行了
nocompile_copy_bundle.sh,把新 bundle 拷进了 App
详见 接入指南。
NoCompile v0.2.7
NoCompile 0.2.7
变更
- 真机显示设备名称:设备列表、日志与注入记录中的真机改为显示 Xcode 中的设备名称(如「张三的 iPhone 16 Pro」),多台真机可以区分。iOS 16 起 App 内只能拿到「iPhone」,现由 Mac 端直接从设备读取
- 真机连不上时给出提示:USB 连接的真机上持续没有 NoCompile 客户端在运行时,控制台会提示一次;若当前工程从
/Applications/NoCompile.app加载客户端,会说明真机需要改用「拷贝 bundle」方式接入 - 真机诊断脚本:新增
Scripts/diagnose_device.sh,一键收集 usbmuxd、设备端口与 NoCompile 日志,判断真机卡在哪一步
修复
- usbmuxd 请求增加超时,避免一次无响应的请求让真机轮询永久停住
- 同一台设备同时以 USB 与网络方式出现时优先走 USB,不再被网络连接拖慢
- 本地 Pod 根目录下不属于 App 的源文件不再被当作新增文件重编
文档
- 明确「从 NoCompile.app 加载 bundle」(
bundleWithPath:@"/Applications/NoCompile.app/...")与DYLD_INSERT_LIBRARIES只适用于模拟器 / macOS,真机上会静默失败。要在真机热重载,请改用「拷贝 bundle」(Run Script 调用nocompile_copy_bundle.sh,再加载 App 内的NoCompile.bundle)或 CocoaPods / SPM - 接入指南新增「真机连不上」排查章节
客户端没有不兼容变化,已编译的 App 无需重新编译。
详见 接入指南。
NoCompile v0.2.6
NoCompile 0.2.6
变更
- 多设备切换与补推:每台设备接入一个 App,只向当前选中的设备推送热重载;切换设备或 App 重新运行后,自动补推缺少的改动
- 控制台日志分类着色:日志按类别加 emoji 与彩色标签,重复日志合并显示;最近工程下显示所在目录
- 检查改动:顶栏新增「检查改动」按钮,并支持全局快捷键(默认 ⌃⌥⌘R)
- 主界面去掉「保存即注入」开关:改动检测统一由 Mac 端处理
- 其他工程的 App 不再接入:同名工程副本或其他工程运行的 App 不会再被接入,也不再每 2 秒重连刷屏
修复
- 文件监听改为按文件指纹判定改动,修复 Xcode 保存后偶发漏检
- 从构建清单补全编译命令:Xcode 清理旧构建日志后,大部分 ObjC 文件仍可热重载(大型工程此前只能解析到极少数编译命令);编译命令缓存随 Xcode 版本失效
- 修复热重载频繁崩溃:类的内存布局变化(增删、重排属性或 ivar)时不再替换该类实现,避免越界访问;vtable 按函数名核对后再覆写;+load 中 swizzle 的分类重新注入不再无限递归
- 连接层线程安全,真机监听出错后自动重建
- 修复 SwiftUI
some View类型变化、资源 hook 安装竞态、C++ 函数内静态对象迁移等问题
客户端有以上修复,需要更新依赖并重新编译 App 才能生效;未重新编译的客户端仍可正常热重载,不会被要求重新编译。
详见 接入指南。
NoCompile v0.2.5
NoCompile 0.2.5
变更
- 控制台新增「最近」菜单:顶栏「切换工程」旁可直接选择最近打开的工程快速切换
- 版本兼容判断改按客户端修订号:此前只要 Mac 端版本号与 App 内客户端不同,就会停止热重载并要求重新编译 App;现在只在客户端代码或协议发生不兼容变化时才提示,仅 Mac 端的改动(如本版本)不需要重新编译
修复
- 修复注入后新类的实例收到「定义在其他文件的分类」里的方法时报 unrecognized selector 崩溃:被注入的 dylib 里
alloc出来的是新类的实例,而其他文件的分类只挂在旧类上。现在会把旧类上新类没有的方法(实例方法与类方法)补到新类上 - 示例工程新增场景 B15 覆盖该问题
客户端有这一处修复,需要更新依赖并重新编译 App 才能生效;未更新的 0.2.4 客户端仍可正常热重载,不会被要求重新编译。
详见 接入指南。
NoCompile v0.2.4
NoCompile 0.2.4
变更
- 安装包按芯片拆分:从本版本起分别提供 Apple 芯片(
_arm64)与 Intel(_x86_64)两个 DMG,体积更小;Sparkle 自动更新也按架构分别推送。已安装的旧版会自动升级到与本机芯片匹配的版本
修复
- iOS 与 macOS App 同时连接时,只属于其他平台的源文件不再被借用别的模块的编译命令重编(此前会报找不到 AppKit),资源也按平台分别下发,不再报找不到所属 bundle
- CocoaPods
resource_bundles中的 xcassets 能正确判定所属 bundle 并热重载 - 编译命令持久化缓存,Xcode 清理旧构建日志后仍能找到命令;Xcode 显式模块 PCH 不兼容时自建 PCH
- 以
$sSo开头的 Swift 扩展符号不再被误判为标准库符号 - C / ObjC
static变量状态随注入迁移;swizzle 按函数体配对;弱符号正确重绑 - ObjC ivar 布局变化时跳过方法替换,避免越界访问
- 新增符号提升为全局,后注入的 dylib 绑定到最新实现
- framework 头文件副本同步、显式模块头文件依赖,以及按改动的标识符筛选依赖文件
- framework 内资源、strings、json、颜色集支持热重载,修复克隆文件事件导致的循环触发
示例
- 示例工程扩展为多模块 workspace(动态 framework、静态库、本地 SPM)并新增 CocoaPods 版本,附约 120 个场景的端到端自测
升级后请重新编译运行接入了 NoCompile 的 App,CocoaPods / SPM / Carthage 接入的请同时把依赖更新到 0.2.4。
详见 接入指南。