CMake/Basics

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา

CMake (http://www.cmake.org/ และ http://en.wikipedia.org/wiki/Cmake) เป็นซอฟต์แวร์สำหรับสร้าง build script (ไฟล์ที่นิยามวิธีการคอมไพล์และลิงก์โปรแกรมและไลบรารีที่เขียนด้วยภาษา C++) ที่สามารถใช้ร่วมกับเครื่องมือพัฒนาโปรแกรมที่ได้รับความนิยมหลายๆ ตัว อาทิ Microsoft Visual C++, GNU Compiler Collection, Xcode, และ Eclipse CDT เป็นต้น

การใช้ CMake ช่วยให้เรากำหนดซอฟต์แวร์ที่เราต้องการสร้างเพียงครั้งเดียว หลังจากนั้นเราสามารถพัฒนามันโดยใช้เครื่องมือที่เราชอบบนแพลตฟอร์มใดๆ ก็ได้ CMake จึงอำนวยช่วยความสะดวกให้กับโปรแกรมเมอร์ภาษา C++ ที่ต้องการสร้างซอฟต์แวร์ที่รันบนหลายๆ แพลตฟอร์มอย่างมาก ในบทความนี้เราจะกล่าวถึงวิธีการใช้งาน CMake จัดการซอฟต์แวร์โปรเจคง่ายๆ เป็นการปูพื้นฐานก่อนจะกล่าวถึงการใช้งานที่สลับซับซ้อนขึ้นต่อไป

ปัญหาของการเขียนโปรแกรมสำหรับหลายแพลตฟอร์ม

การเขียนโปรแกรมภาษา C++ ให้คอมไพล์และรันบนหลายๆ แพลตฟอร์ม (เขียนครั้งเดียวแต่รันได้ทั้งบน Windows, Unix, Mac, ฯลฯ) นั่นเป็นเรื่องที่ทำให้โปรแกรมเมอร์ปวดเศียรเวียนเกล้าอย่างหนักมาหลายคนแล้ว เหตุก็เพราะว่า แพลตฟอร์มต่างๆ กันนั้นมี "สภาพแวดล้อม" สำหรับพัฒนาโปรแกรมภาษา C++ ที่ไม่เหมือนกันเอาเสียเลย เราอาจสามารถสรุปปัญหาที่โปรแกรมเมอร์เจอไว้เป็นข้อๆ ได้ดังต่อไปนี้

  1. ไลบรารีภาษา C/C++ บนแพลตฟอร์มต่างๆ ไม่เหมือนกัน เช่น ใน Linux และ Mac จะมีไฟล์ unistd.h แต่ใน Windows ไม่มี หรือใน Mac มีระบบไลบรารีที่เรียกว่า bundle และ framework ซึ่งไม่ปรากฏอยู่ในแพลตฟอร์มอื่นๆ
  2. คอมไพเลอร์ที่ใช้เป็นคนละตัวกัน กล่าวคือ โปรแกรมเมอร์ C++ ใน Windows จะใช้ cl ของ Microsoft ส่วนโปรแกรมเมอร์บน Linux และ Mac จะใช้ gcc หรือ g++ ของ GNU Project นี่หมายความว่าภาษา C++ ใน Windows จะไม่เหมือนกับภาษา C++ ใน Unix และ Mac เป๊ะ และมีข้อแตกต่างยิบย่อยที่ทำให้ซอร์สโค้ดที่เขียนสำหรับแพลตฟอร์มหนึ่งไม่สามารถคอมไพล์บนอีกแพลตฟอร์มหนึ่งได้
  3. เครื่องมือที่ใช้ในการ build โปรแกรมไม่เหมือนกัน โปรแกรมเมอร์บน Windows จะใช้ Visual Studio พวกที่ใช้ Linux ก็จะเขียน Makefile แล้วรัน make ส่วนขา Mac ก็จะใช้ Xcode

Preprocessor Macro

เราสามารถหลีกเลี่ยงสองปัญหาแรกบางส่วนได้ด้วยการเขียน preprocessor macro เพื่อให้คอมไพเลอร์เลือกใช้โค้ดส่วนที่ถูกต้อง ยกตัวอย่าง เช่น หากเราต้องการชื่อของไดเรคทอรีที่โปรแกรมทำงานอยู่ในปัจจุบัน (current working directory ย่อว่า cwd) แล้ว

  • ใน Linux และ Mac เราจะต้องใช้คำสั่ง getcwd ซึ่งอยู่ใน unistd.h
  • แต่ใน Windows เราจะต้องใช้คำสั่ง _getcwd ซึ่งอยู่ใน direct.h

เนื่องจาก cl จะนิยามมาโคร _WIN32 ก่อนคอมไพล์ไฟล์ทุกไฟล์ ดังนั้นเราสามารถเช็คได้ว่า ตอนนี้โปรแกรมถูกคอมไพล์บน Windows หรือแพลตฟอร์มอื่นได้โดยการเช็คว่า _WIN32 ถูกนิยามหรือไม่ ฉะนั้นเราสามารถเลือก include ไฟล์ที่ถูกต้องได้ดังนี้

<geshi lang="c">

  1. ifdef _WIN32
  2. include <direct.h>
  3. else
  4. include <unistd.h>
  5. endif

</geshi>

ส่วนเวลาเรียกใช้คำสั่ง เราสามารถเขียนโค้ดต่อไปนี้ได้

<geshi lang="c"> char *buffer;

  1. ifdef _WIN32

buffer = _getcwd(NULL, 0);

  1. else

buffer = getcwd(NULL, 0);

  1. endif

</geshi>

เครื่องมือและสภาพแวดล้อมที่แตกต่าง

อย่างไรก็ดีการเขียน preprocessor macro ก็ยังไม่สามารถแก้ปัญหาได้ทั้งหมด เนื่องจากคอมไพเลอร์ของแต่ละแพลตฟอร์มมีวิธีการเรียกใช้และการกำหนดออปชันที่แตกต่างกัน นอกจากนี้ การคอมไพล์โปรแกรมภาษา C++ เป็นกระบวนการที่ซับซ้อน ดังนั้นแพลตฟอร์มต่างๆ จึงมีเครื่องมือสำหรับกำหนดกระบวนการนี้เป็นของตัวเอง

ถึงแม้ว่าในปัจจุบัน make จะเป็นเครื่องมือมาตรฐานสำหรับการสร้างซอฟต์แวร์ภาษา C++ ในแพลตฟอร์มที่สืบเชื้อสายมาจาก Unix ทั้งหลาย นอกจากนี้ใน Windows มี nmake ให้ใช้ด้วย อย่างไรก็ดีการใช้ make ทำให้โปรแกรมเมอร์ต้องสละความสะดวกสบายของ IDE ที่ตนถนัด (เนื่องจากผู้เขียนใช้งาน Visual C++ จนติด การต้องไปเขียน Makefile เองจึงเป็นเรื่องที่ทรมานยิ่ง)

แต่ปัญหาที่ใหญ่ที่สุดเกิดขึ้นเมื่อซอฟต์แวร์ที่เราสร้างใช้ไลบรารีภายนอกที่เราไม่ได้เขียนเอง เนื่องจากแพลตฟอร์มต่างๆ มีที่เก็บไลบรารีที่แตกต่างกัน เช่น ใน Mac จะเก็บอยู่ในไดเรคทอรี /Library ส่วนใน Unix อาจเก็บอยู่ที่ /usr หรือ /usr/local ส่วนใน Windows นั้นไม่มีที่เก็บที่แน่นอน เป็นเรื่องของโปรแกรมเมอร์ที่จะต้องรู้ที่เก็บไลบรารีเอง

ในแพลตฟอร์ม Unix มีชุดของเครื่องมือที่เรียกว่า Autotools ซึ่งสามารถตรวจว่าระบบที่จะทำการคอมไพล์ไฟล์มีไลบรารีที่ต้องการให้ใช้หรือไม่ รวมทั้งสร้างไฟล์ชื่อ config.h ซึ่งมี preprocessor macro ซึ่งช่วยให้เรา include ไฟล์และเลือกใช้คำสั่งที่ถูกต้องได้ดังที่กล่าวไว้ข้างบน แต่การใช้ Autotools บังคับให้เราต้องใช้ make ไปโดยปริยาย

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

CMake

CMake เป็นเครื่องมือที่ช่วยตอบสนองความต้องการข้างต้นได้ จากมุมมองของผู้ใช้ CMake แล้วกระบวนการคอมไพล์โปรแกรมสามารถแยกออกเป็นสามขั้นตอนดังต่อไปนี้

  1. เขียนไฟล์ชื่อ CMakeLists.txt เพื่อกำหนดโปรเจค
  2. รัน CMake เพื่อสร้าง build script ที่เฉพาะเจาะจงกับแพลตฟอร์มและเครื่องมือที่เราใชัพัฒนาโปรแกรม
  3. build โปรแกรมด้วยเครื่องมือดังกล่าว

สังเกตว่าหน้าที่ของ CMake คือการอ่านพิมพ์เขียวของโปรเจคจากไฟล์ CMakeLists.txt แล้วสร้าง build script แต่มันไม่ได้ทำการ build โปรแกรมด้วยตัวเองเหมือนกับเครื่องมือลักษณะคล้ายๆ กันตัวอื่น นี่เป็นสาเหตุที่ทำให้เราสามารถใช้เครื่องมืออะไรก็ได้ที่ CMake สนับสนุนในการพัฒนาโปรแกรมตามความถนัดของเรา

การติดตั้ง CMake

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

ผู้ใช้ Debian หรือ Ubuntu สามารถติดตั้ง CMake ผ่าน apt-get ได้ด้วยการสั่ง

> sudo apt-get cmake

ส่วนผู้ใช้ Mac ที่ใช้ MacPorts สามารถติดตั้งได้โดยการสั่ง

> sudo port install cmake

หลังจากติดตั้งแล้วเราสามารถทดสอบว่า CMake ถูกติดตั้งเรียบร้อยดีหรือไม่ด้วยการสั่ง

> cmake

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

เมื่อผู้เขียนรันคำสั่ง cmake บนภายใต้ระบบปฏิบัติการ Mac OSX แล้วได้ผลลัพธ์ดังต่อไปนี้

 cmake version 2.6-patch 4
 Usage

   cmake [options] <path-to-source>
   cmake [options] <path-to-existing-build>

 Options
   <<< ข้อความแสดงออปชันต่างๆ ที่ผู้ใช้สามารถกำหนดได้ >>> 

 Generators

 The following generators are available on this platform:
   Unix Makefiles               = Generates standard UNIX makefiles.
   Xcode                       = Generate XCode project files.
   CodeBlocks - Unix Makefiles  = Generates CodeBlocks project files.
   Eclipse CDT4 - Unix Makefiles
                               = Generates Eclipse CDT 4.0 project files.
   KDevelop3                   = Generates KDevelop 3 project files.
   KDevelop3 - Unix Makefiles   = Generates KDevelop 3 project files.

แต่ถ้ารันมันภายใต้ Windows XP แล้วจะได้ผลลัพธ์ดังต่อไปนี้

 cmake version 2.8.1
 Usage

   cmake [options] <path-to-source>
   cmake [options] <path-to-existing-build>

 Options
   <<< ข้อความแสดงออปชันต่างๆ ที่ผู้ใช้สามารถกำหนดได้ >>>

 Generators

 The following generators are available on this platform:
   Borland Makefiles            = Generates Borland makefiles.
   MSYS Makefiles               = Generates MSYS makefiles.
   MinGW Makefiles              = Generates a make file for use with
                                 mingw32-make.
   NMake Makefiles              = Generates NMake makefiles.
   NMake Makefiles JOM          = Generates JOM makefiles.
   Unix Makefiles               = Generates standard UNIX makefiles.
   Visual Studio 10            = Generates Visual Studio 10 project files.
   Visual Studio 10 Win64      = Generates Visual Studio 10 Win64 project
                                 files.
   Visual Studio 6             = Generates Visual Studio 6 project files.
   Visual Studio 7             = Generates Visual Studio .NET 2002 project
                                 files.
   Visual Studio 7 .NET 2003   = Generates Visual Studio .NET 2003 project
                                 files.
   Visual Studio 8 2005        = Generates Visual Studio .NET 2005 project
                                 files.
   Visual Studio 8 2005 Win64  = Generates Visual Studio .NET 2005 Win64
                                 project files.
   Visual Studio 9 2008        = Generates Visual Studio 9 2008 project files.
   Visual Studio 9 2008 Win64  = Generates Visual Studio 9 2008 Win64 project
                                 files.
   Watcom WMake                = Generates Watcom WMake makefiles.
   CodeBlocks - MinGW Makefiles = Generates CodeBlocks project files.
   CodeBlocks - NMake Makefiles = Generates CodeBlocks project files.
   CodeBlocks - Unix Makefiles  = Generates CodeBlocks project files.
   Eclipse CDT4 - MinGW Makefiles
                               = Generates Eclipse CDT 4.0 project files.
   Eclipse CDT4 - NMake Makefiles
                               = Generates Eclipse CDT 4.0 project files.
   Eclipse CDT4 - Unix Makefiles
                               = Generates Eclipse CDT 4.0 project files.

ผลลัพธ์ทั้งสองแสดงให้เห็นว่าเราสามารถสร้าง build script สำหรับเครื่องมือที่แตกต่างกันได้หลายชนิด และ CMake ยังรู้ด้วยว่าในแพลตฟอร์มต่างๆ กันมีเครื่องมือที่แตกต่างกัน

Hello World ด้วย CMake

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

 helloworld/
     CMakeLists.txt
     main.cpp

โดยที่ main.cpp มีเนื้อหาตามธรรมเนียมดังนี้

<geshi lang="c">

  1. include <stdio.h>

int main() {

 printf("hello, world\n");
 return 0;

} </geshi>

ไฟล์ CMakeLists.txt เป็นพิมพ์เขียวของโปรเจค ซึ่งในกรณีนี้มันมีเนื้อหาดังต่อไปนี้

 PROJECT(sample)
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
 ADD_EXECUTABLE(helloworld main.cpp)

บรรทัดแรกของไฟล์บอกว่าโปรเจคของเรามีชื่อว่า sample ส่วนบรรทัดที่สองเป็นการเช็คว่า CMake ที่เราใช้นั้นใหม่กว่าเวอร์ชัน 2.6 บรรทัดที่สามเป็นบรรทัดบอกว่าเราจะทำการสร้างไฟล์ executable เพียงไฟล์เดียวชื่อ helloworld ด้วยการคอมไพล์ main.cpp

ตอนนี้เราพร้อมที่จะสร้าง build script ด้วย CMake แล้ว อันดับแรกให้ทำการเปลี่ยนไดเรคทอรีไปยังไดเรคทอรี helloworld ที่เราเพิ่งจะสร้างขึ้น

 > cd helloworld

แล้วจึงสั่ง

 > cmake .

เพื่อบอกให้ CMake สร้าง build script โดยอ่าน CMakeLists.txt จากไดเรคทอรีปัจจุบัน การสั่งแบบนี้สอดคล้องกับการใช้ CMake โดยสั่ง

 cmake [options] <path-to-source>

ที่เราเคยเห็นแล้วจากการสั่ง cmake เปล่าๆ ข้างบน

ผลลัพธ์

เนื่องจากเราไม่ได้กำหนดว่าจะให้ CMake ใช้ generator ตัวใด CMake จึงเลือกใช้ generator ตัวที่ถูกเลือกเป็นตัวเลือกอัตโนมัติสำหรับแพลตฟอร์มที่เรารันมัน

เวลาที่ผู้เขียนใช้ Mac ผู้เขียนพบว่า CMake จะสร้าง "Unix Makefiles" ดังนั้นหากเราดูไฟล์ในไดเรคทอรี helloworld หล้งรัน CMake จะมีไฟล์ดังต่อไปนี้

 > ls
 CMakeCache.txt     Makefile                main.cpp
 CMakeFiles         cmake_install.cmake
 CMakeLists.txt

โดยไฟล์ที่เป็นผลลัพธ์ที่สำคัญที่สุดคือ Makefile ซึ่งทำให้เราสามารถสั่ง

 > make

แล้วจะได้ไฟล์ executable ชื่อ helloworld ตามที่เราต้องการ

ในทางกลับกัน ถ้าผู้เขียนใช้ Windows แล้ว CMake จะใช้ generator ชื่อ "Visual Studio 9 2008" เพื่อสร้างไฟล์โปรเจคสำหรับ Visual C++ 2008 เมื่อผู้เขียนสำรวจดูไดเรคทอรี helloworld ก็พบว่ามีไฟล์ดังต่อไปนี้

 C:\***\helloworld>dir
  Volume in drive C is ********
  Volume Serial Number is ****-****

  Directory of C:\***\helloworld

 05/08/2010  08:00 PM    <DIR>          .
 05/08/2010  08:00 PM    <DIR>          ..
 05/08/2010  08:00 PM            23,520 ALL_BUILD.vcproj
 05/08/2010  08:00 PM            12,587 CMakeCache.txt
 05/08/2010  08:00 PM    <DIR>          CMakeFiles
 05/08/2010  07:57 PM                91 CMakeLists.txt
 05/08/2010  08:00 PM             1,473 cmake_install.cmake
 05/08/2010  08:00 PM            26,038 helloworld.vcproj
 05/08/2010  07:56 PM                92 main.cpp
 05/08/2010  08:00 PM             3,151 sample.sln
 05/08/2010  08:00 PM            20,415 ZERO_CHECK.vcproj
                8 File(s)         87,367 bytes
                3 Dir(s)   5,633,990,656 bytes free

ซึ่งผู้เขียนสามารถใช้ Microsoft Visual Studio 2009 เปิดไฟล์ sample.sln เพื่อคอมไพล์ main.cpp ให้กลายเป็น helloworld.exe ได้

เลือก Generator เอง

เราสามารถกำหนดให้ CMake ใช้ generator ตัวอื่นๆ ที่ไม่ใช้ตัวที่มันเลือกให้อัตโนมัติได้ ด้วยการใช้ออปชัน -G "ชื่อ generator" ยกตัวอย่างเช่น หากเราต้องการใช้ Xcode ในการพัฒนาซอฟต์แวร์บนเครื่อง Mac แทนที่จะใช้ Unix Makefiles เราสามารถสั่ง

 > cmake -G "Xcode" .

แทนการสั่ง cmake . ที่กล่าวไปในส่วนที่แล้ว ในกรณีของโปรเจค sample ข้างบน เราได้จะได้ไดเรคทอรีชื่อ sample.xcodeproj ซึ่งสามารถใช้ Xcode เปิดได้

คุณสามารถชื่อของ generator ที่ใช้ได้ในแต่ละแพลตฟอร์มได้จากส่วน "Generators" ของข้อความที่ CMake พิมพ์ออกมาเมื่อเราสั่ง cmake เฉยๆ ใน command prompt

อย่างไรก็ดี หากคุณใช้สั่ง cmake . สร้าง build script ลงในไดเรคทอรี helloworld เสร็จแล้วพยายามจะเปลี่ยน generator ที่ใช้ด้วยการสั่ง cmake -G "Xcode" . แล้ว CMake จะบ่นว่า

 CMake Error: Error: generator : Xcode
 Does not match the generator used previously: Unix Makefiles
 Either remove the CMakeCache.txt file or choose a different binary directory

ปัญหานี้เกิดขึ้นจากข้อจำกัดของ CMake ที่ว่า ในไดเรคทอรีหนึ่งๆ มันสามารถสร้าง build script ของเครื่องมือได้เพียงเครื่องมือเดียวเท่านั้น หากเราต้องการเปลี่ยนเครื่องมือใหม่ เราจะต้องทำให้ CMake "ลืม" build script ของเครื่องมือเดิมด้วยการลบไฟล์ CMakeCache.txt แล้วจึงสั่ง cmake -G "Xcode" . ใหม่อีกรอบ หรือไม่ก็ไปสร้าง build script ในไดเรคทอรีใหม่เลย

In-Source Build และ Out-of-Source Build

สังเกตว่าในการ build โปรเจค sample ในส่วนที่แล้วนั้น ได้เรคทอรี helloworld บรรจุดทั้งซอร์สโค้ด (มีสองไฟล์คือ main.cpp และ CMakeLists.txt) และไฟล์อื่นๆ ที่ CMake สร้างขึ้นไว้ทั้งคู่ การทำเช่นนี้เรียกว่าการทำ in-source build และมันมีข้อเสียดังต่อไปนี้

1. ไดเรคทอรีที่เก็บซอร์สโค้ดสามารถเก็บ build script ของเครื่องมือได้เครื่องมือเดียวเท่านั้น จึงเกิดความไม่สะดวกอย่างยิ่งเวลาต้องการสร้าง build script สำหรับเครื่องมือหลายๆ เครื่องมือ

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

ในทางกลับกัน out-of-source build คือการแยกไดเรคทอรีที่เก็บซอร์สโค้ด (CMake เรียกไดเรคทอรีนี้ว่า source directory) และไดเรคทอรีที่เก็บ build script และข้อมูลอื่นๆ (CMake เรียกไดเรคทอรีนี้ว่า binary directory) ให้เป็นคนละไดเรคทอรีกัน การทำ out-of-source build ช่วยให้เราหลีกเลี่ยงปัญหาข้างต้นทั้งสองข้อได้โดยสิ้นเชิง โดยแลกมากับการจัดระเบียบวิธีการเก็บไฟล์ใหม่ และการพิมพ์ค่ำสั่งเพิ่มอีกเล็กน้อยตอนเรียก CMake เท่านั้น

จัดระเบียบไฟล์ใหม่

เราอาจจัดระเบียบไฟล์เพื่อทำ out-of-source build โดยเอาซอร์สโค้ดทั้งหมดไปใส่ไว้ในไดเรคทอรีชื่อ src ซึ่งทำหน้าที่เป็น source directory และสร้างไดเรคทอรีว่างชื่อ build เพื่อทำหน้าที่เป็น build directory ดังนั้นสำหรับโปรเจค sample เราอาจจัดระเบียบไฟล์ใหม่ดังต่อไปนี้

 helloworld/
     build/
     src/
         CMakeLists.txt
         main.cpp

เรียก CMake จาก build directory

หลังจากนั้น เวลาเราจะสร้าง build script ก็ให้เปลี่ยนไดเรคทอรีไปยัง build:

 > cd helloworld/build

แล้วจึงสั่ง cmake แล้วให้ source directory เป็น argument:

 > cmake ../src

เมื่อสั่งแล้วไฟล์ build script ทุกอย่างจะถูกบรรจุอยุ่ใน build และเมื่อเราเรียก make (สมมติว่าเราเขียนโปรแกรมอยู่บนเครื่อง Mac) แล้วเราจะได้ไฟล์ helloworld อยู่ในไดเรคทอรี build ด้วย

หลังจากที่เราสั่ง cmake โดยให้ source directory เป็น argument ไปเป็นครั้งแรกแล้ว หากเราเข้าไปใน build directory อีกครั้งแล้วสั่ง cmake . อีกครั้ง CMake จะ update ไฟล์ใน build directory ใหม่โดยใช้ generator ตัวเดิม ทำให้เราไม่ต้องพิมพ์ตำแหน่งของ source directory อีกต่อไปเลย ทำให้เกิดความสะดวกขึ้นมาก

สร้าง build script สำหรับเครื่องมือหลายๆ เครื่องมือ

เราสามารถมี build directory ได้หลาย build directory ยกตัวอย่างเช่นหากเราต้องการใช้ Xcode ควบคู่ไปกับ Makefile เราอาจสร้างไดเรคทอรี helloworld/build_xcode และ helloworld/build_make สำหรับเป็น build directory ของเครื่องมือทั้งสอง ตามลำดับ