在aarch64 kylin中测试仓颉语言sdk
·
到仓颉语言网站https://cangjie-lang.cn/download 下载适合自己平台的二进制包。
kylin@kylin-aaa:/data/i$ wget "https://cangjie-lang.cn/v1/files/auth/downLoad?nsId=142267&fileName=cangjie-sdk-linux-aarch64-1.0.5.tar.gz&objectKey=698acfa3bd66ae22b62330b1" -O cj105.tar.gz
2026-08-20 09:55:20 (1.05 MB/s) - 已保存 “cj105.tar.gz” [281794014/281794014])
kylin@kylin-aaa:/data/i$ tar xf cj105.tar.gz
kylin@kylin-aaa:/data/i$ source cangjie/envsetup.sh
kylin@kylin-aaa:/data/i$ cjc -v
cjc: /usr/lib/aarch64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by cjc)
cjc: /usr/lib/aarch64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.11' not found (required by cjc)
解压并设置环境变量后执行cjc,报缺少glibc++动态库错误
kylin@kylin-aaa:/data/i$ sudo docker start p13
p13
kylin@kylin-aaa:/data/i$ sudo docker exec -it p13 bash
root@kylin-aaa:/# cd /par
root@kylin-aaa:/par# source cangjie/envsetup.sh
root@kylin-gtj:/par# cjc -v
Cangjie Compiler: 1.0.5 (cjnative)
Target: aarch64-unknown-linux-gnu
启动一个包含动态库的docker容器,可以执行cjc -v了。
// hello.cj
main() {
println("你好,仓颉")
}
编译源代码hello.cj,结果如下
root@kylin-gtj:/par# cjc hello.cj -o hello
root@kylin-gtj:/par# ./hello
你好,仓颉
还可以用cjpm命令管理一个项目。
root@kylin-gtj:/par# mkdir cj
root@kylin-gtj:/par# cd cj
root@kylin-gtj:/par/cj# cjpm init
cjpm init success
root@kylin-gtj:/par/cj# ls
cjpm.toml src
root@kylin-gtj:/par/cj# cjpm run
hello world
cjpm run finished
再用一个递归的斐波那契数列函数来测试编译后的二进制文件性能。
//package somethinglike 这个是我的文件名
func fib(n: Int64):Int64{
match (n){//match函数相当于是C++中的switch函数
case 0 | 1 => n//当n=0或1时输出n本身
case other where other > 0 =>
fib(other - 1)+fib(other - 2)
case _ => 0//不符合斐波那契数列定义的输入返回0,case _相当于是default
}
}
main(){
println(fib(-1))
for(i in 42..=42){//从1到10,如果没有=,相当于是1<=i<10,即1到9
print("${fib(i)} ")//也可以使用println,但是每输出一个结果就会换行
}
}
先用默认编译,执行速度较慢。
root@kylin-gtj:/par# cjc fib.cj -o fib
root@kylin-gtj:/par# time ./fib
0
267914296
real 0m9.151s
user 0m9.156s
sys 0m0.000s
root@kylin-gtj:/par# cjc -h
Usage:
cjc [option] file...
-O0 Optimization level 0 (default)
-O, -O1 Optimization level 1
-O2 Optimization level 2
-Os Optimization level s, like -O2 with extra optimizations for size
-Oz Optimization level z, like -Os but reduces code size further
-O<value> Set Optimization level
root@kylin-aaa:/par# cjc fib.cj -o fib -O2
root@kylin-aaa:/par# time ./fib
0
267914296
real 0m1.563s
user 0m1.556s
sys 0m0.000s
root@kylin-aaa:/par# ls -l fib*
-rwxr-xr-x 1 root root 991400 Aug 20 02:27 fib
-rw-rw-r-- 1 postgres postgres 590 Aug 20 02:25 fib.cj
可见类似gcc, 有-O系列优化级别。-O2比默认快了好几倍。
编译完成的二进制文件较大,几乎什么都不干都有900KB。
再来编译一个导入标准库的源代码。
//package cjcDemo
// 导入必要的标准库模块
import std.convert.* // 数据类型转换模块
import std.console.* // 控制台输入输出模块
// 定义一个函数,读取用户输入的整数,并返回 Int64 类型的值
func inputInt(info: String): Int64 {
print(info) // 输出提示信息到控制台
let number: Int64 = Int64.parse(Console.stdIn.readln().getOrThrow()) // 读取用户输入并转换为 Int64
return number // 返回输入的整数
}
// 计算斐波那契数列的第 n 项,并返回该项的值及完整数列
func fibonacci(n: Int64): (Int64, Array<Int64>) {
// 创建一个大小为 n+1 的数组,用于存储斐波那契数列的各项,初始化为 0
let dp = Array<Int64>(n + 1, repeat: 0)
// 如果 n 大于 0,则设置第一项为 1(F(1) = 1)
if (n > 0) {
dp[1] = 1
}
// 使用循环计算斐波那契数列的每一项,避免重复计算
for (i in 2..=n) {
dp[i] = dp[i - 1] + dp[i - 2] // 当前项为前两项之和
}
// 返回第 n 项的值和完整的斐波那契数列数组
return (dp[n], dp)
}
// 主函数,程序入口
main(): Int64 {
// 调用 inputInt 函数,提示用户输入非负整数 n
let n = inputInt("请输入一个非负整数 n: ")
// 调用 fibonacci 函数,计算第 n 项及完整的斐波那契数列
let (result, sequence) = fibonacci(n)
// 输出第 n 项的值
println("F(${n}) = ${result}")
// 输出斐波那契数列的所有项
println("斐波那契序列:")
for (i in 0..sequence.size) {
println("F(${i}) = ${sequence[i]}") // 按格式输出每一项的值
}
return 0 // 返回 0 表示程序成功执行
}
可能是版本更新原因,console被废弃了,但还能编译通过。二进制文件膨胀到了3MB。
root@kylin-aaa:/par# cjc demo.cj -o demo -O2
warning: class 'Console' is deprecated. Use related global functions in the std.env instead.
==> demo.cj:10:37:
|
10 | let number: Int64 = Int64.parse(Console.stdIn.readln().getOrThrow()) // 读取用户输入并转换为 Int64
| ^^^^^^^ deprecated
|
# note: this warning can be suppressed by setting the compiler option `-Woff deprecated`
1 warning generated, 1 warning printed.
root@kylin-aaa:/par# ls -l ./demo
-rwxr-xr-x 1 root root 3207584 Aug 20 02:51 ./demo
root@kylin-aaa:/par# ./demo
请输入一个非负整数 n: 42
F(42) = 267914296
斐波那契序列:
F(0) = 0
F(1) = 1
..
F(42) = 267914296
还能检查数组越界,抛出异常。
root@kylin-aaa:/par# ./demo
请输入一个非负整数 n: -1
An exception has occurred:
IndexOutOfBoundsException: The length of the array is 0, but the index is -1.
at default.fibonacci(Int64)(/par/demo.cj:30)
at default.main()(/par/demo.cj:39)
希望用-Os和-Oz优化大小,并没有效果。
root@kylin-aaa:/par#
root@kylin-aaa:/par# cjc demo.cj -o demo -Os
warning: class 'Console' is deprecated. Use related global functions in the std.env instead.
==> demo.cj:10:37:
|
10 | let number: Int64 = Int64.parse(Console.stdIn.readln().getOrThrow()) // 读取用户输入并转换为 Int64
| ^^^^^^^ deprecated
|
# note: this warning can be suppressed by setting the compiler option `-Woff deprecated`
1 warning generated, 1 warning printed.
root@kylin-aaa:/par# ls -l ./demo
-rwxr-xr-x 1 root root 3207304 Aug 20 05:43 ./demo
root@kylin-aaa:/par# cjc demo.cj -o demo -Oz
warning: class 'Console' is deprecated. Use related global functions in the std.env instead.
==> demo.cj:10:37:
|
10 | let number: Int64 = Int64.parse(Console.stdIn.readln().getOrThrow()) // 读取用户输入并转换为 Int64
| ^^^^^^^ deprecated
|
# note: this warning can be suppressed by setting the compiler option `-Woff deprecated`
1 warning generated, 1 warning printed.
root@kylin-aaa:/par# ls -l ./demo
-rwxr-xr-x 1 root root 3207304 Aug 20 05:43 ./demo
root@kylin-aaa:/par# cjc demo.cj -o demo -O1 -Woff deprecated
root@kylin-aaa:/par# ls -l ./demo
-rwxr-xr-x 1 root root 3207392 Aug 20 05:44 ./demo
用ldd命令检查,可见它除了依赖glibc的动态库,还依赖sdk中的libcangjie-runtime.so和libboundscheck.so。如果它们不在环境变量搜索路径中,就会报not found。
kylin@kylin-aaa:/data/i$ ldd demo
./demo: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./demo)
./demo: /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.27' not found (required by ./demo)
./demo: /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by ./demo)
linux-vdso.so.1 => (0x0000007faf955000)
/usr/lib/libzfh.so (0x0000007faf4b0000)
libcangjie-runtime.so => not found
libboundscheck.so => not found
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007faf3e3000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007faf29c000)
/lib/ld-linux-aarch64.so.1 (0x0000007faf92a000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007faf270000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007faf25d000)
奇怪的是,linux aarch64版本sdk中还包含windows x64的库文件,难道用来交叉编译?
root@kylin-gtj:/par# ls -l cangjie/lib
total 2044
-rwxr-x--- 1 postgres postgres 1007104 Feb 28 2023 libstdFFI.dll
-rwxr-x--- 1 postgres postgres 75482 Feb 28 2023 libstdFFI.dll.a
-rwxr-x--- 1 postgres postgres 995728 Feb 28 2023 libstdFFI.so
drwxr-x--- 2 postgres postgres 4096 Feb 28 2023 linux_aarch64_cjnative
drwxr-x--- 2 postgres postgres 4096 Feb 28 2023 windows_x86_64_cjnative
更多推荐



所有评论(0)