CMake tương đương với 'configure --prefix = DIR && thực hiện tất cả cài đặt' là gì?


386

Tôi làm cmake . && make all install. Điều này hoạt động, nhưng cài đặt để /usr/local.

Tôi cần cài đặt một tiền tố khác (ví dụ, để /usr).

Là gì cmakemakedòng lệnh để cài đặt vào /usrthay vì /usr/local?


1
Đây là một câu hỏi tuyệt vời để thay đổi thư mục cài đặt một cách nhanh chóng, nhưng tại sao đây lại là một nhu cầu phổ biến như vậy? Từ quan điểm của tôi, câu trả lời là KHÔNG nên sử dụng tùy chọn dòng lệnh, thay vào đó hãy chỉnh sửa cơ sở CMakeLists.txtđể bạn có thể đặt và quên nó. Tôi không nói rằng không có trường hợp sử dụng phổ biến nào để thay đổi thư mục cài đặt một cách nhanh chóng - rõ ràng có sự đánh giá qua số phiếu bầu - Tôi chỉ khá mới đối với CMake và tò mò khi vấn đề này xuất hiện.
CivilFan

8
@CivFan là để phục vụ cho những người dùng muốn xây dựng và cài đặt dự án đến một vị trí cụ thể, nhưng không phải là những người giống như các nhà phát triển / người bảo trì dự án.
David Röthlisberger

4
@CivFan Vì vậy, với tư cách là người bảo trì, không có gì lạ khi tôi kiểm tra make installđường dẫn tạm thời của mình để đảm bảo mọi thứ cần được cài đặt, đã được cài đặt vào đúng vị trí mà không làm hỏng máy phát triển của tôi. Chỉ là một ví dụ. Một trường hợp khác là biên dịch chéo cho kiến ​​trúc khác.
Daniel

5
@CivFan: Tôi cần điều này vì tôi muốn xây dựng gói RPM. Nếu tôi cần thay đổi CMakeLists.txt, thì tôi cần vá nguồn gốc. Chỉ cần có một tùy chọn dòng lệnh cho phép tôi có được các đường dẫn ngay trong spectệp Fedora .
Martin Uting

1
@CivFan (và những người khác đọc điều này) FYI, thường được coi là một ý tưởng tồi để chỉnh sửa CMakeLists.txttệp nếu bạn chỉ xây dựng và cài đặt phần mềm - ghi đè / cài đặt biến từ dòng lệnh hoặc tệp bộ đệm ban đầu, v.v. là "người tiêu dùng" ưa thích cách thiết lập tùy chọn.
Ryan Pavlik

Câu trả lời:


444

Bạn có thể chuyển vào bất kỳ biến CMake nào trên dòng lệnh hoặc chỉnh sửa các biến được lưu trong bộ nhớ cache bằng ccmake / cmake-gui. Trên dòng lệnh,

cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr. && thực hiện tất cả cài đặt

Sẽ cấu hình dự án, xây dựng tất cả các mục tiêu và cài đặt vào tiền tố / usr. Loại (PATH) không thực sự cần thiết, nhưng sẽ khiến cmake-gui dựa trên Qt trình bày hộp thoại chọn thư mục.

Một số bổ sung nhỏ như ý kiến ​​cho thấy rõ rằng việc cung cấp một sự tương đương đơn giản là không đủ cho một số. Thực hành tốt nhất sẽ là sử dụng một thư mục xây dựng bên ngoài, tức là không phải là nguồn trực tiếp. Ngoài ra để sử dụng cú pháp CMake chung chung trừu tượng hóa trình tạo.

mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr .. && cmake --build. --target cài đặt --config Phát hành

Bạn có thể thấy nó dài hơn một chút và không còn tương đương trực tiếp nữa, nhưng gần với các thực tiễn tốt nhất ở dạng khá ngắn gọn ... --config chỉ được sử dụng bởi các trình tạo đa cấu hình (ví dụ MSVC), bị bỏ qua bởi những người khác.


21
Tự hỏi: PATH là gì? Nó hữu ích cho cmake-gui, giúp chọn widget cho biến đó. Xem tài liệu trong linux.die.net/man/1/cmake-gui (phần thiết lập)
albfan

2
Họ cung cấp gợi ý cho GUI CMake như đã nêu, mọi thứ trong CMake thực sự là một chuỗi, nhưng việc thiết lập PATH, FILEPATH, STRING, BOOL, vv giúp GUI trình bày một widget phù hợp hơn.
Marcus D. Hanwell

13
Bạn cũng có thể sử dụng: "cài đặt cmake --build --target." thay vì thực hiện.
RobertJMaynard

2
Dấu chấm cho sau / usr là gì? /usr .
Bodacydo

5
@bodacydo vị trí của thư mục với CMakeLists.txt chúng tôi đang tạo từ đó.
Kamiccolo


29

Lưu ý rằng trong cả CMake và Autotools, bạn không phải luôn đặt đường dẫn cài đặt vào thời gian định cấu hình. Bạn có thể sử dụng DESTDIR khi cài đặt (xem thêm tại đây ) thay vì như sau:

make DESTDIR=<installhere> install

Xem thêm câu hỏi này giải thích sự khác biệt tinh tế giữa DESTDIR và PREFIX.

Điều này được dành cho cài đặt theo giai đoạn và để cho phép lưu trữ các chương trình ở một vị trí khác với nơi chúng được chạy, ví dụ như /etc/alternativesthông qua các liên kết tượng trưng.

Tuy nhiên, nếu gói của bạn có thể định vị lại và không cần bất kỳ đường dẫn mã hóa (tiền tố) cứng nào được đặt qua giai đoạn cấu hình, bạn thể bỏ qua nó. Vì vậy, thay vì:

cmake -DCMAKE_INSTALL_PREFIX=/usr . && make all install

bạn sẽ chạy:

cmake . && make DESTDIR=/usr all install

Lưu ý rằng, như user7498341 chỉ ra, điều này không phù hợp với những trường hợp bạn thực sự nên sử dụng PREFIX.


9
Tôi thích hiển thị việc sử dụng DESTDIR. Nhưng thực sự điều này là sai. Bạn nên tham khảo tài liệu cmake cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john installsẽ cài đặt phần mềm có liên quan bằng cách sử dụng tiền tố cài đặt, ví dụ: / / usr / cục bộ được cài đặt sẵn với giá trị DESTDIR mà cuối cùng mang lại cho / / nhà / john / usr / địa phương.
Joakim

1
Tôi không nghĩ đó là mâu thuẫn. Nếu gói của bạn có thể định vị lại, bạn không cần CMAKE_INSTALL_PREFIX, hoặc đúng hơn là bạn có thể chọn một trong hai phương thức. Nếu đó không phải là bạn làm vì CMAKE_INSTALL_PREFIX sẽ được đưa vào một nơi nào đó vào thời gian xây dựng.
Bruce Adams

nếu bạn biết rằng trình tạo của bạn là Makefile ... Tôi thích cmake --build build --target install -- DESTDIR=/usrlưu ý hơn: điều này cũng sẽ hoạt động với trình tạo Ninja (quy tắc dường như có $ENV{DESTDIR})
Mizux

@Joakim nhiều như tôi muốn sử dụng CMAKE_INSTALL_PREFIX, làm như vậy đã nhúng đường dẫn cài đặt trong các tệp được biên dịch. Khi điều đó xảy ra, tôi chỉ đơn thuần là xây dựng gói .rpm, vì vậy điều đó sẽ không xảy ra. DESTDIR làm việc như một cơ duyên để đưa mọi thứ vào buildroot.
Ông Redstoner

18

Cách tôi xây dựng các dự án CMake đa nền tảng như sau:

/project-root> mkdir build
/project-root> cd build
/project-root/build> cmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
/project-root/build> cmake --build . --target=install --config=Release
  • Hai dòng đầu tiên tạo thư mục xây dựng ngoài nguồn
  • Dòng thứ ba tạo ra hệ thống xây dựng chỉ định nơi đặt kết quả cài đặt (mà tôi luôn đặt vào ./project-root/build/stage- đường dẫn luôn được coi là tương đối với thư mục hiện tại nếu nó không tuyệt đối)
  • Dòng thứ tư xây dựng dự án được cấu hình .với hệ thống xây dựng được cấu hình trong dòng trước đó. Nó sẽ thực thi installmục tiêu cũng xây dựng tất cả các mục tiêu phụ thuộc cần thiết nếu chúng cần được xây dựng và sau đó sao chép các tệp vào CMAKE_INSTALL_PREFIX(trong trường hợp này là ./project-root/build/stage. Đối với các bản dựng đa cấu hình, như trong Visual Studio, bạn cũng có thể chỉ định cấu hình với --config <config>cờ tùy chọn .
  • Phần tốt khi sử dụng cmake --buildlệnh là nó hoạt động cho tất cả các trình tạo (ví dụ makefiles và Visual Studio) mà không cần các lệnh khác nhau.

Sau đó, tôi sử dụng các tệp đã cài đặt để tạo các gói hoặc đưa chúng vào các dự án khác ...


Cảm ơn đã giải thích từng bước! IMO đây là cách duy nhất, nếu không thì toàn bộ điểm của cmake (độc lập nền tảng) bị loại bỏ ...
helmesjo

1
bạn có quên bao gồm đường dẫn đến các nguồn (../) trong dòng 3 không? BTW này nên là câu trả lời được chấp nhận.
Slava

1
LIne 3 nên làcmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codenamezero

1
Như một ghi chú bổ sung, thực tế, mọi người sử dụng make -j $(nproc), để chỉ định số lượng chủ đề xây dựng, làm cmake --build . --target=install --config=Release -- -j 8cho trình tạo Makefile hoặc cmake --build . --target=install --config=Release -- /m:8cho trình tạo Visual Studio với 8 luồng. Trên thực tế, bạn có thể vượt qua bất kỳ tham số dòng lệnh nào sau--
Cloud

1
@MrRedstoner -jkhông phải là cờ cho cmake, tất cả các cờ đến sau --được chuyển đến hệ thống xây dựng cơ bản ...
Cloud

4

Về câu trả lời của Bruce Adams:

Câu trả lời của bạn tạo ra sự nhầm lẫn nguy hiểm. DESTDIR được thiết kế để cài đặt ra khỏi cây gốc. Nó cho phép người ta thấy những gì sẽ được cài đặt trong cây gốc nếu người ta không chỉ định DESTDIR. PREFIX là thư mục cơ sở mà cài đặt thực sự dựa trên.

Ví dụ: PREFIX = / usr / local chỉ ra rằng đích cuối cùng của gói là / usr / local. Sử dụng DESTDIR = $ HOME sẽ cài đặt các tệp như thể $ HOME là gốc (/). Nếu, giả sử DESTDIR, là / tmp / Destdir, người ta có thể thấy những gì 'thực hiện cài đặt' sẽ ảnh hưởng. Theo tinh thần đó, DESTDIR không bao giờ nên ảnh hưởng đến các đối tượng được xây dựng.

Một phân đoạn makefile để giải thích nó:

install:
    cp program $DESTDIR$PREFIX/bin/program

Các chương trình phải cho rằng PREFIX là thư mục cơ sở của thư mục cuối cùng (nghĩa là sản xuất). Khả năng liên kết chương trình được cài đặt trong DESTDIR = / một cái gì đó chỉ có nghĩa là chương trình không truy cập các tệp dựa trên PREFIX vì đơn giản là nó không hoạt động. cat (1) là một chương trình (ở dạng đơn giản nhất) có thể chạy từ bất cứ đâu. Đây là một ví dụ sẽ không:

prog.pseudo.in:
    open("@prefix@/share/prog.db")
    ...

prog:
    sed -e "s/@prefix@/$PREFIX/" prog.pseudo.in > prog.pseudo
    compile prog.pseudo

install:
    cp prog $DESTDIR$PREFIX/bin/prog
    cp prog.db $DESTDIR$PREFIX/share/prog.db

Nếu bạn đã cố chạy prog từ nơi khác ngoài $ PREFIX / bin / prog, prog.db sẽ không bao giờ được tìm thấy vì nó không nằm trong vị trí dự kiến ​​của nó.

Cuối cùng, / etc / thay thế thực sự không hoạt động theo cách này. Có các liên kết đến các chương trình được cài đặt trong cây gốc (ví dụ vi -> / usr / bin / nvi, vi -> / usr / bin / vim, v.v.).


1
Câu trả lời này có thể được đặt tốt hơn như là một câu trả lời cho stackoverflow.com/questions/11307465/destdir-and-prefix-of-make
Bruce Adams

2

Nó được coi là thực hành xấu để gọi trình tạo thực tế (ví dụ thông qua make) nếu sử dụng CMake . Rất khuyến khích làm điều đó như thế này:

  1. Cấu hình giai đoạn:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. Xây dựng cài đặt các giai đoạn

    cmake --build _builds/foo/debug --config Debug --target install
    

Khi làm theo cách tiếp cận này, trình tạo có thể dễ dàng chuyển đổi (ví dụ -GNinjacho Ninja ) mà không cần phải nhớ bất kỳ lệnh cụ thể nào của trình tạo.


1
Câu trả lời có thể tốt hơn nếu giải thích được cung cấp cho tất cả các đối số được sử dụng và lý do chúng được sử dụng. Đặc biệt, quan điểm của --configlập luận là gì?
Dmitry Kabanov

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.