Tại sao makefiles nên có một mục tiêu cài đặt trên YouTube?


18

Đến từ thế giới của C và C ++, hầu hết các hệ thống xây dựng đều có một installmục tiêu, đáng chú ý là Makefiles ( ví dụ như GNU được đề xuất ) hoặc CMake . Mục tiêu này sao chép các tệp thời gian chạy (tệp thực thi, thư viện, ...) trong hệ điều hành (ví dụ: trong C:\Program Files\Windows).

Điều này cảm thấy thực sự khó khăn, vì đối với tôi , trách nhiệm của hệ thống xây dựng là không cài đặt chương trình (đây thực sự là trách nhiệm của hệ điều hành / quản lý gói). Nó cũng có nghĩa là hệ thống xây dựng hoặc tập lệnh xây dựng phải biết tổ chức các chương trình đã cài đặt, với các biến môi trường, biến đăng ký, liên kết tượng trưng, ​​quyền, v.v.

Tốt nhất, các hệ thống xây dựng nên có một releasemục tiêu sẽ tạo ra một chương trình có thể cài đặt (ví dụ .debhoặc .msi), sau đó vui lòng yêu cầu hệ điều hành cài đặt chương trình đó. Nó cũng sẽ cho phép người dùng gỡ cài đặt mà không cần phải gõ make uninstall.

Vì vậy, câu hỏi của tôi: tại sao hệ thống xây dựng thường khuyên bạn nên có một installmục tiêu?


7
Lập luận của bạn rằng "thực hiện cài đặt" không thuộc trách nhiệm của một hệ thống xây dựng, nhưng trách nhiệm cụ thể hơn nhiều về nền tảng và liên quan đến việc tạo ra một gói có thể cài đặt được.
pmf

2
Dù sao: đôi khi bạn muốn cài đặt một ứng dụng không được xử lý bởi trình quản lý gói / hệ điều hành (vì nó có các phụ thuộc sẽ gây ra xung đột không thể giải quyết bằng trình quản lý gói, v.v.). make installthường cài đặt bên dưới /usr/local(hoặc thậm chí /opt) là các thư mục không được xử lý bởi "hệ thống quản lý gói / hệ điều hành lõi". Không biết liệu Windows có một số quy ước tương tự mặc dù.
Bakuriu

11
"Điều này cảm thấy thực sự hack." Chà, bạn đã mong đợi gì từ thế giới của C / C ++? ;-)
Mason Wheeler

1
Lưu ý rằng make installkhông có ý nghĩa gì khi chúng ta nói về biên dịch chéo
Hagen von Eitzen

1
@HagenvonEitzen nó làm với DESTDIR.
Nax 'vi-vim-nvim'

Câu trả lời:


23

Nhiều tập lệnh xây dựng hoặc Makefiles có mục tiêu cài đặt vì chúng được tạo trước khi trình quản lý gói tồn tại và bởi vì ngay cả ngày nay rất nhiều hệ thống không có trình quản lý gói. Thêm vào đó, có những hệ thống make installthực sự cách quản lý gói ưu tiên.


Tôi tò mò về các hệ thống make installđược ưa thích. Ngoài ra, tôi có nghĩa là người quản lý chương trình khi tôi nói rằng makefiles nên tạo các gói có thể cài đặt. Tôi nghĩ rằng hầu hết tất cả các hệ điều hành đều đi kèm với cách quản lý các chương trình đã cài đặt? Ví dụ: Windows không có trình quản lý gói (ngoài cửa hàng) nhưng vẫn có cách quản lý các chương trình đã cài đặt (thông qua .msicác gói chẳng hạn)
Synxis

2
@Synxis BSD, Linux, Unix đều sử dụng tệp tạo tệp. Tôi không biết có nên sử dụng chúng để cài đặt hay không, nhưng tôi thường không có khả năng đó make install.
Cướp

1
Trong debian ít nhất nó được ưu tiên sử dụng checkinstallhơn make installvì hai lý do: "Bạn có thể dễ dàng gỡ bỏ gói bằng một bước." và "Bạn có thể cài đặt gói kết quả trên nhiều máy." - khi checkinstall xây dựng một .deb và cài đặt nó, nó sử dụng trình quản lý gói ...
Aaron Hall

1
@Synxis - Có một số bản phân phối linux (thường được gọi là distro nguồn) trong đó trình quản lý gói cài đặt chương trình bằng cách tải xuống tệp tar, giải nén nó sau đó chạymake install
slebetman

1
@AaronHall Sửa lỗi cho tôi nếu tôi sai, nhưng tôi có ấn tượng rằng một checkinstalllời mời thực sự sẽ sử dụng make install và giám sát các hành động của nó để xây dựng gói.
cmaster - phục hồi monica

5

A makefilecó thể không có installmục tiêu và quan trọng hơn, bạn có thể có các chương trình thậm chí không thể cài đặt được (ví dụ: vì chúng nên chạy từ thư mục bản dựng của chúng hoặc vì chúng có thể chạy được cài đặt ở bất cứ đâu). Các installmục tiêu chỉ là một ước cho thường makefile-s.

Tuy nhiên, nhiều chương trình yêu cầu tài nguyên bên ngoài được chạy (ví dụ: phông chữ, cơ sở dữ liệu, tệp cấu hình, v.v.). Và thực thi của họ thường đưa ra một số giả thuyết về các tài nguyên này. Ví dụ, trình bashbao của bạn thường đọc một số tệp khởi tạo từ /etc/bash.bashrcvv .... Các tài nguyên này thường nằm trong hệ thống tệp (xem hier (7) để biết các quy ước về phân cấp tệp) và đường dẫn tệp mặc định được xây dựng trong tệp thực thi của bạn.

Cố gắng sử dụng chuỗi (1) trên hầu hết các tệp thực thi của hệ thống của bạn. Bạn sẽ tìm ra đường dẫn tập tin được biết đến với nó.

BTW, đối với nhiều chương trình GNU sử dụng autoconf, bạn có thể chạy make install DESTDIR=/tmp/destdir/mà không cần root. Sau đó /tmp/destdir/được lấp đầy với các tập tin nên được đóng gói sau này.

FWIW, tôi có xu hướng tin rằng chương trình bismon (được cấp phép GPLv3 +) (được mô tả trong báo cáo bismon-chariot-doc.pdf của tôi ) không thể được "cài đặt"; Tôi không chắc có thể chứng minh điều đó và tôi không thể tưởng tượng làm thế nào tôi có thể cài đặt chương trình đó.


2
DESTDIR hoặc các tiền tố khác thường bị lãng quên. Ngay khi các tài nguyên bên ngoài như thư viện động có liên quan, không thể xây dựng phần mềm mà không biết nơi nào sẽ được cài đặt . Cũng tuyệt vời để cài đặt đến các vị trí không chuẩn, ví dụ /opthoặc vào $HOME. Cách duy nhất để tránh các tiền tố khác nhau là sử dụng các thùng chứa, nhưng đó tất nhiên là một giải pháp dành riêng cho Linux.
amon

2
Tôi đã thấy nhiều hơn một gói mà nếu bạn đã thử DESTDIR = / tmp / Destdir sẽ không hoạt động sau khi được cài đặt ở nơi bình thường vì DESTDIR đã được sử dụng trong việc tạo đường dẫn.
Joshua

@amon: Tôi không chắc chắn tôi sẽ mô tả các container là đặc thù của Linux. Linux có thể là một nền tảng mục tiêu chung cho việc container hóa, nhưng một số dạng công nghệ container tồn tại trong hầu hết các hệ điều hành hiện đại.
Kevin

1
@Joshua Không nên, DESTDIR chỉ nên có liên quan trong bước cài đặt. Bạn sẽ có thể làm: ./configure --prefix="/opt/foo" && make && DESTDIR=/tmp/foo make install và có thể di chuyển gói đến /opt/foomà không có vấn đề gì.
Nax 'vi-vim-nvim'

3

Có một số lý do mà đến với tâm trí.

  • Nhiều phần mềm tạo gói - chẳng hạn như hệ thống xây dựng Debian , và vòng quay IIRC - đã mong đợi từ tập lệnh xây dựng để "cài đặt" chương trình vào một thư mục con đặc biệt. Vì vậy, nó được thúc đẩy bởi khả năng tương thích ngược theo cả hai hướng.
  • Người dùng có thể muốn cài đặt phần mềm vào không gian cục bộ, như trong $HOMEthư mục. Không phải tất cả các nhà quản lý gói hỗ trợ nó.
  • Vẫn có thể có những môi trường không có gói.

Tôi đã đặt lại câu hỏi một chút, ý tôi là người quản lý chương trình khi tôi nói rằng makefiles nên tạo các gói có thể cài đặt.
Synxis

1

Một lý do không được đề cập là có rất nhiều lần bạn không sử dụng phiên bản phần mềm hiện tại hoặc sử dụng phiên bản sửa đổi của phần mềm. Cố gắng tạo một gói tùy chỉnh không chỉ có nhiều công việc hơn mà còn có thể xung đột với các gói hiện được tạo và phân phối. Trong mã nguồn mở, điều này xảy ra rất nhiều đặc biệt là nếu các thay đổi vi phạm được giới thiệu trong các phiên bản tương lai bạn đang sử dụng.

Giả sử bạn đang sử dụng dự án nguồn mở FOO hiện đang có trên phiên bản 2.0.1 và bạn đang sử dụng phiên bản 1.3.0. Bạn không muốn sử dụng bất cứ điều gì ở trên vì phiên bản 2.0.0 không tương thích với những gì bạn đang làm, nhưng có một sửa lỗi duy nhất trong 2.0.1 mà bạn rất cần. Có make installtùy chọn cho phép bạn cài đặt phần mềm 1.3.0 đã sửa đổi mà không phải lo lắng về việc tạo gói và cài đặt nó trên hệ thống của bạn.


1

Các bản phân phối Linux thường tách biệt bảo trì chương trình khỏi bảo trì gói. Một hệ thống xây dựng tích hợp tạo gói sẽ buộc các nhà bảo trì chương trình cũng thực hiện bảo trì gói.

Đây thường là một ý tưởng tồi. Các bản phân phối có rất nhiều cơ sở hạ tầng để xác minh tính nhất quán nội bộ, cung cấp nhị phân cho nhiều nền tảng đích, thực hiện các thay đổi nhỏ để tích hợp tốt hơn với phần còn lại của hệ thống và cung cấp trải nghiệm nhất quán cho người dùng báo cáo lỗi.

Để tạo các gói trực tiếp từ hệ thống xây dựng, bạn sẽ phải tích hợp hoặc bỏ qua tất cả các cơ sở hạ tầng này. Tích hợp nó sẽ là rất nhiều công việc cho lợi ích đáng ngờ, và bỏ qua nó sẽ mang lại trải nghiệm người dùng tồi tệ hơn.

Đây là một trong những vấn đề "hàng đầu của chuỗi thức ăn" điển hình trong các hệ thống đa đảng. Nếu bạn có nhiều hệ thống phức tạp, cần có một hệ thống phân cấp rõ ràng trong đó hệ thống nào chịu trách nhiệm điều phối tất cả các hệ thống khác.

Trong trường hợp quản lý cài đặt phần mềm, trình quản lý gói là thành phần này và nó sẽ chạy hệ thống xây dựng của gói, sau đó đưa đầu ra qua giao diện thuận tiện ("tệp trong thư mục sau bước cài đặt"), tạo gói và chuẩn bị gói nó để tải lên một kho lưu trữ.

Trình quản lý gói đứng ở giữa hệ thống xây dựng và kho lưu trữ ở đây và ở vị trí tốt nhất để tích hợp tốt với cả hai.

Bạn có thể nhận thấy rằng chỉ có một vài trong số các gói JavaScript có sẵn thông npmqua apt- điều này chủ yếu là do người JavaScript đã quyết định điều đó npmvà kho lưu trữ liên quan sẽ là đầu của chuỗi thức ăn của họ, khiến nó gần như không thể gửi các gói này dưới dạng các gói Debian.

Với mũ Nhà phát triển Debian của tôi trên: nếu bạn phát hành phần mềm nguồn mở, vui lòng để lại bao bì cho các nhà bảo trì phân phối. Nó tiết kiệm cho cả bạn và chúng tôi rất nhiều công việc.


Bạn đã không nói gì về lý do tại sao có một mục tiêu cài đặt, và dường như với tôi rằng hầu hết những gì bạn đã viết cũng sẽ áp dụng cho nó ...
tò mò

1
@cquildannii, cần có một số giao diện giữa hệ thống xây dựng và trình quản lý gói, và điều này xảy ra là đơn giản nhất, vì vậy nó đã thắng.
Simon Richter

1

Vâng, các nhà phát triển ứng dụng là những người biết nơi mỗi tệp nên đi. Họ có thể để nó trong tài liệu, và để các nhà bảo trì gói đọc nó và xây dựng một kịch bản cho mỗi gói. Có thể các nhà bảo trì gói sẽ giải thích sai tài liệu và sẽ phải gỡ lỗi tập lệnh cho đến khi nó hoạt động. Điều này là không hiệu quả. Nhà phát triển ứng dụng nên viết một kịch bản để cài đặt đúng ứng dụng mà anh ta đã viết.

Anh ta có thể viết một tập lệnh cài đặt với một tên tùy ý hoặc có thể làm cho nó trở thành một phần của quy trình của một số tập lệnh khác. Tuy nhiên, có một lệnh cài đặt tiêu chuẩn, make install(một quy ước có trước các trình quản lý gói), việc thực hiện các gói trở nên thực sự dễ dàng. Nếu bạn nhìn vào mẫu PKGBUILD để tạo các gói Archlinux , bạn có thể thấy rằng chức năng mà các gói thực sự chỉ đơn giản là làm một make DESTDIR="$pkgdir/" install. Điều này có thể hoạt động cho phần lớn các gói và có thể nhiều hơn với một chút sửa đổi. Nhờ make(và các autotools) là tiêu chuẩn, bao bì thực sự, thực sự dễ dà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.