Tại sao luôn luôn ./configure; làm; thực hiện cài đặt; như 3 bước riêng biệt?


118

Mỗi khi bạn biên dịch nội dung nào đó từ nguồn, bạn thực hiện theo 3 bước giống nhau:

$ ./configure
$ make
$ make install

Tôi hiểu rằng chia quá trình cài đặt thành các bước khác nhau là rất hợp lý, nhưng tôi không hiểu, tại sao mỗi lập trình viên trên hành tinh này phải viết đi viết lại ba lệnh giống nhau chỉ để hoàn thành một công việc duy nhất. Theo quan điểm của tôi, sẽ hoàn toàn có ý nghĩa nếu ./install.shtập lệnh được phân phối tự động với mã nguồn chứa văn bản sau:

#!/bin/sh
./configure
make
make install

Tại sao mọi người lại làm 3 bước riêng biệt?


2
Nếu hệ thống xây dựng được viết đúng - và thường là như vậy - bạn có thể bỏ qua bước thứ hai.
reinierpost

Câu hỏi của bạn không phải là ngu ngốc. Bạn có thể xây dựng chương trình của mình trong môi trường Linux và sau đó bạn có thể sử dụng bằng một số ứng dụng ảo hóa hoặc bạn có thể xây dựng trực tiếp trong môi trường windows bằng mingw.
Mihai8

Câu trả lời:


121

Bởi vì mỗi bước làm những việc khác nhau

Chuẩn bị (thiết lập) môi trường để xây dựng

./configure

Tập lệnh này có rất nhiều tùy chọn mà bạn nên thay đổi. Thích --prefixhoặc --with-dir=/foo. Điều đó có nghĩa là mỗi hệ thống có một cấu hình khác nhau. Đồng thời ./configurekiểm tra các thư viện bị thiếu cần được cài đặt. Bất cứ điều gì sai ở đây đều không tạo ra ứng dụng của bạn . Đó là lý do tại sao các bản phân phối có các gói được cài đặt ở những nơi khác nhau, bởi vì mọi bản phân phối đều cho rằng tốt hơn nên cài đặt một số thư viện và tệp nhất định vào một số thư mục nhất định. Nói là chạy ./configurenhưng thực tế bạn nên thay đổi luôn.

Ví dụ, hãy xem trang web gói Arch Linux . Ở đây, bạn sẽ thấy rằng bất kỳ gói nào đều sử dụng tham số cấu hình khác (giả sử chúng đang sử dụng công cụ tự động cho hệ thống xây dựng).

Xây dựng hệ thống

make

Đây thực sự là make all theo mặc định. Và mỗi thực hiện có các hành động khác nhau để làm. Một số thực hiện xây dựng, một số kiểm tra sau khi xây dựng, một số kiểm tra từ các kho SCM bên ngoài. Thông thường, bạn không phải cung cấp bất kỳ tham số nào, nhưng một số gói thực thi chúng theo cách khác.

Cài đặt vào hệ thống

make install

Điều này cài đặt gói ở nơi được chỉ định với cấu hình. Nếu bạn muốn, bạn có thể chỉ định ./configuređể trỏ đến thư mục chính của bạn. Tuy nhiên, rất nhiều tùy chọn cấu hình đang trỏ đến /usrhoặc /usr/local. Điều đó có nghĩa là sau đó bạn phải sử dụng thực sự sudo make installvì chỉ root mới có thể sao chép tệp vào / usr và / usr / local.


Bây giờ bạn thấy rằng mỗi bước là một yêu cầu trước cho bước tiếp theo. Mỗi bước là một bước chuẩn bị để làm cho mọi thứ hoạt động theo một dòng chảy không có vấn đề. Các phân phối sử dụng phép ẩn dụ này để xây dựng các gói (như RPM, deb, v.v.).

Ở đây bạn sẽ thấy rằng mỗi bước thực sự là một trạng thái khác nhau. Đó là lý do tại sao các trình quản lý gói có các trình bao bọc khác nhau. Dưới đây là ví dụ về trình bao bọc cho phép bạn tạo toàn bộ gói trong một bước. Nhưng hãy nhớ rằng mỗi ứng dụng có một trình bao bọc khác nhau (thực sự những trình bao bọc này có tên như spec, PKGBUILD, v.v.):

def setup:
... #use ./configure if autotools is used

def build:
... #use make if autotools is used

def install:
... #use make all if autotools is used

Ở đây người ta có thể sử dụng công cụ tự động, có nghĩa là ./configure, makemake install. Nhưng một cái khác có thể sử dụng SCons, thiết lập liên quan đến Python hoặc một cái gì đó khác.

Như bạn thấy việc chia nhỏ từng trạng thái giúp mọi thứ dễ dàng hơn nhiều cho việc bảo trì và triển khai, đặc biệt là đối với những người bảo trì gói và phân phối.


23
Đọc lại điều này, khoảng một năm sau, tôi phải nói thêm rằng tất cả đều có lý, và vẫn có thể có một lệnh gọi duy nhất thực hiện tất cả 3 bước với cấu hình mặc định của chúng. Tất cả chúng đều có cấu hình mặc định, nếu không bạn không thể gọi chúng mà không có đối số.
erikbwork

Đôi khi tôi có thể thực hiện cài đặt mà không cần thực hiện. Điều đó có nghĩa là gì? Nếu tôi bỏ qua thực hiện, tôi có thể thực hiện cài đặt không?
CMCDragonkai

3
installphụ thuộc vào alldo đó make installsẽ gọimake all

câu trả lời xuất sắc, tuy nhiên tôi không hiểu lý do tại sao đôi khi một make install được yêu cầu và thời điểm khác không có (một làm đơn, làm tất cả những sự kỳ diệu)
HanniBaL90

make installchỉ cần cài đặt tài nguyên khác nhau vào vị trí được xác định trước. Nếu bạn chỉ quan tâm đến tệp thực thi, bạn có thể sử dụng tệp thực thi từ thư mục xây dựng và thêm trình xây dựng vào PATH của bạn.
jdhao

31

Đầu tiên, nó phải là ./configure && make && make installvì mỗi thứ phụ thuộc vào sự thành công của cái trước. Một phần lý do là sự tiến hóa và một phần lý do là sự thuận tiện cho quy trình phát triển.

Ban đầu, hầu hết Makefilecác s sẽ chỉ chứa các lệnh để biên dịch một chương trình và việc cài đặt sẽ được giao cho người dùng. Một quy tắc bổ sung cho phépmake install đặt đầu ra đã biên dịch ở một nơi có thể đúng; vẫn còn rất nhiều lý do chính đáng mà bạn có thể không muốn làm điều này, bao gồm cả việc không phải là quản trị viên hệ thống, không muốn cài đặt nó. Hơn nữa, nếu tôi đang phát triển phần mềm, có lẽ tôi không muốn cài đặt nó. Tôi muốn thực hiện một số thay đổi và kiểm tra phiên bản có trong thư mục của tôi. Điều này thậm chí còn trở nên nổi bật hơn nếu tôi sẽ có nhiều phiên bản nằm xung quanh.

./configuređi và phát hiện những gì có sẵn trong môi trường và / hoặc được người dùng mong muốn để xác định cách xây dựng phần mềm. Đây không phải là thứ cần thay đổi thường xuyên và có thể mất một khoảng thời gian. Một lần nữa, nếu tôi là một nhà phát triển, không đáng để bạn phải cấu hình lại liên tục. Quan trọng hơn, vì makesử dụng dấu thời gian để xây dựng lại mô-đun, nếu tôi chạy lại configurethì có khả năng cờ sẽ thay đổi và bây giờ một số thành phần trong bản dựng của tôi sẽ được biên dịch với một bộ cờ và những thành phần khác với một bộ cờ khác có thể dẫn đến hành vi khác nhau, không tương thích. Miễn là tôi không chạy lại configure, tôi biết rằng môi trường biên dịch của tôi vẫn như cũ ngay cả khi tôi thay đổi nguồn của mình. Nếu tôi chạy lại trước, hãy xóa mọi nguồn đã xây dựng để đảm bảo mọi thứ được xây dựng đồng nhất.configure , tôi nênmake clean

Trường hợp duy nhất mà ba lệnh được chạy liên tiếp là khi người dùng cài đặt chương trình hoặc một gói được xây dựng (ví dụ: bản gỡ lỗi Debian hoặc rpmbuild của RedHat). Và điều đó giả định rằng gói có thể được cung cấp một cách đơn giản configure, điều này không thường xảy ra đối với trường hợp đóng gói, ít nhất, --prefix=/usrlà mong muốn. Và pacakgers giống như phải đối phó với những gốc giả khi thực hiện make installmột phần. Vì có rất nhiều trường hợp ngoại lệ, nên việc đưa ra ./configure && make && make installquy tắc sẽ gây bất tiện cho rất nhiều người thường xuyên thực hiện nó!


2
Cảm ơn cho lời khuyên với &&!
erikbwork

4

Thứ nhất ./configure không phải lúc nào cũng tìm thấy mọi thứ mà nó cần, hoặc trong những trường hợp khác, nó tìm thấy mọi thứ nó yêu cầu nhưng không phải mọi thứ nó có thể sử dụng. Trong trường hợp đó, bạn sẽ muốn biết về nó (và tập lệnh ./install.sh của bạn dù sao cũng sẽ không thành công!) Ví dụ cổ điển về không thất bại với hậu quả không mong muốn, theo quan điểm của tôi, là biên dịch các ứng dụng lớn như ffmpeg hoặc mplayer. Các thư viện này sẽ sử dụng các thư viện nếu chúng có sẵn nhưng sẽ vẫn biên dịch nếu không có, khiến một số tùy chọn bị vô hiệu hóa. Vấn đề là sau đó bạn phát hiện ra rằng nó đã được biên dịch mà không được hỗ trợ cho một số định dạng này hay một định dạng khác, do đó yêu cầu bạn quay lại và làm lại nó.

Một điều khác ./configure có phần tương tác là cung cấp cho bạn tùy chọn để tùy chỉnh vị trí ứng dụng sẽ được cài đặt trên hệ thống. Các bản phân phối / môi trường khác nhau có các quy ước khác nhau, và bạn có thể muốn tuân theo quy ước trên hệ thống của mình. Ngoài ra, bạn có thể muốn cài đặt nó cục bộ (chỉ cho chính bạn). Theo truyền thống, các bước ./configure và make không được chạy dưới dạng root, trong khi thực hiện cài đặt (trừ khi nó được cài đặt riêng cho chính bạn) phải được chạy dưới dạng root.

Các bản phân phối cụ thể thường cung cấp các tập lệnh thực hiện chức năng ./install.sh này theo cách phân phối nhạy cảm - ví dụ: RPM nguồn + tệp đặc tả + rpmbuild hoặc slackbuilds .

(Chú thích: điều đó đang được nói, tôi đồng ý rằng ./configure; make; make install; có thể trở nên cực kỳ tẻ nhạt.)


Tất cả đều dễ hiểu, nhưng trong mắt tôi không có khả năng nào trong số này bị phá hủy nếu bạn có một tệp bổ sung kết hợp ba bước. Ví dụ: nếu bạn muốn đọc một số cấu hình stdout, bạn vẫn có thể grep cho nó hoặc đặt toàn bộ stdout vào một tệp và đọc nó sau đó.
erikbwork

3
Đúng, nhưng sau đó, tại sao một tệp được yêu cầu? Chỉ cần sử dụng một bí danh (mặc dù bạn sẽ phải nghĩ ra một cái tên hay hơn / ngắn hơn so với 'confmakeins', hôm nay tôi vẫn chưa hết mệt mỏi!). alias confmakeins = '. / configure && make && sudo make install'; thư mục nguồn cd; bánh kẹo;
Soz

Nghe hay đấy. Tôi chưa bao giờ tự viết bí danh, vì vậy tôi không nghĩ về nó!
erikbwork

3

configure có thể thất bại nếu nó phát hiện ra rằng các phụ thuộc bị thiếu.

makechạy một mục tiêu mặc định, mục tiêu đầu tiên được liệt kê trong Makefile. Mục tiêu này thường là all, nhưng không phải luôn luôn. Vì vậy, bạn chỉ có thể make all installnếu bạn biết đó là mục tiêu.

Vì thế ...

#!/bin/sh

if ./configure $*; then
  if make; then
    make install
  fi
fi

hoặc là:

./configure $* && ./make && ./make install

$*được bao gồm bởi vì người ta thường phải cung cấp các tùy chọn configure.

Nhưng tại sao không để mọi người tự làm? Đây có thực sự là một chiến thắng lớn như vậy không?


1
Nó không quan trọng chết người, mà là về những gì chúng ta lập trình viên làm: yêu cầu máy tính thực hiện các tác vụ lặp đi lặp lại cho chúng ta. Đúng?
erikbwork

1
Tốt ... configure là một phần của bộ công cụ GNU Automake, là một tiện ích bổ sung cho Make. Make đã tồn tại trong nhiều năm và làm rất tốt công việc của mình. Điều đó nói rằng, mọi người đã nghĩ ra những cách khác để xử lý quá trình thực hiện. Ant và cmake có những người theo dõi họ. Nhưng các phần của quá trình xây dựng (như cấu hình, xây dựng và cài đặt) vẫn là tất cả các lệnh riêng biệt.
rồng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.