上週,我一直在作一個 SQL 網站(sql-steps.wizardzines.com/,一個 SQL 示例列表)。我使用 sqlite 運行網站上的全部查詢,而且我想在其中一個例子(這個)中使用窗口函數。html
可是我使用的是 Ubuntu 18.04 中的 sqlite 版本,它太舊了,不支持窗口函數。因此我須要升級 sqlite!linux
事實證實,這個過程超麻煩(如一般同樣),可是很是有趣!我想起了一些有關可執行文件和共享庫如何工做的信息,結論使人滿意。因此我想在這裏寫下來。git
(劇透:www.sqlite.org/howtocompil… 中解釋瞭如何編譯 SQLite,它只需花費 5 秒左右,這比我平時從源碼編譯的體驗容易了許多。)github
SQLite 的下載頁面有一個用於 Linux 的 SQLite 命令行工具的二進制文件的連接。我下載了它,它能夠在筆記本電腦上運行,我覺得這就完成了。sql
可是後來我嘗試在構建服務器(Netlify) 上運行它,獲得了這個極其奇怪的錯誤消息:「File not found」。我進行了追蹤,並肯定 execve
返回錯誤代碼 ENOENT,這意味着 「File not found」。這有點使人發狂,由於該文件確實存在,而且有正確的權限。shell
我搜索了這個問題(經過搜索 「execve enoen」),找到了這個 stackoverflow 中的答案,它指出要運行二進制文件,你不只須要二進制文件存在!你還須要它的加載程序才能存在。(加載程序的路徑在二進制文件內部)bash
要查看加載程序的路徑,可使用 ldd
,以下所示:服務器
$ 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
複製代碼
因此 /lib/ld-linux.so.2
是加載程序,而該文件在構建服務器上不存在,多是由於 Xenial(Xenial 是 Ubuntu 16.04,本文應該使用的是 18.04 「Bionic Beaver」)安裝程序不支持 32 位二進制文件(?),所以我須要嘗試一些不一樣的東西。ionic
好吧,我想我也許能夠安裝來自 debian testing 的 sqlite 軟件包。嘗試從另外一個我不使用的 Debian 版本安裝軟件包並非一個好主意,可是出於某種緣由,我仍是決定嘗試一下。函數
此次絕不意外地破壞了我計算機上的 sqlite(這也破壞了 git),但我設法經過 sudo dpkg --purge --force-all libsqlite3-0
恢復了,並使全部依賴於 sqlite 的軟件再次工做。
我還嘗試僅從 Debian sqlite 軟件包中提取 sqlite3 二進制文件並運行它。絕不意外,這也行不通,但這個更容易理解:我有舊版本的 libreadline(.so.7
),但它須要 .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
複製代碼
我花費這麼多時間嘗試下載 sqlite 二進制的緣由是我認爲從源代碼編譯 sqlite 既煩人又耗時。可是顯然,下載隨便一個 sqlite 二進制文件根本不適合我,所以我最終決定嘗試本身編譯它。
這有指導:如何編譯 SQLite。它是宇宙中最簡單的東西。一般,編譯的感受是相似這樣的:
./configure
./configure
make
編譯 SQLite 的方式以下:
gcc shell.c sqlite3.c -lpthread -ldl
全部代碼都在一個文件(sqlite.c
)中,而且沒有奇怪的依賴項!太奇妙了。
對我而言,我實際上並不須要線程支持或 readline 支持,所以我用編譯頁面上的說明來建立了一個很是簡單的二進制文件,它僅使用了 libc 而沒有其餘共享庫。
$ 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)
複製代碼
我認爲 SQLite 的構建過程如此簡單很酷,由於過去我很樂於編輯 sqlite 的源碼來了解其 B 樹的實現方式。
鑑於我對 SQLite 的瞭解,這並不使人感到意外(它在受限環境/嵌入式中確實能夠很好地工做,所以能夠以一種很是簡單/最小的方式進行編譯是有意義的)。 但這真是太好了!
via: jvns.ca/blog/2019/1…
做者:Julia Evans 選題:lujun9972 譯者:geekpi 校對:wxy