SQLite 真的很容易編譯
上週,我一直在做一個 SQL 網站(https://sql-steps.wizardzines.com/,一個 SQL 示例列表)。我使用 sqlite 執行網站上的所有查詢,並且我想在其中一個例子(這個)中使用視窗函式。
但是我使用的是 Ubuntu 18.04 中的 sqlite 版本,它太舊了,不支援視窗函式。所以我需要升級 sqlite!
事實證明,這個過程超麻煩(如通常一樣),但是非常有趣!我想起了一些有關可執行檔案和共享庫如何工作的資訊,結論令人滿意。所以我想在這裡寫下來。
(劇透:https://www.sqlite.org/howtocompile.html 中解釋瞭如何編譯 SQLite,它只需花費 5 秒左右,這比我平時從原始碼編譯的體驗容易了許多。)
嘗試 1:從它的網站下載 SQLite 二進位制檔案
SQLite 的下載頁面有一個用於 Linux 的 SQLite 命令列工具的二進位制檔案的連結。我下載了它,它可以在膝上型電腦上執行,我以為這就完成了。
但是後來我嘗試在構建伺服器(Netlify) 上執行它,得到了這個極其奇怪的錯誤訊息:“File not found”。我進行了追蹤,並確定 execve
返回錯誤程式碼 ENOENT,這意味著 “File not found”。這有點令人發狂,因為該檔案確實存在,並且有正確的許可權。
我搜尋了這個問題(通過搜尋 “execve enoen”),找到了這個 stackoverflow 中的答案,它指出要執行二進位制檔案,你不僅需要二進位制檔案存在!你還需要它的載入程式才能存在。(載入程式的路徑在二進位制檔案內部)
要檢視載入程式的路徑,可以使用 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 位二進位制文件(?),因此我需要嘗試一些不同的東西。
嘗試 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 的方式如下:
- 從下載頁面下載整合的 tarball
- 執行
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 的構建過程如此簡單很酷,因為過去我很樂於編輯 sqlite 的原始碼來了解其 B 樹的實現方式。
鑑於我對 SQLite 的瞭解,這並不令人感到意外(它在受限環境/嵌入式中確實可以很好地工作,因此可以以一種非常簡單/最小的方式進行編譯是有意義的)。 但這真是太好了!
via: https://jvns.ca/blog/2019/10/28/sqlite-is-really-easy-to-compile/
作者:Julia Evans 選題:lujun9972 譯者:geekpi 校對:wxy
訂閱“Linux 中國”官方小程式來檢視
相關文章
- Sqlite記錄01_ubuntu 12.04編譯sqliteSQLiteUbuntu編譯
- xcode 編譯opencv ios容易出現的錯誤XCode編譯OpenCViOS
- 做軟體測試工程師真的很容易嗎?工程師
- 【譯】五個ES6功能,讓你編寫程式碼更容易
- C++編譯SQLite資料庫以及如何使用加密資料庫SQLCipherC++編譯SQLite資料庫加密
- [譯] SQLite 底層查詢原理SQLite
- [譯]從 SQLite 逐步遷移到 RoomSQLiteOOM
- [譯] 從 SQLite 逐步遷移到 RoomSQLiteOOM
- 【譯】程式設計不容易程式設計
- 【譯】「開源」其實很容易
- 為什麼 SQLite 用 C 編寫?SQLite
- Java編譯與反編譯Java編譯
- 編譯編譯
- hadoop編譯—+2.x編譯Hadoop編譯
- gcc 編譯器與 clang 編譯器GC編譯
- 編譯器的編譯基本過程編譯
- 一張圖解析 編譯器編譯流程圖解編譯
- ubuntu下編譯交叉編譯工具鏈Ubuntu編譯
- [譯]iOS編譯器iOS編譯
- 程式碼線上編譯器(上)- 編輯及編譯編譯
- 一段很不容易的翻譯
- 開源編譯工具和編譯軟體編譯
- Make編譯之編譯32bit ffmpeg編譯
- N1064編譯鏈編譯編譯
- webrtc編譯Web編譯
- 編譯VIM編譯
- acl 編譯編譯
- 交叉編譯編譯
- gcc編譯GC編譯
- srilm編譯編譯
- 編譯版本編譯
- 編譯 ncurses編譯
- 編譯宏編譯
- 編譯原理編譯原理
- 編譯 zsh編譯
- 編譯 git編譯Git
- 【SQLite】SQLite簡介SQLite
- GCC編譯過程(預處理->編譯->彙編->連結)GC編譯