Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

·1. Test Code

·2. Cross Compilation

oCommand Structure

oFunction of Each Part

·3. Execute Test

·4. Environment Variable `$PATH`

o4.1 System-level Configuration Files (Global Settings)

o4.2 User-level Configuration Files (Personal Settings)

o4.3 Shell Built-in Defaults

·5. How to Find the Source of the Current `PATH`?

·Common Modification Scenarios

1. Test Code

// test_sqlite.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./sqlite3.h"

// Query callback function
static int callback(void *data, int argc, char **argv, char **azColName) {
    for (int i = 0; i < argc; i++) {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("-----------------------------------\n");
    return 0;
}

static int callback2(void *data, int argc, char **argv, char **azColName) {
    for (int i = 0; i < argc; i++) {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("-----------------------------------\n");
    return 0;
}

// Callback function: process query results
static int feature_callback(void *feature_ptr, int argc, char **argv, char **azColName) {
    if (argc > 0 && argv[0]) {
        // Copy the queried feature to the passed pointer
        sprintf((char*)feature_ptr, "%s", argv[0]);
        return 0;  // Return 0 indicates to continue processing subsequent rows (though there will only be one row here)
    }
    return 1;  // Return non-zero value indicates to stop processing
}

int main(int argc, char **argv) {
    sqlite3 *db;
    char *err_msg = 0;
    int rc;
    const char *sql;
    const char *data = "Result Callback";

    // 1. Open database
    rc = sqlite3_open("test.db", &db);
    if (rc) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        return(0);
    } else {
        fprintf(stdout, "Database opened successfully\n");
    }

    // 2. Create table
    sql = "CREATE TABLE IF NOT EXISTS TEST ("
          "ID INT PRIMARY KEY     NOT NULL,"
          "NAME           TEXT    NOT NULL,"
          "AGE            INT     NOT NULL,"
          "ADDRESS        CHAR(50),"
          "SALARY         REAL);";
    rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        fprintf(stdout, "Table created successfully\n");
    }

    // 3. Insert data
    sql = "INSERT INTO TEST (ID,NAME,AGE,ADDRESS,SALARY) "
          "VALUES (1, 'Zhang San', 32, 'Beijing', 20000.00 ); "
          "INSERT INTO TEST (ID,NAME,AGE,ADDRESS,SALARY) "
          "VALUES (2, 'Li Si', 25, 'Shanghai', 15000.00 ); "
          "INSERT INTO TEST (ID,NAME,AGE,ADDRESS,SALARY) "
          "VALUES (3, 'Wang Wu', 23, 'Guangzhou', 2000.00 ); "
          "INSERT INTO TEST (ID,NAME,AGE,ADDRESS,SALARY) "
          "VALUES (4, 'Zhao Liu', 25, 'Shenzhen', 65000.00 );";
    rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        fprintf(stdout, "Data inserted successfully\n");
    }

    // 4. Query data
    sql = "SELECT * FROM TEST";
    rc = sqlite3_exec(db, sql, callback, (void*)data, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        fprintf(stdout, "Data queried successfully\n");
    }
    printf("\n****************************************\n");
    // 4.1 Query specific data
    char sql2[256];
    char feature[1024] = {0};  // Buffer to store query results
    memset(sql2,0,sizeof(sql2));
    memset(feature,0,sizeof(feature));
    // Construct SQL query statement
    //snprintf(sql2, sizeof(sql2), "SELECT FEATURE FROM FEATURE WHERE USER_ID = %d", user_id);
    //snprintf(sql2, sizeof(sql2), "SELECT AGE FROM TEST WHERE NAME = '%s'", "Zhang San"); // Strings need to be enclosed in single quotes
    // Execute query
    rc = sqlite3_exec(db, sql2, feature_callback, (void*)feature, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        return -1;  // Query failed
    } else {
        fprintf(stdout, "Data queried successfully\n");
        if (feature[0] != '\0') {
            //printf("Feature for user ID %d is: %s\n", user_id, feature);
            printf("Feature for user %s is: %s\n", "Zhang San", feature);
        } else {
            //printf("No record found for user ID %d\n", user_id);
            printf("No record found for user ID %s\n", "Zhang San");
        }
    }
    printf("\n****************************************\n");
    // 5. Update data
    sql = "UPDATE TEST set SALARY = 25000.00 where ID=1; "
          "SELECT * FROM TEST";
    rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        fprintf(stdout, "Data updated successfully\n");
    }
    // 6. Delete data
    sql = "DELETE FROM TEST where ID=2; "
          "SELECT * FROM TEST";
    rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        fprintf(stdout, "Data deleted successfully\n");
    }
    // 7. Close database
    sqlite3_close(db);
    return 0;
}

Note: Strings in SQL statements need to be enclosed in single quotes

<span>snprintf(sql2, sizeof(sql2), "SELECT AGE FROM TEST WHERE NAME = '%s'", "Zhang San"); // Strings need to be enclosed in single quotes</span>

Project Directory

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

2. Cross Compilation

Set up the cross-compilation toolchain

export PATH=$PATH:/home/user/Desktop/nuc980-sdk/buildroot-2022.02.3/output/host/bin

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

Direct compilation will report an error

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

Compile specifying the dynamic library search location and name

arm-linux-gcc sqlite3_test.c -o sqlite3_test -L/home/user/Desktop/sqlite3/install/lib -lsqlite3

This command compiles a C language program under an ARM architecture Linux system. Let’s analyze its components in detail:

Command Structure

arm-linux-gcc sqlite3_test.c -o sqlite3_test -L/home/user/Desktop/sqlite3/install/lib -lsqlite3

Function of Each Part

1.arm-linux-gcc It belongs to the cross-compilation toolchain, capable of compiling executable programs for one architecture (e.g., x86 PC) on a system of another architecture (like ARM).

2.sqlite3_test.c This is the name of the source file, which is your written C language source code file.

3.-o sqlite3_test“-o” is the output file parameter, “sqlite3_test” is the name of the executable file generated after compilation.

4.-L/home/user/Desktop/sqlite3/install/lib“-L” is used to specify the search path for library files. Here it tells the compiler to look in the directory /home/user/Desktop/sqlite3/install/lib for the required library files.

5.-lsqlite3“-l” is the link library parameter, “sqlite3” is the name of the library. This parameter links the SQLite3 database dynamic library (usually libsqlite3.so ) during compilation.

During the compilation process, it will look for the SQLite3 library in the specified path /home/user/Desktop/sqlite3/install/lib and link it to the program, ultimately generating an executable file named sqlite3_test that can run on ARM architecture Linux systems.

3. Execute Test

Reference Article[Step-by-Step Guide — Porting Sqlite3 Database on Arm Linux Development Boards] .Article Link

Step-by-Step Guide — Porting Sqlite3 Database on Arm Linux Development Boards

Using Deployment Method One Run

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

Copy the cross-compiled file to the development board for testing

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

Temporary test command, dynamic library runtime search command

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib

Run again

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

Using Deployment Method Two Run Check the value of the environment variable $LD_LIBRARY_PATH

echo $LD_LIBRARY_PATH

Temporary setting

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/my/custom/lib

Permanent, set user configuration ~/.bashrc, found it did not take effect. Use command to check system configuration

grep -r ‘PATH=’ /etc/*

Code Testing and Environment Setup for Sqlite3 on Arm Linux Development Boards

Modify /etc/profile file, add the corresponding path Restart to take effect.

# cd /etc # vi profile export PATH=”/bin:/sbin:/usr/bin:/usr/sbin” export PATH=$PATH:/root/sqlite3/install/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/sqlite3/install/lib if [ “$PS1” ]; then if [ “`id -u`” -eq 0 ]; then export PS1=’# ‘ else export PS1=’$ ‘ fi fi export EDITOR=’/bin/vi’ # Source configuration files from /etc/profile.d for i in /etc/profile.d/*.sh ; do if [ -r “$i” ]; then . $i fi done unset i

4. Environment Variable $PATH

The assignment location of the environment variable $PATH depends on system configuration and Shell type.

4.1 System-level Configuration Files (Global Settings)

These files are maintained by the system administrator and affect all users:

·/etc/environment

o Loaded by PAM (Pluggable Authentication Modules) at system startup, independent of Shell.

oExample:

PATH=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”

·/etc/profile

o Loaded when all login Shells start (applies to bash,sh etc.).

o Usually contains calls to scripts in the /etc/profile.d/ directory.

·/etc/profile.d/*.sh

o Scripts automatically added by the system or packages (e.g., Java, Python, etc.).

4.2 User-level Configuration Files (Personal Settings)

These files are located in the user’s home directory and only affect the current user:

·~/.bashrc (for bash Shell)

o Loaded for non-login interactive Shells (like directly opening a terminal).

o Usually indirectly called through ~/.bash_profile (see below).

·~/.bash_profile or ~/.profile

o Loaded for login Shells (like ssh login,su – username).

oExample:

if [ -f ~/.bashrc ]; then . ~/.bashrc fi PATH=”$HOME/bin:$PATH” # Add personal bin directory

·~/.bash_login (less commonly used)

o Loaded only if ~/.bash_profile does not exist.

4.3 Shell Built-in Defaults

If none of the above files set PATH, the Shell may use built-in defaults (though this is rare). For example:

·bash default PATH usually includes /usr/bin:/bin.

Temporary setting (session-level)

· Directly execute in the terminal (only valid for the current session):

export PATH=”/my/custom/bin:$PATH”

5. How to Find the Source of the Current PATH?

1. Check system configuration:

grep -r ‘PATH=’ /etc/*

2. Check user configuration:

grep ‘PATH=’ ~/.bashrc ~/.bash_profile ~/.profile

3. Debug loading process:

bash –login -x 2>&1 | grep ‘PATH=’

Common Modification Scenarios

· Add personal tool directory: Add to ~/.bashrc or ~/.bash_profile PATH=”$HOME/bin:$PATH”.

· Update path after installing software: For example, create a script in /etc/profile.d/ (like java.sh).

Leave a Comment