VCPKG ระบบจัดการแพคเกจ จากทีม Visual C++

หลาย ๆ คนที่เคยใช้ Linux เนี่ย ไม่ว่าจะเป็น Debian, Redhat หรือ Arch จะคุ้นเคยกับการใช้ระบบ package management system ในการติดตั้ง software ต่าง ๆ รวมทั้งการติดั้ง library สำหรับใช้ในโปรเจคภาษา C หรือ C++ ด้วย ซึ่งมันติดตั้งได้ง่ายมาก แค่คำสั่งหนึ่งบรรทัดมันก็ติดตั้งได้ละ

ในหลายภาษาเองก็มีการจัดการ package สำหรับ library เป็นของตัวเอง อย่าง go get หรือ npm install เป็นต้น

แต่ ใน C++ นั้นไม่มีวิธีการจัดการในตัวมันเอง ยิ่งถ้าเราใช้ระบบปฎิบัติการอย่าง Windows ที่ก็ไม่มีระบบจัดการแพคเกจ (อย่างเป็นทางการ) เป็นของตัวเอง ก็จะยิ่งเหนื่อยหน่อย เวลาเซ็ตอัพโปรเจคทีก็ต้องมานั่งดาวน์โหลด Library มาเซ็ต path และอื่น ๆ ก็รู้สึกว่าน่าเบื่อใช่ไหมครับ

วันนี้เราขอเสนอ หนึ่งในทางเลือก package management ของ C++ ที่ชื่อว่า VCPKG

VCPKG จาก Microsoft

VCPKG เป็นตัวจัดการแพคเกจจาก Microsoft ที่ทำงานได้ทั้งบน Windows, MacOS และ Linux มันเป็นตัวจัดการ library ที่ทำงานบน command line ทั้งนี้หลังจากติดตั้งเสร็จ เราจะทำให้มันทำงานร่วมกับ Visual Studio ได้เลย โดยตัว package ที่ติดตั้งมาจะถูกพบโดย Visual Studio ทำให้เราไม่ต้องตั้งค่าวุ่นวายอีก

นอกจากนั้น ตัว vcpkg สามารถทำงานร่วมกับ CMAKE ได้อีกด้วย (แต่เดี๋ยวจะพูดถึงตรงนี้อีกทีทีหลังครับ)

การติดตั้ง VCPKG

การติดตั้งนั้นง่ายมาก วิธีติดตั้งทำตามบน github ได้เลย ซึ่งจริง ๆ บน Windows ก็ทำแค่

> git clone https://github.com/Microsoft/vcpkg.git
> cd vcpkg
> .\bootstrap-vcpkg.bat
> .\vcpkg integrate install

แค่นั้นเอง

ติดตั้ง package บน VCPKG

ตัว package ต่าง ๆ สามารถติดตั้งได้ง่าย ๆ ด้วยคำสั่ง vcpkg install <packagename> เช่น vcpkg install sfml เป็นต้น

VCPKG จะทำการดาวน์โหลดซอร์สโค๊ดของ package ทั้งที่เราเป็นคนใส่ และ dependency ทั้งหมดของ package ที่เราเลือก (ถ้ายังไม่มีแพคเกจดังกล่าวในระบบ) จากนั้นมันจะทำการ build package ทั้งหมดในเครื่องเรา และติดตั้งไปใน directory ของมันเอง

การใช้งานใน Visual Studio

อันนี้ง่ายมาก คือ library ที่เราติดตั้งเนี่ยครับ เราสามารถ #include ได้เลย ไม่ต้องแก้อะไรอีก และเมื่อ #include แล้ว VS จะ link library ที่เราใช้ให้อัตโนมัติ

อย่างอันนี้ผมแค่สร้างโปรเจคใหม่ขึ้นมา เพิ่มไฟล์ใหม่เข้าไป แล้วก็สั่ง build ใช้งานได้เลย ง่ายมาก

การใช้งานกับ CMake

สำหรับโปรเจคที่เป็น CMake เนี่ย เราจะสร้างไฟล์ CMakelist.txt โดยนอกจากที่เราจะเพิ่มไฟล์เข้าไปในโปรเจคแล้ว เราก็จะเพิ่มพวกคำสั่ง find_package() กับ target_link_libraries() เข้าไปอีกหน่อยนึง โดยตอนที่เราติดตั้งแพคเกจ vcpkg จะแนะนำว่าให้ใส่อะไรลงไปบ้าง ….

-- Performing post-build validation done
Building package sfml[core]:x64-windows... done
Installing package sfml[core]:x64-windows...
Installing package sfml[core]:x64-windows... done
Elapsed time for package sfml:x64-windows: 35.96 s

Total elapsed time: 3.321 min

The package sfml:x64-windows provides CMake targets:

    find_package(SFML CONFIG REQUIRED)
    # Note: 7 target(s) were omitted.
    target_link_libraries(main PRIVATE FLAC OpenAL OpenGL Vorbis)

อย่างอันนี้ผมติดตั้ง SFML มันก็จะแนะนำมาเลยว่า ต้องใส่ find_package(SFML CONFIG REQUIRED) กับ target_link_libraries(main PRIVATE FLAC OpenAL OpenGL Vorbis) ใน CMakelists.txt นะ

แต่กรณีของ SFML เนี่ยคนที่เขาทำ package เขาเหมือนจะลืมบอกเรื่องของ module ไปครับ เราก็ต้องไปใส่ให้มันครบ (ฮา) ก็จะวุ่นวายหน่อยนึง อย่างไฟล์ CMakelists.txt ของผมจะมีหน้าตาประมาณนี้ ถึงจะบิลด์โปรเจคผ่าน

cmake_minimum_required(VERSION 3.15)

project(testSFML)

add_executable(main "main.cpp")

find_package(SFML CONFIG COMPONENTS system window graphics REQUIRED)
target_link_libraries(main PRIVATE FLAC OpenAL OpenGL Vorbis sfml-graphics)

ถึงจุดนี้ ถ้าสมมติว่าผมใช้ Visual Studio ผมสามารถที่จะเปิดโปรเจคนี้โดยการเลือก File > Open > Folder... แล้ว Visual Studio ก็จะเปิดโปรเจคขึ้นมาด้วยตัว CMake Support ของ VS เอง

หรือถ้าจะไม่ใช้ Visual Studio CMake Support เราก็สามารถใช้ CMake เพื่อสร้างตัว Build File ด้วยวิธีปรกติครับ แต่จะต้องใช้ CMake Toolchain file ของ VCPKG ด้วย option -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake

ซึ่งถ้าจำไม่ได้ว่าไฟล์อยู่ไหน ให้ลองรัน vcpkg integrate install มันจะแสดงคำสั่งนี้ขึ้นมาให้ครับ

“Triplet”

Triplet เป็นคอนเซพท์ของ VCPKG ที่เหมือน platform ต่าง ๆ ที่ VCPKG รองรับ โดยก็จะมีส่วนของ isa และส่วนของ os เช่น x86-windows หรือ x64-windows ซึ่ง ถ้าโปรเจคที่เราทำงานด้วยนั้นใช้ target ที่ไม่ตรงกับ triplet ที่เราติดตั้ง โปรเจคเราก็จะ build ไม่ผ่านครับ

ทีนี้ ตอนที่เราติดตั้ง package เราสามารถระบุได้เลยว่าจะใช้ triplet ไหน โดยใช้ : คั่นระหว่าง package และ triplet

เช่น vcpkg install sfml:x86-windows

ซึ่งถ้าเราไม่ระบุ มันจะใช้ค่า default โดยค่า default บน Windows ก็จะเป็น x86-windows แต่เราสามารถเพิ่ม environment variable ชื่อว่า VCPKG_DEFAULT_TRIPLET เพื่อเปลี่ยนตัว default เป็น triplet ที่เราต้องการได้เลยครับ