Zxilly
Calm down
Zxilly's Blog

修复仓颉在 macOS 26 上构建时的 missing SG_READ_ONLY flag 错误

起因

当使用仓颉 1.0.3 在 macOS 26 Tahoe 上构建二进制时,运行构建的二进制会提示错误

bash-3.2$ ./target/release/bin/main
dyld[29505]: __DATA_CONST segment missing SG_READ_ONLY flag in /Users/runner/work/action/action/cjtest/target/release/bin/main
dyld[29505]: __DATA_CONST segment missing SG_READ_ONLY flag
Abort trap: 6

原因

查看 macho dyld 源码 可知

if ( !isDylibStub() && policy.enforceDataSegmentPermissions() ) {
    if ( (strcmp(seg->segname, "__DATA") == 0) && (seg->initprot != (VM_PROT_READ | VM_PROT_WRITE)) )
        return Error("__DATA segment permissions is not 'rw-'");
    if ( strcmp(seg->segname, "__DATA_CONST") == 0 ) {
        if ( seg->initprot != (VM_PROT_READ | VM_PROT_WRITE) )
            return Error("__DATA_CONST segment permissions is not 'rw-'");
        if ( (seg->flags & SG_READ_ONLY) == 0 ) {
            bool isSplitSegMarker = false;
            if ( this->isDylibOrStub() && this->hasSplitSegInfo(isSplitSegMarker) && !isSplitSegMarker ) {
                // dylibs intended for dyld cache are allowed to not have SG_READ_ONLY set
            }
            else if ( this->inDyldCache() ) {
                // dylibs in dyld cache are allowed to not have SG_READ_ONLY set
            }
            else if ( this->isStaticExecutable() ) {
                // static excutables don't use dyld so have no way to make DATA_CONST read-only
            }
            else if ( policy.enforceDataConstSegmentPermissions() ) {
                return Error("__DATA_CONST segment missing SG_READ_ONLY flag");
            }
        }
    }
}

policy.enforceDataConstSegmentPermissions() 返回 true 时,__DATA_CONST 应该被正确的设置 bit 位 SG_READ_ONLY,否则则无法链接。 据 LLVM 社区报告,苹果应该在 macOS 13 已经启用了该功能,但是更加广泛的限制直到 macOS 26 才被启用。

查看 policy.enforceDataConstSegmentPermissions() 的逻辑可知

bool Policy::enforceDataConstSegmentPermissions() const
{
    // dylibs in shared region don't set SG_READ_ONLY because of __objc_const
    if ( _pathMayBeInSharedCache )
        return false;
    return (_enforcementEpoch >= Platform::Epoch::spring2025);
}

macOS 26.0 对应的是 fall2025,因此触发了这个错误。

Workaround

修复此错误需要对编译器本体进行改动,由于仓颉的后端使用 LLVM 15,可能需要从新版本 backport 特性。当前可用的 workaroud 是在 link-option 中指定 -no_data_const,彻底禁用 __DATA_CONST 段。ld.lld64 无法单独设置 segment flags,这一变更应该等待仓颉团队实现。

[package]
  cjc-version = "1.0.3"
  name = "test"
  description = "nothing here"
  version = "1.0.0"
  target-dir = ""
  src-dir = ""
  output-type = "executable"
  compile-option = ""
  override-compile-option = ""
  link-option = "-no_data_const"
  package-configuration = {}

[dependencies]

现有行为

添加了 -no_data_const 后,应该可以在 macOS 26 上正确编译运行仓颉二进制了。

bash-3.2$ cat cjpm.toml
[package]
  cjc-version = "1.0.3"
  name = "test"
  description = "nothing here"
  version = "1.0.0"
  target-dir = ""
  src-dir = ""
  output-type = "executable"
  compile-option = ""
  override-compile-option = ""
  link-option = "-no_data_const"
  package-configuration = {}

[dependencies]
bash-3.2$ cjpm build -V
Compiling package `test`: DYLD_LIBRARY_PATH=/Users/runner/hostedtoolcache/cangjie/1.0.3/aarch64/cangjie/runtime/lib/darwin_aarch64_llvm:$DYLD_LIBRARY_PATH cjc -j3 --import-path=/Users/runner/work/action/action/test/target/release --no-sub-pkg --output-dir=/Users/runner/work/action/action/test/target/release/bin --link-options -no_data_const -p /Users/runner/work/action/action/test/src --output-type=exe -o=main
   Finished `build` profile compilation
   Executable files at `/Users/runner/work/action/action/test/target/release/bin`
cjpm build success
bash-3.2$ ./target/release/bin/main
hello world
bash-3.2$ uname -a
Darwin Mac-1761991781781.local 25.0.0 Darwin Kernel Version 25.0.0: Wed Sep 17 21:41:26 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_VMAPPLE arm64
没有标签
首页      代码      修复仓颉在 macOS 26 上构建时的 missing SG_READ_ONLY flag 错误

Zxilly

文章作者

回复 仓颉鼓励师 取消回复

textsms
account_circle
email

Zxilly's Blog

修复仓颉在 macOS 26 上构建时的 missing SG_READ_ONLY flag 错误
起因 当使用仓颉 1.0.3 在 macOS 26 Tahoe 上构建二进制时,运行构建的二进制会提示错误 bash-3.2$ ./target/release/bin/main dyld[29505]: __DATA_CONST segment missing SG_READ_ONLY …
扫描二维码继续阅读
2025-11-01