Last week, I’ve been making an SQL site (sql-steps.wizardzines.com/, a list of SQL examples). I use SQLite to run all queries on the site, and I want to use window functions in one example (this one).
But I’m using the SQLite version of Ubuntu 18.04, which is too old to support window functions. So I need to upgrade SQLite!
As it turns out, this process is extremely cumbersome (as usual), but a lot of fun! I remembered some information about how executables and shared libraries work, and the results were satisfactory. So I want to write it down here.
(according to plot: www.sqlite.org/howtocompil… Explains how to compile SQLite, which takes about five seconds, much easier than my usual experience compiling from source code.
Attempt 1: Download the SQLite binaries from its website
The DOWNLOAD page for SQLite has a link to binaries for the SQLite command-line tool for Linux. I downloaded it, it ran on my laptop, and I thought I was done.
But then I tried to run it on the build server (Netlify) and got this extremely strange error message: “File not found.” I tracked it down and determined that execve returned the error code ENOENT, which means “File not found.” This is a bit maddening because the file actually exists and has the right permissions.
I searched for this question (by searching for ‘execve Enoen’) and found the answer in this StackOverflow, which states that to run binaries, you don’t just need binaries to exist! You also need its loader to exist. (The path to the loader is inside the binary)
To see the path of the loader, use LDD, as follows:
$ ldd sqlite3
linux-gate.so.1 (0xf7f9d000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf7f70000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e6e000)
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xf7e4f000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c73000)
/lib/ld-linux.so.2
Copy the code
So /lib/ld-linux.so.2 is the loader, and the file does not exist on the build server, probably because Xenial (Xenial is Ubuntu 16.04, 18.04 “Bionic Beaver”) the installer does not support 32-bit binaries (?) So I need to try something different.
Attempt 2: Install the Debian SQlite3 package
Well, I think I might be able to install the SQLite package from Debian Testing. Trying to install a package from another version of Debian that I don’t use is not a good idea, but for some reason I decided to give it a try.
This time not surprisingly broke SQLite on my computer (which also broke Git), but I managed to recover it via sudo DPKG –purge –force-all libsqlite3-0 and get all the software that relied on SQLite working again.
Attempt 3: Extract the Debian SQlite3 package
I also tried to just extract the SQlite3 binary from the Debian SQLite package and run it. Not surprisingly, this doesn’t work either, but this one is easier to understand: I have an old version of libreadline (.so.7), but it needs.so.8.
$ ./usr/bin/sqlite3
./usr/bin/sqlite3: error while loading shared libraries: libreadline.so.8: cannot open shared object file: No such file or directory
Copy the code
Attempt 4: Compile from source
The reason I spend so much time trying to download SQLite binaries is because I think compiling SQLite from source is annoying and time-consuming. But obviously downloading just any SQLite binary wasn’t for me at all, so I finally decided to try compiling it myself.
Here’s a guide: how to compile SQLite. It’s the simplest thing in the universe. In general, compilation feels something like this:
- run
./configure
- Realizing my lack of dependence
- Run again
./configure
- run
make
- The compilation failed because I installed the wrong version of the dependency
- Go do something else, and then find the binary
SQLite is compiled as follows:
- Download the integrated tarball from the Download page
- run
gcc shell.c sqlite3.c -lpthread -ldl
- Done!!
All the code is in one file (sqlite.c), and there are no weird dependencies! It’s fantastic.
For my part, I didn’t really need thread support or readline support, so I used the instructions on the build page to create a very simple binary that used only liBC and no other shared libraries.
$ ldd sqlite3
linux-vdso.so.1 (0x00007ffe8e7e9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbea4988000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbea4d79000)
Copy the code
This is good, because it makes it easy to experience SQLite
I think it’s cool that the SQLite build process is so simple, because IN the past I’ve enjoyed editing SQLite’s source code to see how its B tree is implemented.
This is not surprising given what I know about SQLite (it does work well in constrained environments/embedded, so it makes sense to be able to compile in a very simple/minimal way). But this is great!
Via: JVNS. Ca/blog / 2019/1…
By Julia Evans (lujun9972
This article is originally compiled by LCTT and released in Linux China