测试duckdb的C插件模板的编译加工和加载

首先下载2个压缩包,第一个是模板,第二个是所需工具

https://github.com/duckdb/extension-template-c 下载 extension-template-c-main.tar.gz

https://github.com/duckdb/extension-ci-tools 下载 extension-ci-tools-main.tar.gz

分别解压,然后把第二个解压出的内容放到第一个的extension-ci-tools空目录下。

首先尝试页面介绍的正规做法

bash 复制代码
make configure
python3 -m venv configure/venv
The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt install python3.11-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment

按照提示安装python3.11-venv

bash 复制代码
apt install python3.11-venv
...
Setting up python3-setuptools-whl (66.1.1-1+deb12u2) ...
Setting up python3-pip-whl (23.0.1+dfsg-1) ...
Setting up libpython3.11-minimal:amd64 (3.11.2-6+deb12u6) ...
Setting up python3.11-minimal (3.11.2-6+deb12u6) ...
Setting up libpython3.11-stdlib:amd64 (3.11.2-6+deb12u6) ...
Setting up python3.11 (3.11.2-6+deb12u6) ...
Setting up python3.11-venv (3.11.2-6+deb12u6) ...

再次

bash 复制代码
make configure
Traceback (most recent call last):
  File "/par/extension-template-c-main/extension-ci-tools/scripts/configure_helper.py", line 44, in <module>
    main()
  File "/par/extension-template-c-main/extension-ci-tools/scripts/configure_helper.py", line 36, in main
    import duckdb
ModuleNotFoundError: No module named 'duckdb'

我只是要编译一个c插件,还要装python的duckdb模块, 太复杂了,放弃了。

看到extension-template-c-main目录下有个CMakeLists.txt,想到用cmake,

bash 复制代码
mkdir build
/par/extension-template-c-main# cd build
/par/extension-template-c-main/build# cmake ..
CMake Error at CMakeLists.txt:8 (message):
  DuckDB extension name is required


-- Configuring incomplete, errors occurred!

我也不知道cmake在哪设置DuckDB extension name,也放弃了。

那就用平常编译c项目的方法,自己写gcc命令行。

看了看目录结构,源代码在extension-template-c-main/src下,它有一个include子目录,extension-template-c-main/duckdb_capi下也有头文件。

所以按照如下编写命令行,编译add_numbers.c通过

bash 复制代码
/par/extension-template-c-main/src# gcc -c add_numbers.c -I include -I ../duckdb_capi

再编译另一个文件capi_quack.c,报错了

bash 复制代码
/par/extension-template-c-main/src# gcc -c capi_quack.c -I include -I ../duckdb_capi
capi_quack.c:5:1: error: return type defaults to 'int' [-Wimplicit-int]
    5 | DUCKDB_EXTENSION_ENTRYPOINT(duckdb_connection connection, duckdb_extension_info info, struct duckdb_extension_access *access) {
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~

好像是不认识DUCKDB_EXTENSION_ENTRYPOINT,到duckdb_capi/duckdb_extension.h中查找,发现这么一句, 后面跟着DUCKDB_EXTENSION_ENTRYPOINT宏定义

c 复制代码
// Note: the DUCKDB_EXTENSION_ENTRYPOINT macro requires DUCKDB_EXTENSION_NAME to be set.

#ifdef DUCKDB_EXTENSION_NAME

// Main entrypoint: opens (and closes) a connection automatically for the extension to register its functionality
// through
#define DUCKDB_EXTENSION_ENTRYPOINT 
...

那就好办了,在capi_quack.c开头添加

c 复制代码
#define DUCKDB_EXTENSION_NAME add

一行

重新执行/par/extension-template-c-main/src# gcc -c capi_quack.c -I include -I ../duckdb_capi

不报错了。

按照通常编译动态库的命令语法,把两个c文件的内容编译到libtest.so

bash 复制代码
/par/extension-template-c-main/src# gcc -fPIC -shared -o libtest.so *.c -I include -I ../duckdb_capi

查看libtest.so中的导出函数,有一个add_init_c_api,就是我们的插件名add打头的。

bash 复制代码
/par/extension-template-c-main/src# nm -D libtest.so
0000000000001371 T RegisterAddNumbersFunction
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w __cxa_finalize@GLIBC_2.2.5
                 w __gmon_start__
000000000000149a T add_init_c_api
0000000000004040 B duckdb_ext_api

然后用extension-ci-tools/scripts中的append_extension_metadata.py添加元数据,因为文件名太长,我把它改名为appendmetadata.py,复制到/par目录。

bash 复制代码
/par/extension-template-c-main/src# python3 ../../appendmetadata.py -l libtest.so -n add -dv v1.2.0  --duckdb-platform linux_amd64 --extension-version 0.1
Creating extension binary:
 - Input file: libtest.so
 - Output file: add.duckdb_extension
 - Metadata:
   - FIELD8 (unused)            = EMPTY
   - FIELD7 (unused)            = EMPTY
   - FIELD6 (unused)            = EMPTY
   - FIELD5 (abi_type)          = C_STRUCT
   - FIELD4 (extension_version) = 0.1
   - FIELD3 (duckdb_version)    = v1.2.0
   - FIELD2 (duckdb_platform)   = linux_amd64
   - FIELD1 (header signature)  = 4 (special value to identify a duckdb extension)

然后用-unsigned选项打开duckdb140 CLI,加载插件成功,文件名叫add_numbers.c,而函数名却叫multiply_numbers_together,从执行结果看,确实是相乘而不是相加,而且只有2个参数,多了报错。

bash 复制代码
/par/extension-template-c-main/src# /par/duckdb140 -unsigned
DuckDB v1.4.0 (Andium) b8a06e4a22
Enter ".help" for usage hints.
D load '/par/extension-template-c-main/src/add.duckdb_extension';
D select multiply_numbers_together(1,2);
┌─────────────────────────────────┐
│ multiply_numbers_together(1, 2) │
│              int64              │
├─────────────────────────────────┤
│                2                │
└─────────────────────────────────┘
D select multiply_numbers_together(1,2,4,8);
Binder Error:
No function matches the given name and argument types 'multiply_numbers_together(INTEGER_LITERAL, INTEGER_LITERAL, INTEGER_LITERAL, INTEGER_LITERAL)'. You might need to add explicit type casts.
        Candidate functions:
        multiply_numbers_together(BIGINT, BIGINT) -> BIGINT


LINE 1: select multiply_numbers_together(1,2,4,8);
               ^
D with t as(select 3 a,7 b)select multiply_numbers_together(a,b) from t;
┌─────────────────────────────────┐
│ multiply_numbers_together(a, b) │
│              int64              │
├─────────────────────────────────┤
│               21                │
└─────────────────────────────────┘
相关推荐
峥嵘life2 小时前
Android16 应用代码新特性
java·开发语言·学习·安全
浮尘笔记2 小时前
Go-Zero API Handler 自动化生成与参数验证集成
开发语言·后端·golang
T - mars2 小时前
数据迁移:MySQL => SQL Server
数据库·mysql
傻啦嘿哟2 小时前
用Requests+BeautifulSoup实现天气预报数据采集:从入门到实战
开发语言·chrome·python
兆。2 小时前
python全栈-数据可视化
开发语言·python·信息可视化
@大迁世界2 小时前
JavaScript 2.0?当 Bun、Deno 与 Edge 运行时重写执行范式
开发语言·前端·javascript·ecmascript
JIngJaneIL2 小时前
记账本|基于SSM的家庭记账本小程序设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·家庭记账本小程序
_Re.3 小时前
DSC 归档配置相关
数据库·oracle·php
大飞pkz3 小时前
【设计模式】适配器模式
开发语言·设计模式·c#·适配器模式