ผลต่างระหว่างรุ่นของ "CMake"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
(หน้าที่ถูกสร้างด้วย 'CMake ([http://www.cmake.org/](http://www.cmake.org/) และ [http://en.wikipedia.org/wiki/Cmake](http://en.wikipedia.org/wiki/Cmake)) …')
 
 
(ไม่แสดง 12 รุ่นระหว่างกลางโดยผู้ใช้ 2 คน)
แถว 1: แถว 1:
CMake ([http://www.cmake.org/](http://www.cmake.org/) และ [http://en.wikipedia.org/wiki/Cmake](http://en.wikipedia.org/wiki/Cmake))
+
# [[CMake/Basics|การใช้ CMake เบื้องต้น]]
เป็นซอฟต์แวร์สำหรับสร้าง build script
+
# [[CMake/Multiple Targets|เมื่อโปรเจคมีหลาย "เป้าหมาย"]]
(ไฟล์ที่นิยามวิธีการคอมไพล์และลิงก์โปรแกรมและไลบรารีที่เขียนด้วยภาษา C++)
+
# [[CMake/config.h|config.h และการตรวจสอบแพลตฟอร์ม]]
ที่สามารถใช้ร่วมกับเครื่องมือพัฒนาโปรแกรมที่ได้รับความนิยมหลายๆ ตัว
+
# [[CMake/external libraries|การใช้ไลบรารีภายนอก กรณีศึกษา OpenGL และ GLUT]]
อาทิ 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](http://osxbook.com/book/bonus/ancient/whatismacosx//programming.html)
 
ซึ่งไม่ปรากฏอยู่ในแพลตฟอร์มอื่นๆ
 
 
 
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](http://en.wikipedia.org/wiki/Preprocessor_macro)
 
เพื่อให้คอมไพเลอร์เลือกใช้โค้ดส่วนที่ถูกต้อง ยกตัวอย่าง เช่น หากเราต้องการชื่อของไดเรคทอรีที่โปรแกรมทำงานอยู่ในปัจจุบัน
 
(current working directory ย่อว่า cwd) แล้ว
 
 
 
* ใน Linux และ Mac เราจะต้องใช้คำสั่ง `getcwd` ซึ่งอยู่ใน `unistd.h`
 
* แต่ใน Windows เราจะต้องใช้คำสั่ง `_getcwd` ซึ่งอยู่ใน `direct.h`
 
 
 
เนื่องจาก `cl` จะนิยามมาโคร `_WIN32` ก่อนคอมไพล์ไฟล์ทุกไฟล์ ดังนั้นเราสามารถเช็คได้ว่า
 
ตอนนี้โปรแกรมถูกคอมไพล์บน Windows หรือแพลตฟอร์มอื่นได้โดยการเช็คว่า `_WIN32` ถูกนิยามหรือไม่
 
ฉะนั้นเราสามารถเลือก include ไฟล์ที่ถูกต้องได้ดังนี้
 
 
 
{% highlight c %}
 
#ifdef _WIN32
 
#include <direct.h>
 
#else
 
#include <unistd.h>
 
#endif
 
 
 
{% endhighlight %}
 
 
 
ส่วนเวลาเรียกใช้คำสั่ง เราสามารถเขียนโค้ดต่อไปนี้ได้
 
 
 
{% highlight c %}
 
char *buffer;
 
#ifdef _WIN32
 
buffer = _getcwd(NULL, 0);
 
#else
 
buffer = getcwd(NULL, 0);
 
#endif
 
 
 
{% endhighlight %}
 
 
 
เครื่องมือและสภาพแวดล้อมที่แตกต่าง
 
----------------------------------
 
 
 
อย่างไรก็ดีการเขียน preprocessor macro ก็ยังไม่สามารถแก้ปัญหาได้ทั้งหมด
 
เนื่องจากคอมไพเลอร์ของแต่ละแพลตฟอร์มมีวิธีการเรียกใช้และการกำหนดออปชันที่แตกต่างกัน
 
นอกจากนี้ การคอมไพล์โปรแกรมภาษา C++ เป็นกระบวนการที่ซับซ้อน
 
ดังนั้นแพลตฟอร์มต่างๆ จึงมีเครื่องมือสำหรับกำหนดกระบวนการนี้เป็นของตัวเอง
 
 
 
ถึงแม้ว่าในปัจจุบัน [`make`](http://en.wikipedia.org/wiki/Make_%28software%29)
 
จะเป็นเครื่องมือมาตรฐานสำหรับการสร้างซอฟต์แวร์ภาษา C++ ในแพลตฟอร์มที่สืบเชื้อสายมาจาก
 
Unix ทั้งหลาย นอกจากนี้ใน Windows มี [`nmake`](http://msdn.microsoft.com/en-us/library/ms930369.aspx)
 
ให้ใช้ด้วย อย่างไรก็ดีการใช้ `make` ทำให้โปรแกรมเมอร์ต้องสละความสะดวกสบายของ IDE
 
ที่ตนถนัด (เนื่องจากผู้เขียนใช้งาน Visual C++ จนติด การต้องไปเขียน Makefile เองจึงเป็นเรื่องที่ทรมานยิ่ง)
 
 
 
แต่ปัญหาที่ใหญ่ที่สุดเกิดขึ้นเมื่อซอฟต์แวร์ที่เราสร้างใช้ไลบรารีภายนอกที่เราไม่ได้เขียนเอง
 
เนื่องจากแพลตฟอร์มต่างๆ มีที่เก็บไลบรารีที่แตกต่างกัน เช่น ใน Mac จะเก็บอยู่ในไดเรคทอรี
 
`/Library` ส่วนใน Unix อาจเก็บอยู่ที่ `/usr` หรือ `/usr/local`
 
ส่วนใน Windows นั้นไม่มีที่เก็บที่แน่นอน เป็นเรื่องของโปรแกรมเมอร์ที่จะต้องรู้ที่เก็บไลบรารีเอง
 
 
 
ในแพลตฟอร์ม Unix มีชุดของเครื่องมือที่เรียกว่า [`Autotools`](http://en.wikipedia.org/wiki/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 จาก[หน้าดาวน์โหลดของเวบไซต์อย่างเป็นทางการ](http://www.cmake.org/cmake/resources/software.html)
 
โดยเลือก installer ที่เหมาะสมกับแพลตฟอร์มที่คุณใช้
 
 
 
ผู้ใช้ Debian หรือ Ubuntu สามารถติดตั้ง CMake ผ่าน `apt-get` ได้ด้วยการสั่ง
 
 
 
> sudo apt-get cmake
 
 
 
ส่วนผู้ใช้ Mac ที่ใช้ [MacPorts](http://www.macports.org/) สามารถติดตั้งได้โดยการสั่ง
 
 
 
> 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` มีเนื้อหาตามธรรมเนียมดังนี้
 
 
 
{% highlight c++ %}
 
#include <stdio.h>
 
 
 
int main()
 
{
 
  printf("hello, world\n");
 
  return 0;
 
}
 
{% endhighlight %}
 
 
 
ไฟล์ `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 ของเครื่องมือทั้งสอง ตามลำดับ
 

รุ่นแก้ไขปัจจุบันเมื่อ 17:00, 12 พฤษภาคม 2553