Assitance in statically linking a SQLite loadable extension in a C program compiled with the amalgamation

Viewed 194

I'm trying to compile SQLite with a C program along with at least one loadable non-core SQLite extension, as statically linked, expecting that to mean that there will be one executable file generated that will depend on no other files at that point.

Right now, I'm trying to just get carray.c loaded. I have the carray.c file and the carray.h file. I've read the SQLite instructions for run-time loadable extensions, especially item 6 for statically linking; but I really don't know enough to understand it properly.

In item 6 of the instructions, would you please tell me the following?

  1. Where it reads, To statically link your extension, simply add the -DSQLITE_CORE compile-time option does this apply to compiling the sqlite3.c file, the carray.c file, or both? And how is this to be done?

I should've said I'm using minGW-W64. I have been compiling the sqlite3.c amalgamation file with my C file by first generating a sqlite3.o file using, gcc -O2 -c sqlite3.c -DSQLITE_ENABLE_JSON1 and then compiling that with my ever-changing code as gcc -O2 sqlite3.o myfile.c -o myfile.exe. And this has been working until trying to incorporate the carray loadable extension.

Earlier I tried compiling sqlite3.c and carray.c each to their own .o files and then compiling them with myfile.c and it compiled without error; but carray was not recognized as a function when I tried to use it. I think it is the initializing/entry point item that is the problem.

  1. I think I understand the name changing regarding SQLITE_EXTENSION_INIT and think I need to us sqlite3_auto_extension() because my C program will require multiple connections, not to the same database file but to multiple files. However, I get very confused at this point. When reading the documentation on sqlite3_auto_extension(), I've no idea what an entry point is or how to use/provide xEntryPoint. It also appears that the database handle is to be passed into xEntryPoint and that confuses me because I thought this was to automatically load the extension into every database connection not just for one handle.

It also reads that Then modify your application to invoke the entry point directly, passing in a NULL pointer as the third "pApi" parameter. I think it reads elsewhere that this is to be done near the beginning of the main C function, but I don't follow how to do it.

  1. Is the carray.h file to be included in my C program?

This SQLite Forum question, especially at post (3), regarding including the extension source in the amalgamation file, is interesting and I think I almost follow it; but don't understand how it compares to the regular instructions, or if it is a better method.

  1. If possible, could you please explain what placing SQLITE_EXTENSION_INIT1 on a line by itself does or how compiling with -DSQLITE_CORE makes it a no-op?

Thank you.


The SQLite forum post mentioned above works. I just appended carray.c to the sqlite3.c amalgamation file, then appended the core_init() function example after it, changed one sqlite3_auto_extension((void*)sqlite3_autobusy_init); to use sqlite3_carray_init, and commented out the other since currently have just one extension to link, and included carray.h in my code. Then compiled the amalgamation as gcc -O2 -c sqlite3.c -DSQLITE_ENABLE_JSON1 -DSQLITE_EXTRA_INIT=core_init. You don't need the first one with JSON1 but I left it in to make sure they'd work together. I'd still like to know how to do the same using the method in the instructions.

Clarification on how to add the extension following the instructions, rather than appending to the amalgamation file, can be found here at this SQLite Forum post.

1 Answers
  1. "Static linking" basically means including the object files directly into the resulting program. And there's no need for you to invoke a compile-only pass (-c) first here. You can compile + link: gcc -DSQLITE_CORE sqlite3.c carray.c -o myfile.exe

  2. As I understand it, sqlite3_auto_extension() is a function that lets you specify an entry point (read: init function, it takes a function pointer as a parameter) for an extension to be auto-loaded when you initialize sqlite. Typically, you would call this in the application that utilizes sqlite, i.e. the driver program. However, of course you can add this to the end of sqlite3.c as well, as you are currently doing, effectively making it "built-in".

  3. No. You should #include the header in your .c file, the preprocessor include-directive is basically a copy-paste of the file contents.

  4. The macro is here: sqlite3ext.h. In its current form, the macro does not make them "no-ops", so I think perhaps the documentation refers to an earlier version. I have 3.34 installed on my machine, and the macro is there defined there surrounded by an #if - #else block regarding SQLITE_CORE, making it a no-op. I could not post the contents of it here, due to not being able to figure out proper formatting for it.

Related