SQLite 真的很容易編譯

上週,我一直在作一個 SQL 網站(sql-steps.wizardzines.com/,一個 SQL 示例列表)。我使用 sqlite 運行網站上的全部查詢,而且我想在其中一個例子(這個)中使用窗口函數。html

可是我使用的是 Ubuntu 18.04 中的 sqlite 版本,它太舊了,不支持窗口函數。因此我須要升級 sqlite!linux

事實證實,這個過程超麻煩(如一般同樣),可是很是有趣!我想起了一些有關可執行文件和共享庫如何工做的信息,結論使人滿意。因此我想在這裏寫下來。git

(劇透:www.sqlite.org/howtocompil… 中解釋瞭如何編譯 SQLite,它只需花費 5 秒左右,這比我平時從源碼編譯的體驗容易了許多。)github

嘗試 1:從它的網站下載 SQLite 二進制文件

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

嘗試 2:安裝 Debian sqlite3 軟件包

好吧,我想我也許能夠安裝來自 debian testing 的 sqlite 軟件包。嘗試從另外一個我不使用的 Debian 版本安裝軟件包並非一個好主意,可是出於某種緣由,我仍是決定嘗試一下。函數

此次絕不意外地破壞了我計算機上的 sqlite(這也破壞了 git),但我設法經過 sudo dpkg --purge --force-all libsqlite3-0 恢復了,並使全部依賴於 sqlite 的軟件再次工做。

嘗試 3:提取 Debian sqlite3 軟件包

我還嘗試僅從 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
複製代碼

嘗試 4:從源代碼進行編譯

我花費這麼多時間嘗試下載 sqlite 二進制的緣由是我認爲從源代碼編譯 sqlite 既煩人又耗時。可是顯然,下載隨便一個 sqlite 二進制文件根本不適合我,所以我最終決定嘗試本身編譯它。

這有指導:如何編譯 SQLite。它是宇宙中最簡單的東西。一般,編譯的感受是相似這樣的:

  • 運行 ./configure
  • 意識到我缺乏依賴
  • 再次運行 ./configure
  • 運行 make
  • 編譯失敗,由於我安裝了錯誤版本的依賴
  • 去作其餘事,以後找到二進制文件

編譯 SQLite 的方式以下:

全部代碼都在一個文件(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 的構建過程如此簡單很酷,由於過去我很樂於編輯 sqlite 的源碼來了解其 B 樹的實現方式。

鑑於我對 SQLite 的瞭解,這並不使人感到意外(它在受限環境/嵌入式中確實能夠很好地工做,所以能夠以一種很是簡單/最小的方式進行編譯是有意義的)。 但這真是太好了!


via: jvns.ca/blog/2019/1…

做者:Julia Evans 選題:lujun9972 譯者:geekpi 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

相關文章
相關標籤/搜索