Chương 16 · Biên dịch phần mềm từ mã nguồn C Chapter 16 · Introduction to Compiling Software from C Source Code
Bốn bước, một script, và quyền tự quyết về phần mềm trên máy bạn Tự nấu phần mềm từ “nguyên liệu” thay vì mua đồ hộp Four steps, one script, and the right to decide what runs on your machine
Phần lớn phần mềm Unix phi độc quyền của bên thứ ba đến tay bạn dưới dạng mã nguồn để bạn tự dựng và cài, và Brian Ward đưa ra hai lý do. Thứ nhất, Unix — và cả Linux — có quá nhiều biến thể và kiến trúc, nên phát hành gói nhị phân cho mọi tổ hợp nền tảng là việc rất khó. Thứ hai, quan trọng ít nhất là ngang thế: việc phân phối mã nguồn rộng khắp trong cộng đồng Unix khuyến khích người dùng đóng góp bản vá lỗi và tính năng mới, và chính điều đó mới làm cho cụm từ open source có ý nghĩa.1
Có hai cách để có phần mềm: lấy sẵn bản đã nấu chín, hoặc lấy “công thức và nguyên liệu” rồi tự nấu. Trên Linux, “nguyên liệu” đó gọi là mã nguồn. Người ta phát mã nguồn vì máy tính có quá nhiều loại khác nhau, và vì khi ai cũng xem được công thức thì ai cũng có thể sửa chỗ sai. Nhớ nhé: mã nguồn là công thức, bạn tự nấu được món của mình.
Most nonproprietary third-party Unix software packages arrive as source code that you build and install yourself, and Brian Ward gives two reasons. First, Unix — and Linux itself — has so many flavors and architectures that distributing binary packages for every possible platform combination would be difficult. Second, and at least as important: widespread source code distribution throughout the Unix community encourages users to contribute bug fixes and new features, which is what gives the term open source its meaning.1
Ward nói thẳng một điều mà nhiều hướng dẫn trên mạng né tránh: bạn có thể lấy gần như mọi thứ trên hệ thống Linux dưới dạng mã nguồn — từ nhân và thư viện C cho tới trình duyệt web — và thậm chí có thể cập nhật toàn bộ hệ thống bằng cách cài lại từ mã nguồn, nhưng bạn có lẽ không nên làm thế, trừ phi bạn thật sự thích quá trình đó hoặc có lý do riêng.1 Các bản phân phối vốn đã có cách dễ dàng để cập nhật phần lõi như các chương trình trong /bin, và một tính chất đặc biệt quan trọng của bản phân phối là chúng thường vá lỗi bảo mật rất nhanh.1 Chương này vì vậy không phải lời kêu gọi “tự biên dịch tất cả”, mà là bộ kỹ năng cho những lần bạn cần tự biên dịch.
Luận đề của chương: cài một gói từ mã nguồn C thường chỉ gồm bốn bước — giải nén kho lưu trữ, cấu hình gói, chạy make để dựng chương trình, rồi chạy make install — và việc học một hệ thống dựng duy nhất, các script cấu hình sinh ra từ bộ công cụ GNU autotools, là đủ để bạn chuyển kiến thức sang những hệ thống dựng khác, vì tất cả đều đặt trên nền make.1
Ý chính: tự cài phần mềm từ mã nguồn chỉ có bốn bước: mở gói ra, chỉnh cấu hình, dựng, rồi cài. Học kỹ một bộ công cụ là bạn dùng được các bộ khác. Nhớ nhé: mở gói — cấu hình — dựng — cài.
The chapter's thesis: installing a package from C source code usually involves just four steps — unpack the source archive, configure the package, run make to build the programs, then run make install — and learning one build system, the configuration scripts generated from the GNU autotools suite, is enough to transfer your knowledge to others, because they all sit on top of make.1
.tar.gz, .tar.bz2 hoặc .tar.xz — nhưng xem mục lục trước bằng tar tvf
Mở gói ra, nhưng ngó trước xem bên trong có gì
Unpack the .tar.gz, .tar.bz2 or .tar.xz — but list it first with tar tvf
./configure để dò đặc tính hệ thống và sinh Makefile từ Makefile.in
Máy tự dò xem máy bạn có gì, rồi viết bản hướng dẫn dựng
Run ./configure to discover your system and generate Makefile from Makefile.in
/usr/local
Dựng xong thì cài vào máy
Build the programs, then install — by default under the /usr/local prefix
Cụm khái niệm 01 Concept cluster 01
Vì sao tự cài, và cách mở một gói mã nguồn cho an toàn Khi nào nên tự cài, và mở gói thế nào Why install it yourself, and how to open a source package safely
Ward không bảo bạn đừng dùng bản phân phối — ông bảo đừng trông đợi bản phân phối lo mọi thứ cho bạn. Ông liệt kê bốn lý do khiến bạn muốn tự cài một số gói: để kiểm soát các tuỳ chọn cấu hình; để cài phần mềm ở bất cứ đâu bạn thích, thậm chí cài nhiều phiên bản khác nhau của cùng một gói; để kiểm soát phiên bản mình chạy, vì bản phân phối không phải lúc nào cũng theo kịp bản mới nhất, đặc biệt với các phần bổ trợ như thư viện Python; và để hiểu rõ hơn một gói vận hành ra sao.1
Máy Linux đã có sẵn “cửa hàng” phần mềm của nó, và cửa hàng đó rất tiện. Nhưng có lúc bạn muốn món hơi khác: bản mới hơn, hoặc có thêm tuỳ chọn, hoặc bạn chỉ muốn nhìn xem nó được làm ra thế nào. Khi đó bạn tự nấu. Nhớ nhé: tự cài khi bạn cần khác đi, chứ không phải để cho oai.
Ward is not telling you to avoid your distribution — he is telling you not to expect it to provide everything. He lists four reasons you might install certain packages yourself: to control configuration options; to install the software anywhere you like, even several different versions of the same package; to control the version you install, since distributions don't always stay up to date with the latest versions, particularly add-ons such as Python libraries; and to better understand how a package works.1
Trước khi bước vào chương này. Ward đặt một chú ý rõ ràng: bạn nên nắm những điều cơ bản ở Chương 15 trước khi tiếp tục chương 16 — nghĩa là phân biệt được lỗi trình biên dịch, cảnh báo trình biên dịch, lỗi trình liên kết và vấn đề thư viện dùng chung.1 Và ở thời điểm bắt đầu thực hành, bạn phải có sẵn mọi công cụ dựng cần thiết trên máy: với Debian và Ubuntu, cách dễ nhất là cài gói build-essential; với các hệ kiểu Fedora, dùng groupinstall nhóm “Development Tools”.1
Định nghĩa. Một hệ thống dựng (build system) là bộ công cụ riêng của một môi trường lập trình dùng để dựng và cài các gói, nằm bên cạnh những công cụ mà bản phân phối cung cấp. Linux có nhiều môi trường lập trình — từ C truyền thống tới các ngôn ngữ script thông dịch như Python — và mỗi môi trường thường có ít nhất một hệ thống như vậy.1
Nói đơn giản. Hệ thống dựng là bộ “dụng cụ bếp” đi kèm công thức: nó biết phải nấu theo thứ tự nào. Mỗi loại bếp có bộ dụng cụ riêng. Nhớ nhé: công thức đi kèm dụng cụ, học một bộ là quen dần các bộ khác.
Definition. A build system is a programming environment's own set of tools for building and installing packages, alongside the ones your Linux distribution provides. Linux hosts many programming environments — from traditional C to interpreted scripting languages such as Python — and each typically has at least one such system.1
1. tar xzf package-1.23.tar.gz
2. ./configure
3. make
4. make install
1. mở gói
2. cấu hình
3. dựng
4. cài
1. tar xzf package-1.23.tar.gz
2. ./configure
3. make
4. make install
-
tar tvf
Xem mục lục trước khi giải nén — thói quen nhỏ, hậu quả lớn Ngó vào gói trước khi mở List before you extract — a small habit with large consequences
Bản phân phối mã nguồn của một gói thường đến dưới dạng tệp
.tar.gz,.tar.bz2hoặc.tar.xz. Trước khi giải nén, Ward yêu cầu bạn kiểm tra nội dung kho lưu trữ bằngtar tvfhoặctar ztvf, bởi một số gói không tự tạo thư mục con trong thư mục nơi bạn giải nén.1 Kết xuất kiểupackage-1.23/Makefile.in,package-1.23/README,package-1.23/main.c— tức mọi thứ nằm dưới một thư mục chung — là dấu hiệu gói có lẽ mở được an toàn.1Trước khi mở một gói nén, hãy liệt kê xem bên trong có gì. Nếu mọi thứ nằm gọn trong một thư mục thì tốt. Nếu không, mở ra sẽ vãi tung toé khắp nơi. Nhớ nhé: ngó trước, mở sau.
A package's source distribution usually arrives as a
.tar.gz,.tar.bz2or.tar.xzfile. Before unpacking, Ward wants you to verify the archive's contents withtar tvfortar ztvf, because some packages don't create their own subdirectory in the directory where you extract them.1 Output likepackage-1.23/Makefile.in,package-1.23/README,package-1.23/main.c— everything under one common directory — means the package is probably okay to unpack.1Bạn gặp nó ở đâuWhere you meet it Nếu mục lục hiện raMakefile,README,main.cmà không có thư mục chung, hãy tạo một thư mục mới vàcdvào đó trước khi giải nén.1 Khi gói không có thư mục riêng — thì bạn tự tạo một thư mục rồi mới mở. If the listing showsMakefile,README,main.cwith no common directory, create a new directory andcdthere before extracting.1Đường dẫn tuyệt đối là cờ đỏ
Ward cảnh báo phải dè chừng những gói chứa tệp có đường dẫn tuyệt đối, ví dụ
/etc/passwdhay/etc/inetd.conf. Ông viết rằng bạn có lẽ sẽ không gặp thứ như vậy, nhưng nếu gặp thì hãy gỡ kho lưu trữ đó khỏi hệ thống: nó nhiều khả năng chứa ngựa thành Troy hoặc mã độc khác.1 Đây chính là lý do kỹ thuật cho thói quen liệt kê trước:tartự nó chỉ làm theo những gì kho lưu trữ nói.2Đọc README trước, luôn luôn
Sau khi giải nén, Ward khuyên hãy tìm những tệp tên đại loại README và INSTALL. Luôn xem README trước vì nó thường chứa mô tả gói, một cuốn hướng dẫn ngắn, các gợi ý cài đặt và thông tin hữu ích khác; nhiều gói cũng kèm tệp INSTALL với hướng dẫn biên dịch và cài đặt. Hãy đặc biệt chú ý tới các tuỳ chọn và định nghĩa đặc biệt của trình biên dịch.1
-
package layout
Ba nhóm tệp trong một gói mã nguồn Trong gói có những loại tệp nào The three families of files inside a source package
Ngoài README và INSTALL, Ward xếp các tệp còn lại vào ba nhóm. Một: tệp liên quan tới hệ thống
make—Makefile,Makefile.in,configure,CMakeLists.txt; vài gói rất cũ đi kèm mộtMakefilemà bạn có thể phải tự sửa, nhưng phần lớn dùng một tiện ích cấu hình như GNU autoconf hay CMake, kèm script hoặc tệp cấu hình để sinhMakefiletừMakefile.indựa trên thiết lập hệ thống của bạn.1 Hai: tệp mã nguồn kết thúc bằng.c,.hhoặc.cc; tệp C có thể nằm gần như bất cứ đâu trong thư mục gói, còn tệp C++ thường mang đuôi.cc,.Choặc.cxx.1 Ba: tệp đối tượng đuôi.ohoặc tệp nhị phân.1Trong gói có ba loại tệp: loại chỉ cách dựng (Makefile, configure), loại là mã nguồn thật (.c, .h), và loại đã dựng sẵn (.o). Loại thứ ba bình thường không nên có. Nhớ nhé: công thức, nguyên liệu, và đồ đã nấu sẵn — loại thứ ba là đáng ngờ.
Beyond README and INSTALL, Ward sorts the remaining files into three categories. One: files relating to the
makesystem —Makefile,Makefile.in,configure,CMakeLists.txt; some very old packages ship aMakefileyou might need to modify, but most use a configuration utility such as GNU autoconf or CMake, with a script or configuration file that generatesMakefilefromMakefile.inbased on your system settings.1 Two: source files ending in.c,.hor.cc; C files may appear just about anywhere in a package directory, while C++ files usually carry.cc,.Cor.cxxsuffixes.1 Three: object files ending in.o, or binaries.1Bạn gặp nó ở đâuWhere you meet it Thấy tệp.otrong một bản phân phối mã nguồn thì trong phần lớn trường hợp nghĩa là gói được đóng gói không tốt — hãy chạymake cleanđể chắc chắn bạn có một lần biên dịch mới hoàn toàn.1 Thấy đồ nấu sẵn lẫn trong nguyên liệu thì bỏ đi, nấu lại từ đầu. Object files in a source distribution mostly mean the package wasn't put together well — runmake cleanto make sure you get a fresh compile.1Ngoại lệ hiếm cho tệp .o
Ward ghi chú rằng bình thường không có tệp đối tượng nào trong bản phân phối mã nguồn, nhưng trong vài trường hợp hiếm bạn có thể gặp — khi người bảo trì gói không được phép phát hành một phần mã nguồn nào đó và bạn phải làm điều gì đó đặc biệt để dùng được các tệp đối tượng ấy.1
Vì sao cần
Makefile.inCác tệp
.inlà khuôn mẫu; ý tưởng là chạy scriptconfiguređể phát hiện đặc tính hệ thống của bạn, rồi thay thế vào các tệp.inđể tạo ra tệp dựng thật.1 Tài liệu Autoconf mô tả đúng cơ chế đó:configuređoán giá trị đúng cho các biến phụ thuộc hệ thống và dùng chúng để tạo mộtMakefiletrong mỗi thư mục của gói.3 -
portability
Vì sao không thể có một
Makefileduy nhất Vì sao mỗi máy cần một bản hướng dẫn riêng Why oneMakefilecan never be enoughMã nguồn C nhìn chung khá khả chuyển, nhưng Ward chỉ ra rằng khác biệt giữa các nền tảng khiến việc biên dịch phần lớn gói bằng một
Makefileduy nhất là bất khả thi. Các giải pháp thời kỳ đầu là cung cấpMakefileriêng cho từng hệ điều hành, hoặc mộtMakefiledễ sửa. Cách tiếp cận ấy tiến hoá thành các script sinh raMakefiledựa trên phân tích chính hệ thống dùng để dựng gói.1Mỗi máy một khác: chỗ để thư viện khác nhau, tên công cụ khác nhau. Một bản hướng dẫn chung không dùng được cho mọi máy. Thế nên người ta viết một script tự dò máy rồi viết bản hướng dẫn riêng. Nhớ nhé: máy nào cũng khác nhau một chút, nên phải dò rồi mới dựng.
C source code is usually fairly portable, but Ward points out that differences on each platform make it impossible to compile most packages with a single
Makefile. Early solutions provided individual Makefiles per operating system, or one Makefile that was easy to modify. That approach evolved into scripts that generate Makefiles based on an analysis of the system used to build the package.1Bạn gặp nó ở đâuWhere you meet it Mỗi dòngchecking for…màconfigurein ra chính là một lần kiểm tra khác biệt nền tảng đang diễn ra trước mắt bạn.3 Những dòng “checking…” chạy vèo vèo chính là lúc máy đang tự dò. Everychecking for…lineconfigureprints is one platform difference being tested in front of you.3Vì sao Ward chọn autotools cho chương này
Ward xem xét biên dịch và cài đặt mã nguồn C với chỉ một trong số các hệ thống dựng: các script cấu hình sinh ra từ bộ GNU autotools. Lý do ông đưa ra: hệ thống này nhìn chung được coi là ổn định, nhiều tiện ích Linux cơ bản dùng nó, và vì nó đặt trên nền các công cụ sẵn có như
make, sau khi thấy nó hoạt động bạn sẽ chuyển được kiến thức sang các hệ thống dựng khác.1Điều Autoconf hứa với người dùng cuối
Tài liệu Autoconf nói rõ điều làm nên giá trị của cách tiếp cận này: các script cấu hình do Autoconf sinh ra độc lập với Autoconf khi chạy, nên người dùng không cần cài Autoconf; và chúng không cần sự can thiệp thủ công, thường cũng không cần tham số chỉ định loại hệ thống, mà tự kiểm tra sự hiện diện của từng tính năng.4
Cụm khái niệm 02 Concept cluster 02
GNU autoconf: một script dò máy, rồi viết Makefile cho bạn
Script configure: máy tự dò rồi tự viết hướng dẫn
GNU autoconf: a script that inspects your machine, then writes the Makefile
GNU autoconf là một hệ thống phổ biến để sinh Makefile tự động. Gói dùng hệ thống này đi kèm các tệp tên configure, Makefile.in và config.h.in. Các tệp .in là khuôn mẫu; ý tưởng là chạy script configure để khám phá đặc tính hệ thống của bạn, rồi thay thế vào các tệp .in để tạo ra tệp dựng thật.1 Với người dùng cuối thì việc này rất dễ: để sinh Makefile từ Makefile.in, chỉ cần chạy ./configure.1
Có một script tên là configure. Bạn chạy nó, nó tự đi xem máy bạn có gì — có trình biên dịch không, thư viện nằm ở đâu — rồi nó viết ra bản hướng dẫn dựng hợp với máy bạn. Bạn chỉ cần gõ đúng một dòng. Nhớ nhé: gõ ./configure, rồi để máy tự lo phần dò.
GNU autoconf is a popular system for automatic Makefile generation. Packages using it come with files named configure, Makefile.in and config.h.in. The .in files are templates; the idea is to run the configure script to discover the characteristics of your system, then make substitutions in the .in files to create the real build files.1 For the end user it's easy: to generate a Makefile from Makefile.in, run ./configure.1
Điều configure để lại sau lưng. Nếu mọi việc trôi chảy, Ward mô tả rằng configure tạo ra một hoặc nhiều Makefile và một tệp config.h, cùng một tệp đệm config.cache để khỏi phải chạy lại một số kiểm tra.1 Tài liệu Autoconf bổ sung một chi tiết đáng lưu ý: tệp đệm — thường tên config.cache, bật bằng --cache-file=config.cache hoặc gọn hơn là -C — mặc định bị tắt ở các phiên bản Autoconf hiện đại, chính để tránh những rắc rối do vô tình dùng lại tệp đệm cũ.3 Trang này giữ cách mô tả của sách trong phần thân và ghi chú khác biệt ở đây thay vì lặng lẽ chọn một bên.
Chuỗi lệnh chuẩn. Tài liệu Autoconf tóm gọn toàn bộ quy trình vào ba dòng cho người dựng từ bản phát hành: ./configure, make, make install. Trong đó make check là bước tuỳ chọn chạy các bài tự kiểm tra bằng chính các tệp nhị phân vừa dựng mà chưa cài.3
Nói đơn giản. Ba dòng lệnh thôi: cấu hình, dựng, cài. Giữa chừng có thể thử make check để xem món có ổn không trước khi dọn lên bàn. Nhớ nhé: configure — make — make install.
The standard sequence. The Autoconf manual compresses the whole procedure into three lines for someone building from a distribution tarball: ./configure, make, make install. make check is the optional step in between, running any self-tests with the just-built, not-yet-installed binaries.3
configure.ac → autoconf → configure
configure + Makefile.in → Makefile
configure + config.h.in → config.h
configure → config.status, config.log
khuôn mẫu + máy của bạn
→ bản hướng dẫn riêng
→ nhật ký để tra khi hỏng
configure.ac → autoconf → configure
configure + Makefile.in → Makefile
configure + config.h.in → config.h
configure → config.status, config.log
-
--prefix
--prefix — tuỳ chọn hữu ích nhất của
configure--prefix — chọn chỗ để cài --prefix — the most usefulconfigureoptionWard gọi
--prefixlà một trong những tuỳ chọn hữu ích nhất: nó chỉ định thư mục cài đặt. Mặc định, đíchinstallcủa mộtMakefiledo autoconf sinh ra dùng tiền tố/usr/local— nghĩa là chương trình nhị phân vào/usr/local/bin, thư viện vào/usr/local/lib, và cứ thế.1 Bạn sẽ thường muốn đổi tiền tố ấy bằng./configure --prefix=new_prefix.1Mặc định, phần mềm bạn tự dựng sẽ được cài vào
/usr/local. Nhưng bạn có thể bảo nó cài vào bất kỳ đâu — kể cả một thư mục trong nhà bạn. Như thế gỡ đi cũng dễ. Nhớ nhé: --prefix là chỗ bạn chọn nơi cài.Ward calls
--prefixone of the most useful options: it specifies the installation directory. By default theinstalltarget of an autoconf-generated Makefile uses a prefix of/usr/local— binaries go in/usr/local/bin, libraries in/usr/local/lib, and so on.1 You will often want to change that with./configure --prefix=new_prefix.1Bạn gặp nó ở đâuWhere you meet it Trong ví dụ thực hành của Ward,./configure --prefix=$HOME/mycoreutilsđặt toàn bộ gói GNU coreutils vào thư mục nhà, để bạn không làm hỏng hệ thống.1 Ví dụ trong sách: cài vào thư mục riêng trong nhà bạn, xong xoá đi cũng chẳng sao. In Ward's hands-on example,./configure --prefix=$HOME/mycoreutilsputs the whole GNU coreutils package in your home directory, so you can't mess up your system.1Tiền tố này là một quy ước của GNU, không phải của autoconf
GNU Coding Standards quy định rằng giá trị mặc định của
prefixphải là/usr/local, và mọi thư mục cài đặt khác đều là thư mục con củaprefixhoặcexec_prefix, chứ không có gì được cài thẳng vào hai thư mục gốc ấy.5exec_prefixmặc định bằng$(prefix)và dành cho những thư mục chứa tệp phụ thuộc kiến trúc máy — chương trình thực thi và thư viện — trong khi$(prefix)dùng trực tiếp cho các thư mục còn lại.5Đổi tiền tố không nên bắt biên dịch lại
Cũng trong tài liệu đó có một câu đáng nhớ khi bạn nghi ngờ một gói cư xử lạ: chạy
make installvới giá trịprefixkhác với giá trị lúc dựng không nên biên dịch lại chương trình.5 Tài liệu Autoconf nói thêm rằng cách khả chuyển nhất vẫn là truyền đúng vị trí choconfigure; các cách ghi đè lúcmake installchỉ là lối tắt và có nền tảng gặp hạn chế với ngữ nghĩa thư viện dùng chung.6 -
configure options
Những tuỳ chọn thiết yếu khác — khi
--helpquá dài để đọc Vài tuỳ chọn đáng nhớ The other essential options — when--helpis too long to readPhần lớn phiên bản
configurecó tuỳ chọn--helpliệt kê các lựa chọn cấu hình khác. Ward nhận xét thẳng: đáng tiếc là danh sách ấy thường dài tới mức khó biết cái nào quan trọng. Ông chắt ra một nhóm thiết yếu:--bindir=directorycài tệp thực thi vào directory;--sbindir=directorycài tệp thực thi hệ thống;--libdir=directorycài thư viện;--disable-sharedngăn gói dựng thư viện dùng chung, điều mà tuỳ thư viện có thể tránh được phiền phức về sau; và--with-package=directorychoconfigurebiết package nằm ở directory, rất tiện khi một thư viện cần thiết nằm ở vị trí phi tiêu chuẩn.1Có vài công tắc hay dùng: chọn chỗ để chương trình, chọn chỗ để thư viện, và bảo nó “thư viện tôi cần nằm ở đây này”. Danh sách đầy đủ thì rất dài, nên chỉ cần nhớ mấy cái hay dùng. Nhớ nhé: --prefix là chính, còn lại là chỉnh lặt vặt.
Most versions of
configurehave a--helpoption listing other configuration options. Ward is blunt: the list is usually so long that it's hard to work out what might be important. He distils an essential set:--bindir=directoryinstalls executables there;--sbindir=directoryinstalls system executables;--libdir=directoryinstalls libraries;--disable-sharedprevents the package from building shared libraries, which depending on the library can save hassles later; and--with-package=directorytellsconfigurethat package is in directory, handy when a needed library sits in a nonstandard location.1Bạn gặp nó ở đâuWhere you meet it Ward cảnh báo rằng không phải mọi scriptconfiguređều nhận dạng tuỳ chọn--with-…, và có thể khó xác định cú pháp chính xác.1 Không phải gói nào cũng hiểu mọi công tắc — nên đọc--helpcủa chính gói đó. Ward warns that not allconfigurescripts recognise the--with-…form, and the exact syntax can be hard to determine.1Các biến thư mục chuẩn, theo nguồn gốc của chúng
Những tuỳ chọn
--bindir,--sbindir,--libdiránh xạ một-một vào các biến thư mục của GNU Coding Standards:bindirlà$(exec_prefix)/bincho chương trình người dùng chạy được;sbindirlà$(exec_prefix)/sbincho chương trình chỉ hữu ích với quản trị viên;libexecdirlà$(exec_prefix)/libexeccho chương trình được chương trình khác gọi chứ không phải người dùng gọi;datarootdirlà$(prefix)/share;sysconfdirlà$(prefix)/etc; cònlocalstatedirlà$(prefix)/varcho dữ liệu chương trình sửa đổi trong lúc chạy.5Vì sao mặc định được viết theo
${prefix}Tài liệu Autoconf giải thích: mặc định của các tuỳ chọn thư mục nhìn chung được biểu đạt theo
${prefix}, nên chỉ cần chỉ định--prefixlà ảnh hưởng tới mọi thư mục khác chưa được nêu tường minh.6 Đó là lý do một dòng--prefixduy nhất đủ để di dời cả gói. -
CPPFLAGS / CFLAGS / LDFLAGS
Biến môi trường — nơi
configurerất khó tính Ba biến hay dùng, và một dấu gạch dễ quên Environment variables — whereconfigureis very pickyBạn có thể tác động tới
configurebằng các biến môi trường mà nó đưa vào biến củamake. Ward nêu ba biến quan trọng nhất:CPPFLAGS,CFLAGSvàLDFLAGS— nhưng cảnh báo rằngconfigurecó thể rất khó tính với biến môi trường. Ví dụ, bạn thường nên dùngCPPFLAGSthay vìCFLAGScho thư mục tệp tiêu đề, vìconfigurehay chạy bộ tiền xử lý độc lập với trình biên dịch.1Ba cái “hộp” bạn có thể nhét chỉ dẫn vào: một cho chỗ tìm tệp tiêu đề, một cho trình biên dịch, một cho bước nối các mảnh lại. Chọn nhầm hộp là hỏng. Nhớ nhé: tìm tệp .h thì dùng CPPFLAGS, đừng dùng CFLAGS.
You can influence
configurewith environment variables that it feeds into make variables. Ward names the three most important:CPPFLAGS,CFLAGSandLDFLAGS— but warns thatconfigurecan be very picky about them. For instance, you should normally useCPPFLAGSrather thanCFLAGSfor header file directories, becauseconfigureoften runs the preprocessor independently of the compiler.1Bạn gặp nó ở đâuWhere you meet it Trongbash, cách dễ nhất là đặt phép gán ngay trước./configure:CPPFLAGS=-DDEBUG ./configure. Bạn cũng có thể truyền biến như một tuỳ chọn:./configure CPPFLAGS=-DDEBUG.1 Gõ biến ngay trước lệnh, hoặc gõ nó như một tham số phía sau — cả hai đều được. Inbashthe easiest way is to put the assignment in front of./configure:CPPFLAGS=-DDEBUG ./configure. You can also pass a variable as an option:./configure CPPFLAGS=-DDEBUG.1Tìm tệp tiêu đề và thư viện ở nơi phi tiêu chuẩn
Ward cho hai công thức cụ thể: để bộ tiền xử lý tìm trong include_dir, chạy
CPPFLAGS=-Iinclude_dir ./configure; để trình liên kết tìm trong lib_dir, chạyLDFLAGS=-Llib_dir ./configure.1 Nếu lib_dir chứa thư viện dùng chung, lệnh trên có lẽ không đặt đường dẫn cho trình liên kết động lúc chạy; khi đó dùng thêm tuỳ chọn-rpath:LDFLAGS="-Llib_dir -Wl,-rpath=lib_dir" ./configure.17Một dấu gạch thiếu, một lỗi khó hiểu
Ward dựng sẵn cái bẫy: quên dấu
-trong-I, tức gõCPPFLAGS=Iinclude_dir ./configure, sẽ sinh ra lỗiconfigure: error: C compiler cannot create executableskèm dòngSee 'config.log' for more details.1 Đào vàoconfig.logmới thấy nguyên nhân thật:gcc: error: Iinclude_dir: No such file or directory.1 Thông điệp lớn hơn: lỗi màconfigurein ra thường không phải lỗi thật.Vì sao nên truyền biến trên dòng lệnh
Tài liệu Autoconf đưa một lý do kỹ thuật cho lối viết
./configure VAR=value: một số gói có thể chạy lạiconfiguretrong lúc dựng, và khi đó giá trị tuỳ chỉnh đặt trong môi trường có thể bị mất; đặt biến ngay trên dòng lệnhconfiguretránh được vấn đề này.8 -
make targets
Bốn đích
makemà autoconf tặng thêm Bốn lệnh make hay dùng The four extramaketargets autoconf gives youKhi
configuređã chạy được, Ward chỉ ra rằngMakefilenó sinh ra có một số đích hữu ích ngoàiallvàinstalltiêu chuẩn.make cleanxoá mọi tệp đối tượng, tệp thực thi và thư viện.make distcleangiốngcleannhưng xoá mọi tệp được sinh tự động, gồm cả cácMakefile,config.h,config.log— ý tưởng là sau khi chạy, cây mã nguồn trông như một bản phân phối vừa mới giải nén.make checkchạy bộ bài kiểm tra mà một số gói kèm theo. Vàmake install-stripgiốnginstallnhưng lược bỏ bảng ký hiệu cùng thông tin gỡ lỗi khỏi tệp thực thi và thư viện khi cài; tệp nhị phân đã lược bỏ chiếm ít không gian hơn nhiều.1Ngoài “dựng” và “cài”, còn bốn lệnh nữa: dọn dẹp, dọn sạch về như lúc mới mở gói, chạy thử, và cài bản gọn nhẹ. Nhớ nhé: clean là quét nhà, distclean là trả lại nguyên trạng.
Once
configureworks, Ward points out that the generated Makefile has several useful targets beyond the standardallandinstall.make cleanremoves all object files, executables and libraries.make distcleanis likecleanbut also removes all automatically generated files, including Makefiles,config.handconfig.log— the idea being that after it runs, the source tree should look like a newly unpacked distribution.make checkruns the battery of tests some packages ship. Andmake install-stripis likeinstallexcept it strips the symbol table and other debugging information from executables and libraries when installing; stripped binaries require much less space.1Bạn gặp nó ở đâuWhere you meet it Khi bạn muốn cấu hình lại gói cho một hệ thống khác,make distcleanlà bước đưa cây mã nguồn về trạng thái sạch trước khi chạy lạiconfigure.6 Muốn làm lại từ đầu thì gõmake distcleantrước. When you want to reconfigure the package for another system,make distcleanis the step that returns the source tree to a clean state before runningconfigureagain.6Vì sao
installcố tình không lược bỏ ký hiệuGNU Coding Standards nêu lý do đằng sau cặp
install/install-strip: đừng lược bỏ tệp thực thi khi cài, vì điều đó giúp cho việc gỡ lỗi có thể cần về sau, và ngày nay không gian đĩa rẻ trong khi bộ nạp động thường bảo đảm các phần gỡ lỗi không được nạp trong lúc chạy bình thường; người cần bản nhị phân đã lược bỏ có thể gọi đíchinstall-strip.9 Công cụ thực hiện việc lược bỏ làstrip, vốn loại bỏ ký hiệu khỏi tệp đối tượng.10cleanvàdistcleantheo đúng định nghĩa chuẩnCùng tài liệu ấy định nghĩa:
cleanxoá mọi tệp trong thư mục hiện tại thường được tạo ra khi dựng chương trình, nhưng không xoá những tệp ghi lại cấu hình; còndistcleanxoá mọi tệp được tạo ra bởi việc cấu hình hoặc dựng, sao cho nếu bạn chỉ giải nén và dựng thì saumake distcleanchỉ còn lại những tệp vốn có trong bản phân phối.9 Đó chính là ranh giới giữa hai lệnh mà Ward mô tả.check: thử trước khi càiĐịnh nghĩa chuẩn của
checklà thực hiện các bài tự kiểm tra, nếu có: người dùng phải dựng chương trình trước khi chạy kiểm tra nhưng không cần cài, và tác giả gói phải viết bài kiểm tra sao cho chúng chạy được khi chương trình đã dựng mà chưa cài.9 Đây là lý domake checknằm giữamakevàmake installchứ không phải sau cùng. -
config.log
Đọc
config.logtừ dưới lên — nhưng đừng đọc ngay cuối Khi configure hỏng thì tra nhật ký ở đâu Readingconfig.logbackwards — but not from the very endNếu có gì sai trong quá trình
configuremà nguyên nhân không hiển nhiên, bạn có thể xemconfig.log. Đáng tiếc, Ward lưu ý,config.logthường là một tệp khổng lồ, khiến việc định vị nguồn gốc chính xác của vấn đề trở nên khó.1 Cách tiếp cận chung là đi tới tận cuối tệp — chẳng hạn gõGviết hoa trongless— rồi lật ngược lên cho tới khi thấy vấn đề.1Khi bước cấu hình hỏng, có một tệp nhật ký ghi lại mọi thứ. Nó rất dài. Mẹo là nhảy xuống cuối rồi tìm ngược lên, chứ không đọc từ đầu. Nhớ nhé: lỗi thật thường nằm ngay phía trên chỗ bạn tìm thấy.
If something goes wrong during
configureand the cause isn't obvious, you can examineconfig.log. Unfortunately, Ward notes,config.logis often a gigantic file, which makes pinpointing the exact source difficult.1 The general approach is to go to the very end of the file — for example by typing a capitalGinless— and then page back up until you see the problem.1Bạn gặp nó ở đâuWhere you meet it Ward tinh chỉnh mẹo này: vẫn còn rất nhiều thứ ở cuối vìconfiguređổ toàn bộ môi trường của nó ra đó — biến kết xuất, biến đệm và các định nghĩa khác — nên thay vì lật ngược, hãy tìm ngược một chuỗi nhưfor more details.1 Đừng lật từng trang: hãy tìm ngược một cụm chữ quen thuộc. Ward refines the trick: there's still a lot at the end becauseconfiguredumps its entire environment there — output variables, cache variables and other definitions — so rather than paging up, search backward for a string such asfor more details.1Cú pháp tìm ngược trong
lessWard nhắc rằng bạn khởi tạo một lần tìm ngược trong
lessbằng lệnh?; và có khả năng cao lỗi sẽ nằm ngay phía trên chỗ lần tìm của bạn dừng lại.1 Trong ví dụ về dấu gạch bị thiếu, phầnconfig.logđáng giá gồm bốn dòng đánh số dòng của chính script —configure:5037: checking whether the C compiler workscho tớiconfigure:5101: result: no— với dònggcc: error:nằm chính giữa.1config.loglà gì theo tài liệu gốcTài liệu Autoconf mô tả
config.logđúng bằng một câu:configuretạo ra scriptconfig.statusđể bạn tái lập cấu hình hiện tại trong tương lai, và một tệpconfig.logchứa kết xuất hữu ích cho việc gỡ lỗi chínhconfigure.3 Nói cách khác, nó không phải nhật ký của chương trình bạn dựng — nó là nhật ký của bước dò.
Cụm khái niệm 03 Concept cluster 03
Cài ở đâu, cài bằng gì, và giữ cho hệ thống khỏi thành mớ hỗn độn Cài vào chỗ nào cho gọn gàng Where to install, with what, and how to keep the system from becoming a mess
Ward đảo ngược trọng tâm ở đây: biết cách dựng và cài phần mềm là tốt, nhưng biết khi nào và ở đâu nên cài gói của riêng mình còn hữu ích hơn. Vì các bản phân phối cố nhồi càng nhiều phần mềm càng tốt lúc cài đặt, bạn nên luôn kiểm tra xem tự cài một gói có tốt hơn không.1
Biết nấu là một chuyện. Biết nên nấu món nào, và để món đó vào ngăn nào trong tủ, mới là chuyện quan trọng hơn. Nhớ nhé: cài đúng chỗ thì sau này dọn mới dễ.
Ward flips the emphasis here: knowing how to build and install software is good, but knowing when and where to install your own packages is even more useful. Because distributions try to cram in as much software as possible at installation, you should always check whether installing a package yourself would be better.1
Danh sách hai chiều của Ward. Ông không bán ý tưởng một chiều. Lợi thế của việc tự cài: bạn tuỳ biến được mặc định của gói; bạn thường hiểu rõ hơn cách dùng nó; bạn kiểm soát bản phát hành mình chạy; sao lưu một gói tự cài dễ hơn; và phân phối gói tự cài qua mạng cũng dễ hơn, miễn kiến trúc nhất quán và vị trí cài tương đối biệt lập.1 Bất lợi: nếu gói đã có sẵn trên hệ thống, bạn có thể ghi đè các tệp quan trọng và gây rắc rối — tránh điều đó bằng tiền tố /usr/local; việc này tốn thời gian; gói tuỳ chỉnh không tự nâng cấp, một mối lo đặc biệt với các gói tương tác qua mạng vì bạn muốn luôn có bản vá bảo mật mới nhất; nếu bạn không thật sự dùng gói đó thì bạn đang phí thời gian; và luôn có nguy cơ cấu hình sai.1
Định nghĩa. Tiền tố (prefix) là thư mục gốc mà toàn bộ cây cài đặt của một gói treo bên dưới. Tiền tố mặc định trong GNU autoconf và nhiều gói khác là /usr/local, thư mục truyền thống cho phần mềm cài tại chỗ; việc nâng cấp hệ điều hành bỏ qua /usr/local, nên bạn sẽ không mất thứ gì đã cài ở đó khi nâng cấp hệ điều hành.1
Nói đơn giản. Tiền tố là cái ngăn tủ bạn chọn để cất phần mềm tự cài. Ngăn tiêu chuẩn tên là /usr/local, và khi hệ điều hành nâng cấp thì nó không đụng vào ngăn này. Nhớ nhé: /usr/local là ngăn của riêng bạn.
Definition. The prefix is the root directory under which a package's entire installed tree hangs. The default prefix in GNU autoconf and many other packages is /usr/local, the traditional directory for locally installed software; operating system upgrades ignore /usr/local, so you won't lose anything installed there during an OS upgrade.1
prefix = /usr/local
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
sysconfdir = $(prefix)/etc
ngăn gốc = /usr/local
chương trình → bin
thư viện → lib
cấu hình → etc
prefix = /usr/local
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
sysconfdir = $(prefix)/etc
-
make -n install
Chạy thử trước khi cài thật Diễn tập trước khi làm thật Rehearse the install before you do it
Trong ví dụ coreutils, trước khi cài Ward yêu cầu làm một lần chạy khan bằng
make -n install, để thấymake installsẽ làm gì mà không thật sự cài. Hãy duyệt qua kết xuất, và nếu không có gì lạ — chẳng hạn gói định cài vào chỗ nào khác ngoài thư mụcmycoreutilscủa bạn — thì mới cài thật bằngmake install.1Trước khi cài thật, bảo máy “diễn thử” đi: nó sẽ kể ra định chép những gì đi đâu, mà chưa chép gì cả. Đọc xong thấy ổn thì mới làm thật. Nhớ nhé: diễn thử một lần, đỡ hối hận một lần.
In the coreutils example, Ward asks you to do a dry run with
make -n installfirst, to see whatmake installdoes without actually doing it. Browse the output, and if nothing seems strange — such as the package installing anywhere other than yourmycoreutilsdirectory — then do the real install withmake install.1Bạn gặp nó ở đâuWhere you meet it Sau khi cài, bạn sẽ có thư mục conmycoreutilstrong thư mục nhà, chứabin,sharevà các thư mục con khác — và vì nó độc lập với phần còn lại của hệ thống, bạn có thể xoá sạch mà không lo gây hỏng.1 Cài xong, muốn bỏ thì xoá cả thư mục đó là xong — không ảnh hưởng gì tới máy. After installing you'll have amycoreutilssubdirectory in your home directory containingbin,shareand others — and because it's independent of the rest of your system, you can remove it completely without worrying about causing damage.1Bài tập đầy đủ của Ward
Ví dụ thực hành trong sách là cài gói GNU coreutils vào thư mục nhà của chính bạn để chắc chắn không làm hỏng hệ thống: lấy gói từ
ftp.gnu.org/gnu/coreutils/(bản mới nhất thường là tốt nhất), giải nén, chuyển vào thư mục của nó, rồi./configure --prefix=$HOME/mycoreutils, sau đómake.111 Tiếp đó hãy thử chạy một trong các tệp thực thi vừa tạo, chẳng hạn./src/ls, và chạymake checkđể thực hiện một loạt bài kiểm tra trên gói — việc này có thể mất một lúc, nhưng thú vị.1Bạn vừa dựng lại chính những công cụ mình dùng
Ward chốt bài tập bằng một nhận xét có chủ ý: hãy xem qua các chương trình trong
bin, vì bạn vừa dựng nhiều công cụ cơ bản mà bạn đã học ở Chương 2.1 Ông cũng nói thẳng ở mục sau: chẳng có mấy ý nghĩa khi cài những gói như coreutils —ls,catvà tương tự — trừ phi bạn đang dựng một hệ thống rất tuỳ biến; ngược lại, nếu bạn quan tâm sống còn tới máy chủ mạng như Apache thì cách tốt nhất để kiểm soát hoàn toàn là tự cài lấy.1 -
checkinstall
Cài bằng công cụ đóng gói, để còn gỡ được về sau Cài kiểu có “phiếu bảo hành” Installing through a packaging tool, so you can remove it later
Trên phần lớn bản phân phối, bạn có thể cài phần mềm mới như một gói mà sau này vẫn bảo trì được bằng công cụ đóng gói của bản phân phối. Ward nói các bản phân phối dựa trên Debian, như Ubuntu, có lẽ là dễ nhất: thay vì chạy
make installtrơn, bạn cài bằng tiện íchcheckinstall, dạng# checkinstall make install.1Có một cách cài thông minh hơn: thay vì chép tệp lung tung, bạn bảo máy ghi lại danh sách mọi thứ đã chép, rồi gói danh sách đó lại. Sau này muốn gỡ, chỉ cần nói “gỡ gói này”. Nhớ nhé: cài có ghi sổ thì gỡ mới sạch.
On most distributions you can install new software as a package that you can maintain later with your distribution's packaging tools. Ward says Debian-based distributions such as Ubuntu are perhaps the easiest: rather than running a plain
make install, you install with thecheckinstallutility, as# checkinstall make install.1Bạn gặp nó ở đâuWhere you meet it Chạy lệnh này sẽ hiện các thiết lập liên quan tới gói sắp dựng và cho bạn cơ hội thay đổi; khi bạn tiếp tục,checkinstalltheo dõi mọi tệp sẽ được cài lên hệ thống và đặt chúng vào một tệp.deb— sau đó bạn dùngdpkgđể cài và gỡ gói mới.112 Nó hỏi bạn vài câu, rồi tạo ra một “hộp” gói đúng chuẩn để cài và gỡ như mọi gói khác. Running it shows the settings for the package you're about to build and lets you change them; when you proceed,checkinstalltracks all the files to be installed and puts them into a.debfile — you then usedpkgto install and remove the new package.112Phía RPM thì rườm rà hơn
Ward nói rõ rằng tạo một gói RPM phức tạp hơn một chút, vì trước hết bạn phải tạo một cây thư mục cho gói của mình. Việc này làm được bằng lệnh
rpmdev-setuptree; xong xuôi thì dùng tiện íchrpmbuildđể đi qua các bước còn lại. Ông khuyên nên theo một hướng dẫn trực tuyến cho quy trình này.113Khi
/usr/localbắt đầu mất kiểm soátWard thừa nhận nhược điểm của tiền tố truyền thống: nếu bạn cài nhiều phần mềm tuỳ chỉnh,
/usr/localcó thể biến thành một mớ hỗn độn khủng khiếp — hàng nghìn tệp nhỏ lạ lẫm lọt vào cây thư mục ấy, và bạn có thể chẳng biết chúng từ đâu ra.1 Lời khuyên của ông khi mọi thứ thật sự trở nên khó bảo: hãy tự tạo gói của mình, tức quay lại đúng kỹ thuậtcheckinstall/rpmbuildở trên.1 -
pkg-config
pkg-config— hỏi thư viện xem nó cần cờ gì Hỏi thẳng thư viện xem nó ở đâupkg-config— asking a library which flags it needsCó vô số thư viện bên thứ ba trên một hệ thống, nên giữ hết chúng ở một chỗ chung thì lộn xộn; nhưng cài mỗi thư viện với một tiền tố riêng lại gây rắc rối khi dựng các gói cần tới chúng. Ward nêu ví dụ cụ thể: muốn biên dịch OpenSSH thì bạn cần thư viện OpenSSL — làm sao cho quy trình cấu hình của OpenSSH biết OpenSSL nằm đâu và cần những thư viện nào?1 Nhiều thư viện nay dùng chương trình
pkg-configkhông chỉ để quảng bá vị trí tệp tiêu đề và thư viện, mà còn để chỉ định chính xác các cờ bạn cần để biên dịch và liên kết.1Thư viện nằm rải rác khắp máy. Thay vì bạn phải đi tìm, có một chương trình nhỏ hỏi hộ: “thư viện này ở đâu, cần khai báo gì?” Nó trả lời gọn một dòng. Nhớ nhé: đừng đoán chỗ thư viện — hỏi pkg-config.
The multitude of third-party libraries makes keeping them all in one common location messy, yet installing each under a separate prefix causes problems when building packages that need them. Ward's concrete example: to compile OpenSSH you need the OpenSSL library — how do you tell the OpenSSH configuration process where the OpenSSL libraries are and which ones are required?1 Many libraries now use the
pkg-configprogram not only to advertise the locations of their include files and libraries but also to specify the exact flags you need to compile and link.1Bạn gặp nó ở đâuWhere you meet it Cú pháp làpkg-config options package1 package2 …; ví dụpkg-config --libs zlibcho kết quả-lz, cònpkg-config --list-allhiện mọi thư viện mà nó biết kèm mô tả ngắn.114 Ví dụ: hỏi về thư viện nén zlib, nó trả lời đúng một chữ-lz. The syntax ispkg-config options package1 package2 …; for examplepkg-config --libs zliboutputs-lz, whilepkg-config --list-allshows every library it knows about with a brief description.114Các tệp
.pc— dữ liệu đằng sau câu trả lờiNhìn sau hậu trường,
pkg-configtìm thông tin gói bằng cách đọc các tệp cấu hình kết thúc bằng.pc. Ward trưng raopenssl.pccủa thư viện OpenSSL trên một hệ Ubuntu, nằm ở/usr/lib/x86_64-linux-gnu/pkgconfig, với các dòng nhưprefix=/usr,libdir=${exec_prefix}/lib/x86_64-linux-gnu,Libs: -L${libdir} -lssl -lcryptovàLibs.private: -ldl -lz.1 Ông lưu ý bạn có thể sửa tệp này, chẳng hạn thêm-Wl,-rpath=${libdir}vào cờ thư viện để đặt đường dẫn tìm thư viện lúc chạy.1Nó tìm
.pcở đâu — và vì sao bạn thường không thấyMặc định,
pkg-configtìm trong thư mụclib/pkgconfigthuộc tiền tố cài đặt của chính nó: mộtpkg-configcài với tiền tố/usr/localsẽ tìm trong/usr/local/lib/pkgconfig.1 Ward kèm một chú ý rất thực tế: bạn sẽ không thấy tệp.pccho nhiều gói trừ phi cài các gói phát triển — ví dụ để cóopenssl.pctrên Ubuntu, bạn phải cài góilibssl-dev.1Hai cách đưa
.pcở nơi phi tiêu chuẩn vào tầm vớiVì mặc định
pkg-configkhông đọc tệp.pcnào ngoài tiền tố cài đặt của nó, một tệp ở chỗ như/opt/openssl/lib/pkgconfig/openssl.pcsẽ nằm ngoài tầm với. Ward nêu hai cách: tạo liên kết tượng trưng (hoặc bản sao) từ các tệp.pcthật tới thư mụcpkgconfigtrung tâm; hoặc đặt biến môi trườngPKG_CONFIG_PATHđể bao gồm các thư mụcpkgconfigphụ — nhưng ông nói thẳng rằng chiến lược thứ hai không hoạt động tốt trên phạm vi toàn hệ thống.114 -
separate build directory
Thư mục dựng riêng — giữ cây mã nguồn nguyên vẹn Dựng ở một chỗ khác, đừng bày bừa lên nguyên liệu A separate build directory — keeping the source tree pristine
Nếu bạn muốn thí nghiệm với các tuỳ chọn, Ward chỉ cách tạo thư mục dựng riêng: tạo một thư mục mới ở bất cứ đâu trên hệ thống, rồi từ thư mục đó chạy script
configurenằm trong thư mục mã nguồn gốc của gói. Bạn sẽ thấyconfiguretạo một rừng liên kết tượng trưng trong thư mục dựng mới, nơi mọi liên kết trỏ ngược về cây mã nguồn trong thư mục gói ban đầu.1Thay vì nấu ngay trên đống nguyên liệu, bạn bày một cái bàn khác rồi nấu ở đó. Nguyên liệu vẫn sạch, và bạn có thể nấu nhiều kiểu cùng lúc. Nhớ nhé: dựng ở bàn riêng, nguyên liệu giữ nguyên.
If you want to experiment with options, Ward shows how to use a separate build directory: create a new directory anywhere on the system and, from there, run the
configurescript in the original package source directory. You'll findconfiguremakes a symbolic link farm in your new build directory, where all the links point back to the source tree in the original package directory.1Bạn gặp nó ở đâuWhere you meet it Một số nhà phát triển thích bạn dựng gói theo lối này vì cây mã nguồn gốc không bao giờ bị sửa đổi; cách này cũng hữu ích khi bạn muốn dựng cho nhiều nền tảng hoặc nhiều bộ tuỳ chọn cấu hình từ cùng một gói mã nguồn.1 Hữu ích khi bạn muốn thử nhiều kiểu dựng khác nhau từ cùng một bộ nguyên liệu. Some developers prefer that you build this way because the original source tree is never modified; it's also useful when you want to build for more than one platform or option set from the same source package.1Tên chính thức của kỹ thuật này
Tài liệu Autoconf gọi đây là VPATH build và mô tả cơ chế: bạn
cdtới thư mục nơi bạn muốn đặt tệp đối tượng và tệp thực thi, rồi chạy scriptconfigure;configuretự động tìm mã nguồn trong thư mục chứa chính nó và trong...15 Tài liệu cũng cảnh báo: với mộtmakekhông phải GNU, an toàn hơn là biên dịch gói cho một hệ thống tại một thời điểm ngay trong thư mục mã nguồn, và dùngmake distcleantrước khi cấu hình lại cho hệ thống khác.15Họ hàng gần: cài theo giai đoạn với
DESTDIRChương 16 không bàn tới
DESTDIR, nhưng nó là công cụ đứng ngay cạnh--prefixkhi bạn đóng gói, nên đáng phân biệt cho rõ.DESTDIRlà một biến được thêm vào trước mỗi tệp đích khi cài, do người dùng chỉ định trên dòng lệnhmakedưới dạng tên tệp tuyệt đối, ví dụmake DESTDIR=/tmp/stage install: một bước cài lẽ ra đặt/usr/local/bin/foosẽ đặt/tmp/stage/usr/local/bin/foo.16 Khác biệt cốt lõi:--prefixthay đổi nơi chương trình nghĩ rằng nó được cài, cònDESTDIRchỉ dời nơi tệp được chép tới lần này — tài liệu nói rõ rằng việc chỉ địnhDESTDIRkhông được thay đổi hoạt động của phần mềm theo bất kỳ cách nào, nên giá trị của nó không được nhúng vào nội dung tệp nào cả.16 Nó chỉ nên được hỗ trợ trong các đíchinstall*vàuninstall*, và thường dùng nhất khi tạo gói.16
Cụm khái niệm 04 Concept cluster 04
Vá mã nguồn, và đọc lỗi biên dịch cho đúng chỗ Vá mã nguồn và đọc thông báo lỗi Applying patches, and reading build errors in the right place
Phần lớn thay đổi với mã nguồn phần mềm ngày nay xuất hiện dưới dạng nhánh trong bản mã nguồn trực tuyến của nhà phát triển, chẳng hạn một kho Git. Nhưng thỉnh thoảng bạn vẫn nhận được một bản vá cần áp vào mã nguồn để sửa lỗi hoặc thêm tính năng. Ward ghi chú rằng bạn cũng có thể thấy từ diff được dùng như từ đồng nghĩa của patch, vì chương trình diff chính là thứ tạo ra bản vá.1
Bản vá là một tờ giấy ghi “ở dòng này, bỏ chữ cũ, thêm chữ mới”. Có một chương trình đọc tờ giấy đó và sửa hộ bạn. Nhớ nhé: bản vá là danh sách những chỗ cần sửa, không phải bản mã nguồn mới.
Most changes to software source code now arrive as branches of the developer's online source, such as a Git repository. But every now and then you get a patch that you need to apply against source code to fix bugs or add features. Ward notes you may also see the term diff used as a synonym for patch, because the diff program is what produces the patch.1
Trước khi gỡ rối, hãy đọc được kết xuất make. Ward đặt một điều kiện tiên quyết: nếu bạn hiểu khác biệt giữa lỗi trình biên dịch, cảnh báo trình biên dịch, lỗi trình liên kết và vấn đề thư viện dùng chung như mô tả ở Chương 15, bạn sẽ không quá chật vật với phần lớn trục trặc khi dựng phần mềm.1 Ông cũng nói thẳng rằng bạn khó có khả năng gặp những vấn đề trong mục này khi dựng bằng autoconf — nhưng biết chúng trông thế nào thì chẳng bao giờ thừa.1
Định nghĩa. Phần đầu một bản vá trông như --- src/file.c.orig theo sau là +++ src/file.c và một dòng phạm vi dạng @@ -2,16 +2,12 @@. Bản vá thường chứa thay đổi cho nhiều hơn một tệp: hãy tìm ba dấu gạch liên tiếp (---) trong bản vá để thấy những tệp nào bị sửa.1
Nói đơn giản. Nhìn mấy dòng đầu là biết bản vá đụng vào tệp nào. Dấu ba gạch mở đầu mỗi tệp mới. Nhớ nhé: đọc đầu bản vá trước khi áp nó.
Definition. The beginning of a patch looks like --- src/file.c.orig followed by +++ src/file.c and a range line such as @@ -2,16 +2,12 @@. Patches usually contain alterations to more than one file: search the patch for three dashes in a row (---) to see which files have alterations.1
--- src/file.c.orig
+++ src/file.c
@@ -2,16 +2,12 @@
$ patch -p0 < patch_file
tệp cũ → tệp mới
vị trí cần sửa
rồi chạy: patch -p0
--- src/file.c.orig
+++ src/file.c
@@ -2,16 +2,12 @@
$ patch -p0 < patch_file
-
patch -p0
Đứng đúng thư mục — điều kiện thật sự của
patchĐứng đúng chỗ rồi mới vá Standing in the right directory — whatpatchreally requiresWard nhấn mạnh: hãy luôn xem phần đầu bản vá để xác định thư mục làm việc cần thiết. Trong ví dụ của ông, bản vá nhắc tới
src/file.c; do đó bạn phải chuyển tới thư mục chứasrc, chứ không phải vào chính thư mụcsrc.1 Áp bản vá bằng lệnhpatch -p0 < patch_file; nếu mọi việc trôi chảy,patchthoát mà không làm ồn, để lại cho bạn một bộ tệp đã cập nhật.1Bản vá ghi đường đi tới tệp cần sửa. Bạn phải đứng đúng chỗ để đường đi đó khớp. Đứng sai một bậc là hỏng. Nhớ nhé: nhìn đường dẫn trong bản vá rồi đứng cho khớp.
Ward stresses that you should always look at the beginning of a patch to determine the required working directory. In his example the patch refers to
src/file.c; therefore you should change to the directory that containssrc, not to thesrcdirectory itself.1 Apply it withpatch -p0 < patch_file; if all goes well,patchexits without a fuss, leaving you with an updated set of files.1Bạn gặp nó ở đâuWhere you meet it Nếupatchhỏi bạnFile to patch:thì thường là bạn không ở đúng thư mục — nhưng cũng có thể mã nguồn của bạn không khớp với mã nguồn trong bản vá.1 Nếu nó hỏi “vá tệp nào?” thì gần như chắc là bạn đứng sai chỗ. Ifpatchasks youFile to patch:, it usually means you're not in the correct directory — but it could also mean your source code doesn't match the source in the patch.1Khi mã nguồn không khớp, hãy dừng lại
Ward không khuyến khích cố chữa: trong trường hợp mã nguồn không khớp bản vá, bạn có lẽ hết cách. Kể cả nếu bạn nhận ra được một số tệp cần vá, những tệp khác vẫn sẽ không được cập nhật đúng, để lại cho bạn một cây mã nguồn không biên dịch nổi.1
-plàm gì, theo trang hướng dẫnTrang
patch(1)định nghĩa-pnum(hay--strip=num) là: lược bỏ tiền tố ngắn nhất chứa num dấu gạch chéo dẫn đầu khỏi mỗi tên tệp tìm thấy trong tệp vá; một chuỗi nhiều dấu gạch chéo liền nhau được tính là một. Ví dụ trong trang đó: với tên/u/howard/src/blurfl/blurfl.c,-p0giữ nguyên toàn bộ tên,-p1chou/howard/src/blurfl/blurfl.c, còn-p4choblurfl/blurfl.c.17 -
patch -p1
Khi bản vá mang theo số phiên bản gói Khi tên thư mục trong bản vá không khớp When the patch carries a package version in its paths
Đôi khi bạn gặp một bản vá tham chiếu tới phiên bản gói, kiểu
--- package-3.42/src/file.c.origvà+++ package-3.42/src/file.c. Nếu số phiên bản của bạn hơi khác — hoặc bạn chỉ vừa đổi tên thư mục — bạn có thể bảopatchlược bỏ các thành phần đường dẫn dẫn đầu. Đứng ở thư mục chứasrcnhư trước, đểpatchbỏ qua phầnpackage-3.42/, tức lược một thành phần, hãy dùngpatch -p1 < patch_file.1Nếu bản vá viết “package-3.42/src/file.c” mà thư mục của bạn tên khác, bạn bảo nó “bỏ giúp tôi bậc đầu tiên” — đó chính là con số sau chữ
-p. Nhớ nhé: -p là số bậc thư mục cần bỏ.Sometimes you come across a patch that refers to a package version, like
--- package-3.42/src/file.c.origand+++ package-3.42/src/file.c. If you have a slightly different version number — or you just renamed the directory — you can tellpatchto strip leading path components. Standing in the directory containingsrcas before, to makepatchignore thepackage-3.42/part, that is strip one leading component, usepatch -p1 < patch_file.1Bạn gặp nó ở đâuWhere you meet it Bản vá sinh từ một kho Git thường mang tiền tốa/vàb/— tiền tố nguồn và đích mặc định củagit diff— nên-p1là con số bạn dùng thường xuyên nhất trong thực tế.2417 Trong thực tế bạn sẽ dùng-p1nhiều hơn-p0. Patches generated from a Git repository usually carrya/andb/prefixes —git diff’s default source and destination prefixes — which is why-p1is the number you reach for most often in practice.2417patchchọn tên tệp thế nàoTrang hướng dẫn mô tả một quy trình có thứ tự:
patchlập một danh sách tên tệp ứng viên theo thứ tự (cũ, mới,Index:), và một cái tên bị bỏ qua nếu nó không có đủ số dấu gạch chéo để thoả mãn tuỳ chọn-pnum; tên/dev/nullcũng bị bỏ qua.17 Nếu không tên nào từ các quy tắc này cho kết quả, bạn sẽ được hỏi tên tệp cần vá — chính là câuFile to patch:mà Ward cảnh báo.17Một cái bẫy có sẵn trong trang
patch(1)Trang hướng dẫn liệt kê một hành vi đáng nhớ trong mục BUGS: nếu bạn áp một bản vá đã áp rồi,
patchtưởng đó là bản vá ngược và đề nghị gỡ bản vá ra.17 Trang này ghi chú đó là quan sát từ tài liệupatch, không phải từ sách của Ward. -
make error
Lỗi thật, lỗi bị bỏ qua, và lỗi vọng lại Dòng lỗi nào mới đáng đọc Real errors, ignored errors, and echoes
Trước khi bàn chi tiết, Ward yêu cầu bạn phải đọc được vài kiểu kết xuất
make, và quan trọng nhất là biết phân biệt lỗi với lỗi đã bị bỏ qua. Dòngmake: *** [target] Error 1là một lỗi thật mà bạn cần điều tra. Nhưng một sốMakefilenghi ngờ rằng một điều kiện lỗi có thể xảy ra trong khi biết rằng lỗi ấy vô hại: bạn thường có thể bỏ qua thông báo dạngmake: *** [target] Error 1 (ignored).1Máy in ra rất nhiều dòng đỏ, nhưng không phải dòng nào cũng là lỗi thật. Có dòng ghi rõ “(ignored)” — nghĩa là “không sao đâu”. Nhớ nhé: đọc kỹ chữ trong ngoặc trước khi hoảng.
Before the specifics, Ward wants you to be able to read certain kinds of
makeoutput, and above all to know the difference between an error and an ignored error. The linemake: *** [target] Error 1is a real error you need to investigate. But some Makefiles suspect an error condition might occur while knowing it's harmless: you can usually disregard messages likemake: *** [target] Error 1 (ignored).1Bạn gặp nó ở đâuWhere you meet it GNUmakethường tự gọi chính nó nhiều lần trong các gói lớn, mỗi lần được đánh dấu[N]trong thông báo lỗi, vớiNlà một con số; bạn thường tìm ra lỗi nhanh bằng cách nhìn vào lỗimakeđứng ngay sau thông báo lỗi của trình biên dịch.1 Nhìn dòng lỗi đầu tiên, đừng nhìn dòng cuối cùng. GNUmakeoften calls itself many times in large packages, each instance marked[N]in the error message, whereNis a number; you can often find the error quickly by looking at themakeerror that comes directly after the compiler error message.1Đọc một chồng lỗi lồng nhau
Ward trưng ra một chồng điển hình: thông báo lỗi trình biên dịch liên quan tới
file.c, rồimake[3]: *** [file.o] Error 1, rồimake[3]: Leaving directory '/home/src/package-5.0/src', và tiếp tục vọng lên quamake[2],make[1]cho tớimake: *** [all] Error 2.1 Ông chỉ rõ: ba dòng đầu tiên mới cho bạn thông tin cần thiết — rắc rối nằm quanhfile.c, đặt tại/home/src/package-5.0/src.1 Học cách lọc bỏ các lỗimakephía sau giúp ích rất nhiều cho việc đào ra nguyên nhân thật.1Dấu
***nghĩa là gìTài liệu GNU
makegiải thích phần mà Ward mô tả bằng ví dụ: nếu không có***kèm theo thông báo, thì tiến trình con đã thất bại nhưng quy tắc trong makefile được đặt tiền tố bằng ký tự đặc biệt-, nênmakeđã bỏ qua lỗi ấy.18 Đó chính là cơ chế đằng sau hậu tố(ignored). -
missing header
Bốn lỗi cụ thể, và cách lần ra tệp tiêu đề bị thiếu Bốn lỗi hay gặp và cách chữa Four specific errors, and how to track down a missing header
Ward liệt kê bốn lỗi dựng thường gặp. Một:
src.c:22: conflicting types for 'item'kèm/usr/include/file.h:47: previous declaration of 'item'— lập trình viên đã khai báo lạiitemmột cách sai lầm ở dòng 22 củasrc.c; bạn thường sửa được bằng cách gỡ dòng gây lỗi, bằng chú thích,#ifdef, hoặc cách nào khác hiệu quả.1 Hai:src.c:37: 'time_t' undeclared (first use this function)rồisrc.c:37: parse error before '...'— lập trình viên quên một tệp tiêu đề then chốt.1Bốn lỗi quen thuộc: khai báo hai lần, quên khai báo, thiếu tệp tiêu đề, và thiếu công cụ. Cách chữa cũng quen: đọc số dòng, tra sách hướng dẫn, thêm dòng khai báo hoặc cài thêm gói. Nhớ nhé: lỗi bao giờ cũng ghi rõ tệp nào, dòng nào.
Ward lists four common build errors. One:
src.c:22: conflicting types for 'item'with/usr/include/file.h:47: previous declaration of 'item'— the programmer made an erroneous redeclaration ofitemon line 22 ofsrc.c; you can usually fix it by removing the offending line, with a comment, an#ifdef, or whatever works.1 Two:src.c:37: 'time_t' undeclared (first use this function)followed bysrc.c:37: parse error before '...'— the programmer forgot a critical header file.1Bạn gặp nó ở đâuWhere you meet it Ward gọi các trang hướng dẫn là cách tốt nhất để tìm tệp tiêu đề bị thiếu: nhìn dòng gây lỗi, tìm xuôi chỗ dùng biến quanh một lời gọi hàm, rồi tra trang hướng dẫn của hàm đó.1 Tra sách hướng dẫn của hàm đó, phần SYNOPSIS ghi sẵn dòng include cần thêm. Ward calls the manual pages the best way to find a missing header file: look at the offending line, search forward for the variable's use around a function call, then read that function's manual page.1Lần theo
time_t, từng bước mộtWard đi hết ví dụ: dòng 37 của
src.ccó lẽ là một khai báo biến nhưtime_t v1;; tìm xuôiv1trong chương trình sẽ thấy nó dùng quanh một lời gọi hàm, ví dụv1 = time(NULL);. Giờ chạyman 2 timehoặcman 3 timeđể tìm các lời gọi hệ thống và thư viện têntime(); trong trường hợp này trang hướng dẫn mục 2 có thứ bạn cần, với phầnSYNOPSISghi#include <time.h>vàtime_t time(time_t *t);.119 Nghĩa làtime()cầntime.h: đặt#include <time.h>ở đầusrc.crồi thử lại.1Lỗi ba: tệp tiêu đề không tìm thấy
src.c:4: pkg.h: No such file or directorytheo sau là một danh sách lỗi dài nghĩa là trình biên dịch đã chạy bộ tiền xử lý C trênsrc.cnhưng không tìm thấy tệppkg.h. Mã nguồn có lẽ phụ thuộc vào một thư viện bạn cần cài, hoặc bạn chỉ cần cung cấp đường dẫnincludephi tiêu chuẩn — thường là thêm một tuỳ chọn-IvàoCPPFLAGS, và hãy nhớ có thể bạn cũng cần một cờ-Lđi kèm cho trình liên kết.1 Nếu có vẻ không phải do thiếu thư viện, có khả năng nhỏ là bạn đang biên dịch cho một hệ điều hành mà mã nguồn này không hỗ trợ; hãy kiểm traMakefilevà các tệp README về nền tảng.1Tìm gói chứa tệp tiêu đề
Ward đưa hai công cụ cụ thể theo họ bản phân phối: trên hệ dựa trên Debian, thử
apt-file search pkg.h— lệnh này có thể tìm ra gói phát triển bạn cần; với các bản phân phối dùngyum, thửyum provides */pkg.h.120Lỗi bốn: thiếu chính công cụ
Thông báo
make: prog: Command not foundnghĩa là để dựng gói, bạn cầnprogtrên hệ thống. Ward phân hai nhánh: nếuproglà thứ nhưcc,gcchayldthì bạn chưa cài các tiện ích phát triển; còn nếu bạn nghĩprogđã có trên máy, hãy thử sửaMakefileđể chỉ định đường dẫn đầy đủ củaprog.1 Trong vài trường hợp hiếm với mã nguồn cấu hình kém,makedựngprogrồi dùng ngay, giả định rằng thư mục hiện tại (.) nằm trong đường dẫn lệnh của bạn; nếu$PATHcủa bạn không có thư mục hiện tại, bạn có thể sửaMakefileđổiprogthành./prog, hoặc tạm thời nối.vào đường dẫn.1
Đính chính Corrections
Ba ngộ nhận mà người đọc lần đầu hay mắc Ba chỗ hay hiểu nhầm Three misconceptions first readers hit
Phần này thuộc mức đọc Đầy đủ: nó đối chiếu điều người đọc thường nghĩ với điều bản văn thật sự nói.
Phần này hơi khó, bạn có thể bỏ qua và quay lại sau. Nhớ nhé: hiểu chậm mà chắc vẫn hơn.
This block belongs to the Đầy đủ (full) reading level: it sets what readers usually assume against what the text actually says.
“Người dùng Linux giỏi thì cài mọi thứ từ mã nguồn” "A good Linux user installs everything from source"
Ngộ nhận: dùng trình quản lý gói là dấu hiệu của người mới; tự biên dịch mới là cách làm “đúng”.
Bản văn nói: Ward viết rằng bạn có thể cập nhật và bổ sung toàn bộ hệ thống bằng cách cài lại từ mã nguồn, nhưng bạn có lẽ không nên làm thế trừ phi bạn thật sự thích quá trình đó hoặc có lý do khác.1 Ông nhấn mạnh rằng các bản phân phối cung cấp cách dễ dàng để cập nhật phần lõi và thường sửa lỗi bảo mật rất nhanh, còn gói tự cài thì không tự nâng cấp — một mối lo đặc biệt với phần mềm tương tác qua mạng.1
Misconception: using a package manager marks you as a beginner; compiling yourself is the "proper" way.
The text says: Ward writes that you can update and augment your entire system by reinstalling parts from source, but you probably shouldn't, unless you really enjoy the process or have some other reason.1 He stresses that distributions provide easy ways to update core parts and usually fix security problems very quickly, while custom packages do not automatically upgrade themselves — a particular concern for software that interacts with the network.1
“configure chạy xong sạch nghĩa là make sẽ chạy được”
"A clean configure means make will work"
Ngộ nhận: bước cấu hình là cửa kiểm tra đầy đủ; qua được nó thì phần còn lại chỉ là hình thức.
Bản văn nói: Ward viết rõ rằng một bước configure thành công không nhất thiết có nghĩa là bước make sẽ chạy được, dù khả năng là khá cao.1 Và khi lỗi xảy ra ở bước cấu hình, thông báo bề mặt cũng thường không phải nguyên nhân: ví dụ dấu gạch bị thiếu cho ra C compiler cannot create executables, trong khi nguyên nhân thật — gcc: error: Iinclude_dir: No such file or directory — chỉ lộ ra trong config.log.1
Misconception: the configure step is a complete gate; pass it and the rest is a formality.
The text says: Ward writes plainly that a successful configure step doesn't necessarily mean the make step will work, though the chances are pretty good.1 And when configure itself fails, the surface message is often not the cause: a missing dash yields C compiler cannot create executables, while the real cause — gcc: error: Iinclude_dir: No such file or directory — appears only inside config.log.1
“Giải nén một kho lưu trữ thì có gì mà phải kiểm tra” "Extracting an archive is harmless, so why check it"
Ngộ nhận: tar chỉ mở gói, nên cùng lắm là bày bừa vài tệp.
Bản văn nói: hậu quả nhẹ đúng là bừa bộn — một kho lưu trữ không có thư mục chung sẽ để lại một đống lộn xộn lớn trong thư mục hiện tại.1 Nhưng Ward nêu cả trường hợp nặng: nếu bạn thấy tệp mang đường dẫn tuyệt đối như /etc/passwd hay /etc/inetd.conf, hãy gỡ kho lưu trữ khỏi hệ thống, vì nó nhiều khả năng chứa ngựa thành Troy hoặc mã độc khác.1 Đó là lý do tar tvf đứng trước tar xvf.2
Misconception: tar only unpacks things, so the worst case is a few stray files.
The text says: the mild consequence is indeed mess — an archive with no common directory leaves a big mess in your current directory.1 But Ward also names the severe case: if you see files with absolute pathnames such as /etc/passwd or /etc/inetd.conf, remove the archive from your system, because it probably contains a Trojan horse or other malicious code.1 That is why tar tvf comes before tar xvf.2
Tự kiểm tra Self-check
Bạn đã tự dựng được một gói chưa? Thử trả lời xem nào Could you build a package yourself now?
Trả lời bằng lời của bạn, không tra sách. Nếu một câu khiến bạn ngập ngừng, đó chính là mục bạn nên đọc lại.
Thử trả lời miệng thôi, không cần giở lại. Câu nào bí thì quay lại đọc phần đó nhé. Nhớ nhé: chỗ bí chính là chỗ cần học.
Answer in your own words, without looking back. Whichever question makes you hesitate points at the section you should reread.
-
Bốn bước để cài một gói từ mã nguồn C là gì, theo đúng thứ tự?
Gợi ý sâu hơn: bước nào là bước duy nhất phụ thuộc vào đặc tính máy của bạn?
-
Vì sao nên chạy
tar tvftrước khi giải nén, và hai dấu hiệu xấu bạn đang tìm là gì?Gợi ý sâu hơn: dấu hiệu nào chỉ gây bừa bộn, dấu hiệu nào buộc bạn phải xoá kho lưu trữ?
-
configurelàm gì với các tệp.in, và nó để lại những tệp nào sau khi chạy?Gợi ý sâu hơn: tệp nào là nhật ký để tra khi hỏng, và mẹo tìm trong tệp đó là gì?
-
Tiền tố mặc định của một
Makefiledo autoconf sinh ra là gì, và vì sao lại là thư mục đó?Gợi ý sâu hơn:
bindirvàlibdirmặc định được viết theo biến nào? -
Khi nào bạn dùng
CPPFLAGSthay vìCFLAGS, và vì sao?Gợi ý sâu hơn: thêm gì vào
LDFLAGSnếu thư viện ở nơi phi tiêu chuẩn là thư viện dùng chung? -
make cleanvàmake distcleankhác nhau ở điểm nào?Gợi ý sâu hơn: sau
distcleanthì cây mã nguồn trông như thế nào? -
Con số sau
-ptrongpatch -p1có ý nghĩa gì?Gợi ý sâu hơn: câu hỏi
File to patch:thường có nghĩa gì? -
Trong một chồng lỗi
make[3],make[2],make[1], bạn đọc dòng nào trước?Gợi ý sâu hơn: hậu tố
(ignored)nói với bạn điều gì?
Cài phần mềm từ mã nguồn có mấy bước? Kể theo thứ tự.
Vì sao nên ngó vào gói nén trước khi mở nó ra?
Script
configurelàm gì cho bạn?--prefixdùng để làm gì?Muốn thử xem
make installsẽ làm gì mà chưa cài thật thì gõ gì?Bản vá (patch) là gì?
Thấy dòng lỗi có chữ
(ignored)thì bạn có cần lo không?
What are the four steps of installing a package from C source code, in order?
Why run
tar tvfbefore extracting, and what two bad signs are you looking for?What does
configuredo with the.infiles, and which files does it leave behind?What is the default prefix of an autoconf-generated Makefile, and why that directory?
When do you use
CPPFLAGSrather thanCFLAGS, and why?How do
make cleanandmake distcleandiffer?What does the number after
-pinpatch -p1mean?In a stack of
make[3],make[2],make[1]errors, which line do you read first?
Khép lại chương Closing the chapter
Dựng phần mềm thường là bước đệm để học về lập trình và phát triển phần mềm. Các công cụ trong chương này và chương trước gỡ bỏ sự bí ẩn về nơi phần mềm hệ thống của bạn đến từ đâu. Và không khó để đi tiếp những bước sau: nhìn vào bên trong mã nguồn, thực hiện thay đổi, và tạo ra phần mềm của chính bạn.1
Biết tự dựng phần mềm là bước đầu để hiểu phần mềm được làm ra thế nào. Khi bạn đã mở được “hộp”, chẳng còn gì bí ẩn nữa — bước sau chỉ là sửa thử một dòng. Nhớ nhé: mở hộp ra xem, rồi sửa thử một dòng.
Building software is often a stepping stone to learning about programming and software development. The tools in this chapter and the previous one take the mystery out of where your system software came from. And it's not difficult to take the next steps: looking inside the source code, making changes, and creating your own software.1