원클릭으로
cangjie-ffi-build
仓颉FFI/C互操作配置构建指导。当需要了解仓颉 C 互操作项目的配置/构建/运行方法(包括动态库、静态库及不同平台),应使用此 Skill
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
仓颉FFI/C互操作配置构建指导。当需要了解仓颉 C 互操作项目的配置/构建/运行方法(包括动态库、静态库及不同平台),应使用此 Skill
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
| name | cangjie-ffi-build |
| description | 仓颉FFI/C互操作配置构建指导。当需要了解仓颉 C 互操作项目的配置/构建/运行方法(包括动态库、静态库及不同平台),应使用此 Skill |
| 平台 | 动态库 | 静态库 |
|---|---|---|
| Linux | lib<name>.so | lib<name>.a |
| macOS | lib<name>.dylib | lib<name>.a |
| Windows | lib<name>.dll | lib<name>.lib |
注意:Windows 平台上依赖动态库,目前 cjc 和 cjpm 实现有差异:编译时,cjc 对动态库是否有
lib前缀不敏感,cjpm 则要求动态库必须有lib前缀。运行时,cjc 编出的可执行文件,依赖的动态库必须加上lib前缀,而 cjpm 构建出的可执行文件,依赖的动态库一定不能有lib前缀。请务必熟悉这个规则(实际是规格问题,未来会修复),保证能正常构建和运行。
| 选项 | 说明 |
|---|---|
-L <path> / --library-path <path> | 指定库文件搜索目录(优先级高于 LIBRARY_PATH 环境变量) |
-l <name> / --library <name> | 链接库文件,格式为 lib[name].[extension](如 -l draw 链接 libdraw.so/.a/.dll) |
# 编译 C 代码为动态库
clang -shared -fPIC -fstack-protector-all native.c -o libnative.so
# 编译 C 代码为静态库
clang -c -fstack-protector-all native.c -o native.o && ar rcs libnative.a native.o
# 编译仓颉代码并链接
cjc -L . -l native main.cj -o main
# 运行(动态库须确保在搜索路径上)
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./main
# 编译 C 代码为动态库
clang -shared -fPIC -fstack-protector-all native.c -o libnative.dylib
# 编译 C 代码为静态库
clang -c -fstack-protector-all native.c -o native.o && ar rcs libnative.a native.o
# 编译仓颉代码并链接
cjc -L . -l native main.cj -o main
# 运行(动态库须确保在搜索路径上)
export DYLD_LIBRARY_PATH=.:$DYLD_LIBRARY_PATH
./main
# 编译 C 代码为动态库(导出函数需加 __declspec(dllexport) 修饰)
clang -shared -fstack-protector-all native.c -o libnative.dll
# 编译仓颉代码并链接
cjc -L . -l native main.cj -o main.exe
# 运行(动态库须确保在搜索路径上)
./main.exe
注意:Windows 平台上 C 函数需使用
__declspec(dllexport)修饰以导出符号。
编译 C 代码时应启用栈保护选项,防止缓冲区溢出攻击:
# 推荐选项(二选一)
clang -fstack-protector-all ... # 全部函数开启栈保护
clang -fstack-protector-strong ... # 对含局部数组/地址操作的函数开启栈保护
cjpm init # 初始化项目
在 cjpm.toml 中通过 [ffi.c] 节配置 C 库依赖:
[package]
name = "myproject"
cjc-version = "1.0.5"
version = "1.0.0"
output-type = "executable"
[ffi.c]
native = { path = "./libs/" } # path 是 C 动态/静态库所在路径
cjpm build # 构建时自动链接 [ffi.c] 设置的 C 库
cjpm run # 构建并运行
| 配置项 | 说明 | 示例 |
|---|---|---|
output-type | 输出类型 | "executable" / "static" / "dynamic" |
compile-option | 传给 cjc 的额外编译选项 | "-O1" |
link-option | 传给链接器的选项 | "-z noexecstack -z relro -z now" |
当需要区分不同目标平台的库路径时,可使用 [target] 节:
Linux x86_64:
[ffi.c]
native = { path = "./libs/linux_x86_64/" }
macOS aarch64:
[ffi.c]
native = { path = "./libs/macos_aarch64/" }
Windows x86_64:
[ffi.c]
native = { path = ".\\libs\\windows_x86_64\\" }
对于需要安全加固的项目,建议在 link-option 中添加链接器安全标志:
[package]
link-option = "-z noexecstack -z relro -z now"
| 选项 | 说明 |
|---|---|
-z noexecstack | 禁止栈上执行代码,防止栈溢出攻击 |
-z relro | 设置 GOT 为只读,防止 GOT 覆写攻击 |
-z now | 立即绑定所有符号,配合 relro 使用 |
# 1. 编写 C 代码 (native.c)
# 2. 编译 C 代码为动态库
clang -shared -fPIC -fstack-protector-all native.c -o libnative.so
# 3. 使用 cjc 直接编译
cjc -L . -l native main.cj -o main
./main
# 或使用 cjpm 项目编译
# 将 libnative.so 放到 libs/ 目录下
# 在 cjpm.toml 中配置 [ffi.c] native = { path = "./libs/" }
cjpm build && cjpm run
# 1. 编写 C 代码 (native.c),导出函数加 __declspec(dllexport) 修饰
# 2. 编译 C 代码为动态库
clang -shared -fstack-protector-all native.c -o libnative.dll
# 3.1 使用 cjc 编译
cjc -L . -l native main.cj -o main.exe
./main.exe
# 3.2 基于 cjpm 项目构建
# 将 libnative.dll 放到 libs/ 目录下(用于编译链接)
# 基于前面提到的运行问题,libs/ 下还应放一个名为 native.dll 的副本
# 在 cjpm.toml 中配置 [ffi.c] native = { path = "./libs/" }
# 构建,依赖 libnative.dll
cjpm build
# 运行,依赖 native.dll
cjpm run
SOC 직업 분류 기준
当需要构建鸿蒙应用项目时,使用此 Skill 执行构建流程。此 Skill 包含完整的构建命令、构建流程说明、构建失败处理流程。构建脚本会自动执行依赖安装、仓颉预编译、资源生成、编译、打包等步骤。
在鸿蒙应用(Cangjie)开发中,当需要使用 stdx 拓展库(如 crypto、encoding、net、log、actors 等),或在构建/链接阶段出现 stdx 相关错误时,使用此 Skill 获取/解压 stdx 包,并指导在 entry/cjpm.toml 中正确配置 bin-dependencies.path-option。
在进行仓颉工程或鸿蒙应用开发时的第一步,应该优先读取该SKILL,用来确定后续的开发步骤。
仓颉语言内置注解。当需要了解仓颉 SDK 提供的内置注解(@sourcePackage/@sourceFile/@sourceLine/@When/@FastNative/@Frozen/@Attribute/@Deprecated)的用途、语法和最优实践时,应使用此 Skill。
仓颉语言附录参考。当需要查阅仓颉语言的关键字列表、运算符优先级与结合性、运算符重载函数签名、运行时环境变量配置、包兼容性规则、TokenKind枚举类型时,应使用此 Skill。
仓颉标准库 Array 类型详细指南。当需要了解 Array 的构造、元素访问、切片、拼接、查找、排序、拷贝、反转、映射、扁平化等操作的完整 API 和用法时,应使用此 Skill。