Linux中國

GNU Autotools 介紹

你有沒有下載過流行的軟體項目的源代碼,要求你輸入幾乎是儀式般的 ./configure; make && make install 命令序列來構建和安裝它?如果是這樣,你已經使用過 GNU Autotools 了。如果你曾經研究過這樣的項目所附帶的一些文件,你可能會對這種構建系統的顯而易見的複雜性感到害怕。

好的消息是,GNU Autotools 的設置要比你想像的要簡單得多,GNU Autotools 本身可以為你生成這些上千行的配置文件。是的,你可以編寫 20 或 30 行安裝代碼,並免費獲得其他 4,000 行。

Autotools 工作方式

如果你是初次使用 Linux 的用戶,正在尋找有關如何安裝應用程序的信息,那麼你不必閱讀本文!如果你想研究如何構建軟體,歡迎閱讀它;但如果你只是要安裝一個新應用程序,請閱讀我在在 Linux 上安裝應用程序的文章。

對於開發人員來說,Autotools 是一種管理和打包源代碼的快捷方式,以便用戶可以編譯和安裝軟體。 Autotools 也得到了主要打包格式(如 DEB 和 RPM)的良好支持,因此軟體存儲庫的維護者可以輕鬆管理使用 Autotools 構建的項目。

Autotools 工作步驟:

  1. 首先,在 ./configure 步驟中,Autotools 掃描宿主機系統(即當前正在運行的計算機)以發現默認設置。默認設置包括支持庫所在的位置,以及新軟體應放在系統上的位置。
  2. 接下來,在 make 步驟中,Autotools 通常通過將人類可讀的源代碼轉換為機器語言來構建應用程序。
  3. 最後,在 make install 步驟中,Autotools 將其構建好的文件複製到計算機上(在配置階段檢測到)的相應位置。

這個過程看起來很簡單,和你使用 Autotools 的步驟一樣。

Autotools 的優勢

GNU Autotools 是我們大多數人認為理所當然的重要軟體。與 GCC(GNU 編譯器集合)一起,Autotools 是支持將自由軟體構建和安裝到正在運行的系統的腳手架。如果你正在運行 POSIX 系統,可以毫不保守地說,你的計算機上的操作系統里大多數可運行軟體都是這些這樣構建的。

即使是你的項目是個玩具項目不是操作系統,你可能會認為 Autotools 對你的需求來說太過分了。但是,儘管它的名氣很大,Autotools 有許多可能對你有益的小功能,即使你的項目只是一個相對簡單的應用程序或一系列腳本。

可移植性

首先,Autotools 考慮到了可移植性。雖然它無法使你的項目在所有 POSIX 平台上工作(這取決於你,編碼的人),但 Autotools 可以確保你標記為要安裝的文件安裝到已知平台上最合理的位置。而且由於 Autotools,高級用戶可以輕鬆地根據他們自己的系統情況定製和覆蓋任何非最佳設定。

使用 Autotools,你只要知道需要將文件安裝到哪個常規位置就行了。它會處理其他一切。不需要可能破壞未經測試的操作系統的定製安裝腳本。

打包

Autotools 也得到了很好的支持。將一個帶有 Autotools 的項目交給一個發行版打包者,無論他們是打包成 RPM、DEB、TGZ 還是其他任何東西,都很簡單。打包工具知道 Autotools,因此可能不需要修補、魔改或調整。在許多情況下,將 Autotools 項目結合到流程中甚至可以實現自動化。

如何使用 Autotools

要使用 Autotools,必須先安裝它。你的發行版可能提供一個單個的軟體包來幫助開發人員構建項目,或者它可能為每個組件提供了單獨的軟體包,因此你可能需要在你的平台上進行一些研究以發現需要安裝的軟體包。

Autotools 的組件是:

  • automake
  • autoconf
  • automake
  • make

雖然你可能需要安裝項目所需的編譯器(例如 GCC),但 Autotools 可以很好地處理不需要編譯的腳本或二進位文件。實際上,Autotools 對於此類項目非常有用,因為它提供了一個 make uninstall 腳本,以便於刪除。

安裝了所有組件之後,現在讓我們了解一下你的項目文件的組成結構。

Autotools 項目結構

GNU Autotools 有非常具體的預期規範,如果你經常下載和構建源代碼,可能大多數都很熟悉。首先,源代碼本身應該位於一個名為 src 的子目錄中。

你的項目不必遵循所有這些預期規範,但如果你將文件放在非標準位置(從 Autotools 的角度來看),那麼你將不得不稍後在 Makefile 中對其進行調整。

此外,這些文件是必需的:

  • NEWS
  • README
  • AUTHORS
  • ChangeLog

你不必主動使用這些文件,它們可以是包含所有信息的單個匯總文檔(如 README.md)的符號鏈接,但它們必須存在。

Autotools 配置

在你的項目根目錄下創建一個名為 configure.ac 的文件。autoconf 使用此文件來創建用戶在構建之前運行的 configure shell 腳本。該文件必須至少包含 AC_INITAC_OUTPUT M4 宏。你不需要了解有關 M4 語言的任何信息就可以使用這些宏;它們已經為你編寫好了,並且所有與 Autotools 相關的內容都在該文檔中定義好了。

在你喜歡的文本編輯器中打開該文件。AC_INIT 宏可以包括包名稱、版本、報告錯誤的電子郵件地址、項目 URL 以及可選的源 TAR 文件名稱等參數。

AC_OUTPUT 宏更簡單,不用任何參數。

AC_INIT([penguin], [2019.3.6], [[seth@example.com][8]])
AC_OUTPUT

如果你此刻運行 autoconf,會依據你的 configure.ac 文件生成一個 configure 腳本,它是可以運行的。但是,也就是能運行而已,因為到目前為止你所做的就是定義項目的元數據,並要求創建一個配置腳本。

你必須在 configure.ac 文件中調用的下一個宏是創建 Makefile 的函數。 Makefile 會告訴 make 命令做什麼(通常是如何編譯和鏈接程序)。

創建 Makefile 的宏是 AM_INIT_AUTOMAKE,它不接受任何參數,而 AC_CONFIG_FILES 接受的參數是你要輸出的文件的名稱。

最後,你必須添加一個宏來考慮你的項目所需的編譯器。你使用的宏顯然取決於你的項目。如果你的項目是用 C++ 編寫的,那麼適當的宏是 AC_PROG_CXX,而用 C 編寫的項目需要 AC_PROG_CC,依此類推,詳見 Autoconf 文檔中的 Building Programs and Libraries 部分。

例如,我可能會為我的 C++ 程序添加以下內容:

AC_INIT([penguin], [2019.3.6], [[seth@example.com][8]])
AC_OUTPUT
AM_INIT_AUTOMAKE
AC_CONFIG_FILES([Makefile])
AC_PROG_CXX

保存該文件。現在讓我們將目光轉到 Makefile

生成 Autotools Makefile

Makefile 並不難手寫,但 Autotools 可以為你編寫一個,而它生成的那個將使用在 ./configure 步驟中檢測到的配置選項,並且它將包含比你考慮要包括或想要自己寫的還要多得多的選項。然而,Autotools 並不能檢測你的項目構建所需的所有內容,因此你必須在文件 Makefile.am 中添加一些細節,然後在構造 Makefile 時由 automake 使用。

Makefile.am 使用與 Makefile 相同的語法,所以如果你曾經從頭開始編寫過 Makefile,那麼這個過程將是熟悉和簡單的。通常,Makefile.am 文件只需要幾個變數定義來指示要構建的文件以及它們的安裝位置即可。

_PROGRAMS 結尾的變數標識了要構建的代碼(這通常被認為是 原語 primary 目標;這是 Makefile 存在的主要意義)。Automake 也會識別其他原語,如 _SCRIPTS_ DATA_LIBRARIES,以及構成軟體項目的其他常見部分。

如果你的應用程序在構建過程中需要實際編譯,那麼你可以用 bin_PROGRAMS 變數將其標記為二進位程序,然後使用該程序名稱作為變數前綴引用構建它所需的源代碼的任何部分(這些部分可能是將被編譯和鏈接在一起的一個或多個文件):

bin_PROGRAMS = penguin
penguin_SOURCES = penguin.cpp

bin_PROGRAMS 的目標被安裝在 bindir 中,它在編譯期間可由用戶配置。

如果你的應用程序不需要實際編譯,那麼你的項目根本不需要 bin_PROGRAMS 變數。例如,如果你的項目是用 Bash、Perl 或類似的解釋語言編寫的腳本,那麼定義一個 _SCRIPTS 變數來替代:

bin_SCRIPTS = bin/penguin

Automake 期望源代碼位於名為 src 的目錄中,因此如果你的項目使用替代目錄結構進行布局,則必須告知 Automake 接受來自外部源的代碼:

AUTOMAKE_OPTIONS = foreign subdir-objects

最後,你可以在 Makefile.am 中創建任何自定義的 Makefile 規則,它們將逐字複製到生成的 Makefile 中。例如,如果你知道一些源代碼中的臨時值需要在安裝前替換,則可以為該過程創建自定義規則:

all-am: penguin
        touch bin/penguin.sh

penguin: bin/penguin.sh
        @sed "s|__datadir__|@datadir@|" $< >bin/$@

一個特別有用的技巧是擴展現有的 clean 目標,至少在開發期間是這樣的。make clean 命令通常會刪除除了 Automake 基礎結構之外的所有生成的構建文件。它是這樣設計的,因為大多數用戶很少想要 make clean 來刪除那些便於構建代碼的文件。

但是,在開發期間,你可能需要一種方法可靠地將項目返回到相對不受 Autotools 影響的狀態。在這種情況下,你可能想要添加:

clean-local:
        @rm config.status configure config.log
        @rm Makefile
        @rm -r autom4te.cache/
        @rm aclocal.m4
        @rm compile install-sh missing Makefile.in

這裡有很多靈活性,如果你還不熟悉 Makefile,那麼很難知道你的 Makefile.am 需要什麼。最基本需要的是原語目標,無論是二進位程序還是腳本,以及源代碼所在位置的指示(無論是通過 _SOURCES 變數還是使用 AUTOMAKE_OPTIONS 告訴 Automake 在哪裡查找源代碼)。

一旦定義了這些變數和設置,如下一節所示,你就可以嘗試生成構建腳本,並調整缺少的任何內容。

生成 Autotools 構建腳本

你已經構建了基礎結構,現在是時候讓 Autotools 做它最擅長的事情:自動化你的項目工具。對於開發人員(你),Autotools 的介面與構建代碼的用戶的不同。

構建者通常使用這個眾所周知的順序:

$ ./configure
$ make
$ sudo make install

但是,要使這種咒語起作用,你作為開發人員必須引導構建這些基礎結構。首先,運行 autoreconf 以生成用戶在運行 make 之前調用的 configure 腳本。使用 -install 選項將輔助文件(例如符號鏈接)引入到 depcomp(這是在編譯過程中生成依賴項的腳本),以及 compile 腳本的副本(一個編譯器的包裝器,用於說明語法,等等)。

$ autoreconf --install
configure.ac:3: installing &apos;./compile&apos;
configure.ac:2: installing &apos;./install-sh&apos;
configure.ac:2: installing &apos;./missing&apos;

使用此開發構建環境,你可以創建源代碼分發包:

$ make dist

dist 目標是從 Autotools 「免費」獲得的規則。這是一個內置於 Makefile 中的功能,它是通過簡單的 Makefile.am 配置生成的。該目標可以生成一個 tar.gz 存檔,其中包含了所有源代碼和所有必要的 Autotools 基礎設施,以便下載程序包的人員可以構建項目。

此時,你應該仔細查看存檔文件的內容,以確保它包含你要發送給用戶的所有內容。當然,你也應該嘗試自己構建:

$ tar --extract --file penguin-0.0.1.tar.gz
$ cd penguin-0.0.1
$ ./configure
$ make
$ DESTDIR=/tmp/penguin-test-build make install

如果你的構建成功,你將找到由 DESTDIR 指定的已編譯應用程序的本地副本(在此示例的情況下為 /tmp/penguin-test-build)。

$ /tmp/example-test-build/usr/local/bin/example
hello world from GNU Autotools

去使用 Autotools

Autotools 是一個很好的腳本集合,可用於可預測的自動發布過程。如果你習慣使用 Python 或 Bash 構建器,這個工具集對你來說可能是新的,但它為你的項目提供的結構和適應性可能值得學習。

而 Autotools 也不只是用於代碼。Autotools 可用於構建 Docbook 項目,保持媒體有序(我使用 Autotools 進行音樂發布),文檔項目以及其他任何可以從可自定義安裝目標中受益的內容。

via: https://opensource.com/article/19/7/introduction-gnu-autotools

作者:Seth Kenlon 選題:lujun9972 譯者:wxy 校對:wxy

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


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國