在 Linux 環境底下透過原始碼安裝軟體,從下載、驗證、解壓縮、到安裝

28 minute read

簡介

前陣子發現國外有個專案叫做 Linux From Scratch (LFS),內容是教你一步一步打造屬於自己的 Linux,看完這個專案的簡介以及前面幾個章節以後實在心癢難耐,相信對於喜歡新奇事物或是挑戰的人,看到那篇介紹之後都會躍躍欲試。

但不是每個人對於 Linux 都是那麼熟悉,像我大概只比知道 ls, mkdir, ifconfig 這些簡單指令好一些些而已…,而 LFS 專案內會需要自己手動安裝一些套件,不過沒關係,LFS 的 2.3 節 內介紹了兩篇手動安裝套件的文章,就以這兩篇文章為基礎,一起試著自己在 Linux 底下安裝套件吧!

Prerequisite

  • 一台 Linux 的電腦、或是虛擬機

我在練習的時候是使用 Docker 上運行 ubuntu:latest 的這個映像檔,不過其他方式或是其他 Linux 發行版 應該也是大同小異

透過套件(apt、dpkg) 安裝以及自己編譯並安裝的差異

以 FFmpeg 安裝為例

FFmpeg 是一套指令介面的開源影音轉檔工具,如果你知道格式工廠的話,FFmpeg 的功能就類似於它,只是是指令介面而且功能更強。由於它是開源軟體且功能強大,常常可以在許多其他的影音程式中見到它的蹤影

在 FFmpeg 的官網中可以找到原始碼以及驗證金鑰等資訊,很適合拿來作為練習的材料,那我們就先從下載 FFmpeg 的原始碼開始吧。

下載

FFmpeg 的下載網頁 可以看到許多打包好的下載選項,包含 Linux, Windows, MacOS 等等,另外也有 git repo 的連結,但既然作為一個開發者,不用指令來下載就不酷了!

我們將下載網頁繼續向下捲動,可以看到他們提供了不同版本的原始碼,並以不同的方式 (xz, bzip2, gzip) 壓縮。這篇文章撰寫時最新的版本為 FFmpeg 4.3.2 “4:3”,那我們就以這個版本以及 gzip 壓縮格式來作為範例。

Linux 下常用的下載套件有以下兩種

如果對方有推送至網路上的 git repo 的話,也能使用

  • git

來下載原始碼,可以自行在網路上尋找它們之間的差異,並使用自己熟悉的套件來做下載,以我自己的習慣來說,下載檔案我用 wget,而 curl 會用在 RESTful Api 的測試上,下面就繼續接著介紹這幾個套件的下載方式。

wget

wget 的使用方式很直覺,直接在 wget 後面接上要下載的檔案的 url 即可。

wget https://ffmpeg.org/releases/ffmpeg-4.3.2.tar.gz

除此之外,wget 還有其他進階用法,例如續傳、批次下載等等,詳細請參考這篇 Linux 使用 wget 指令自動下載網頁檔案教學與範例 - G.T.Wang

curl

要使用 curl 下載的話需要多指定一些參數如下

# 將連結的檔案下載下來並命名為 ffmpeg.tar.gz
curl -o ffmpeg.tar.gz https://ffmpeg.org/releases/ffmpeg-4.3.2.tar.gz

或是

# 將連結的檔案下載下來並以連結原先的檔名命名
curl -O https://ffmpeg.org/releases/ffmpeg-4.3.2.tar.gz

有關 curl 的更多使用方式可以參考這個厲害的部落格 TechBridge 技術共筆部落格 上的這篇文章 Linux Curl Command 指令與基本操作入門教學 - KD Chang

git

git 的話比較單純,官方也一並把指令提供給大家,只要複製貼上即可將最新版本的原始碼複製下來。

# 將指定的 repo 複製下來並命名為 ffmpeg
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg

由於使用這個方式下載下來的檔案不是壓縮檔,而是已經是包含所有原始碼的資料夾,因此也不需下面介紹的驗證與解壓縮步驟,可以直接跳至安裝的章節。

驗證

今天我們取得一個軟體的來源可能不是在官方網站,或者下載時受到攻擊,導致拿到的檔案可能藏有病毒或是已經毀損,此時我們可以透過驗證來確保下載來的檔案和官方提供的檔案內容是一致的。最常見的驗證方式是計算 checksum,而 checksum 是由 雜湊函式 產生,因此任兩個內容一致的檔案,其 checksum 一定會相同。

講到 checksum 一般會先想用 md5sum,這是一個預先安裝在大多數 Linux 發行版的套件,不過 ffmpeg 提供的是 pgp 的密鑰,所以這邊只會講解 pgp 的驗證方法,關於 md5sum 的使用方式可以參考 Linux 產生 MD5 與 SHA1 校驗碼 Checksum 使用教學,檢查檔案是否損毀 - G.T.Wang

gpg

我們再次回到 ffmpeg 的下載頁面,並下載相對應的 pgp signature,如果原先下載的是 gzip 的原始碼,那就下載 gzip 旁邊的 pgp signature,同理 bzip2 就要下載 bzip2 旁邊的 pgp signature。

這邊再次快速複習一下 wget 的用法

wget https://ffmpeg.org/releases/ffmpeg-4.3.2.tar.gz.asc

接著就是這個章節的主角,pgp 驗證了。我在這裡的時候撞了滿多次牆,但學到的東西滿多的,所以一併把錯誤的過程也記錄下來。

首先我下載了 gpg 這個套件(對,我沒打錯,真的不是 pgp 而是 gpg),然後我找到了這篇文章 How to Verify PGP Signature of Downloaded Software on Linux 並試著用上面的指令來驗證,先試試看 –import

# Explanation of '--import' in '--help'
# --import import/merge keys
gpg --import ffmpeg-4.3.2.tar.gz.asc

# gpg: directory '/root/.gnupg' created
# gpg: keybox '/root/.gnupg/pubring.kbx' created
# gpg: no valid OpenPGP data found.
# gpg: Total number processed: 0

看起來是失敗了…,雖然我沒有 .sig 檔,但試另一個指令 –verify–fingerprint 看看呢?

# Explanation of '--verify' in '--help'
# --verify verify a signature
gpg --verify ffmpeg-4.3.2.tar.gz.asc ffmpeg-4.3.2.tar.gz

# gpg: Signature made Sat Jul 11 10:41:19 2020 UTC
# gpg:                using RSA key FCF986EA15E6E293A5644F10B4322F04D67658D8
# gpg:                issuer "ffmpeg-devel@ffmpeg.org"
# gpg: Can't check signature: No public key


# Explanation of '--fingerprint' in '--help'
# --fingerprint list keys and fingerprints
gpg --fingerprint ffmpeg-4.3.2.tar.gz.asc

# gpg: /root/.gnupg/trustdb.gpg: trustdb created
# gpg: error reading key: No public key

看起來還是不行…,不過這次的訊息比較明確了,它指出我沒有公鑰來檢查這個 pgp signature,但在 ffmpeg 的網站上並沒有找到關於這個公鑰的相關資訊,因此我再度求助於 Google 並找到了這篇文章 UNIX / Linux PGP TarBall File Signature Keys Verification - Vivek Gite。上面記載了另一個 gpg 的參數 –recv-key–keyserver

gpg --recv-key <publicKey>
## we can also get keys from speifici key server ##
gpg --keyserver pgpkeys.mit.edu --recv-key <publicKey>

上面那段指令的意思就是到 pgpkeys.mit.edu 這個網站去取得某一串公鑰(所以 MIT 架了一個網站用來存放公鑰來讓大家存取,cooooooool!),那就來實測這個指令看看吧

gpg --keyserver pgpkeys.mit.edu --recv-key FCF986EA15E6E293A5644F10B4322F04D67658D8

# gpg: key B4322F04D67658D8: public key "FFmpeg release signing key <ffmpeg-devel@ffmpeg.org>" imported
# gpg: Total number processed: 1
# gpg:               imported: 1

看起來有匯入這個公鑰了,那來試試看另一個參數 –list-keys,觀察有沒有什麼變化

gpg --list-keys

# /root/.gnupg/pubring.kbx
# ------------------------
# pub   rsa2048 2011-04-26 [SC]
#       FCF986EA15E6E293A5644F10B4322F04D67658D8
# uid           [ unknown] FFmpeg release signing key <ffmpeg-devel@ffmpeg.org>
# sub   rsa2048 2011-04-26 [E]

OK,ffmpeg 的公鑰確實有匯進我的電腦了,那我們回頭再次驗證下載回來的 ffmpeg 壓縮檔吧

gpg --verify ffmpeg-4.3.2.tar.gz.asc ffmpeg-4.3.2.tar.gz

# gpg: Signature made Sat Jul 11 10:41:19 2020 UTC
# gpg:                using RSA key FCF986EA15E6E293A5644F10B4322F04D67658D8
# gpg:                issuer "ffmpeg-devel@ffmpeg.org"
# gpg: Good signature from "FFmpeg release signing key <ffmpeg-devel@ffmpeg.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: FCF9 86EA 15E6 E293 A564  4F10 B432 2F04 D676 58D8

雖然訊息顯示 Good signature 但下面又有一段警語,根據 Gite 寫的那篇文章裡面提到

The signature is good, but you don’t trust this PGP key. In other words, the file has not tampered.

表示壓縮檔雖然通過了密鑰的檢查,但不確定密鑰本身就是原始作者提供的,如果很確定那組密鑰就是官方提供的,我們可以透過下面這個指令讓系統知道這組密鑰是沒問題的

# Explanation of '--edit-key' in '--help'
# --edit-key sign or edit a key
gpg --edit-key ffmpeg-devel@ffmpeg.org trust

到這邊我們可以假設下載來的 ffmpeg 原始碼壓縮檔是正常沒有被調包或毀損的,那麼就開始準備解壓縮嘍。

解壓縮

.tar.gz 這個副檔名含有兩個意思,.tar 是用來將一群檔案打包為一個檔案,而 .gz 表示用 gzip 做壓縮,一共含有兩個動作。

關於解壓縮 tarball (壓縮過的 tar 檔的簡稱),鳥哥的私房菜中這篇文章 第八章、檔案與檔案系統的壓縮,打包與備份 寫得非常詳盡,如果只是想應用的話我們可以快速找到 8.3.1 tar 這個章節並把裡面的指令拿出來用

# -x 表示解壓縮
# -v 表示將街壓縮的過程印在終端機上
# -f 後面指定要解壓縮的檔案
tar -xvf ffmpeg-4.3.2.tar.gz

Tip: 參數可以用 -zxvf 或 -xvf 都可以。

接著應該可以看到當前目錄底下有一個 ffmpeg-4.3.2 資料夾,最強轉檔工具 ffmpeg 的原始碼就都放在這個資料夾裡面了。

安裝

進到 ffmpeg-4.3.2 資料夾底下,有兩個非常重要的檔案,一個叫做 README.md 另一個叫做 INSTALL.md,README 裡面說明了整個資料夾結構,而 INSTALL 解釋該如何編譯並安裝這套工具,只要下載任何套件或原始碼一定都是先從這兩個檔案開始看起。透過 catvi 等指令,我們可以看到 INSTALL 裡面寫了以下內容:

## Installing FFmpeg

1. Type `./configure` to create the configuration. A list of configure
options is printed by running `configure --help`.

    `configure` can be launched from a directory different from the FFmpeg
sources to build the objects out of tree. To do this, use an absolute
path when launching `configure`, e.g. `/ffmpegdir/ffmpeg/configure`.

2. Then type `make` to build FFmpeg. GNU Make 3.81 or later is required.

3. Type `make install` to install all binaries and libraries you built.

NOTICE
------

 - Non system dependencies (e.g. libx264, libvpx) are disabled by default.

照著指示先輸入 ./configure

./configure

Notice: 由於我用的是 docker 上剛建好,很乾淨的 ubuntu 發行版,因此拋出了一些錯誤表示找不到 nasm/yasm ,我到 Stackoverflow 上搜尋,找到了下面這個問題 yasm/nasm not found or too old. Use –disable-yasm for a crippled build,按照解答提供的指令 apt-get install yasm 安裝套件後即可通過 configure。

下一步是 make 也就是編譯並建置專案,這邊根據電腦效能,可能會花上數分鐘,完成之後就是安裝嘍!

make

make install

Notice: 這裡系統提示找不到 make 指令,如果和我遇到一樣的問題,只要透過 apt 套件管理器安裝即可 apt-get install make

到此安裝流程就完成了,可以使用 ffmpeg 的檢查版本來確認一下是否有安裝成功。

ffmpeg -version

# ffmpeg version 4.3.2 Copyright (c) 2000-2021 the FFmpeg developers
# built with gcc 9 (Ubuntu 9.3.0-17ubuntu1~20.04)
# configuration: 
# libavutil      56. 51.100 / 56. 51.100
# libavcodec     58. 91.100 / 58. 91.100
# libavformat    58. 45.100 / 58. 45.100
# libavdevice    58. 10.100 / 58. 10.100
# libavfilter     7. 85.100 /  7. 85.100
# libswscale      5.  7.100 /  5.  7.100
# libswresample   3.  7.100 /  3.  7.100

如果有出現上列訊息而且版本跟你下載的版本一致的話,就表示下載成功嘍!接著就可以自己試著使用 ffmpeg 將影片轉成 gif,或者將圖片裁減,體驗一下 ffmpeg 的魅力吧!

總結

這篇文章所展示的原始碼編譯及安裝過程中,沒有遇到太多困難的問題,而在實務上可能會遇到其他問題,像是開頭提到的文章 Building and Installing Software Packages for Linux 中,第 7 章到第 14 章中作者所遇到的狀況,有些是需要改 makefile 的參數,有些需要更改電腦的設定。除此之外,還有許多議題沒有講到,像是

  • md5sum 的使用方式
  • wget 及 curl 的進階使用技巧
  • 使用 xmkmf 從 IMakefile 產出 Makefile
  • Makefile 的內容及撰寫

但希望至少這篇文章能夠作為一個起始點,讓「原始碼編譯並安裝」這件事不再是那麼模糊的概念。