ffi_build

Linux lib<name>.so

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ffi_build" with this command: npx skills add kong-baiming/cangjie-dev/kong-baiming-cangjie-dev-ffi-build

仓颉C互操作配置构建指导

  1. 各平台库文件命名对照

平台 动态库 静态库

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 前缀。请务必熟悉这个规则(实际是规格问题,未来会修复),保证能正常构建和运行。

  1. cjc 编译器链接选项

选项 说明

-L <path> / --library-path <path>

指定库文件搜索目录(优先级高于 LIBRARY_PATH 环境变量)

-l <name> / --library <name>

链接库文件,格式为 lib[name].[extension] (如 -l draw 链接 libdraw.so/.a/.dll )

  1. 使用 cjc 直接编译

2.1 Linux

编译 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

2.2 macOS

编译 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

2.3 Windows

编译 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) 修饰以导出符号。

2.4 安全编译建议

编译 C 代码时应启用栈保护选项,防止缓冲区溢出攻击:

推荐选项(二选一)

clang -fstack-protector-all ... # 全部函数开启栈保护 clang -fstack-protector-strong ... # 对含局部数组/地址操作的函数开启栈保护

  1. 基于 cjpm 项目编译(推荐)

3.1 项目初始化

cjpm init # 初始化项目

3.2 cjpm.toml 配置

在 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 动态/静态库所在路径

3.3 构建与运行

cjpm build # 构建时自动链接 [ffi.c] 设置的 C 库 cjpm run # 构建并运行

3.4 其他相关 cjpm.toml 配置项

配置项 说明 示例

output-type

输出类型 "executable" / "static" / "dynamic"

compile-option

传给 cjc 的额外编译选项 "-O1"

link-option

传给链接器的选项 "-z noexecstack -z relro -z now"

3.5 不同平台的 cjpm.toml 配置

当需要区分不同目标平台的库路径时,可使用 [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\" }

3.6 链接安全加固选项

对于需要安全加固的项目,建议在 link-option 中添加链接器安全标志:

[package] link-option = "-z noexecstack -z relro -z now"

选项 说明

-z noexecstack

禁止栈上执行代码,防止栈溢出攻击

-z relro

设置 GOT 为只读,防止 GOT 覆写攻击

-z now

立即绑定所有符号,配合 relro 使用

  1. 完整示例

4.1 Linux 完整编译流程

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

4.2 Windows 完整编译流程

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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

inner_annotation

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

struct

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

convert

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

unittest

No summary provided by upstream source.

Repository SourceNeeds Review