SQLite User Forum

Including the lsm1 extension in the amalgam file
Login

Including the lsm1 extension in the amalgam file

(1) By George on 2022-08-30 16:14:34 [link] [source]

Is there an easy way to create an amalgam that includes the lsm1 extension? I have not found any documentation to this effect, and it seems like the list of extensions included in the amalgam file is hard coded.

(2) By Keith Medcalf (kmedcalf) on 2022-08-30 17:47:05 in reply to 1 [link] [source]

I include the lsm1 extension in my custom build. It is rather easy to add any extension into SQLite3.

Simply build the extension source. There is in-bred capability to create the entire extension as a single lsm1.c file.

The file main.c when initializing the sqlite3 instance executes a function defined by preprocessor symbol SQLITE_EXTRA_INIT. Simply make this point to a function that calls the lsm1 (or whatever extensions you want available) init function. You will probably need to write this yourself.

Then compile them all and link them together making sure that the appropriate defines are defines (such as SQLITE_CORE so that the various bits talk directly rather than through a number of trampolines).

(3) By George on 2022-08-30 19:02:57 in reply to 2 [link] [source]

I see the lsm1.c target in main.mk but it is not include in the Makefile generated by configure (I'm on macOS), and configure has no --enable-lsm1 flag. Do you manually configure the makefile? Is there a reason lsm1 seems like a second-class citizen compared to the other extensions?

(4) By Keith Medcalf (kmedcalf) on 2022-08-30 19:27:02 in reply to 3 [link] [source]

No. Only a few of the many extensions may be included in the sqlite3 library as distributed. Some extensions are put in the debugging tool and not the core.

In other words, there is no "as distributed" way to configure the "as distributed" code to include the lsm1 extension in the core. Just as there is no "as distributed" way to include any of the other not-already-in-the-core extensions to the core using only the "as distributed" bundle.

This is not to say, however, that it cannot be done. It is just that you have to do it, not the maintainers of the sqlite3 distribution.

(5) By George on 2022-08-30 20:06:20 in reply to 4 [link] [source]

Thanks for all the help. I think I mostly understand now.

My current plan then is to build (or download) the amalgam file, and then run make -f ../sqlite/Makefile.linux-gcc lsm1.c which currently correctly creates lsm1.c and lsm1.h (and happily runs on macOS with TCL installed despite being labeled linux-gcc). Then, I embed both the amalgam and the amalgamated lsm1 files into my project and build with SQLITE_CORE and SQLITE_ENABLE_LSM1 defined.

The part I still find confusing is when to call the sqlite3_lsm_init function. You seem to indicate I should be calling it during SQLITE_EXTRA_INIT, but it takes a sqlite3 *db parameter which I don't think I have access to during init. It seems like it should be sufficient to call sqlite_lsm_init when I open a new database connection (passing NULL for pAPI if I understand correctly).

Does this sound accurate?

(6) By Keith Medcalf (kmedcalf) on 2022-08-30 20:49:40 in reply to 5 [link] [source]

Yes, that is accurate.

However, you need to compile the lsm1.c with -DSQLITE_CORE defined. The parameter passed to the init function is so that the trampoline can be located. Defining SQLITE_CORE (as is done when compiling the core) tells the extension to use direct calls rather than the trampoline and therefore has no need of a parameter (ie, it is 0).

Eg. get the lsm1.c and lsm1.h files however you like.

create a function like this:

int core_init(const char* dummy)
{
    return sqlite3_auto_extension((void*)sqlite3_lsm_init);
}

and then compile thusly:

gcc -DSQLITE_CORE -DSQLITE_EXTRA_INIT=core_init sqlite3.c lsm1.c coreinit.c ...

The lsm1 virtual table will be available on every connection opened using this version of the library.

(7) By Keith Medcalf (kmedcalf) on 2022-08-30 20:58:27 in reply to 6 [link] [source]

Basically, this defines SQLITE_EXTRA_INIT as function core_init.

If you examine the source for SQLite3, you will see that in main.c where the library is initialized, after the "as distributed" initialization is complete, that the function pointed to by the SQLITE_EXTRA_INIT define will be run.

This function adds the sqlite3_lsm1_init routine into the auto_extension list (the list of stuffs to run when a new connection is created). This means every new connection will have the lsm1 extension registered.

You can either append lsm1.c to and coreinit to the amalgamation, or they can be separate compilation units (when compiling lsm1.c you must have SQLITE_CORE defined -- if it were part of the sqlite3.c file (ie, you appended it there) then this requirement will be met automatically -- SQLITE_CORE is always defined when compiling sqlite3.c).

(8) By George on 2022-08-31 18:30:38 in reply to 7 [link] [source]

OK, I think I almost have this working. The last issue is that building lsm1.c results in a large number of implicit conversion warnings, as well as warnings about ambiguous expansion of MAX and MIN. Am I missing a define or flag, or is my invocation for generating lsm1.c incorrect (make -f ../sqlite/Makefile.linux-gcc lsm1.c)?

(9) By Keith Medcalf (kmedcalf) on 2022-08-31 19:57:41 in reply to 8 [source]

The lsm1 extension is in ext/lsm1. If you make that directory current and then run tool/mklsm1c.tcl (that is, I use the command line tclsh tool\mklsm1c.tcl in the etc/lsm1 directory to create the self-contained lsm1.c file which is deposited in etc/lsm1). I never bothered to look at what the linux makefile was doing because I am not using linux primarily, and the method of using the tcl tool to generate the lsm1.c file works on all operating systems.

I see a bunch of 'warning: useless storage class specifier in empty declaration' that are merely telling you that, in case you didn't know, assigning a storage-class (ie, auto, static, extern, etc) to a struct declaration that does not actually allocate storage is a useless endeavor.

If allowed to the MinGW (GCC 10.2) compiler will generate a huge amount of warning messages. They are accurate, but irrelevant. The compiler just does not know that they are irrelevant, but spews them just in case the code writer did something stupid.

That said, however, my own "private" branch has many changes to the SQLite3 code -- such as removing all the cruft added to the CLI and putting it (and all the extensions including my own) and other changes (such as more and better introspection pragmas) -- in the "core".