CMake ทำงานอย่างไร


158

ฉันไม่ได้ขอสิ่งนี้ด้วยตนเอง ฉันหวังว่าคำถามนี้จะเป็นข้อมูลอ้างอิงสำหรับมือใหม่หลายคนที่ชอบฉันพบว่ามันน่างงงวยอย่างมากเกี่ยวกับสิ่งที่เกิดขึ้นเบื้องหลังเมื่อสิ่งเล็ก ๆ น้อย ๆCMakeLists.txtไฟล์

cmake_minimum_required (VERSION 2.6)
project(Tutorial)
add_executable(Tutorial tutorial.cpp)

และเช่นขนาดเล็ก tutorial.cpp

int main() { return 0; } 

มีไฟล์จำนวนมากที่ถูกสร้างขึ้น

CMakeCache.txt  cmake_install.cmake  Makefile
CMakeLists.txt  tutorial.cpp

และCMakeFilesโฟลเดอร์ที่มีไฟล์และโฟลเดอร์มากมาย

CMakeCCompiler.cmake               CMakeOutput.log    Makefile.cmake
cmake.check_cache                  CMakeSystem.cmake  progress.marks
CMakeCXXCompiler.cmake             CMakeTmp           TargetDirectories.txt
CMakeDetermineCompilerABI_C.bin    CompilerIdC        Tutorial.dir
CMakeDetermineCompilerABI_CXX.bin  CompilerIdCXX
CMakeDirectoryInformation.cmake    Makefile2

ไม่เข้าใจว่าเกิดอะไรขึ้นเบื้องหลัง (เช่น: เหตุใดจึงต้องมีการสร้างไฟล์และวัตถุประสงค์ของพวกเขา) เป็นอุปสรรคที่ใหญ่ที่สุดในการเรียนรู้ CMake

ถ้าใครรู้คุณช่วยอธิบายหน่อยได้ไหมเพื่อลูกหลาน? จุดประสงค์ของไฟล์เหล่านี้คืออะไรและเมื่อฉันพิมพ์cmake .สิ่งที่ cmake กำหนดค่าและสร้างก่อนที่จะสร้างโครงการคืออะไร


1
ฉันตระหนักถึงการสร้างนอกแหล่งที่มา ในกรณีที่ทุกคนไม่ได้ทำบิลด์จากแหล่งที่มาและยังคงมองหาวิธีล้างไฟล์ที่สร้างขึ้นเทคนิคนี้ใช้ได้ดี: stackoverflow.com/a/12055610/453673
Nav

3
มีคำอธิบายที่ยอดเยี่ยมที่: aosabook.org/en/cmake.htmlและอาจตอบคำถามในเชิงลึก (ซึ่งไม่สามารถสรุปโดยย่อได้ที่นี่)
parasrish

@SebTu ลิงก์เสีย ไม่มีหน้า cmake.html
Nav

3
@Nav Yap สับสนไวยากรณ์มาร์กอัปขออภัย สำหรับคนใหม่ที่จะ CMake ผมขอแนะนำให้อ่าน: ดังนั้นนี่รุ่นแก้ไขสถาปัตยกรรมของ CMake มันให้ข้อมูลเพียงพอที่จะรับรู้ว่า cmake ทำงานอย่างไรโดยไม่ปล่อยให้ตัวเองเป็นรายละเอียด
SebNag

คำตอบ:


92

ความลับคือคุณไม่ต้องเข้าใจว่าไฟล์ที่สร้างขึ้นทำอะไร

CMake นำเสนอความซับซ้อนมากมายในระบบการสร้างซึ่งส่วนใหญ่จะจ่ายเมื่อคุณใช้สำหรับการสร้างโครงการซอฟต์แวร์ที่ซับซ้อน

ข่าวดีก็คือ CMake ทำงานได้ดีในการรักษาความยุ่งเหยิงมากมายจากคุณ: ใช้ แหล่งที่มาและคุณไม่จำเป็นต้องดูไฟล์ที่สร้างขึ้น หากคุณยังไม่ได้ทำสิ่งนี้ (ซึ่งฉันคิดว่าเป็นกรณีที่คุณเขียนcmake .) โปรดตรวจสอบพวกเขาก่อนที่จะดำเนินการต่อไปไป การรวมไดเรกทอรีสร้างและแหล่งข้อมูลนั้นเจ็บปวดอย่างมากกับ CMake และไม่ใช่วิธีที่ระบบควรจะใช้

โดยย่อ: แทน

cd <source_dir>
cmake .

ใช้เสมอ

cd <build_dir_different_from_source_dir>
cmake <source_dir>

แทน. ฉันมักจะใช้โฟลเดอร์ย่อยที่ว่างเปล่าbuildภายในไดเรกทอรีแหล่งที่มาของฉันเป็นไดเรกทอรีการสร้าง

เพื่อบรรเทาความเจ็บปวดของคุณให้ฉันให้ภาพรวมโดยย่อเกี่ยวกับไฟล์ที่เกี่ยวข้องที่ CMake สร้าง:

  • ไฟล์โครงการ / Makefiles - สิ่งที่คุณสนใจจริง ๆ : ไฟล์ที่จำเป็นในการสร้างโครงการของคุณภายใต้ตัวสร้างที่เลือก สิ่งนี้สามารถเป็นอะไรก็ได้ตั้งแต่ Unix Makefile ไปจนถึงโซลูชัน Visual Studio
  • CMakeCache.txt - นี่คือการจัดเก็บคีย์ / ค่าสตริงถาวรซึ่งใช้ในการแคชค่าระหว่างการทำงาน ค่าที่เก็บไว้ในที่นี้สามารถเป็นพา ธ ไปยังการขึ้นต่อกันของไลบรารีหรือกำหนดว่าจะสร้างคอมโพเนนต์เพิ่มเติมหรือไม่ รายการตัวแปรส่วนใหญ่จะเหมือนกับรายการที่คุณเห็นเมื่อเรียกใช้ccmakeหรือcmake-guiหรือสิ่งนี้มีประโยชน์ในการดูเป็นครั้งคราว แต่ฉันขอแนะนำให้ใช้เครื่องมือดังกล่าวสำหรับการเปลี่ยนแปลงค่าใด ๆ หากเป็นไปได้
  • ไฟล์ที่สร้าง - สิ่งนี้สามารถเป็นอะไรก็ได้ตั้งแต่ไฟล์ที่สร้างอัตโนมัติไปจนถึงการส่งออกมาโครที่ช่วยให้คุณรวมโครงการที่สร้างขึ้นใหม่เข้ากับโครงการ CMake อื่น ๆ สิ่งเหล่านี้ส่วนใหญ่สร้างขึ้นตามความต้องการเท่านั้นและจะไม่ปรากฏในโครงการง่าย ๆ เช่นจากคำถามของคุณ
  • สิ่งอื่นใดที่มีเสียงดังมากเพื่อให้ระบบการสร้างมีความสุข โดยเฉพาะอย่างยิ่งฉันไม่ต้องการที่จะใส่ใจกับสิ่งที่เกิดขึ้นภายในCMakeFilesไดเรกทอรีย่อย

โดยทั่วไปคุณไม่ควรยุ่งกับไฟล์ใด ๆ ที่ CMake สร้างให้คุณ ปัญหาทั้งหมดสามารถแก้ไขได้จากภายในไม่CMakeLists.txtทางใดก็ทางหนึ่ง ตราบใดที่ผลลัพธ์สร้างโครงการของคุณตามที่คาดไว้คุณก็คงสบายดี ไม่ต้องกังวลมากเกินไปเกี่ยวกับรายละเอียดเต็มไปด้วยเลือด - เพราะนี่คือสิ่งที่ CMake พยายามไว้ให้คุณตั้งแต่แรก


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

1
CMakeFilesไดเรกทอรีมีCMakeError.logและCMakeOutput.logสำคัญสำหรับการแก้ไขปัญหาการสร้าง CMake
Serge Rogatch

1
สองสิ่งที่บางครั้งคุณจำเป็นต้องตรวจสอบในCMakeFiles/target_name.dirไดเรกทอรีคือflags.makeและlink.txtไฟล์ ฉันต้องตรวจสอบสิ่งเหล่านี้ในโครงการที่ซับซ้อนซึ่งสืบทอดการตั้งค่าสถานะ / สิ่งที่เชื่อมโยงจากโครงการต้นน้ำ เช่น: ฉันมีข้อผิดพลาดเนื่องจาก TPL A มีการพึ่งพา TPL B และโครงการของฉันก็ขึ้นกับ B ซึ่งฉันติดตั้งในเครื่อง แต่ A ใช้เวอร์ชัน B จากระบบของฉัน (แทนที่จะติดตั้งในเครื่อง) ซึ่งมีตัวเลือกการเปิดใช้งานที่แตกต่างกันและมาก่อนทำให้เกิดข้อผิดพลาดในโครงการของฉัน ดูเฉพาะที่ link.txt ฉันสามารถค้นหาสิ่งที่เกิดขึ้นได้
bartgol

13

ตามที่ระบุไว้ในเว็บไซต์:

Cmake เป็นระบบสร้างข้ามแพลตฟอร์มสำหรับการจัดการกระบวนการสร้างซอฟต์แวร์โดยใช้วิธีคอมไพเลอร์

ในกรณีส่วนใหญ่จะใช้ในการสร้างโครงการ / สร้างไฟล์ - ในตัวอย่างของคุณมีการผลิตMakefileที่ใช้ในการสร้างซอฟต์แวร์ของคุณ (ส่วนใหญ่บนแพลตฟอร์ม Linux / Unix)

Cmake อนุญาตให้มีการสร้างไฟล์ข้ามแพลตฟอร์มที่จะสร้างโครงการเฉพาะ / สร้างไฟล์สำหรับการรวบรวม / แพลตฟอร์มเฉพาะ

ตัวอย่างเช่นคุณอาจพยายามรวบรวมซอฟต์แวร์ของคุณใน Windows ด้วย Visual Studio จากนั้นมีไวยากรณ์ที่เหมาะสมในCMakeLists.txtไฟล์ของคุณคุณสามารถเปิด

cmake .

ในไดเรกทอรีของโครงการของคุณบนแพลตฟอร์ม Windows, Cmake จะสร้างไฟล์โครงการ / โซลูชันที่จำเป็นทั้งหมด ( .slnฯลฯ )

หากคุณต้องการที่จะสร้างซอฟต์แวร์ของคุณบนแพลตฟอร์ม Linux / Unix คุณก็จะไปที่ไดเรกทอรีต้นทางที่คุณมีของคุณCMakeLists.txtไฟล์และเรียกการเดียวกันcmake .และมันจะสร้างไฟล์ทั้งหมดที่จำเป็นสำหรับคุณที่จะสร้างซอฟแวร์ผ่านง่าย หรือmakemake all

ที่นี่คุณมีการนำเสนอที่ดีมากเกี่ยวกับฟังก์ชัน Cmake สำคัญhttp://www.elpauer.org/stuff/learning_cmake.pdf

แก้ไข

หากคุณต้องการให้ห้องสมุดขึ้นอยู่กับแพลตฟอร์มรวมถึง / คำจำกัดความของตัวแปร ฯลฯ คุณสามารถใช้ไวยากรณ์นี้ในCMakeLists.txtไฟล์

IF(WIN32)
   ...do something...
 ELSE(WIN32)
   ...do something else...
 ENDIF(WIN32)

นอกจากนี้ยังมีคำสั่งมากมายที่มีการใช้งานซึ่งคุณสามารถป้องกันไม่ให้บิลด์ล้มเหลวและ Cmake จะแจ้งให้คุณทราบว่าตัวอย่างเช่นคุณไม่มีบูสเตอร์เพิ่มfilesystemและregexติดตั้งในระบบของคุณ ในการทำเช่นนั้นคุณสามารถใช้ไวยากรณ์ต่อไปนี้:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

มีการตรวจสอบว่ามันจะสร้าง makefiles สำหรับระบบ / IDE / คอมไพเลอร์ที่เหมาะสม


1
ขอบคุณ Patryk คำตอบที่เป็นประโยชน์ แต่ไฟล์ PDF ที่คุณเชื่อมโยงอธิบายส่วนใหญ่เป็นขั้นตอนที่สองของการเรียนรู้ CMake ซึ่งโดยทั่วไปแล้วการนำ CMake ไปใช้ ฉันกำลังถามเกี่ยวกับคำอธิบายของด่านแรกซึ่งคนเราต้องเข้าใจว่าเกิดอะไรขึ้นใน CMake!
Nav

@ ไม่ฉันได้ขยายคำตอบของฉันเล็กน้อย คุณยังสามารถค้นหาข้อมูลเพิ่มเติมได้จากเว็บ
Patryk

นี้ค่อนข้างไกลจากการตอบคำถามที่ถาม
SenhorLucas

1

CMake ทำงานอย่างไรเป็นคำถามสำหรับนักพัฒนาดังนั้นคำถามนี้ไม่สามารถตอบได้ที่นี่

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

CMake เป็นเครื่องมือที่มีความแข็งแกร่งในอุตสาหกรรม มันเป็นกระบวนการที่ซับซ้อนมากโดยอัตโนมัติและคำนึงถึงตัวแปรมากมายที่คุณอาจไม่ได้รับรู้โดยเฉพาะอย่างยิ่งในฐานะนักพัฒนาใหม่ที่ค่อนข้างจะทำงานกับความรู้ที่ จำกัด ของระบบปฏิบัติการและเครื่องมือสร้างที่ CMake สามารถจัดการได้ เหตุผลที่สร้างไฟล์จำนวนมากและทำไมสิ่งต่าง ๆ จึงดูซับซ้อนเนื่องจากระบบอื่น ๆ เหล่านั้นมีความซับซ้อนและต้องมีการคิดและอัตโนมัติ นอกจากนี้ยังมีปัญหาของ "แคช" และคุณสมบัติประหยัดเวลาอื่น ๆ ของเครื่องมือเพื่อทำความเข้าใจทุกอย่างใน CMake จะหมายถึงการทำความเข้าใจทุกอย่างในเครื่องมือสร้างและระบบปฏิบัติการเหล่านี้และการรวมกันที่เป็นไปได้ของตัวแปรเหล่านี้ซึ่งคุณสามารถจินตนาการได้ว่าเป็นไปไม่ได้

เป็นสิ่งสำคัญที่จะต้องทราบว่าหากคุณไม่รับผิดชอบการจัดการระบบการสร้างข้ามแพลตฟอร์มขนาดใหญ่และฐานรหัสของคุณคือ KLOC บางตัวอาจสูงถึง 100KLOG โดยใช้ CMake ดูเหมือนเล็กน้อยเหมือนกับการใช้การกำจัดต้นไม้ป่าไม้ 100,000 ดอลลาร์ เครื่องกำจัดวัชพืชออกจากสวน 2 ฟุตด้วยสวนดอกไม้ 2 ฟุต (โดยวิธีถ้าคุณไม่เคยเห็นเครื่องดังกล่าวคุณควรมองหาหนึ่งใน youtube พวกเขาน่าทึ่ง)

หากระบบการสร้างของคุณมีขนาดเล็กและเรียบง่ายน่าจะดีกว่าถ้าคุณเขียนไฟล์ด้วยตัวเองหรือเขียนสคริปต์ด้วยตัวเอง เมื่อ makefiles ของคุณไม่มั่นคงหรือคุณต้องการสร้างเวอร์ชันของระบบของคุณบนแพลตฟอร์มอื่นคุณสามารถสลับไปใช้ CMake ได้ ณ จุดนี้คุณจะมีปัญหามากมายในการแก้ปัญหาและคุณสามารถถามคำถามที่เน้นมากขึ้นเกี่ยวกับเรื่องนี้ ในระหว่างนี้ลองอ่านหนังสือที่ยอดเยี่ยมบางเล่มที่เขียนเกี่ยวกับ CMake หรือดีกว่านั้นลองเขียนด้วยตัวคุณเอง! 8)

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