CMake ที่เทียบเท่ากับ 'configure --prefix = DIR && ทำการติดตั้งทั้งหมด' คืออะไร


386

cmake . && make all installที่ฉันทำ งานนี้ /usr/localแต่การติดตั้งไป

ฉันต้องติดตั้งกับคำนำหน้าอื่น (ตัวอย่างเช่นถึง/usr)

คืออะไรcmakeและmakeบรรทัดคำสั่งเพื่อติดตั้ง/usrแทน/usr/local?


1
นี่เป็นคำถามที่ดีสำหรับการเปลี่ยนไดเรกทอรีการติดตั้งได้ทันที แต่ทำไมสิ่งนี้จึงเป็นความต้องการทั่วไป จากมุมมองของฉันคำตอบไม่ควรใช้ตัวเลือกบรรทัดคำสั่งแทนที่จะแก้ไขฐานCMakeLists.txtเพื่อให้คุณสามารถตั้งค่าและลืมมันได้ ฉันไม่ได้บอกว่าไม่มีกรณีการใช้งานทั่วไปสำหรับการเปลี่ยนไดเรกทอรีการติดตั้งได้ทันที - เห็นได้ชัดว่ามีการตัดสินจากจำนวนคะแนน - ฉันแค่ค่อนข้างใหม่สำหรับ CMake และอยากรู้อยากเห็นเมื่อปัญหานี้เกิดขึ้น
CivFan

8
@CivFan มันให้ความสำคัญกับผู้ใช้ที่ต้องการสร้างและติดตั้งโครงการไปยังสถานที่เฉพาะ แต่ไม่ใช่คนเดียวกับนักพัฒนา / ผู้ดูแลโครงการ
David Röthlisberger

4
@CivFan ดังนั้นในฐานะผู้ดูแลมันไม่ใช่เรื่องแปลกสำหรับฉันที่จะทดสอบmake installเส้นทางชั่วคราวเพื่อให้แน่ใจว่าทุกสิ่งที่จะต้องติดตั้งติดตั้งไปยังตำแหน่งที่ถูกต้องโดยไม่ทำให้เครื่องพัฒนาของฉันสับสน เพียงแค่ตัวอย่างเดียว อีกกรณีหนึ่งคือการรวบรวมข้ามสำหรับสถาปัตยกรรมอื่น
Daniel

5
@CivFan: ฉันต้องการสิ่งนี้เพราะฉันต้องการสร้างแพ็คเกจ RPM หากฉันต้องการเปลี่ยนCMakeLists.txtมันฉันต้องแก้ไขแหล่งต้นฉบับ การมีตัวเลือกบรรทัดคำสั่งทำให้ฉันสามารถรับพา ธ ได้อย่างถูกต้องในspecไฟล์Fedora
Martin Ueding

1
@CivFan (และคนอื่น ๆ ที่อ่านข้อความนี้) FYI โดยทั่วไปถือว่าเป็นความคิดที่ดีที่จะแก้ไขCMakeLists.txtไฟล์หากคุณเพียงแค่สร้างและติดตั้งซอฟต์แวร์ - การแทนที่ / การตั้งค่าตัวแปรจากบรรทัดคำสั่งหรือไฟล์แคชเริ่มต้น ฯลฯ เป็นที่ต้องการของผู้บริโภค วิธีการตั้งค่าตัวเลือก
Ryan Pavlik

คำตอบ:


444

คุณสามารถส่งผ่านตัวแปร CMake ใด ๆ บนบรรทัดคำสั่งหรือแก้ไขตัวแปรแคชโดยใช้ ccmake / cmake-gui บนบรรทัดคำสั่ง

cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr && ทำการติดตั้งทั้งหมด

จะกำหนดค่าโครงการสร้างเป้าหมายทั้งหมดและติดตั้งไปยังคำนำหน้า / usr ประเภท (PATH) ไม่จำเป็นอย่างเคร่งครัด แต่จะทำให้ cmt-based cmake-gui แสดงไดอะล็อกตัวเลือกไดเรกทอรี

การเพิ่มเติมเล็กน้อยในขณะที่ความคิดเห็นทำให้ชัดเจนว่าการให้ความเท่าเทียมง่าย ๆ นั้นไม่เพียงพอสำหรับบางคน แนวปฏิบัติที่เหมาะสมที่สุดคือการใช้ไดเรกทอรีสร้างภายนอกเช่นไม่ใช่แหล่งโดยตรง นอกจากนี้เพื่อใช้ไวยากรณ์ทั่วไปของ CMake ที่เป็นนามธรรมทำให้ตัวกำเนิด

mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX: PATH = / usr .. && cmake - build - การติดตั้งเป้าหมาย

คุณสามารถเห็นว่ามันใช้เวลานานขึ้นเล็กน้อยและไม่เทียบเท่าโดยตรงอีกต่อไป แต่ใกล้กับแนวปฏิบัติที่ดีที่สุดในรูปแบบที่ค่อนข้างกระชับ ... --config ถูกใช้โดยเครื่องกำเนิดไฟฟ้าที่มีการกำหนดค่าหลายรูปแบบ (เช่น MSVC) เท่านั้น โดยคนอื่น.


21
สิ่งที่สงสัย: เส้นทางคืออะไร? มันมีประโยชน์สำหรับ cmake-gui ช่วยเลือกวิดเจ็ตสำหรับตัวแปรนั้น ดู doc ในlinux.die.net/man/1/cmake-gui (ส่วนชุด)
albfan

2
พวกเขาให้คำแนะนำเกี่ยวกับ CMake GUI ตามที่ระบุไว้ทุกอย่างใน CMake เป็นสตริงที่มีประสิทธิภาพ แต่การตั้งค่า PATH, FILEPATH, STRING, BOOL และอื่น ๆ ช่วยให้ GUI นำเสนอวิดเจ็ตที่เหมาะสมมากขึ้น
Marcus D. Hanwell

13
คุณยังสามารถใช้: "cmake - build --target install" แทนการทำ
RobertJMaynard

2
จุดสำหรับ after / usr คืออะไร /usr .
bodacydo

5
@bodacydo ตำแหน่งของโฟลเดอร์ด้วย CMakeLists.txt ที่เรากำลังสร้าง
Kamiccolo

48

สามารถข้ามส่วน ": เส้นทาง" ในคำตอบที่ยอมรับได้ ไวยากรณ์นี้อาจเป็นที่น่าจดจำมากขึ้น:

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

... ที่ใช้ในคำตอบที่นี่


7
:PATHไม่ได้เป็นความผิดพลาด
kirbyfan64sos

29

โปรดทราบว่าในทั้ง CMake และAutotoolsคุณไม่จำเป็นต้องตั้งค่าพา ธ การติดตั้งในเวลาที่กำหนด คุณสามารถใช้DESTDIRณ เวลาติดตั้ง (ดูได้ที่นี่ ) แทนใน:

make DESTDIR=<installhere> install

ดูคำถามนี้ซึ่งอธิบายความแตกต่างเล็กน้อยระหว่าง DESTDIR และคำนำหน้า

สิ่งนี้มีไว้สำหรับการติดตั้งแบบกำหนดระยะเวลาและอนุญาตให้จัดเก็บโปรแกรมในตำแหน่งที่แตกต่างจากที่ทำงานเช่น/etc/alternativesผ่านลิงก์สัญลักษณ์

อย่างไรก็ตามหากแพ็กเกจของคุณสามารถ relocatable และไม่จำเป็นต้องมีเส้นทางฮาร์ดโค้ด (คำนำหน้า) ใด ๆ ที่ตั้งค่าผ่านขั้นตอนการกำหนดค่าคุณอาจข้ามได้ ดังนั้นแทนที่จะ:

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

คุณจะทำงาน:

cmake . && make DESTDIR=/usr all install

โปรดทราบว่าตามที่ผู้ใช้ 7498341 ชี้ให้เห็นสิ่งนี้ไม่เหมาะสำหรับกรณีที่คุณควรใช้คำนำหน้า


9
DESTDIRผมชอบการแสดงการใช้งานของ แต่จริงๆแล้วมันผิด คุณควรอ้างอิงถึง cmake docs cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html ... make DESTDIR=/home/john installซึ่งจะติดตั้งซอฟต์แวร์ที่เกี่ยวข้องโดยใช้คำนำหน้าการติดตั้งเช่น“ / usr / local” ที่เติมด้วยค่า DESTDIR ซึ่งในที่สุดก็ให้“ / home / john / usr / local”
Joakim

1
ฉันไม่คิดว่ามันขัดแย้ง หากแพ็คเกจของคุณสามารถเปลี่ยนตำแหน่งได้คุณไม่จำเป็นต้องใช้ CMAKE_INSTALL_PREFIX หรือเลือกวิธีใดวิธีหนึ่ง ถ้าไม่ใช่คุณจะทำเพราะ CMAKE_INSTALL_PREFIX จะถูกอบในบางที่เวลาสร้าง
Bruce Adams

ถ้าคุณรู้ว่าคุณคือกำเนิด Makefile ... ฉันชอบcmake --build build --target install -- DESTDIR=/usrหมายเหตุ: นี้ยังต้องทำงานกับเครื่องกำเนิดไฟฟ้านินจา (กฎดูเหมือนว่าจะมี$ENV{DESTDIR})
Mizux

@ Joakim มากที่สุดเท่าที่ฉันต้องการใช้ CMAKE_INSTALL_PREFIX ทำเช่นนั้นฝังเส้นทางการติดตั้งในไฟล์ที่รวบรวม เมื่อมันเกิดขึ้นฉันเพิ่งสร้างแพ็คเกจ. rpm ดังนั้นมันจะไม่ทำเช่นนั้น DESTDIR ทำงานเหมือนมีเสน่ห์ในการทำให้สิ่งต่าง ๆ เป็น buildroot
นาย Redstoner

18

วิธีที่ฉันสร้างโครงการข้ามแพลตฟอร์ม CMake มีดังต่อไปนี้:

/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
  • สองบรรทัดแรกสร้างไดเรกทอรีบิลด์ที่ไม่มีแหล่งที่มา
  • บรรทัดที่สามสร้างระบบบิลด์โดยระบุตำแหน่งที่จะวางผลการติดตั้ง (ซึ่งฉันมักจะใส่ไว้./project-root/build/stage- พา ธ นั้นจะถูกพิจารณาว่าสัมพันธ์กับไดเรกทอรีปัจจุบันเสมอหากไม่ได้สมบูรณ์)
  • บรรทัดที่สี่สร้างโปรเจ็กต์ที่กำหนดค่า.ด้วย buildsystem ที่กำหนดค่าไว้ในบรรทัดก่อน มันจะดำเนินการinstallเป้าหมายซึ่งสร้างเป้าหมายขึ้นอยู่กับความจำเป็นทั้งหมดหากต้องการสร้างและคัดลอกไฟล์ลงในCMAKE_INSTALL_PREFIX(ซึ่งในกรณีนี้คือ./project-root/build/stageสำหรับบิวด์คอนฟิเกอเรชันหลายแบบเช่นใน Visual Studio คุณสามารถระบุการกำหนดค่าด้วย--config <config>ธงตัวเลือก
  • ส่วนที่ดีเมื่อใช้cmake --buildคำสั่งคือมันทำงานได้กับเครื่องกำเนิดไฟฟ้าทั้งหมด (เช่น makefiles และ Visual Studio) โดยไม่ต้องใช้คำสั่งอื่น

หลังจากนั้นฉันใช้ไฟล์ที่ติดตั้งเพื่อสร้างแพ็คเกจหรือรวมไว้ในโครงการอื่น ...


ขอบคุณสำหรับคำอธิบายทีละขั้นตอน! IMO นี่เป็นวิธีเดียวมิฉะนั้นจุดรวมของ cmake (ความเป็นอิสระของแพลตฟอร์ม) จะถูกยกเลิก ...
helmesjo

1
คุณลืมใส่เส้นทางไปยังแหล่งที่มา (../) ในบรรทัด 3 หรือไม่? BTW นี้ควรเป็นคำตอบที่ยอมรับได้
Slava

1
LIne 3 ควรเป็นcmake -G "<generator>" -DCMAKE_INSTALL_PREFIX=stage ..
codenamezero

1
ในฐานะที่เป็นบันทึกเพิ่มเติมในทางปฏิบัติคนใช้make -j $(nproc)เพื่อระบุจำนวนของการสร้างกระทู้ทำcmake --build . --target=install --config=Release -- -j 8สำหรับเครื่องกำเนิดไฟฟ้า Makefile หรือcmake --build . --target=install --config=Release -- /m:8สำหรับเครื่องกำเนิดไฟฟ้า Visual Studio ด้วย 8 กระทู้ ที่จริงแล้วคุณสามารถส่งพารามิเตอร์ commandline ใด ๆ หลังจาก--
Cloud

1
@MrRedstoner -jไม่ได้เป็นธงสำหรับ CMake เป็นธงทั้งหมดมาหลังจากที่--จะผ่านไปเป็นระบบพื้นฐาน ...
มีเมฆ

4

เกี่ยวกับคำตอบของ Bruce Adams:

คำตอบของคุณสร้างความสับสนอันตราย DESTDIR มีไว้สำหรับการติดตั้งจากทรีรูท อนุญาตให้ใครดูว่าจะติดตั้งอะไรในทรีรูทหากยังไม่ได้ระบุ DESTDIR คำนำหน้าเป็นไดเรกทอรีฐานตามการติดตั้งจริง

ตัวอย่างเช่น PREFIX = / usr / local บ่งชี้ว่าปลายทางสุดท้ายของแพ็กเกจคือ / usr / local การใช้ DESTDIR = $ HOME จะติดตั้งไฟล์ราวกับว่า $ HOME เป็นรูท (/) ถ้าพูดว่า DESTDIR คือ / tmp / destdir ใคร ๆ ก็สามารถเห็นว่า 'ทำการติดตั้ง' จะมีผลกระทบอะไร ด้วยจิตวิญญาณนั้น DESTDIR ไม่ควรกระทบกระเทือนวัตถุที่สร้างขึ้น

ส่วน makefile เพื่ออธิบาย:

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

โปรแกรมต้องสมมติว่าคำนำหน้าเป็นไดเรกทอรีฐานของไดเรกทอรีสุดท้าย (เช่นการผลิต) ความเป็นไปได้ของการเชื่อมโยงโปรแกรมที่ติดตั้งใน DESTDIR = / บางอย่างเท่านั้นหมายความว่าโปรแกรมไม่สามารถเข้าถึงไฟล์ตามคำนำหน้าอย่างที่มันจะไม่ทำงาน cat (1) เป็นโปรแกรมที่ (ในรูปแบบที่ง่ายที่สุด) สามารถเรียกใช้ได้จากทุกที่ นี่คือตัวอย่างที่จะไม่:

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

หากคุณพยายามรัน prog จากที่อื่นที่ไม่ใช่ $ PREFIX / bin / prog จะไม่พบ prog.db เนื่องจากไม่อยู่ในตำแหน่งที่คาดหวัง

ในที่สุด / etc / ทางเลือกใช้งานไม่ได้ด้วยวิธีนี้จริงๆ มี symlink ไปยังโปรแกรมที่ติดตั้งในทรีรูท (เช่น vi -> / usr / bin / nvi, vi -> / usr / bin / vim เป็นต้น)


1
คำตอบนี้อาจเป็นคำตอบที่ดีกว่าสำหรับstackoverflow.com/questions/11307465/destdir-and-prefix-of-make
Bruce Adams

2

ก็ถือว่าการปฏิบัติที่ดีที่จะเรียกใช้เครื่องกำเนิดไฟฟ้าที่เกิดขึ้นจริง (เช่นผ่านทางmake) ถ้าใช้CMake ขอแนะนำให้ทำเช่นนี้:

  1. กำหนดค่าเฟส:

    cmake -Hfoo -B_builds/foo/debug -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_DEBUG_POSTFIX=d -DCMAKE_INSTALL_PREFIX=/usr
    
  2. สร้างและติดตั้งเฟส

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

เมื่อทำตามวิธีนี้เครื่องกำเนิดไฟฟ้าสามารถสลับได้อย่างง่ายดาย (เช่น-GNinjaสำหรับนินจา ) โดยไม่ต้องจำคำสั่งเฉพาะของเครื่องกำเนิดใด ๆ


1
คำตอบน่าจะดีกว่านี้ถ้ามีคำอธิบายให้ทุกข้อโต้แย้งที่ใช้และทำไมพวกเขาถึงใช้ โดยเฉพาะประเด็นของการ--configโต้แย้งคืออะไร?
Dmitry Kabanov

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.