Phụ lục A. Đóng gói nâng cao

Mục lục

A.1. Các thư viện được chia sẻ
A.2. Quản lý debian/package.symbols
A.3. Multiarch
A.4. Biên dịch một gói phần mềm chia sẻ
A.5. Gói phần mềm Debian native

Sau đây là một vài gợi ý và chỉ dẫn cho các đề tài đóng gói nâng cáo mà bạn rất có thể phải đối mặt. Bạn rất được khuyến khích đọc tất cả những tài liệu liên quan được đề nghị ở đây.

Bạn có thể cần phải thay đổi các tập tin khuôn mẫu đóng gói tạo ra bởi lệnh dh_make để biết được các đề tài được nói tới trong chương này. Lệnh debmake mới hơn có thể sẽ nói về các đề tài này tốt hơn.

Trước khi đóng gói các thư viện được chia sẻ, bạn nên đọc những tài liệu liên quan sau một cách chi tiết:

Sau đây là một số gợi ý được đơn giản hóa quá mức để giúp bạn bắt đầu:

  • Các thư viện chia sẻ là các tập tin đối tượng ELF chứa mã biên dịch.

  • Các thư viện chia sẻ được phân phối bởi các tập tin *.so. (Không phải các tập tin *.a hay các tập tin *.la)

  • Các thư viện chia sẻ được sử dụng phần lớn để chia sẻ những mã thông dụng giữa nhiều tập tin thực thi với cơ chế ld.

  • Các thư viện chia sẻ thỉnh thoảng được sử dụng để cung cấp nhiều phần mở rộng có thể cắm vào một tập tin thực thi với cơ chế dlopen.

  • Các thư viện chia sẻ xuất các ký hiệu đại diện cho các đối tượng được biên dịch như là các tham biến, các hàm, và các class; và cho phép truy cập tới chúng từ các tập tin thực thi được kết nối tới chúng.

  • SONAME của một thư viện chia sẻ libfoo.so.1: objdump -p libfoo.so.1 | grep SONAME [88]

  • SONAME của một thư viện chia sẻ thường khớp với tên tập tin thư viện (nhưng không phải luôn luôn như vậy).

  • SONAME của các thư viện chia sẻ được kết nối tới /usr/bin/foo: objdump -p /usr/bin/foo | grep NEEDED [89]

  • libfoo1: gói phần mềm thư viện cho thư viện chia sẻ libfoo.so.1 với phiên bản SONAME ABI 1.[90]

  • Các kịch bản bảo trì gói phần mềm của gói phần mềm thư viện phải gọi lệnh ldconfig dưới các tình huống cụ thể để tạo các kết nối tượng trưng cho SONAME.[91]

  • libfoo1-dbg: gói phần mềm ký hiệu dò lỗ chứa các ký hiệu dò lỗi cho gói phần mềm thư viện chia sẻ libfoo1.

  • libfoo-dev: gói phần mềm phát triển chứa những tập tin tiêu đề v.v. cho thư viện chia sẻ libfoo.so.1.[92]

  • Các gói Debian không nên chứa các tập tin lưu trữ *.la nói chung.[93]

  • Gói phần mềm Debian nói chung không nên sử dụng RPATH.[94]

  • Mặc dù nó có thể đã lạc hậu và chỉ tồn tại như là tài liêu tham khảo thứ cấp, Hướng dẫn Đóng gói thư viện Debian có thể vẫn hữu dụng.

Khi bạn đóng gói một thư viện chia sẻ, bạn nên tạo một tập tin debian/package.symbols để quản lý phiên bản thấp nhất liên quan tới từng ký hiệu cho các thay đổi ABI tương thích ngược dưới cùng một SONAME của thư viện cho cùng một tên gói phần mềm thư viện.[95] Bạn nên đọc những tài liệu liên quan chính thống sau đây một cách chi tiết:

Sau đây là một ví dụ sơ khảo để tạo một gói phần mềm libfoo1 tương ứng với phiên bản thượng nguồn 1.3 với tập tin debian/libfoo1.symbols phù hợp:

  • Chuẩn bị một sườn cho cây mã nguồn Debian hóa sử dụng tập tin thượng nguồn libfoo-1.3.tar.gz.

    • Nếu đây là lần đóng gói đầu tiên của gói phần mềm libfoo1, tạo một tập tin debian/libfoo1.symbols rỗng.

    • Nếu phiên bản thượng nguồn trước đó 1.2 được đóng gói thành gói phần mềm libfoo1 với một tập tin debian/libfoo1.symbols phù hợp trong gói phần mềm nguồn của nó, hãy sử dụng lại tập tin đó.

    • Nếu bản thượng nguồn trước đó 1.2 không được đóng gói với tập tin debian/libfoo1.symbols, tạo một tập tin như là tập tin symbols từ tất cả các gói phần mềm nhị phân có sẵn của một tên gói phần mềm thư viện chứa cùng SONAME của một thư viện, ví dụ, các phiên bản 1.1-11.2-1. [97]

      $ dpkg-deb -x libfoo1_1.1-1.deb libfoo1_1.1-1
      $ dpkg-deb -x libfoo1_1.2-1.deb libfoo1_1.2-1
      $ : > symbols
      $ dpkg-gensymbols -v1.1 -plibfoo1 -Plibfoo1_1.1-1 -Osymbols
      $ dpkg-gensymbols -v1.2 -plibfoo1 -Plibfoo1_1.2-1 -Osymbols
      
  • Tạo các bản biên dịch thử của cây mã nguồn với các công cụ như là debuildpdebuild. (Nếu điều này thất bại do thiếu ký hiệu v.v., đã có một số thay đổi ABI không tương thích ngược buộc bạn phải tăng tên gói phần mềm thư viện chia sẻ lên một tên như là libfoo1a và bạn nên bắt đầu lại từ đầu.)

    $ cd libfoo-1.3
    $ debuild
    ...
    dpkg-gensymbols: warning: some new symbols appeared in the symbols file: ...
     see diff output below
    --- debian/libfoo1.symbols (libfoo1_1.3-1_amd64)
    +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
    @@ -127,6 +127,7 @@
      foo_get_name@Base 1.1
      foo_get_longname@Base 1.2
      foo_get_type@Base 1.1
    + foo_get_longtype@Base 1.3-1
      foo_get_symbol@Base 1.1
      foo_get_rank@Base 1.1
      foo_new@Base 1.1
    ...
    
  • Nếu bạn thấy sự khác biệt in ra bởi lệnh dpkg-gensymbols như trên, giải nén tập tin symbols phù hợp cập nhật mới nhất từ gói phần mềm nhị phân được tạo ra của thư viện chia sẻ. [98]

    $ cd ..
    $ dpkg-deb -R  libfoo1_1.3_amd64.deb libfoo1-tmp
    $ sed -e 's/1\.3-1/1\.3/' libfoo1-tmp/DEBIAN/symbols \
            >libfoo-1.3/debian/libfoo1.symbols
    
  • Biên dịch các gói phần mềm phát hành với các công cụ như debuildpdebuild.

    $ cd libfoo-1.3
    $ debuild -- clean
    $ debuild
    ...
    

Bên cạnh các ví dụ ở trên, chúng ta cần phải kiểm tra tương thích ABI hơn nữa và tăng các phiên bản cho một vài ký hiệu bằng tay nếu cần. [99]

Mặc dù đây chỉ là một tài liệu tham khảo thứ cấp, Debian wiki UsingSymbolsFiles và những trang điện tử kết nối tới nó có thể rất hữu dụng.

Tính năng multiarch được giới thiệu ở Debian wheezy tích hợp hỗ trợ cho cài đặt xuyên nền tảng của các gói phần mềm nhị phân (đặc biệt i386<->amd64, nhưng cũng một vài kết hợp khác) trong dpkgapt. Bạn nên đọc các tài liệu tham khảo sau một cách chi tiết:

Nó sử dụng bộ ba như là i386-linux-gnux86_64-linux-gnu cho đường dẫn cài đặt của các thư viện chia sẻ. Đường dẫn bộ ba thực sự được đặt giá trị linh động theo tham biến $(DEB_HOST_MULTIARCH) dùng lệnh dpkg-architecture(1) cho từng lần biên dịch gói phần mềm nhị phân. Ví dụ, đường dẫn để cài đặt các thư viện multiarch được thay đổi như sau:[100]

Sau đây là một vài ví dụ về tình huống băm gói phần mềm multiarch tiêu biểu cho các gói:

  • một gói phần mềm nguồn cho libfoo-1.tar.gz

  • một gói phần mềm nguồn công cụ bar-1.tar.gz viết bằng một ngôn ngữ biên dịch.

  • một gói phần mềm nguồn công cụ baz-1.tar.gz viết bằng một ngôn ngữ thông dịch

Xin chú ý rằng gói phần mềm phát triển nên chứa một kết nối tượng trưng cho thư viện chia sẻ tương ứng không có số phiên bản. Ví dụ: /usr/lib/x86_64-linux-gnu/libfoo.so -> libfoo.so.1

Bạn có thể biên dịch một gói phần mềm thư viện Debian cho phép hỗ trợ multiarch dh(1) như sau:

Hãy chắc chắn rằng gói phần mềm thư viện chia sẻ chỉ chứa duy nhất các tập tin được trông đợi, và gói phần mềm -dev của bạn vẫn hoạt động tốt.

Tất cả các tập tin được cài đặt cùng lúc với gói phần mềm multiarch vào cùng một đường dẫn nên có cùng một nội dung chính xác như nhau. Bạn phải cẩn thận với những sự khác biệt tạo ra bởi thứ tự byte dữ liệu và thuật toán nén.

Nếu một gói phần mề được bảo trì chỉ cho Debian hoặc có thể chỉ cho việc dùng nội bộ, mã nguồn của nó có thể chứa tất các tập tin debian/* bên trong nó. Có 2 cách để đóng gói nó.

Bạn có thể tạo một tập tin lưu trữ thượng nguồn bằng việc loại trừ tất cả các tập tin debian/* và đóng gói nó như là một gói phần mềm nhị phân Debian không native như ở Phần 2.1, “Luồng làm việc tạo ra gói Debian”. Đây là cách thông thường mọi người khuyến khích sử dụng.

Một cách khác là cách làm của một gói phần mềm Debian native.

  • Tạo một gói phần mềm nguồn Debian native dưới định dạng 3.0 (native) bằng việc sử dụng một tập tin nén tar đơn độc chứa tất cả các tập tin bên trong.

    • package_version.tar.gz
    • package_version.dsc
  • Biên dịch các gói phần mềm nhị phân Debian từ gói phần mềm nguồn Debian native.

    • package_version_arch.deb

Ví dụ, nếu bạn có các tập tin nguồn trong thư mục ~/mypackage-1.0 mà không có các tập tin debian/*, bạn có thể tạo một gói phần mềm Debian native cho nó bằng việc chạy lệnh dh_make như sau:

$ cd ~/mypackage-1.0
$ dh_make --native

Sau đó thư mục debian và nội dụng của nó được tạo như là ở Phần 2.8, “Khởi tạo gói Debian mới”. Hành động này không tạo một tập tin lưu trữ vì đây là một gói phần mềm Debian native. Nhưng đó là điểm khác biệt duy nhất. Phần còn lại của quá trình đóng gói thực tế là không khác gì.

Sau khi chạy lệnh dpkg-buildpackage, bạn sẽ thấy các tập tin sau trong thư mục cha:

  • mypackage_1.0.tar.gz

    Đây là tập tin mã nguồn tạo ra từ thư mục mypackage-1.0 bởi lệnh dpkg-source command. (Phần hậu tố của nó không phải là orig.tar.gz.)

  • mypackage_1.0.dsc

    Đây là bản tóm tắt của những nội dung của mã nguồn như ở trong gói phần mềm Debian không native. (There có mã tu chỉnh Debian.)

  • mypackage_1.0_i386.deb

    Đây là gói phần mềm nhị phân hoàn chỉnh của bạn như là gói phần mềm Debian không native. (Không có mã tu chỉnh Debian.)

  • mypackage_1.0_i386.changes

    Tập tin này mô tả những thay đổi được tạo ra trong phiên bản gói phần mềm hiện tại như ở trong gói phần mềm Debian không native. (Không có bản tu chỉnh Debian.)



[88] Ngoài ra: readelf -d libfoo.so.1 | grep SONAME

[89] Ngoài ra: readelf -d libfoo.so.1 | grep NEEDED

[95] Các thay đổi ABI không tương thích ngược thông thường cần bạn phải cập nhật SONAME của thư viện và tên gói phần mềm thư viện chia sẻ sang những tên mới.

[96] Với các thư viện C++ và các tình huống khác mà theo dõi từng ký hiệu là vô cùng khó khăn, thay vì như trên hãy làm theo Hướng dẫn Chính sách về Debian, 8.6.4 "Hệ thống shlibs",

[97] Tất cả các phiên bản trước đó của các gói phần mềm Debian có sẵn tại http://snapshot.debian.org/. Phiên bản tu chỉnh Debian được cắt bỏ khỏi phiên bản để giúp việc backport gói phần mềm (tạo gói phần mềm chứa các cập nhật mới cho các bản phân phối Debian cũ) dễ hơn: 1.1 << 1.1-1~bpo70+1 << 1.1-11.2 << 1.2-1~bpo70+1 << 1.2-1

[98] Phiên bản tu chỉnh Debian được cắt bỏ khỏi phiên bản để giúp việc backport gói phần mềm (tạo gói phần mềm chứa các cập nhật mới cho các bản phân phối Debian cũ) dễ hơn: 1.3 << 1.3-1~bpo70+1 << 1.3-1

[100] Các đường dẫn thư viện chuyên dụng cũ như /lib32//lib64/ không được sử dụng nữa.

[101] Ngoài ra, bạn có thể thêm các đối số --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH)--libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) cho ./configure. Xin hãy chú ý rằng tham số --libexecdir thông báo đường dẫn ngầm định để cài đặt các chương trình thực thi được chạy bởi các chương trình khác thay vì bởi người dùng. Giá trị ngầm định Autotools của nó là /usr/libexec/ nhưng ngầm định của Debian là /usr/lib/.