Introduction
SQLite3 is a lightweight database designed specifically for embedded systems with limited memory. It is commonly used in embedded Linux application development, and its syntax is similar to MySQL.
To enable the program you write to be cross-compiled on a host machine (Ubuntu) and have the compiled executable run on a development board, you need to ensure two environments are properly set up: the host development environment and the runtime environment of the development board. This includes ensuring that compilers, linkers, and various libraries (such as the C/C++ standard libraries and other third-party libraries) are compatible between the two environments.
Checking the Host Toolchain
The host toolchain can be installed following the steps in Running C and C++ Programs (Click to jump 🚀)
Checking the Development Board Toolchain
Note that we are using the official Buildroot SDK for the TaiShan development board. This SDK only installs one linker, ld-linux-aarch64.so.1, located in /lib64. To verify its configuration, execute the following:
./ld-linux-aarch64.so.1 --help
This will display the dynamic library search paths configured for the linker, which are the directories where the linker will look for libraries when running a program. (These paths are related to the PATH environment variable). If the necessary libraries for your program are not in these paths, the program will not run.
Fortunately, Buildroot has already included SQLite3 by default in the /usr/lib64 directory during the compilation process.
This means the development board environment is already set up, and no changes are needed.
What if the SDK you compile yourself doesn't include these libraries?
What if the development board doesn't even have the SQLite3 executable? - The solution is at the end of the article.
1. Setting up the SQLite3 Development Environment on the Host
This step is actually optional if you only need to compile and run the program on the embedded device. However, sometimes you might want to verify the functionality of the program on the host machine first, in which case setting up the SQLite3 environment on the host is necessary. You can do this with just two commands (for Ubuntu):
sudo apt-get install sqlite3
- This installs the binary executable for SQLite3, allowing you to interact with the database via the command line. To verify successful installation, run sqlite3 --version.
sudo apt-get install libsqlite3-dev
- This installs the SQLite3 dynamic libraries (.so) and the include header files that match your host’s processor architecture.
At this point, you can interact with a database through APIs in your C program. Here's an example:
#include <stdio.h>
#include <sqlite3.h> // Include the header file
int main(){
sqlite3* my_db;
int ret = sqlite3_open("test_database.db", &my_db);
if(ret == SQLITE_OK){
printf("database connected!");
}
return 0;
}
2
3
4
5
6
7
8
9
10
Next, compile the program (make sure to include the linking parameters):
- gcc test.c -lsqlite3 Run the .out file and observe the output. Of course, this executable cannot yet run on the ARM development board. 2. Finding the Cross-Compiler Toolchain's Linker Search Path If you've successfully installed the aarch64-linux-gnu toolchain, execute the following:
- cd /usr/aarch64-linux-gnu/bin
- ld --verbose | grep SEARCH_DIR Similar to the previous step, this will display the dynamic library search paths for the cross-compiler toolchain.
Choose one of the paths, for example, /usr/lib, remember this path. Later, the compiled libraries will be placed in this location. 3. Download the Official Source Code
- Official website: https://www.sqlite.org/index.html
Download the source code and upload it to any directory on your virtual machine, then extract it:
- tar zxvf sqlite-autoconf-3450100.tar.gz 4. Create a New Configuration Navigate to the extracted folder:
- cd sqlite-autoconf-3450100 Create a new configuration file and add the following code:
- vi aarch64-configure
#!/bin/bash
ARCH="aarch64"
DEST_CPU="arm64"
HOST_OS="linux"
HOST_ARCH="x86_64"
export LINK_host="g++"
export CXX_host="g++"
export CC_host="gcc"
export AR_host="ar"
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export LD=aarch64-linux-gnu-ld
export RANLIB=aarch64-linux-gnu-ranlib
export AR=aarch64-linux-gnu-ar
export AS=aarch64-linux-gnu-as
if []; then
./configure --prefix=$PWD/output \
--host=aarch64-linux-gnueabi
fi
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
5. Execute Configuration and Compilation
Execute the following commands in sequence:
- ./aarch64-configure
- make
- make install This will generate an output folder.
Inside this folder:Bin contains the executable programs. Include contains the library header files. Lib contains the library files. Share contains the man documentation (which can be ignored for now).
Note that the files generated here are meant to run on the ARM processor, not your host machine.
6. Copy the Files
Copy the five files from the lib folder into the path you remembered in Step 2.
You don’t need to worry about the include header files; they have already been placed into the search path during the installation.
7. Cross-Compile and Test on the Board
Once the environment is set up, cross-compile the test program:
- aarch64-linux-gnu-gcc test.c -lsqlite3 Transfer the compiled program to the development board, execute it, and check the result. Success!
A .db file will also be successfully generated in the same directory:
That's it!
8. What If Your SDK Doesn’t Have These Libraries?
If your SDK doesn’t include these libraries, place the compiled library files into the directory mentioned in the "Check Development Board Toolchain" section.
9. What If SQLite3’s Executable Program is Missing on the Development Board?
- Method 1: Modify the Buildroot configuration and recompile a new image.
- Method 2: Copy the compiled executable from the /bin directory to any directory listed in your PATH environment variable.