Đối với nhiều người dùng Linux và các nhà phát triển, việc biên dịch và cài đặt phần mềm từ mã nguồn có vẻ phức tạp hơn so với việc sử dụng trình quản lý gói truyền thống. Tuy nhiên, quy trình này lại mang đến sự linh hoạt và kiểm soát tối đa đối với các ứng dụng bạn muốn triển khai. Tin vui là một mô hình ba bước đơn giản đã trở thành tiêu chuẩn cho hầu hết các dự án mã nguồn mở, giúp quá trình này trở nên dễ dàng hơn bạn nghĩ. Bài viết này của thichcongnghe.net sẽ đi sâu vào giải mã ba lệnh cốt lõi: ./configure
, make
, và make install
, để bạn có thể tự tin làm chủ việc xây dựng phần mềm từ mã nguồn trên hệ điều hành Linux của mình.
Biên Dịch Từ Mã Nguồn Là Gì?
Các chương trình mà bạn chạy trên máy tính được chia thành hai loại chính: chương trình thông dịch (interpreted) và chương trình biên dịch (compiled). Chương trình thông dịch là các tệp văn bản chứa mã nguồn, được một chương trình khác – trình thông dịch – đọc và thực thi khi bạn chạy. Ngược lại, chương trình biên dịch là các tệp nhị phân độc lập (standalone binary files) chứa mã máy, có thể chạy trực tiếp trên hệ thống.
Các tệp thực thi biên dịch rất phổ biến, đặc biệt đối với các chương trình lớn. Khi bạn biên dịch từ mã nguồn, bạn sử dụng một trình biên dịch (compiler) như gcc
để tạo ra một tệp thực thi (executable) từ mã nguồn của ứng dụng. Mã nguồn này có thể được phân tán trong nhiều tệp riêng lẻ.
Cửa sổ terminal Linux minh họa quá trình biên dịch hoặc cài đặt phần mềm
Vì quá trình biên dịch phần mềm từ mã nguồn có thể phức tạp và tốn thời gian, nó thường được tự động hóa thông qua một chương trình khác, phổ biến nhất là Make
. Bạn có thể viết các tệp Makefile
để kiểm soát cách một dự án xây dựng chương trình thực thi cuối cùng của nó.
Trong các dự án phức tạp hơn, các tệp Makefile
có thể trở nên rất lớn và khó quản lý. Điều này đặc biệt đúng với các ứng dụng di động cần hoạt động trên nhiều kiến trúc và môi trường khác nhau. Để đáp ứng những tình huống này, nhiều dự án tự động tạo Makefile
của họ bằng cách sử dụng các công cụ như autoconf/automake
.
Quy Trình Biên Dịch 3 Bước Phổ Biến: configure, make, install
Kết quả của tất cả những điều trên là một mô hình chung mà phần lớn phần mềm sử dụng để biên dịch từ mã nguồn:
./configure && make && make install
Nhiều chương trình phổ biến sử dụng mô hình này — hoặc một biến thể của nó — bao gồm Apache, được giải thích rõ ràng trong tệp INSTALL của nó:
Đoạn trích từ file INSTALL của Apache hướng dẫn các bước biên dịch configure, make và make install
Node.js là một ví dụ khác về phần mềm sử dụng mô hình này. Tệp BUILDING.md của nó chứa các hướng dẫn liên quan:
Hướng dẫn biên dịch phần mềm Node.js từ file BUILDING.md minh họa quy trình configure, make, make install
Mỗi dự án có cách tiếp cận riêng để biên dịch mã nguồn của mình, ngay cả khi đó chỉ là một biến thể đơn giản của mô hình ba bước. Một điểm khác biệt quan trọng là cách bạn chạy chuỗi lệnh. Chạy với toán tử logic AND (&&
) sẽ khiến chuỗi lệnh dừng lại nếu một phần của nó thất bại:
./configure && make && make install
Ngoài ra, bạn có thể chạy từng lệnh riêng lẻ, nhưng vẫn trên một dòng duy nhất, bằng cách sử dụng dấu chấm phẩy:
./configure; make; make install
Cách này sẽ khiến mỗi phần chạy, ngay cả khi các bước trước đó đã thất bại. Lựa chọn của bạn không phải lúc nào cũng tạo ra nhiều khác biệt thực tế, và bạn cũng có thể chạy chúng thành ba lệnh riêng biệt:
./configure
make
make install
Bạn có thể không muốn cài đặt hoàn chỉnh phần mềm, mà chỉ muốn chạy nó trực tiếp từ thư mục của nó. Điều này hoàn toàn có thể chấp nhận được; bạn chỉ cần bỏ qua lệnh make install
.
Một số kho lưu trữ chứa tập lệnh configure
, những kho khác (như grep
) yêu cầu bạn chạy một tập lệnh khác để tạo ra tệp configure
này trước. Nếu bạn đang tìm kiếm tùy chọn dễ dàng nhất, hãy luôn tham khảo tệp INSTALL, BUILD hoặc README và làm theo khuyến nghị của dự án.
./configure: Bước Khởi Đầu Quan Trọng
Tập lệnh shell configure
thường là điểm khởi đầu của quá trình biên dịch. Nó thiết lập phần còn lại của quy trình cho môi trường cụ thể của bạn.
Tập lệnh này kiểm tra các phụ thuộc (dependencies) khác nhau mà dự án yêu cầu. Nó đảm bảo rằng tất cả các yếu tố cần thiết đều hiện diện và chính xác, ở các phiên bản phù hợp. Chạy ./configure
và bạn sẽ nhận được một tệp tên là Makefile
, được sử dụng ở giai đoạn tiếp theo.
Bản thân tập lệnh configure
cũng có khả năng cấu hình cao, thông qua các tùy chọn dòng lệnh. Chạy ./configure --help
để có mô tả toàn diện về chúng.
Cả configure
và make
đều tạo ra rất nhiều output. Nếu bạn chỉ muốn chạy các lệnh này và bỏ qua những gì chúng làm đằng sau hậu trường, bạn có thể sử dụng tùy chọn --quiet
để chặn hầu hết output.
Nếu không có tập lệnh configure
, một dự án có thể cung cấp cách để tạo ra nó. Ví dụ, kho lưu trữ htop
bao gồm một tập lệnh autogen.sh
. Chạy lệnh này sẽ tạo ra một tập lệnh configure
:
Kết quả chạy script autogen.sh trong mã nguồn htop, cho thấy việc tạo ra file configure
Các dự án rất đơn giản, và những dự án không được viết bằng ngôn ngữ C, có thể hoàn toàn không có tập lệnh configure
. Trong trường hợp này, quy trình ba bước trở thành hai bước: chỉ cần chạy make && make install
.
Tập lệnh configure
thường kiểm soát những gì xảy ra sau đó trong quá trình cài đặt. Đặc biệt, tùy chọn --prefix
là phổ biến. Tùy chọn này định nghĩa thư mục gốc mà phần mềm sẽ được cài đặt. Theo mặc định, đây là /usr/local
, nhưng bạn có thể cung cấp một tùy chọn thay thế nếu bạn muốn tổ chức các tệp của mình theo cách khác.
make: Xử Lý Công Việc Chính
Khi configure
đã tạo ra một Makefile
, bạn có thể bắt đầu quá trình biên dịch phần mềm thực sự. Chương trình make
đọc Makefile
và kiểm tra một loạt các quy tắc để quyết định những gì cần biên dịch.
Các Makefile
được viết thủ công thường dễ đọc, một khi bạn đã quen với cú pháp của chúng. Trong trường hợp đơn giản nhất, một Makefile
mô tả cách tạo một tệp từ một tệp khác, khi tệp sau cũ hơn. Ví dụ, Makefile
này mô tả quá trình biên dịch một chương trình rất đơn giản:
program: program.c
gcc -o program program.c
Ở đây, tệp thực thi program
phụ thuộc vào tệp nguồn program.c
. Khi make
chạy, nó sẽ kiểm tra tệp so với các phụ thuộc của nó. Nếu không có gì thay đổi kể từ lần biên dịch cuối cùng — tức là program
mới hơn program.c
— make
sẽ đơn giản thoát, an toàn với giả định rằng không cần phải làm gì. Tuy nhiên, nếu program.c
đã thay đổi, nó sẽ chạy gcc
và biên dịch chương trình.
Bàn phím cơ Das Keyboard minh họa công việc lập trình và biên dịch mã nguồn
Còn rất nhiều điều về make
ngoài trường hợp đơn giản nhất này, và các Makefile
được tạo tự động có xu hướng phức tạp hơn nhiều. Ví dụ, Makefile
được tạo tự động cho chương trình htop
dài 2.440 dòng:
Đoạn trích từ file Makefile tự động tạo của dự án htop trên Linux
Nhưng bạn không cần phải lo lắng về điều này. Trừ khi bạn đang chỉnh sửa mã nguồn — hoặc tự viết mã nguồn của riêng mình — bạn có thể chạy make
mà không cần quá bận tâm đến những gì đang xảy ra bên trong.
Bước make
có thể mất một thời gian dài để chạy, đặc biệt đối với phần mềm phức tạp liên quan đến một số thành phần. Hãy kiên nhẫn, và đừng lo lắng nếu make
thất bại. Nguyên nhân thường là do thiếu phụ thuộc, và một trong những lợi ích của make
là nó sẽ tiếp tục quá trình biên dịch mà không làm mất đi công việc đã thực hiện.
Hoàn Tất Với make install
Một quá trình biên dịch thông thường sẽ tạo ra một tệp thực thi đã được biên dịch, nằm ở thư mục gốc của dự án hoặc thường trong một thư mục con tên là bin
. Đây thường là một chương trình độc lập mà bạn có thể chạy thông qua đường dẫn đầy đủ của nó:
Kết quả lệnh make trong thư mục cli tạo ra thư mục bin chứa file thực thi
Điều này rất tốt cho việc thử nghiệm hoặc phát triển phần mềm của riêng bạn, nhưng cuối cùng bạn sẽ muốn cài đặt phần mềm ở một vị trí thuận tiện hơn.
Hầu hết các Makefile
đều có mục tiêu install
mà make
sẽ kiểm tra khi bạn chạy make install
. Lệnh này thường sẽ sử dụng lệnh install
để sao chép các tệp riêng lẻ và đặt các quyền cũng như quyền sở hữu thích hợp.
Vị trí cài đặt sẽ phụ thuộc vào cách bạn chạy configure
. Hãy nhớ rằng vị trí mặc định cho các tệp thực thi là /usr/local/bin
, mà bạn có thể không có quyền ghi vào đó. Nếu người dùng của bạn không thể ghi vào vị trí cài đặt, bạn sẽ cần chạy sudo make install
và cung cấp mật khẩu root để tiếp tục.
Bất kể vị trí cài đặt là gì, nó nên nằm trong biến môi trường PATH
của bạn để bạn có thể chạy chương trình chỉ bằng cách gõ tên của nó trên dòng lệnh, thay vì đường dẫn đầy đủ.
Cú pháp lệnh ECHO trên Linux minh họa cách kiểm tra biến môi trường PATH
Kết Luận
Việc biên dịch và cài đặt phần mềm từ mã nguồn trên Linux, với quy trình configure
, make
, install
đã trở thành một nền tảng cơ bản cho người dùng hệ điều hành này. Bằng cách hiểu rõ vai trò của từng bước – từ kiểm tra phụ thuộc và cấu hình môi trường với ./configure
, biên dịch mã nguồn thành tệp thực thi với make
, cho đến việc tích hợp ứng dụng vào hệ thống với make install
– bạn không chỉ có thể tùy chỉnh và khắc phục sự cố hiệu quả hơn mà còn có cái nhìn sâu sắc hơn về cách hoạt động của phần mềm mã nguồn mở.
Giờ đây, khi bạn gặp một dự án yêu cầu biên dịch từ mã nguồn, hãy nhớ ba lệnh đơn giản này và sự tự tin rằng bạn đang làm chủ hệ thống của mình. Bạn đã từng biên dịch phần mềm từ mã nguồn Linux chưa? Hãy chia sẻ kinh nghiệm và những mẹo vặt của bạn trong phần bình luận bên dưới để cộng đồng thichcongnghe.net cùng học hỏi nhé!