imfuxiao / LibrimeKit

librime to ios. use swift package manager.
19 stars 11 forks source link

发布的 Frameworks 文件缺少对 Apple Silicon 电脑的支持 #6

Closed tansongchen closed 12 months ago

tansongchen commented 1 year ago

我用的是 M2 Max 的 Mac Studio,目前无法编译运行仓的主程序,因为 LibrimeKit 没有发布针对 Apple Silicon 电脑的库版本

image

所以对于 librime,需要增加 export PLATFORM=SIMULATORARM64 以及相关编译。

而对于 librime 的依赖,是用 lipo 提取 arm64x86_64 的代码,没有看到 simulator 相关选项,是不是 arm64 的依赖也可以用于 Apple Silicon 电脑上的 simulator?

imfuxiao commented 1 year ago

抱歉,我用的还是 intel x86 设备,所以无法对 M 系列做测试。

不过我看之前关闭的 issue 里面有用 m 系列的伙伴做过编译,arm64应该是可以使用的。最好是能在 m 系列设备的模拟器上测试下。

tansongchen commented 1 year ago

这个 issue https://github.com/imfuxiao/LibrimeKit/issues/4 里从报错信息可以看出他用的应该还是 2.0 版本以前的 LibrimeKit,更新了之后可能不一样。

我观察到以下现象:

如果提供给 xcodebuild 的是一个 FAT library,那生成的应该是 ios-arm64_x86_64-simulator,现在只有 ios-x86_64-simulator 说明编译 librime 及各依赖时没有生成给 Apple Silicon 上 simulator 的代码

imfuxiao commented 1 year ago

这个 issue #4 里从报错信息可以看出他用的应该还是 2.0 版本以前的 LibrimeKit,更新了之后可能不一样。

我观察到以下现象:

  • boost-iosx 编译得到的各个 xcframework 文件夹里都有个子文件叫作 ios-arm64_x86_64-simulator
  • librime.xcframework 以及它的各个依赖里只有 ios-x86_64-simulator

如果提供给 xcodebuild 的是一个 FAT library,那生成的应该是 ios-arm64_x86_64-simulator,现在只有 ios-x86_64-simulator 说明编译 librime 及各依赖时没有生成给 Apple Silicon 上 simulator 的代码

FAT lib 我记得是有问题的,在用 Framwork 后,就不需要 FAT lib 了,可以尝试在编译脚本中加上SIMULATORARM64: to build for iOS simulator 64 bit (arm64) 这个参数试试。

tansongchen commented 1 year ago

然后我修改了一下 librime.xcframework 生成的代码,加入一次 export PLATFORM=SIMULATORARM64 的编译后,确实能得到 ios-arm64_x86_64-simulator。但是对于依赖来说,在脚本里没有指定 simulator 的平台,让我有些困惑。这两个的逻辑为什么不一样?

imfuxiao commented 1 year ago

然后我修改了一下 librime.xcframework 生成的代码,加入一次 export PLATFORM=SIMULATORARM64 的编译后,确实能得到 ios-arm64_x86_64-simulator。但是对于依赖来说,在脚本里没有指定 simulator 的平台,让我有些困惑。这两个的逻辑为什么不一样?

你指哪两个逻辑?

tansongchen commented 1 year ago

就是说 librime 编译的方式是依次指定 PLATFORM=OS64, SIMULATORARM64, SIMULATOR64,然后将三次不同的 librime.a 收集起来做成 Framework;但是它的依赖,比如 libglog 编译的方式是一次就生成一个包含多种二进制代码的文件,然后用 lipo 分解之后做成 Framework。

对于 librime 本身来说我已经能用 export PLATFORM=SIMULATORARM64 来生成合适的 Framework,但是对于依赖来说因为没有指定 simulator 平台的地方,所以无法用这种方法

imfuxiao commented 1 year ago

这是因为在编译依赖包的时候在参数中指定了编译参数。xcode.mk 51 行,所以编译出来是个 FAT lib。完了在拆成两个不同的 lib 制作出 framework.

tansongchen commented 1 year ago

我也注意到这个选项了,按理说 -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" 应该能让产生的库同时包含 x86_64 simulator 和 arm64 simulator 的代码,但是不知道为什么得到的那个 Framework 文件就是没有 arm64 的。

另外 xcodebuild 是可以接受 FAT lib 作为输入的,前提是这个 FAT 包含的是针对同一平台(如 macOS)的不同架构(arm64, x86_64)的代码,而且似乎对于 simulator 来说输入必须是一个 FAT lib,参考 https://github.com/apotocki/boost-iosx/blob/master/scripts/build.sh#L261 ,这里 boost 就是先把各个架构的 simulator 合并成一个 FAT 然后传给 xcodebuild 的。而我们 build 出来的那个 libglog.a,好像只含有 iOS arm64 的代码以及 macOS simulator x86_64 的代码,而没有 macOS simulator arm64 的代码,这是我目前没有搞明白的地方……

tansongchen commented 1 year ago

经过又一些排查我悟了,

https://cmake.org/cmake/help/latest/prop_tgt/IOS_INSTALL_COMBINED.html

这里面说 IOS_INSTALL_COMBINED 这个选项已弃用,因为它合并 ios 和 simulator 的代码之后,会无法识别出 arm64 simulator 的代码,原因是

Universal binaries can only differentiate code based on CPU type, so this only made sense before the days of arm64 macOS machines (i.e. iOS Simulator/arm64).

所以要想支持 Apple Silicon 做开发,只能把它改成像 librime.a 一样的分别编译了。

如果对这个解决方案没有意见的话,我可以再开一个 pr 来搞这部分

imfuxiao commented 1 year ago

经过又一些排查我悟了,

https://cmake.org/cmake/help/latest/prop_tgt/IOS_INSTALL_COMBINED.html

这里面说 IOS_INSTALL_COMBINED 这个选项已弃用,因为它合并 ios 和 simulator 的代码之后,会无法识别出 arm64 simulator 的代码,原因是

Universal binaries can only differentiate code based on CPU type, so this only made sense before the days of arm64 macOS machines (i.e. iOS Simulator/arm64).

所以要想支持 Apple Silicon 做开发,只能把它改成像 librime.a 一样的分别编译了。

如果对这个解决方案没有意见的话,我可以再开一个 pr 来搞这部分

赞~,可以的,因为我本地是 x86 环境,所以 m 系列一直没做关注。

我刚看了 build.sh, 注意到 build_sim_libs 函数编译 simulator 部分,应该是把 arm64 与 x86 合并起来的。

# 206 行
-arch $1

# 243 行
    build_sim_libs arm64
    build_sim_libs x86_64
tansongchen commented 12 months ago

今天尝试了下载 GitHub Action 上的 2.2.0 Frameworks 文件并编译 Hamster,Rosetta 和原生都出现下面的错误:

/Users/tansongchen/Public/Hamster/Packages/RimeKit/Sources/ObjC/irime_api.m:2:9 'rime_api.h' file not found

可能是因为 Hamster 仓库与你本地的代码不同,需要等你更新代码之后再测试

tansongchen commented 12 months ago

这个问题看起来与 #4 遇到的相同,但是我用的是最新的 macOS 14.1.1 和 Xcode 15.0.1,应该不是环境的问题

image
imfuxiao commented 12 months ago

今天尝试了下载 GitHub Action 上的 2.2.0 Frameworks 文件并编译 Hamster,Rosetta 和原生都出现下面的错误:

/Users/tansongchen/Public/Hamster/Packages/RimeKit/Sources/ObjC/irime_api.m:2:9 'rime_api.h' file not found

可能是因为 Hamster 仓库与你本地的代码不同,需要等你更新代码之后再测试

嗯嗯,代码的问题,代码目前做了变更,还没提交,framework 里面没有头文件了,修改后的代码中的导入头文件路径改为相对路径了,irime_api.m 改动后的代码

#import "../C/rime_api.h"
#import "../C/rime_levers_api.h"
tansongchen commented 12 months ago

感谢,改完这两行之后 iPhone 15 和 iPhone 15 (Rosetta) 都能成功编译运行了。

imfuxiao commented 12 months ago

感谢,改完这两行之后 iPhone 15 和 iPhone 15 (Rosetta) 都能成功编译运行了。

赞,感谢你提交的 PR。