[技術] uClinux上Berkeley DB v4.5.20移植手記

Written on 4:01 下午 by Yu Lai

轉載自: http://blog.iyi.cn/hily/archives/2006/10/uclinuxberkeley_db_v4520.html

Berkeley DB 是一個很棒的開源的嵌入式數據庫,它主要運行在Unix/Linux上。現在它已成為Oracle的一部分,叫作Oracle Berkeley DB
下面主要介紹一下它在我最近玩的uClinux上的移植過程。

Hily Jiang
Email&Gtalk: hilyjiang at Gmail
Blog: http://hily.iyi.cn/

下載頁面:
http://dev.sleepycat.com/downloads/releasehistorybdb.html

(一)解壓

linux:/home/work/db # tar -zxf db-4.5.20.tar.gz
linux:/home/work/db # cd db-4.5.20/
linux:/home/work/db/db-4.5.20 # ls
. db_checkpoint db_upgrade libdb_java README
.. db_deadlock db_verify LICENSE rep
btree db_dump dist lock repmgr
build_unix db_dump185 docs log rpc_client
build_vxworks db_hotbackup env mod_db4 rpc_server
build_windows dbinc examples_c mp sequence
clib dbinc_auto examples_cxx mutex tcl
common db_load examples_java os test
crypto dbm fileops os_vxworks txn
cxx db_printlog hash os_windows xa
db db_recover hmac perl
db185 dbreg hsearch php_db4
db_archive db_stat java qam

docs目錄下有我們需要的文檔,包括快速入門、各種語言的API手冊等資料。

(二)配置和編譯
建立一個腳本以方便配置。由於unix/linux編譯時的工作路徑必須是build_unix,因此我們需要在build_unix目錄下創建腳本。
我創建了一個名為myconfig的腳本,內容如下:

1 #!/bin/sh
2
3 CC=arm-elf-gcc \
4 CFLAGS="-Os -D__uClinux__ -fno-builtin -I/home/uClinux-dist/linux-2.4.x/include -I/home/uClinux-dist/lib/uClibc/include -I/home/uClinux-dist/lib/uClibc/include/../ " \
5 LDFLAGS="-Wl,-elf2flt -Wl,-move-rodata -L/home/uClinux-dist/lib/uClibc/lib -L/home/uClinux-dist/lib/uClibc/lib/../ -lc " \
6 ../dist/configure \
7 --prefix=/home/work/db/Berkeley.DB \
8 --build=i686-linux \
9 --host=arm-elf-linux \
10 --disable-cryptography \
11 --disable-hash \
12 --disable-queue \
13 --disable-replication \
14 --disable-statistics \
15 --disable-verify \
16 --disable-compat185 \
17 --disable-cxx \
18 --disable-debug \
19 --disable-debug_rop \
20 --disable-debug_wop \
21 --disable-diagnostic \
22 --disable-dump185 \
23 --disable-java \
24 --disable-mingw \
25 --disable-o_direct \
26 --disable-posixmutexes \
27 --disable-pthread_api \
28 --disable-rpc \
29 --disable-smallbuild \
30 --disable-tcl \
31 --disable-test \
32 --disable-uimutexes \
33 --enable-umrw \
34 --disable-shared \
35 --enable-static \
36 --enable-fast-install \
37 --disable-libtool-lock \
38 --disable-largefile

關於configure配置參數的含義,可以運行"../dist/configure --help"查看幫助,這裡不再介紹。
要強調的一點是uClibc只能用靜態編譯,因此一定要選擇--disable-shared。
接著執行./myconfig運行配置並編譯安裝函數庫:
linux:/home/work/db/db-4.5.20/build_unix # ./myconfig >/dev/null
configure: WARNING: In the future, Autoconf will not detect cross-tools
whose name does not start with the host triplet. If you think this
configuration is useful to you, please write to autoconf@gnu.org.
cat: /etc/ld.so.conf.d/*.conf: No such file or directory
linux:/home/work/db/db-4.5.20/build_unix # make >/dev/null && make install >/dev/null
../dist/../hmac/sha1.c:96: warning: `R0' redefined
/usr/local/lib/gcc-lib/arm-elf/2.95.3/../../../../arm-elf/include/sys/ucontext.h:40: warning: this is the location of the previous definition
../dist/../hmac/sha1.c:97: warning: `R1' redefined
/usr/local/lib/gcc-lib/arm-elf/2.95.3/../../../../arm-elf/include/sys/ucontext.h:42: warning: this is the location of the previous definition
../dist/../hmac/sha1.c:98: warning: `R2' redefined
/usr/local/lib/gcc-lib/arm-elf/2.95.3/../../../../arm-elf/include/sys/ucontext.h:44: warning: this is the location of the previous definition
../dist/../hmac/sha1.c:99: warning: `R3' redefined
/usr/local/lib/gcc-lib/arm-elf/2.95.3/../../../../arm-elf/include/sys/ucontext.h:46: warning: this is the location of the previous definition
../dist/../hmac/sha1.c:100: warning: `R4' redefined
/usr/local/lib/gcc-lib/arm-elf/2.95.3/../../../../arm-elf/include/sys/ucontext.h:48: warning: this is the location of the previous definition
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
warning: .rodata section contains relocations
strip: /home/work/db/Berkeley.DB/bin/db_archive: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_checkpoint: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_deadlock: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_dump: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_hotbackup: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_load: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_printlog: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_recover: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_stat: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_upgrade: 不可識別的文件格式
strip: /home/work/db/Berkeley.DB/bin/db_verify: 不可識別的文件格式

編譯過程中會出現一些warning,不用理它們。
安裝完後,會在指定的安裝目錄/home/work/db/Berkeley.DB下生成函數庫:
linux:/home/work/db/db-4.5.20/build_unix # cd /home/work/db/Berkeley.DB/
linux:/home/work/db/Berkeley.DB # ls
. .. bin docs include lib
linux:/home/work/db/Berkeley.DB # ll lib/
總用量 1962
drwxr-xr-x 2 root root 104 2006-10-08 12:57 .
drwxr-xr-x 6 root root 144 2006-10-08 12:57 ..
-rw-r--r-- 1 root root 1002266 2006-10-08 12:57 libdb-4.5.a
-rw-r--r-- 1 root root 1002266 2006-10-08 12:57 libdb.a


(三)數據庫操作測試
創建一個測試程序如下:
linux:/home/work/db/Berkeley.DB # cat -n testdb.c
1 #include
2 #include
3 #include
4
5 #define DESCRIPTION_SIZE 20
6 int main()
7 {
8 DB *dbp; /* DB structure handle */
9 u_int32_t flags; /* database open flags */
10 int ret; /* function return value */
11 char *description = "Grocery bill.";
12 char *description1[DESCRIPTION_SIZE + 1];
13 DBT key, data;
14 float money;
15
16 /* Initialize the structure. This
17 * database is not opened in an environment,
18 * so the environment pointer is NULL. */
19 ret = db_create(&dbp, NULL, 0);
20 if (ret != 0) {
21 /* Error handling goes here */
22 printf("Create fail!\n");
23 }
24
25 /* Database open flags */
26 flags = DB_CREATE; /* If the database does not exist,
27 * create it.*/
28
29 /* open the database */
30 ret = dbp->open(dbp, /* DB structure pointer */
31 NULL, /* Transaction pointer */
32 "/home/my_db.db", /* On-disk file that holds the database. */
33 NULL, /* Optional logical database name */
34 DB_BTREE, /* Database access method */
35 flags, /* Open flags */
36 0); /* File mode (using defaults) */
37 if (ret != 0) {
38 /* Error handling goes here */
39 printf("Created new database.\n");
40 }
41
42 money = 122.45;
43
44 /* Zero out the DBTs before using them. */
45 memset(&key, 0, sizeof(DBT));
46 memset(&data, 0, sizeof(DBT));
47
48 key.data = &money;
49 key.size = sizeof(float);
50
51 data.data = description;
52 data.size = strlen(description) +1;
53
54 ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE);
55 if (ret == DB_KEYEXIST) {
56 dbp->err(dbp, ret,
57 "Put failed because key %f already exists", money);
58 }
59
60 memset(&data, 0, sizeof(DBT));
61
62 data.data = &description1;
63 data.ulen = DESCRIPTION_SIZE + 1;
64 data.flags = DB_DBT_USERMEM;
65 dbp->get(dbp, NULL, &key, &data, 0);
66
67 printf("data: %s\n", (char *)data.data);
68
69 /* When we're done with the database, close it. */
70 if (dbp != NULL)
71 dbp->close(dbp, 0);
72
73 return 0;
74 }

這個程序會在目標板上/home/目錄下創建一個文件名為my_db.db的數據庫,接著增加一條記錄,然後從數據庫中讀取出新添加的這條記錄,最後關閉數據庫。
程序要燒寫到目標板上,需要進行交叉編譯:
linux:/home/work/db/Berkeley.DB # arm-elf-gcc -O3 -Wall -mapcs-32 -mtune=arm7tdmi -fno-builtin -msoft-float -Os -D__uClinux__ -D__ARM_CPU__ -I/home/work/uClinux-dist/lib/uClibc/include -I/home/uClinux-dist/linux-2.4.x/include -I/home/work/db/Berkeley.DB/include -D_DEBUG_ -c testdb.c -o testdb.o
linux:/home/work/db/Berkeley.DB # arm-elf-gcc testdb.o -nostartfiles -Wl, -elf2flt -L/home/uClinux-dist/lib/uClibc/lib -L/home/work/db/Berkeley.DB/lib /home/uClinux-dist/lib/uClibc/lib/crt0.o /home/uClinux-dist/lib/uClibc/lib/crti.o /home/uClinux-dist/lib/uClibc/lib/crtn.o -lc -ldb -o testdb
linux:/home/work/db/Berkeley.DB # ll
總用量 1217
drwxr-xr-x 6 root root 280 2006-10-08 13:22 .
drwxr-xr-x 4 root root 144 2006-10-08 12:50 ..
drwxr-xr-x 2 root root 376 2006-10-08 12:57 bin
drwxr-xr-x 14 root root 384 2006-10-08 12:57 docs
drwxr-xr-x 2 root root 96 2006-10-08 12:57 include
drwxr-xr-x 2 root root 104 2006-10-08 12:57 lib
-rwxr--r-- 1 root root 584476 2006-10-08 13:22 testdb
-rw-r--r-- 1 root root 2171 2006-10-08 13:22 testdb.c
-rw------- 1 root root 2163 2006-10-08 13:09 testdb.c~
-rwxr-xr-x 1 root root 673683 2006-10-08 13:22 testdb.gdb
-rw-r--r-- 1 root root 1540 2006-10-08 13:22 testdb.o

生成的可執行文件比較大,將近600KB。
燒寫到目標機上後運行,結果如下:
# /home/testdb
data: Grocery bill.

搞定~
總的來說,Berkeley DB還是比較易用的。就是生成的可執行文件還是太大些 :-(

If you enjoyed this post Subscribe to our feed

No Comment

張貼留言