Github Template Project

Template Project เป็นฟีเจอร์นึงที่ผมเพิ่งค้นพบว่า GitHub ทำได้! ซึ่งฟีเจอร์นี้เองก็ตามชื่อเลย มันคือการสร้างโปรเจคขึ้นมาเป็นเทมเพลต เพื่อเวลาที่เราสร้างโปรเจคใหม่เราจะได้ไม่ต้องเริ่มจากศูนย์ครับ เราสามารถที่จะเลือก template ที่เรามีเพื่อให้ github ใส่ไฟล์เริ่มต้นที่เราต้องการเข้าไปในโปรเจคใหม่เลยโดยที่ไม่ต้องเซ็ตอัพใหม่ อย่างเช่นโปรเจคนี้ผมเซ็ตให้ใช้เทมเพลตที่เป็นโปรเจคชื่อ sdl2-gl-project-template

ก็จะได้โปรเจคหน้าตาแบบนี้เลย ไม่ต้องมาเสียเวลาเซ็ตอัพโปรเจคใหม่อีก

ทั้งนี้การใช้ template จะแตกต่างกับการ clone โปรเจคอื่นเข้ามาเป็นโปรเจคตั้งต้นตรงที่โปรเจคใหม่จะไม่มี history ของโปรเจคที่เป็น template ติดมาด้วย ทำให้เราไม่ต้องมานั่งลบ history ออก ส่วนข้อเสียคือถ้าเรามีการแก้ไขเทมเพลตใหม่ เราจะ merge มาที่โปรเจคนี้ไม่ได้ (เพราะไม่ได้มี origin ที่เกี่ยวข้องกัน) แต่ผมว่า ณ.จุดนั้นโปรเจคใหม่เองก็น่าจะแตกต่างกับ template มากอยู่แล้ว ดังนั้นคงไม่ต้องกังวลอะไรครับ

การสร้างโปรเจคเป็นเทมเพลตเองก็ไม่ได้ยากอะไรครับ เราสร้างโปรเจคปรกติขึ้นมา แก้โค๊ด เพิ่มไฟล์อะไรให้เรียบร้อยตามที่ต้องการ จากนั้นก็เลือก template repository โปรเจคนี้ก็จะกลายเป็น template project ไปครับ

ลองดูครับ เหมาะกับคนที่เขียนโปรเจคเล็ก ๆ เยอะ ๆ จะได้ไม่ต้องมาเซ็ตอัพโปรเจคบ่อยๆ

ทั้งนี้เราสามารถที่จะเซ็ต git subproject ของ template ได้ เมื่อเราสร้างโปรเจคใหม่จาก template เราจะได้ subproject ติดมาด้วยครับ

อ้างอิง: GitHub

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 ที่เราต้องการได้เลยครับ

NAS ตัวใหม่ที่เข้าถึงได้ตลอดเวลา

เมื่อ 4 ปีก่อน ผมเปลี่ยน NAS มาเป็น Zyxel NSA325v2 ซึ่งพอคิด ๆ ไป 4 ปีมันก็เร็วเหมือนกันแฮะ จริง ๆ แล้วเจ้า Zyxel+Arch Linux ที่ใช้เองก็ใช้งานได้ดีไม่งอแงอะไรครับ แต่ว่าเราเริ่มรู้สึกว่ามันไม่ค่อยจะพอใช้แล้ว

เมื่อสักปลายปีที่แล้วผมเริ่มศึกษา Unreal Engine 4 จริงจัง แล้วเจอตออยู่อย่างคือขนาดโปรเจค โปรเจคของ UE ที่ผมทำอยู่มีขนาดราว ๆ 20-30GB ซึ่งถ้าไปใช้บริการฟรีอย่าง Github หรือ Bitbucket แล้วจะเจอแคปขนาดโปรเจคที่ 2GB เท่านั้น ถ้าอยากได้พื้นที่มากกว่านี้ก็ต้องจ่ายเพิ่ม แล้วพอจ่ายเพิ่มเองก็ได้แค่ราว ๆ 50GB เท่านั้น ก็ขึ้นอยู่กับเวลาเท่านั้นเองว่าขนาดโปรเจคมันจะไปได้ขนาดนั้นเมื่อไหร่

ผมก็เลยลองมองหาออปชันอื่นที่น่าจะทำให้เราทำงานได้ง่ายกว่า ก็พบว่า เอ๊ะแล้วถ้าเราใช้ NAS เราเป็น VCS ล่ะ NAS ตัวเก่าที่ผมใช้มีขนาดถึง 4TB ดังนั้นจะเอามาใช้เพื่อการนี้ย่อมไม่มีปัญหาอยู่แล้ว แต่ปัญหาอยู่ที่จะเข้าถึงได้อย่างไรมากกว่า

เข้าถึงได้ตลอดเวลา ผ่าน Zerotier

ออปชันแรกที่ผมดูคือการใช้ Dynamic DNS แต่เนื่องจากเนตเวิร์คที่บ้านเนี่ย IPv4 อยู่หลัง NAT เลยไม่สามารถเข้าถึงได้จากเนตเวิร์คส่วนใหญ่ครับ ดังนั้นออปชันนี้ก็เลยตกไป (ซึ่งจริง ๆ ก็ดีนะ เพราะวิธีนี้ไม่ค่อยปลอดภัยเท่าไหร่)

วิธีที่สองที่ดูคือการใช้ VPN แทน ซึ่งอันนี้โชคดีอย่างนึง คือมีคนสอนมาว่ามี service ที่ชื่อว่า Zerotier ซึ่งให้บริการ VPN ฟรี ตัวซอฟต์แวร์เป็น Open Source และมีการเข้ารหัสตลอดทาง สิ่งที่เราต้องทำคือสมัครเป็นสมชิกของบริการนี้ ติดตั้ง Client ที่ทุกเครื่องที่ต้องการเข้าถึง VPN สร้าง Network ในระบบขึ้นมาแล้วก็ Join ซะ (รายละเอียดจะไม่พูดถึงนะครับตรงนี้)

ปัญหาคือ ไอ้เจ้า Client เนี่ย มันไม่รองรับ NAS ตัวที่ผมใช้ครับ …

NAS เครื่องใหม่…หรือเครื่องเก่า

ผมตัดสินใจ … หรือเรียกว่าตัดใจก็ได้มั้ง? ที่จะเปลี่ยน NAS ใหม่อีกครั้ง ทั้ง ๆ ที่เครื่องเก่าก็ยังใช้งานได้ดี คราวนี้ไอเดียคือ เราจะให้มันรัน service มากกว่าแค่เป็น NAS และตัวดาวน์โหลด BitTorrent เจ้า NAS ตัวใหม่นี่จะเป็นตัวที่ดูแลเรื่องการพัฒนาซอฟต์แวร์และสามารถรันซอฟต์แวร์ที่เราเขียนขึ้นเพื่อใช้เองได้ด้วย ดังนั้นมันจะต้องเป็นเครื่องที่แรงพอสมควร

ในตอนแรกก็คิดว่าจะประกอบคอมขึ้นมาเพื่อการนี้โดยเฉพาะ แต่พอคิดเรื่องจำนวนเงินที่ต้องจ่าย … ผมก็ถอยไปออปชันที่สอง ก็คือไปเอาคอมเก่าของพี่ชายมาใช้ (พี่ชายผมทุกวันนี้ใช้แลปท็อปและไม่ค่อยเล่นเกมคอมแล้ว) แต่พอได้มาเสร็จเมนบอร์ดดันมาเสีย ก็เลยต้องเปลี่ยนเมนบอร์ด ผมมีซีพียูเก่าอยู่ (เป็น Core i5 4460) ก็เอามาใช้กับคอมเครื่องนี้

HDD เปลี่ยนใหม่ทั้งหมด เป็น WD RED 4TB x2 กับ Seagate Ironwolf 4TB สามตัวนี้เอามาต่อกันเป็น Software RAID5 ความจุรวม 8TB (ผมยังมี 2TB อีกสามตัว แต่ยังไม่ได้ใส่ เพราะว่าเคสไม่มีที่แล้ว)

Arch Linux OS เพื่อนเก่า

ตอนแรกเลยก็คิดว่า จะไปทาง NAS OS เต็มตัว ก็เลยติดตั้ง FreeNAS ไป แต่สุดท้ายก็ไม่ชอบ มันมีปัญหาอย่างนึงคือทุก Service ที่เราติดตั้งไปมันกลายเป็น VM ตัวใหม่ ดังนั้นถ้าเราจะใช้ Zerotier เราก็ต้องตามไปติดตั้งมันทุก VM (หรือตั้งค่าให้มัน route ผ่าน VM เครื่องนึงที่รัน Zerotier) จริง ๆ แล้วชอบ Web UI มันนะครับ ดูเหมือนทำงานด้วยสะดวก แต่มันไม่เข้ากับวิธีที่เราใช้ มันก็เลยต้องจากไป

ตัวเลือกต่อไปก็เลยเป็นตัวเลือกเก่าที่เราใช้บริการมานาน นั่นคือ Arch Linux ซึ่งสำหรับคนที่เคยใช้จะรู้ว่าการติดตั้งให้มันทำงานได้นั้นต้องใช้เวลาและความอดทนระดับนึง (เพราะต้องคอนฟิกทุกอย่างที่เราใช้) แต่พอผ่านจุดนึงไปแล้วเราแทบไม่ต้องไปยุ่งอะไรกับมันอีก

Service เดิมที่เคยใช้

Service เดิมที่ผมใช้ประจำ ก็คือ Samba กับ Transmission ซึ่งพอร่วมกับเครื่องที่สเปคสูงขึ้น มันก็รันเร็วขึ้นมากครับ

Samba ตอนนี้สามารถก็อปปี้ไฟล์ได้ด้วยความเร็วเฉี่ยว ๆ 100MB/s ซึ่งก็แทบจะติดเพดานของ Gigabit Ethernet แล้ว ส่วนตัว Transmission เองก็สามารถรองรับ torrent file ได้มากขึ้น ไม่มีอาการดีเลย์ตอนเปิดเครื่องละ

อ้อ ผมใช้ Nginx เป็น Web Server ซึ่งก่อนหน้านี้แทบไม่ได้ใช้อะไรจริงจัง แต่คราวนี้มันจะรับบทเป็นพระเอกในฐานะ Reverse Proxy Server ครับ

Service ใหม่ กับการรองรับกับการพัฒนาซอฟต์แวร์

สำหรับ Service ใหม่ ๆ ตัวแรกที่ผมติดตั้งก่อนเพื่อนคือ Gitea ตัวนี้เป็น Git Hosting Service ที่หน้าตาแทบจะลอก Github มาเลย (ฟีเจอร์ก็ใกล้เคียงกัน) ตัวนี้เขียนบน Go ครับ

Gitea in action

ตัวที่สองคือ Jenkins คือดู CI Server อยู่หลายตัว แล้วก็พบว่า สุดท้ายแล้วก็หนี Industry Standard ไม่พ้น

Jenkins

Jenkins มีหน้าที่บิลด์โค๊ดทุกครั้งที่ผม push อะไรเข้าไปใน Gitea แล้วหลังจากนั้นก็จะ Deploy Code ไปรันบนเครื่องทันที … ฟังดูดีใช่ไหมครับ ปัญหาคือแล้วจะรันยังไงล่ะ ???

ตอนแรกคือลืมคิดไปเลย เพราะว่าถ้าจะให้ Jenkins มันติดตั้งโปรแกรมที่ผมเขียนลงในเครื่องเนี่ย มันต้องมีสิทธิเทียบเท่า Root แล้วผมอ่านวิธี Deploy มันแล้วปวดหมองมาก (ฮา) ผมก็เลยไปเลือกใช้อีกออปชันนึงแทน นั่นคือ Docker เพราะว่ามันอยู่นอกเหนือตัว OS ระบบดังนั้น เราก็เลยไม่ต้องใช้สิทธิระดับ Root (ถึงแม้ว่า docker users จะมีสิทธิค่อนข้างสูงก็ตาม) ก็สามารถติดตั้งได้เหมือนกัน แล้วตอนรันก็แค่เรียก docker run เท่านั้นเอง

ซึ่งตอนนี้มีโปรแกรมนึงที่ผมเขียนด้วย go แล้วสร้างเป็น docker image เก็บไว้ในเครื่อง เป็นโปรแกรมที่จะดึง rss feed มาอ่านแล้วไปเรียก transmission เพื่อเพิ่มไฟล์ torrent ใหม่เข้าไปโดยที่ผมไม่ต้องมานั่งกดเอง โปรแกรมนี้จะตั้งให้รันหลังจากบูทเครื่องแล้ว 15 นาที และรันซ้ำทุกวันที่เวลาเดียวกัน การตั้งค่าให้รันตามเวลานี้ตั้งผ่าน systemd timer ครับ

ส่วนโปรแกรมอื่นเดี๋ยวคงตามมา ผมเริ่มทดลองสร้างอะไรแปลก ๆ ให้รันบนเครื่องนี้บ้างแล้วเหมือนกัน (หลัก ๆ ใช้ Go และ .Net Core) เอาไว้เดี๋ยวเอารูปมาโชว์ครับ แน่นอนว่าผมใช้คนเดียวไม่แบ่งใคร (ฮา)

Performance นอกบ้าน

อันนี้เป็นประเด็นหลักที่ย้ายเครื่องเลย (ฮา) ก็เลยต้องพูดถึงสักหน่อย

  • การก็อปปี้ไฟล์เข้าออกผ่าน Samba ก็ทำได้ถึงราว ๆ 30MB/s ครับ (ขึ้นกับเนตเวิร์คที่เราใช้ด้วย) ผมว่าไม่เลวนะ
  • การ clone/push-pull git อันนีได้ไม่สูงเท่า ก็ได้ราว ๆ 10MB/s (ขึ้นกับเนตเวิร์คเช่นเคย) ถ้าไม่ใช่โปรเจคใหญ่ก็ไม่มีปัญหามั้ง แต่ถ้าใหญ่หน่อยก็อาจจะต้องรอครับ แต่มันไม่ตัดนะ

ผมว่าความเร็วประมาณนี้ถือว่าโอเคนะ คือมันไม่เร็วเท่า Hosting แต่ราคาถูกกว่าแน่ ๆ

ปัญหาที่เจอ

มีปัญหาบ้างเล็กน้อย คือเหมือน Router จะมีปัญหาเวลารันไปนาน ๆ มันดันไปบล็อก zerotier เฉยเลย ก็รีสตาร์ท router ใหม่เท่านั้นเอง

อ้อ ค่าไฟน่าจะเพิ่มขึ้นพอสมควรครับ ห้องอาจจะร้อนบ้าง อันนี้ก็ต้องดูนิดนึง

สรุป

สรุปคือ เนื่องจาก NAS เก่าไม่ตอบโจทย์ความต้องการที่เปลี่ยนไป ผมก็เลยสร้างเครื่องใหม่ขึ้นมาแทน โดยมีสเปคโดยรวมสูงกว่ามาก นอกจากนี้ผมใช้ Zerotier เพื่อเข้าถึงบริการต่าง ๆ จากนอกบ้าน ผ่านระบบเครือข่ายเสมือน (VPN) ทำให้ไม่ต้องใช้ public ip และมีความปลอดภัยมากกว่าเพราะว่าไม่ได้เปิดให้คนภายนอกเข้าถึงได้ ความเร็วที่ใช้จากภายนอกก็ถือว่าไม่ได้เลวร้ายครับ ใช้ได้โอเคเลย

ผมติดตั้งซอฟต์แวร์ที่ใช้กับการพัฒนาซอฟต์แวร์มากขึ้น เป็นวง CI/CD ที่สมบูรณ์สำหรับซอฟต์แวร์เขียนใช้เองบางตัว แล้วตัว git ก็ใช้งานได้ดีกับเงื่อนไขที่เรามี ก็เลยไม่ต้องใช้ github ละ

ข้อเสียก็มีบ้าง ปัญหาก็มีบ้าง แต่โดยรวมกับสองสามเดือนที่ผ่านมาก็ถือว่าแฮปปี้ครับ