Biên dịch một gói phần mềm trên Ubuntu [Howto]

Mình mất công dịch hướng dẫn này tại Help của Ubuntu và thêm nhận xét của mình, hi vọng bạn đang tìm kiếm có thể dễ dàng tìm thấy điều mình cần.

Trong trình quản lý phần mềm Synaptic (Ubuntu) ta dễ dàng tìm thấy rất nhiều gói phần mềm hoặc phần mềm của hãng thứ 3, thế nhưng nhiều khi bạn vẫn muốn dịch các gói này từ mã nguồn của nó (sources) bởi vì:

  • Gói đó không có trong các repositories
  • Gói trong thư viện repositories quá cũ, muốn cái mới cơ 🙂
  • Gói trong thư viện quản lý bị giới hạn nhiều chức năng với các lí do khác nhau mà ta chả biết
  • Gói trong thư viện có nhiều lỗi (bug) đã được chỉnh sửa bởi tác giả của gói phần mềm đó.
  • Bạn muốn thử bản patch của bạn, xem có sửa được lỗi (bug) của phiên bản đó hay không.
  • Đơn giản là bạn muốn thử biên dịch xem thế nào.

Thực tế là mình vẫn khoái build từ mã nguồn hơn, nhưng hơi tốn thời gian. Ubuntu còn có thư viện quản lý tốt, chứ nếu mà dùng freeBSD thì có mà ngồi khóc, biên dịch 1 cái chờ mỏi cả mắt hic.

Background

Khi biên dịch các gói phần mềm thì chúng ta cần phải có trình biên dịch cho các gói phần mềm đó, cái này phụ thuộc vào loại ngôn ngữ mà gói đó được viết ra. Thông thường thì chúng được viết trên C và C++, ta có thể dùng các trình biên dịch gcc, g++. Cài đặt trên Ubuntu bằng cách thêm gói: build-essential

sudo apt-get install build-essential

Để có thể chạy được các file cấu hình (thường là chạy ./configure) hoặc autogen.sh trong mã nguồn của các gói thì cần cài thêm vào automake:

sudo apt-get install automake

Cuối cùng, bạn cần phải có checkinstall để có thể kiểm tra xem gói sau khi biên dịch có an toàn cho vào hệ thống của bạn không:

sudo apt-get install checkinstall

Cái này quan trọng vì nhiều khi mình khoái biên dịch, cho chạy vào hệ thống tẹo là toi ngay, xung đột với các phần mềm khác hoặc config linh tinh chẳng hạn 🙂

Do you really need to compile?

Nếu mà bạn định biên dịch một gói vì bạ nghĩ là gói đó không có trong repository, tại sao không tìm kiếm thông tin về gói đó ở trong Ubuntu Package Search hoặc tìm trong reporitory của hãng thứ 3  http://ubuntulinux.nl/source-o-matic .

Bạn cũng có thể kiểm tra xem gói đó có trong repository của bạn không bằng cách dùng lệnh trong Terminal:

apt-cache search <a keyword from the package>

Gõ man apt-cache để biết thêm chi tiết.

Download các mã nguồn

Nói chung thì các gói mã nguồn thường được cho phép tải trên các trang web của chính tác giả cũng như nhà phát triển dưới một vài định dạng quen thuộc là: tar.gz, tar.bz2 hoặc zip. Ví dụ, tìm kiếm về gói httpd của apache thì cứ vào trang chủ của apache thì thế nào cũng ra link download.

Bước tiếp theo là giải nén gói này ra theo các định dạng tương ứng:

tar -xvf file.tar.gz
tar -xvf file.tar.bz2
unzip file.zip

Thỉnh thoảng, bạn cũng phải lấy mã nguồn bằng cách dùng CVS (current versions system) nên cần phải cài gói cvs bằng cách gõ lệnh: apt-get install cvs. Ví dụ, muốn lấy mã nguồn NetworkManager , cần chạy các lệnh sau:

cvs -d :pserver:anonymous@anoncvs.gnome.org:/cvs/gnome login
cvs -d :pserver:anonymous@anoncvs.gnome.org:/cvs/gnome co NetworkManager 

Với rất nhiều gói chúng ta có thể lấy mã nguồn hiện tại có trên mạng bằng cách dùng Bazaar (sudo apt-get install bzr) chứ không cần phải đi tìm kiếm xem gói đó nằm ở đâu cả. Việc này xem ra đơn giản (giống của freeBSD hehe).

Ví dụ:

bzr get lp:network-manager

Ba bước để biên dịch các gói mã nguồn

Phần lớn các chương trình được biên dịch từ các gói phần mềm của Linux thường thông qua 3 bước:

./configure
make
make install

Bước khó khăn nhất thường nằm ở bước configure

configure

configure là một script được dùng để:

  • Kiểm tra rằng PC của bạn thảo mãn những yêu cầu cần thiết để biên dịch gói mã nguồn đó (thường có warning hoặc error để biết)
  • Giúp bạn đổi đường dẫn mặc định nếu trong gói cài đặt đòi hỏi
  • Được dùng để enable/disable một vài lựa chọn trong chương trình sẽ được dịch ra sau đó.
  • Thay đổi đường dân của ứng dụng sẽ được cài đặt sau khi biên dịch (/usr/local/  hay cái khác, ... )

Bạn có thể xem các lựa chọn mà configure có thể cho phép bằng cách thực hiện command tại thư mục mà bạn biên dịch:

./configure --help | less

Ví dụ, mặc định script này sẽ cài đặt ứng dụng vào /usr/local. Nếu bạn muốn đổi đường dẫn này, có thể thực hiện bằng lệnh sau:

./configure --PREFIX=/opt

Thông thường, trước kh cài đặt, configure một gói nào đó nên dành ra vài phút đọc các file README hoặc INSTALL được cung cấp cùng với gói cài đặt, nó sẽ miêu tả các compile nào cần thiết cũng như các gói cần cài đặt sẵn trong hệ thống trước khi biên dịch gói này.

Một thủ thuật khác là nếu bạn biên dịch một gói mà nó có sẵn trong repositories là cài đặt gói đó theo kiểu này (build dependence) bằng lệnh:

sudo apt-get build-dep <package>

Troubleshooting the configure

Mặc dù đã theo các bước ở bên trên nhưng nhiều khi configure vẫn không được, bởi vì nhiều lí do sau:

  • Bạn luôn cần các gói -dev khi biên dịch. Nhớ cái này để khi chạy ./configure báo thiếu gói A chẳng hạn thì phải đi cài gói A-dev chẳng hạn.
  • Để biên dịch các ứng dụng GNOME thì luôn cần gói gnome-devel, ứng dụng chạy trên KDE thì yêu cầu kde-devel.
  • Tên của các thư viện C, C++ luôn bắt đầu với lib, vì thế nếu mà chạy ./configure mà báo thiếu thư viện foo thì phải cài đặt gói libfoo-dev vào.
  • Nếu báo là yêu cầu có "X includes" thì thường là bạn phải cài đặt thêm các gói sau đây: xlibs-dev, xlibs-static-dev, window-system-dev
  • Một kĩ thuật khác để biết xem gói nào cần cài thêm là dùng công cụ auto-apt hoặc apt-file (auto-apt có khi nhanh hơn).
sudo apt-get install auto-apt
sudo auto-apt update
auto-apt search missing-file.h
  • Thử biên dịch bằng cách vô hiệu hóa một vài tính năng mà vì nó mà không biên dịch được bằng cách dùng:
./configure --disable-FEATURE
  • Nếu mà k biết biên dịch tại sao mà lỗi thì đi hỏi Google hoặc help Ubuntu.

Nếu mà không có file configure tồn tại, bạn phải check trong thư mục của gói cài đặt xem có file configure.ac không (nên đọc xem file INSTALL hoặc README cẩn thận lại). Nếu file configure.ac tồn tại, thì tức là đã thiếu bước tạo ra file configure rồi. Nên giờ phải tạo nó ra (cài thêm gói autoconf vào: sudo apt-get install autoconf)

Sau đó, bạn có thể gõ: autoconf và file configure sẽ được tạo ra.

Compiling the Package

Hi vọng, sau khi bước configure kết thúc, bước cài đặt chính thức có thể bắt đầu. Bước này có thể thực hiện bằng cách gọi:

make

Nếu mọi thứ đều ok thì bạn phải thấy được bản copy của chương trình sau khi dịch trong thư mục mã nguồn hiện tại. Bạn costheer thử chạy bằng cách:

src/program_name

Nếu mà không được thì là toi rồi, đi liên hệ hoặc xem thiên hạ gỡ rối kiểu gì, fix thế nào nhá.

Installing the Package

Bước này là bước để cài đặt chương trình vào hệ thống. Có thể tạo ra file .deb dùng CheckInstall để có thể remove gói đó dễ dàng nếu mà không muốn bằng cách dùng:

sudo checkinstall

Nếu bạn không khoái tạo ra file .deb thì có cách sau là cài trực tiếp bằng lệnh:

sudo make install

Nhưng cách này có rủi ro là nếu mà gói cài vào hệ thống không ok, muốn gỡ ra thì hơi mệt đấy nên không khuyên dùng cách này.

Notes

  • If the program is a kernel module you will also need gcc-3.4 (on breezy) and the kernel-headers package. They latter can be installed with sudo apt-get install gcc-3.4 linux-headers-$(uname -r). Please note that kernel modules have to be recompiled after each kernel upgrade (and new headers have to be downloaded too). For compiling a complete kernel, look at the KernelCompileHowto.

  • Nếu bạn muốn biên dịch lại một gói Debian đang tồn tại, có thể dùng lệnh dpkg-buildpackage -rfakeroot và nếu gói nào đó thiếu, thì build script sẽ nói rõ là gói nào bị thiếu.
  • Nếu bạn biên dịch từ nguồn CVS,Bzaar, .. nói chung thì cần phải chạy thêm bước autogen.sh để tạo ra file configure cho bạn.

Tham khảo: https://help.ubuntu.com/community/CompilingSoftware

{ 2 comments… add one }
  • Hiếu February 16, 2012, 9:45 pm

    Bạn cho mình hỏi làm sao để cài gói gmake trên Ubuntu?
    mình compile một chương trình , thì xuất hiện lỗi : gamke[1] : f90: Command not found.
    mong bạn chỉ giúp mình, nếu có thể, bạn mail cho mình luôn nha! mình tìm khắp các diễn đàn về Ubuntu, nhưng được biết gmake và make có sự khác nhau, gmake trong Unix, còn make là trên Linux đúng không bạn?!

    Reply
  • Nguyễn Khanh May 5, 2013, 4:28 pm

    Chào bạn, mình đang Demo thuật toán REM trên NS2, nhưng không biết convert từ REM.CC thành REM.NS, không biết bạn có biết không ? Nếu biết thì Email giúp mình với nhé : it.hongkhanh@yahoo.com

    Reply

Leave a Comment