一段代码,两个系统:仓颉怎么处理「跨平台」这件事
内容提要
仓颉跨平台提供三种工具:@When条件编译按函数或声明筛选代码,最简单实用;source-set按目录区分平台,但属实验特性,会迫使使用者开启experimental,影响构建与测试;common/specific用于声明跨平台接口契约与各平台实现。真实项目mmap-cj因source-set拖累使用者,最终切回@When。建议初学者优先用@When。
延伸解读
实验特性带来的连锁成本
source-set 目前是实验特性,使用者必须开启 experimental 才能编译。mmap-cj 的案例显示,这会让依赖它的项目也被迫打开开关,甚至导致 cjpm test 失败。对库作者而言,选择实验特性不只是自己的技术选型,还会把成本转嫁给所有下游用户。
三种工具的选择逻辑
文章对比了 @When、source-set 和 common/specific 的粒度:@When 针对单个函数或声明,source-set 针对整个目录,common/specific 用于声明跨平台接口契约。选择时需权衡代码整洁度与使用者负担,尤其发布给他人使用的库应优先考虑兼容性。
常见错误与排查提示
初学者容易混淆 @When 中的 "Linux"(首字母大写)与 cjpm 配置中的 os.linux(小写点分)。此外,@When 不能叠加,需用 && 合并条件;common 函数若只写签名则必须提供 specific 实现,否则会报函数体缺失或找不到匹配。
Q&A
仓颉处理跨平台有哪几种方式?
仓颉提供三种跨平台工具:@When条件编译、source-set按目录区分平台、common/specific声明接口契约与实现。
@When条件编译怎么用?
@When根据条件决定代码是否参与编译,例如@When[os == "Linux"]修饰函数,只有目标系统为Linux时该函数才被编译。条件可包括os、arch、backend、debug、test,支持!=取反,多个条件用&&组合。
source-set和common/specific有什么区别?
source-set按目录区分平台,整个目录只在特定平台编译;common/specific用于声明跨平台接口契约与各平台实现,common定义接口,specific提供具体实现。两者可配合使用。
为什么mmap-cj项目从source-set切回@When?
因为source-set是实验特性,使用者必须开启experimental才能编译,且会导致cjpm test失败。切回@When后,使用者无需任何额外配置即可正常构建和测试。
初学者应该优先学哪种跨平台方式?
建议优先学习@When条件编译,它最简单、最不容易出错,且不需要实验开关,是目前最实用的方式。
使用source-set有哪些坑?
常见坑包括:公共文件忘记加@NonProduct标记、两个目录写了相同features、main函数写在公共目录、公共文件里写了没有函数体的函数(需加common)。此外,source-set是实验特性,会迫使使用者开启experimental,且可能导致cjpm test失败。