Chương 6. Biên dịch gói

# Chương 6. Biên dịch gói

Việc viết lại tài liệu này với các nội dung cập nhật và nhiều các ví dụ thực tế hơn đã có ở Guide for Debian Maintainers. Vui lòng sử dụng tài liệu mới này như là tài liệu hướng dẫn chính.

Bây giờ chúng ta xem như đã sẵn sàng để biên dịch gói.

## 6.1. (Tái) biên dịch toàn bộ

Để có thể (tái) biên dịch toàn bộ gói một cách đúng đắn, bạn cần phải đảm bảo là bạn đã cài đặt

- gói `build-essential`,

- các gói liệt kê ở trong mục `Build-Depends` (xem Phần 4.1, “`control`”), và

- các gói được liệt kê trong mục `Build-Depends-indep` (see Phần 4.1, “`control`”).

Sau đó bạn thực thi lệnh sau ở trong thư mục nguồn:

    $ dpkg-buildpackage -us -uc

Lệnh này sẽ làm hết tất cả những thứ cần thiết để tạo gói nhị phân và nguồn hoàn chỉnh cho bạn. Nó sẽ

- xóa sạch cây thư mục nguồn (`debian/rules clean`)

- biên dịch gói nguồn (`dpkg-source -b`)

- biên dịch chương trình (`debian/rules build`)

- biên dịch gói nhị phân (`fakeroot debian/rules binary`)

- tạo tập tin `.dsc`

- tạo tập tin `.changes`, dùng lệnh dpkg-genchanges

Nếu kết quả biên dịch đạt mức thỏa mãn yêu cầu, kí tên các tập tin `.dsc` và `.changes` dùng mã GPG riêng tư của bạn bằng lệnh debsign. Bạn cần phải nhập mật mã, hai lần. [62]

Đối với một gói không đến từ Debian, ví dụ như `gentoo`, bạn sẽ thấy những tập tin sau trong thư mục cấp trên (`~/gentoo`) sau khi biên dịch các gói xong:

- `gentoo_0.9.12.orig.tar.gz`

  Đây là tập tin nén chứa mã nguồn nguyên gốc từ các nhà phát triển, chỉ được đổi tên về tên như trên để tuân thủ theo quy định của Debian. Chú ý rằng tập tin trên được tạo trước tiên bởi lệnh `dh_make -f ../gentoo-0.9.12.tar.gz`.

- `gentoo_0.9.12-1.dsc`

  Đây là tóm tắt nội dung của mã nguồn. Tập tin này được tạo ra từ tập tin `control`, và nó được sử dụng khi giải nén mã nguồn bằng lệnh dpkg-source(1).

- `gentoo_0.9.12-1.debian.tar.gz`

  Tập tin nén này chứa các nội dung trong thư mục `debian`. Mỗi điều chỉnh bạn thêm vào mã nguồn ban đầu được lưu ở dạng một bản vá quilt trong `debian/patches`.

  Nếu bất cứ ai muốn tự tạo gói từ đầu, họ có thể làm thế bằng việc sử dung ba tập tin phía trên. Quy trình giải nén thì khá dễ dàng: chỉ cần sao chép ba tập tin đến một nơi khác và chạy lệnh `dpkg-source -x gentoo_0.9.12-1.dsc`. [63]

- `gentoo_0.9.12-1_i386.deb`

  Đây là gói nhị phân hoàn chỉnh của bạn. Bạn có thể dùng lệnh dpkg để cài đặt và tháo gỡ gói nhị phân này như những gói khác.

- `gentoo_0.9.12-1_i386.changes`

  Tập tin này mô tả tất cả những thay đổi trong phiên bản hiện thời của gói; nó được dùng bởi các chương trình bảo trì kho FTP của Debian để cài đặt các gói nhị phân và gói nguồn. Nó một phần được tạo ra từ tập tin `changelog` và tập tin `.dsc`.

  Trong lúc bạn làm việc với gói, biểu hiện của gói sẽ thay đổi và những tính năng mới sẽ được thêm vào. Những người tải gói của bạn về có thể nhìn vào tập tin này và nhìn sơ nhanh được có những gì đã thay đổi. Các chương trình bảo trì kho Debian sẽ đăng các nội dung của tập tin này lên bó thư debian-devel-changes@lists.debian.org.

Các tập tin `gentoo_0.9.12-1.dsc` và `gentoo_0.9.12-1_i386.changes` phải được ký tên bằng lệnh debsign với mã GPG riêng tư của bạn trong thư mục `~/.gnupg/`, trước khi tải chúng lên kho FTP của Debian. Chữ ký GPG chứng minh những tập tin này là thật sự của bạn bằng mã GPG công cộng của bạn.

Lệnh debsign có thể được dùng để ký tên với mã nhận dạng của khóa GPG bí mật của bạn (tốt cho việc tài trợ các gói) được chỉ ra trong dòng sau trong tập tin `~/.devscripts`:

    DEBSIGN_KEYID=Your_GPG_keyID

Những chuỗi số dài trong các tập tin `.dsc` và `.changes` là mã băm SHA1/SHA256 cho những tập tin đã được đề cập. Bất kỳ ai tải xuống các tập tin của bạn có thể sử dung và kiểm tra chúng bằng lệnh sha1sum(1) hoặc sha256sum(1) và nếu các số không khớp, họ sẽ biết ngay là tập tin đã bị lỗi hoặc đã bị chỉnh sửa.

## 6.2. Tự động biên dịch

Debian hỗ trợ nhiều cổng với mạng lưới biên dịch tự động chạy các dịch vụ buildd trên các máy tính chạy nhiều nền tảng khác nhau. Mặc dù bạn không cần phải tự làm điều này, bạn cần phải biết những gì sẽ xảy ra với các gói phần mềm của bạn. Hãy nhìn vào cách chúng biên dịch các gói phần mềm của bạn cho nhiều nền tảng. [64]

Đối với các gói phần mềm cho nền tảng `Architecture: any`, hệ thống tự động biên dịch thực hiện hành động tái biên dịch. Nó đảm bảo việc cài đặt của

- gói `build-essential`, và

- các gói được liệt kê trong trường `Build-Depends` (see Phần 4.1, “`control`”).

Sau đó nó chạy lệnh sau trong thư mục nguồn:

    $ dpkg-buildpackage -B

Lệnh này sẽ làm tất cả mọi thứ để tạo ra các gói phần mềm nhị phân phụ thuộc vào nền tảng trên một nền tảng khác. Nó sẽ:

- xóa sạch cây thư mục nguồn (`debian/rules clean`)

- biên dịch chương trình (`debian/rules build`)

- biên dịch các gói phần mềm nhị phân phụ thuộc vào nền tảng (`fakeroot debian/rules binary-arch`)

- ký tên vào tập tin nguồn `.dsc`, dùng lệnh gpg

- tạo và ký tên tập tin sẽ được tải lên `.changes`, dùng lệnh dpkg-genchanges và gpg

Đây là lý do bạn thấy gói phần mềm của bạn cho các nền tảng khác.

Mặc dù các gói phần mềm liệt kê trong trường `Build-Depends-Indep` bị buộc phải được cài đặt cho quá trình đóng gói bình thường của chúng tôi (xem Phần 6.1, “(Tái) biên dịch toàn bộ”), chúng không bị buộc phải được cài đặt bởi hệ thống tự động biên dịch bởi vì nó biên dịch chỉ những gói phần mềm phụ thuộc vào nền tảng. [65] Điểm khác biệt giữa thủ tục đóng gói bình thường và đóng gói tự động là cái gì chỉ ra bạn nên ghi lại những gói phần mềm bắt buộc trong trường `Build-Depends` hay `Build-Depends-Indep` của tập tin `debian/control` (xem Phần 4.1, “`control`”).

## 6.3. Lệnh debuild

Bạn có thể tự động hóa hành động biên dịch xung quanh việc thực thi lệnh dpkg-buildpackage và lệnh debuild. Xem debuild(1).

Lệnh debuild chạy lệnh lintian để thực hiện bài kiểm tra tĩnh sau khi biên dịch gói phần mềm Debian. Lệnh lintian có thể được thay đổi với các dòng sau trong tập tin `~/.devscripts`:

    DEBUILD_DPKG_BUILDPACKAGE_OPTS="-us -uc -I -i"
    DEBUILD_LINTIAN_OPTS="-i -I --show-overrides"

Dọn dẹp mã nguồn và tái biên dịch gói phần mềm từ tài khoản của bạn thì đơn giản như sau:

    $ debuild

Bạn có thể dọn dẹp cây mã nguồn đơn giản như sau:

    $ debuild -- clean

## 6.4. Gói phần mềm `pbuilder`

Để có một môi trường biên dịch (chroot) sạch sẽ để kiểm tra các điều kiện biên dịch, gói phần mềm `pbuilder` rất hữu dụng. [66] Nó đảm bảo việc biên dịch sạch sẽ từ mã nguồn dưới hệ thống biên dịch tự động `sid` cho các nền tảng khác nhau và tránh một lỗi nghiêm trọng FTBFS (Thất Bại Biên Dịch Từ Nguồn) vốn luôn nằm trong thể loại RC (Nghiêm Trọng Cho Phát Hành). [67]

Hãy tùy chỉnh gói phần mềm `pbuilder` như sau:

- Làm cho thư mục `/var/cache/pbuilder/result` có thể ghi được bởi tài khoản của bạn.

- tạo một thư mục, ví dụ như ``/var/cache/pbuilder/hooks``, có thể ghi được bởi người dùng, để đặt mã kịch bản mồi vào.

- cấu hình `~/.pbuilderrc` hoặc `/etc/pbuilderrc` để bao gồm những thứ sau:

      AUTO_DEBSIGN=${AUTO_DEBSIGN:-no}
      HOOKDIR=/var/cache/pbuilder/hooks

Trước tiên hãy khởi động hệ thống `pbuilder` chroot nội bộ như sau:

    $ sudo pbuilder create

Nếu bạn đang có một gói phần mềm chứa mã nguồn hoàn chỉnh, chạy các lệnh sau dưới thư mục nơi các tập tin ``foo`.orig.tar.gz`, ``foo`.debian.tar.gz`, và ``foo`.dsc` tồn tại để cập nhật hệ thống `pbuilder` chroot nội bộ và để biên dịch các gói phần mềm nhị phân trong nó:

    $ sudo pbuilder --update
    $ sudo pbuilder --build foo_version.dsc

Các gói phần mềm vừa mới được biên dịch mà không có chữ ký GPG sẽ được đặt ở `/var/cache/pbuilder/result/` với chủ sở hữu không phải là root.

Các chữ ký GPG trên các tập tin `.dsc` và `.changes` có thể được tạo ra như sau:

    $ cd /var/cache/pbuilder/result/
    $ debsign foo_version_arch.changes

Nếu bạn có một cây thư mục chứa mã nguồn đã được cập nhật nhưng chưa tạo ra gói phần mềm chứa mã nguồn tương ứng, thay vì thế hãy chạy các lệnh sau trong thư mục nguồn nơi thư mục `debian` tồn tại:

    $ sudo pbuilder --update
    $ pdebuild

Bạn có thể đăng nhập vào môi trường chroot với lệnh `pbuilder --login --save-after-login` và cấu hình nó theo ý bạn muốn. Môi trường này có thể được lưu bằng việc rời khỏi dòng lệnh với thao tác `^D` (Control-D).

Phiên bản mới nhất của lệnh lintian có thể được chạy từ môi trường `chroot` dùng kịch bản mồi ``/var/cache/pbuilder/hooks`/B90lintian` cấu hình như sau: [68]

    #!/bin/sh
    set -e
    install_packages() {
            apt-get -y --allow-downgrades install "$@"
            }
    install_packages lintian
    echo "+++ lintian output +++"
    su -c "lintian -i -I --show-overrides /tmp/buildd/*.changes" - pbuilder
    # use this version if you don't want lintian to fail the build
    #su -c "lintian -i -I --show-overrides /tmp/buildd/*.changes; :" - pbuilder
    echo "+++ end of lintian output +++"

Bạn cần phải có kết nối đến môi trường `sid` mới nhất để biên dịch gói phần đúng cách cho `sid`. Trên thực tế, `sid` có thể gặp vấn đề làm cho bạn cảm thấy khó khăn hơn khi di chuyển toàn bộ hệ thống của bạn. Gói phần mềm `pbuilder` có thể giúp bạn đối mặt với loại tình huống này.

Bạn có thể cần phải cập nhật các gói phần mềm `stable` sau khi chúng được tung ra cho `stable-proposed-updates`, `stable/updates`, v.v. [69] Cho những tình huống như thế, việc bạn có thể đang chạy một hệ thống `sid` không phải là một lý do đủ tốt cho việc thất bại trong cập nhật chúng đúng cách. Gói phần mềm `pbuilder` có thể giúp bạn truy cập các môi trường của bất cứ bản phân phối hệ điều hành nào xuất phát từ Debian trên cùng một nền tảng.

Xem http://www.netfort.gr.jp/~dancer/software/pbuilder.html, pdebuild(1), pbuilderrc(5), và pbuilder(8).

## 6.5. Lệnh git-buildpackage và những lệnh tương tự

Nếu thượng nguồn của bạn dùng một hệ thống quản lý mã nguồn (VCS) [70] để bảo trì mã nguồn của họ, bạn cũng nên xem xét việc sử dụng nó. Nó có thể giúp bạn gộp và chọn các bản vá từ thượng nguồn dễ hơn. Có nhiều gói phần mềm chứa mã kịch bản dùng cho việc đóng gói các gói phần mềm Debian cho từng VCS.

- `git-buildpackage`: a giải pháp để giúp việc đóng gói phần mềm Debian với các kho mã nguồn Git.

- `svn-buildpackage`: các chương trình giúp đỡ để bảo trì các gói phần mềm Debian với Subversion.

- `cvs-buildpackage`: một tập hợp các kịch bản đóng gói Debian cho các cây mã nguồn CVS.

Việc sử dụng `git-buildpackage` đang dần trở nên phổ biến đối với các nhà phát triển Debian để quản lý các gói phần mềm Debian với máy phục vụ Git trên alioth.debian.org. [71] Gói phần mềm này cung cấp nhiều lệnh để tự động hóa các thao tác đóng gói:

- gbp-import-dsc(1): import a previous Debian package to a Git repository.

- gbp-import-orig(1): import a new upstream tar to a Git repository.

- gbp-dch(1): generate the Debian changelog from Git commit messages.

- git-buildpackage(1): biên dịch các gói Debian từ một kho Git.

- git-pbuilder(1): biên dịch các gói Debian từ một kho Git dùng lệnh pbuilder/cowbuilder.

Những lệnh sau dùng 3 nhánh để theo dõi thao tác đóng gói:

- `main` cho cây mã nguồn của gói phần mềm Debian.

- `upstream` for cây mã nguồn của thượng nguồn.

- `pristine-tar` cho tập tin nén thượng nguồn tạo ra bởi tham số `--pristine-tar`.[72]

Bạn có thể cấu hình `git-buildpackage` với `~/.gbp.conf`. Xem gbp.conf(5). [73]

## 6.6. Tái biên dịch nhanh

Với một gói phần mềm lớn, bạn có thể không muốn biên dịch lại từ đầu mỗi lần bạn tinh chỉnh các chi tiết trong `debian/rules`. Dành cho mục đích kiểm tra, bạn có thể tạo một tập tin `.deb` mà không cần tái biên dịch các mã nguồn từ thượng nguồn như sau[74]:

    $ fakeroot debian/rules binary

Hoặc đơn giản chạy lệnh sau để xem nó có biên dịch được hay không:

    $ fakeroot debian/rules build

Khi bạn hoàn tất tinh chỉnh, hãy nhớ tái biên dịch với thủ tục chính quy. Bạn có khả năng không thể tải lên được đúng cách nếu bạn cố gắng tải các tập tin `.deb` được biên dịch theo cách này.

## 6.7. Sơ đồ lệnh

Đây là một bản tóm tắt cho thấy các lệnh biên dịch gói phần mềm phối hợp như thế nào trong sơ đồ lệnh. Có nhiều cách để làm một thứ.

- `debian/rules` = kịch bản của người bảo trì cho biên dịch gói phần mềm

- dpkg-buildpackage = lõi của công cụ biên dịch gói phần mềm

- debuild = dpkg-buildpackage + lintian (biên dịch với các biến môi trường dọn dẹp sạch sẽ)

- pbuilder = lõi của công cụ sắp đặt môi trường chroot Debian.

- pdebuild = pbuilder + dpkg-buildpackage (biên dịch trong chroot)

- cowbuilder = tăng tốc tốc độ chạy của pbuilder

- git-pbuilder = lệnh với ngữ pháp dễ sử dụng thay thế cho lệnhpdebuild (dùng bởi lệnhgbp buildpackage)

- gbp = quản lý mã nguồn của gói phần mềm dưới kho git

- gbp buildpackage = pbuilder + dpkg-buildpackage + gbp

Mặc dù việc sử dụng các lệnh cấp cao hơn như gbp buildpackage và pbuilder đảm bảo một môi trường biên dịch phần mềm hoàn hảo, hãy đặt sự quan trọng vào việc hiểu các lệnh cấp thấp như `debian/rules` và dpkg-buildpackage được thực thi như thế nào dưới các lệnh cấp cao.

[62] Mã GPG này phải được ký tên bởi một nhà phát triển Debian để có thể được kết nối tới mạng lưới tín nhiệm và phải được đăng ký vào tập hợp mã tin cậy của Debian. Điều này cho phép các gói bạn tải lên được chấp nhận vào kho của Debian. Xem Tạo một mã GPG mới và Debian Wiki về Ký tên lên mã.

[63] Bạn có thể tránh việc áp dụng các bản vá quilt dưới định dạng nguồn `3.0 (quilt)` khi kết thúc việc giải nén với tham số `--skip-patches`. Một lựa chọn khác là bạn có thể chạy lệnh `dquilt pop -a` sau khi làm xong các thao tác thông thường.

[64] Hệ thống tự động biên dịch thực tế cần các kế hoạch phức tạp hơn nhiều kế hoạch được giải thích ở đây. Những chi tiết như thế là quá tầm của tài liệu này.

[65] Khác với khi dưới gói phần mềm `pbuilder`, môi trường chroot dưới gói `sbuild` vốn được sử dụng bởi hệ thống tự động biên dịch không buộc sử dụng một hệ thống nhỏ gọn và có thể có nhiều gói phần mềm thừa đã được cài đặt.

[66] Bởi vì gói phần mềm `pbuilder` vẫn đang tiếp tục tiến hóa, bạn nên kiểm tra môi trường cấu hình thực sự bằng việc đọc tài liệu hướng dẫn mới nhất.

[67] Xem http://buildd.debian.org/ để biết thêm về việc tự động biên dịch các gói phần mềm Debian.

[68] Điều này giả sử là `HOOKDIR=/var/cache/pbuilder/hooks`. Bạn có thể tìm thấy nhiều ví dụ của các kịch bản mồi trong thư mục `/usr/share/doc/pbuilder/examples`.

[69] Có một vài giới hạn cho những cập nhật như vậy đối với gói phần mềm `stable` của bạn.

[70] Xem Các hệ thống quản lý phiên bản để biết thêm.

[71] Debian wiki Alioth hướng dẫn cách sử dụng dịch vụ alioth.debian.org.

[72] Tham số `--pristine-tar` chạy lệnh pristine-tar, lệnh này tạo ra một bản sao nguyên vẹn của tập tin nén thượng nguồn chưa chỉnh sửa bằng việc sử dụng một tập tin nhị phân delta nhỏ và những nội dung của tập tin nén vốn được giữ trong nhánh `upstream` trong VCS.

[73] Đây là một vài nguồn thông tin điện tử có sẵn cho các đối tượng người đọc thông thái.

- Biên dịch các Gói Phần Mềm Debian với git-buildpackage (`/usr/share/doc/git-buildpackage/manual-html/gbp.html`)

- các gói phần mềm debian trong git

- Dùng Git cho đóng gói phần mềm Debian

- git-dpm: các gói phần mềm Debian trong công cụ quản lý Git

[74] Các biến môi trường vốn được cấu hình bình thường với các giá trị phù hợp không được gán giá trị với phương pháp này. Đừng bao giờ tạo các gói phần mềm thực sự để được tải lên với phương pháp nhanh này.

Chương 5. Các tệp khác trong thư mục `debian` |  | Chương 7. Kiểm tra gói để tìm lỗi