EST. 2026 — บันทึกงานเซิร์ฟเวอร์จริง SYSADMIN · SECURITY · AI · DIRECTADMIN เล่มที่ 01
THE SYSADMIN ALMANAC
หน้าหลัก / Web / Build APM บน Windows ตอนที่ 1: เตรียมเครื่องมือและแตก build kit
Web — Build APM บน Windows

Build APM บน Windows ตอนที่ 1: เตรียมเครื่องมือและแตก build kit

โดย Ton-Or ·22 ต.ค. 2026·อ่าน 14 นาที
Build APM บน Windows ตอนที่ 1: เตรียมเครื่องมือและแตก build kit

build ที่ล้มกลางทางเพราะเครื่องมือไม่ครบ เสียเวลามากกว่าการเตรียมเครื่องให้ถูกตั้งแต่ต้น ตอนนี้เลยเป็นตอนที่น่าเบื่อที่สุดของซีรีส์ แต่เป็นตอนที่ทำให้อีกหกตอนไม่พัง

พอดีผมเขียนซีรีส์นี้จากการ build จริงบนเครื่องของผมเมื่อวันที่ 22 ตุลาคม และข้อสรุปที่ผมได้ก่อนเริ่มเขียนคือ ความผิดพลาดที่แพงที่สุดไม่ได้อยู่ในขั้น compile แต่อยู่ในขั้นเตรียมเครื่อง เช่น ลง Visual Studio ไม่ครบ component เพราะมันจะไปโผล่ตอน build ผ่านไปแล้วราว 80 นาที ตอนนี้เลยเขียนละเอียดทุกคำสั่ง ทุกคำสั่งบอกว่ารันที่ terminal ไหน ผลที่ควรเห็นคืออะไร และตรวจอย่างไรว่าถูก ถ้ายังไม่ได้อ่านภาพรวมของซีรีส์ ให้เริ่มที่ สารบัญ Build APM บน Windows ก่อน

สิ่งที่ตอนนี้จะพาทำ คือติดตั้งเครื่องมือทั้งหมดที่ต้องมีเอง (ใช้สิทธิ์ admin รอบเดียว) แตก build kit ลง C:\apm-build แล้วอ่านทำความเข้าใจโครงสร้างของ kit กับสคริปต์กลางสามตัว คือ lib.ps1, build-all.ps1 และ build.cmd เมื่อจบตอนนี้ยังไม่มีอะไรถูก build เลย แต่เครื่องของคุณพร้อมแล้ว

ก่อนเริ่ม: เครื่องต้องมีอะไร และใครต้องเป็น admin

ตัวเลขด้านล่างมาจากเครื่องที่ผมใช้ทดสอบ (Windows 11, i5-12500H, RAM 32 GB) กับคำแนะนำขั้นต่ำจากการ build ครั้งแรก

60 GBพื้นที่ว่างขั้นต่ำ
16 GBRAM ที่แนะนำ
3-4 GBดาวน์โหลดรวม
1 รอบที่ต้องใช้สิทธิ์ admin
รายการ ขั้นต่ำ ที่ผมใช้ทดสอบ
ระบบปฏิบัติการ Windows 10/11 x64 Windows 11 x64
CPU 4 cores i5-12500H (16 threads)
RAM 8 GB (แนะนำ 16 GB ขึ้นไป) 32 GB
พื้นที่ว่าง 60 GB ใช้จริงประมาณ 45 GB
อินเทอร์เน็ต ต้องมีตลอด ดาวน์โหลดประมาณ 3-4 GB
สิทธิ์ admin เฉพาะตอนติดตั้งเครื่องมือ ตัว build ไม่ต้องใช้ admin

กฎเรื่องสิทธิ์มีข้อเดียวที่ต้องจำ คือ ทำสิ่งที่ต้องติดตั้งลงระบบ (ข้อ 1 ถึงข้อ 15) ใน Terminal (Admin) แล้วปิดมันทิ้ง ส่วนที่เหลือทุกอย่างในซีรีส์ รวมทั้งการ build ทั้งหมด ทำใน pwsh ปกติของ user เหตุผลคือการ build รันโค้ดที่ดาวน์โหลดมาเป็นชั่วโมง ถ้ารันด้วยสิทธิ์ admin แล้วมีอะไรผิดปกติ ความเสียหายจะกว้างกว่ามาก

ใครรันอะไร ด้วยสิทธิ์อะไรTerminal (Admin) · ทำครั้งเดียว1. Visual Studio 2022 Build Tools2. Git, CMake, Ninja, PowerShell 73. Defender exclusion (ไม่บังคับ)4. ปิด terminal นี้ทิ้งข้อ 1 ถึงข้อ 15 ในบทความนี้pwsh ปกติ · ทุกอย่างหลังจากนั้นแตก kit ลง C:\apm-build.\build.cmd (ประมาณ 2.5 ชม.).\deploy.cmdstart MariaDB และ Apacheข้อ 16 เป็นต้นไป และตอนที่ 2 ถึง 7ลงเครื่องมือเสร็จแล้วต้องเปิด terminal ใหม่ทุกครั้ง เพื่อให้ PATH ใหม่มีผล
สิทธิ์ admin ใช้แค่ครั้งเดียวตอนลงเครื่องมือ การ build ทั้งหมดรันเป็น user ปกติ

เรื่องตำแหน่งโฟลเดอร์ ซีรีส์นี้ใช้ C:\apm-build เป็นที่ build และ C:\APM เป็นที่ติดตั้ง ผมเองรันที่ไดรฟ์ D: ได้เหมือนกัน เพราะสคริปต์อ้างอิง path จากตำแหน่งของ kit เอง ถ้าไดรฟ์ C: ของคุณมีที่ว่างไม่ถึง 60 GB ให้วาง kit ไว้ไดรฟ์อื่นได้ แต่ทุกตัวอย่างในบทความจะเขียนเป็น C:\apm-build ให้คุณเปลี่ยนตามเอง ขอให้ใช้ path สั้น ไม่มีช่องว่าง และไม่มีภาษาไทย ผมไม่ได้ทดสอบ path ที่มีช่องว่าง เลยไม่รับรองว่าเครื่องมือทุกตัวใน build ทนได้ และ path ที่สั้นช่วยให้ไม่ชนเพดาน 260 ตัวอักษรของ Windows ตอนที่ ImageMagick clone repo นับสิบตัวลงไป

ติดตั้ง Visual Studio 2022 Build Tools (Terminal Admin)

Visual Studio Build Tools คือ compiler ของ Microsoft (MSVC) แบบไม่มีตัว IDE เหตุผลที่ต้องใช้ตัวนี้ ไม่ใช่ MinGW หรือ compiler อื่น คือ PHP ทางการ build ด้วย MSVC และเป็น ABI เดียวกัน ทั้ง Apache, MariaDB และ ImageMagick ที่ตามมาทดสอบกับ Build Tools 17.14 ที่มี MSVC 14.44 (toolset v143) ผมเลยใช้ตัวเดียวทั้งชุด และแนะนำให้ลงตามนี้

Visual Studio 2022 edition ไหนก็ได้ ขอให้มี C++ x64

สคริปต์ lib.ps1 หา Visual Studio ด้วย vswhere (ฟังก์ชัน Get-VsPath) รับ Visual Studio 2022 ทุก edition ไม่ว่าจะเป็น Build Tools, Community, Professional หรือ Enterprise และลงที่ path ไหนก็ได้ ขอแค่มี component VC.Tools.x86.x64 (MSVC v143 สำหรับ x64) และเป็นรุ่น 17.x ถ้ามี Visual Studio 2022 อยู่แล้ว ไม่ต้องลง Build Tools เพิ่ม แค่เติม component ตามข้อ 3 และข้อ 7 ให้ครบ (ATL และ MFC ขาดบ่อยที่สุด) ส่วนตัวผมยังแนะนำ Build Tools 17.14 เพราะเป็นชุดที่ผมทดสอบทั้งซีรีส์ ส่วน Visual Studio 2019 หรือรุ่น 18 ขึ้นไป สคริปต์จะไม่รับ

ข้อ 1 เปิด Terminal (Admin)

ที่ Windows 11 คลิกขวาที่ปุ่ม Start เลือก Terminal (Admin) แล้วกด Yes ที่หน้าต่าง UAC (ที่ Windows 10 ให้เลือก Windows PowerShell (Admin) แทน) ที่แถบชื่อหน้าต่างต้องมีคำว่า Administrator

ข้อ 2 ยืนยันว่าเป็น admin จริง

รันที่ Terminal (Admin) ที่ไหนก็ได้ (โฟลเดอร์ไม่มีผล)

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

ผลที่ต้องเห็นคือ True ถ้าเป็น False แปลว่าเปิดมาไม่ใช่ admin ให้ปิดแล้วทำข้อ 1 ใหม่

ข้อ 3 สั่ง winget ติดตั้ง Build Tools

รันที่ Terminal (Admin) คำสั่งนี้ยาวบรรทัดเดียว ให้ copy ทั้งบรรทัดตามที่เห็น

winget install --id Microsoft.VisualStudio.2022.BuildTools --exact --override "--quiet --wait --norestart --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --add Microsoft.VisualStudio.Component.VC.CMake.Project --add Microsoft.VisualStudio.Component.VC.ATL --add Microsoft.VisualStudio.Component.VC.ATLMFC --includeRecommended"

ส่วนที่อยู่ใน --override "..." คือ argument ที่ winget ส่งต่อให้ตัวติดตั้งของ Visual Studio โดยตรง ความหมายของแต่ละธง

ธง ทำอะไร
--quiet ไม่เปิดหน้าต่าง installer ตัวติดตั้งทำงานเงียบ ๆ เลยดูเหมือนค้าง ให้รอ อย่าปิด
--wait ให้คำสั่งรอจนติดตั้งเสร็จจริง ถึงจะคืน prompt
--norestart ห้ามรีสตาร์ตเครื่องเอง ถ้าจบแล้วมีข้อความให้รีสตาร์ต ให้รีสตาร์ตเองก่อนทำข้อ 4
--add ... เพิ่ม component ทีละตัว (ตารางถัดไป)
--includeRecommended ลง component ที่ติดมากับ workload แบบแนะนำด้วย

ส่วน component ที่ใส่ไปมีเหตุผลทุกตัว

component ใช้ทำอะไรใน APM
Workload.VCTools ชุด workload "Desktop development with C++" แบบเบา
VC.Tools.x86.x64 ตัวคอมไพเลอร์ MSVC v143 สำหรับ x64
Windows11SDK.26100 header และ lib ของ Windows SDK 10.0.26100
VC.ATL และ VC.ATLMFC ImageMagick ต้องใช้ เพราะ Configure.exe ของมันเป็นโปรแกรม MFC
VC.CMake.Project CMake และ Ninja สำรองที่มากับ VS

ผมไม่ได้เก็บ output ของ winget รอบนี้ไว้ และเวลาติดตั้งขึ้นกับความเร็วเน็ต เลยไม่มีตัวเลขเวลามาบอก สิ่งที่ตรวจได้แน่นอนคือผลในข้อ 4 ถึงข้อ 8 ถ้า winget ถามให้ยอมรับ agreement ของ source ให้พิมพ์ Y แล้วกด Enter ถ้า winget ไม่รู้จักเลย (คำสั่ง winget ไม่พบ) ให้ติดตั้ง App Installer จาก Microsoft Store ก่อน

ข้อ 4 ตรวจตำแหน่งที่ติดตั้ง

รันที่ Terminal (Admin) ที่ไหนก็ได้

& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -products * -property installationPath

ถ้าลงตามข้อ 3 ต้องเห็น path นี้ (ถ้ามี Visual Studio ตัวอื่นอยู่ในเครื่อง จะเห็นหลายบรรทัด ให้ดูว่ามีบรรทัดของรุ่น 2022 ถ้าใช้ edition อื่น ท้าย path จะเป็น 2022\Community หรือชื่อ edition นั้นแทน)

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools

ข้อ 5 ตรวจเวอร์ชัน compiler

Get-ChildItem "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" -Name

บนเครื่องใหม่จะเห็นโฟลเดอร์เดียว เช่น

14.44.35207

ถ้าใช้ edition อื่น ให้เปลี่ยน BuildTools ใน path เป็นชื่อ edition นั้น เลขอาจใหม่กว่านี้ได้ ขอให้ขึ้นต้นด้วย 14.4 เครื่องผมมีโฟลเดอร์เก่าติดมาหลายอันจากการลงในอดีต (14.16 และ 14.29) ซึ่งไม่มีปัญหา เพราะ vcvars64.bat เลือกตัวใหม่สุดให้เอง

ข้อ 6 ตรวจว่า vswhere หา Visual Studio เจอแบบเดียวกับที่สคริปต์หา

รัน query เดียวกับที่ lib.ps1 ใช้ ที่ Terminal (Admin) ที่ไหนก็ได้ (เก็บผลไว้ในตัวแปร $vs เพราะข้อ 7 ใช้ต่อ)

$vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -version '[17.0,18.0)' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
$vs

ต้องเห็น path ติดตั้งของ Visual Studio 2022 หนึ่งบรรทัด เช่น

C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools

path นี้คือรากที่ lib.ps1 ต่อท้ายด้วย \VC\Auxiliary\Build\vcvars64.bat เอง ถ้าได้บรรทัดว่าง แปลว่า vswhere ไม่เจอ Visual Studio 2022 ที่มี C++ x64 tools สคริปต์จะพ่น [ERR] Visual Studio 2022 with C++ x64 tools not found ให้ดูหัวข้อ "ถ้าตรวจแล้วขาด component" กับ "ถ้าพังตรงนี้"

ข้อ 7 ตรวจว่าลง ATL กับ MFC แล้ว

Test-Path "$vs\VC\Tools\MSVC\*\atlmfc\include\afx.h"

ต้องได้ True (ใช้ตัวแปร $vs จากข้อ 6 ถ้าเปิดหน้าต่างใหม่ ให้รันข้อ 6 ซ้ำก่อน) afx.h เป็น header หลักของ MFC ถ้ามีไฟล์นี้แปลว่า ATLMFC ถูกลงแล้ว ข้อนี้คือจุดที่คนพลาดบ่อยที่สุดเพราะ component นี้ไม่ได้มากับ workload พื้นฐาน

ข้อ 8 ตรวจ Windows SDK

Get-ChildItem "${env:ProgramFiles(x86)}\Windows Kits\10\Include" -Name

ในรายการต้องมีโฟลเดอร์ 10.0.26100.0 (เครื่องผมมี SDK รุ่นเก่ากว่าอีกสองตัวติดอยู่ด้วย คือ 10.0.10240.0 กับ 10.0.22621.0 ซึ่งไม่เป็นไร)

ถ้าตรวจแล้วขาด component

ถ้าข้อ 6 ถึงข้อ 8 ตัวใดตัวหนึ่งไม่ผ่าน อย่าลงใหม่ทั้งชุด ให้เปิด Visual Studio Installer จาก Start menu กด Modify ที่ Visual Studio 2022 ของคุณ (Build Tools หรือ edition อื่น) แล้วติ๊กรายการต่อไปนี้ให้ครบ จากนั้นกด Modify อีกครั้งที่มุมขวาล่าง

  • MSVC v143 - VS 2022 C++ x64/x86 build tools
  • Windows 11 SDK (10.0.26100)
  • C++ ATL for latest v143 build tools (x86 & x64)
  • C++ MFC for latest v143 build tools (x86 & x64)
  • C++ CMake tools for Windows

ติดตั้ง Git, CMake, Ninja, PowerShell 7 และตั้ง Defender (Terminal Admin)

ยังอยู่ใน Terminal (Admin) หน้าต่างเดิมต่อได้เลย แต่ละคำสั่งรันทีละบรรทัด รอให้จบก่อนสั่งตัวต่อไป

เครื่องมือแต่ละตัวมีหน้าที่ต่างกัน และมีตัวหนึ่งที่ซ่อนเหตุผลสำคัญอยู่

เครื่องมือ ใช้ทำอะไร
Git for Windows clone source ของ ImageMagick และของ vcpkg และที่สำคัญคือมี bash.exe ที่สคริปต์ของ ImageMagick ต้องเรียก
CMake 3.24 ขึ้นไป build Apache, APR และ MariaDB สคริปต์ใช้ --fresh ซึ่งมีตั้งแต่ 3.24 (ผมทดสอบกับ 4.1.2)
Ninja backend ที่เร็วของ CMake
PowerShell 7 (pwsh) รันสคริปต์ build ทุกตัว ต้อง 7.5 ขึ้นไป ไม่ใช่ Windows PowerShell 5.1 ที่มากับเครื่อง

ข้อ 9 ติดตั้ง Git

winget install --id Git.Git --exact

ข้อ 10 ติดตั้ง CMake

winget install --id Kitware.CMake --exact

ข้อ 11 ติดตั้ง Ninja

winget install --id Ninja-build.Ninja --exact

Ninja จาก winget เป็นแพ็กเกจแบบ portable ซึ่งติดตั้งเข้าโปรไฟล์ของผู้ใช้ที่รันคำสั่ง ถ้าบัญชี admin ที่คุณใช้เปิด Terminal (Admin) เป็นคนละบัญชีกับบัญชีที่ใช้ทำงานปกติ ninja จะไม่ไปอยู่ในบัญชีทำงานของคุณ ข้อ 18 จะจับกรณีนี้ได้ ถ้าเจอ ให้รันบรรทัดข้างบนซ้ำใน pwsh ปกติของบัญชีทำงาน (ไม่ต้องใช้ admin)

ข้อ 12 ติดตั้ง PowerShell 7

winget install --id Microsoft.PowerShell --exact

ข้อ 13 (แนะนำ) ยกเว้นโฟลเดอร์ build จากการสแกนของ Windows Defender

ระหว่าง build จะมีไฟล์ .obj และ .lib หลายหมื่นไฟล์เกิดขึ้น Defender จะสแกนทุกไฟล์ที่ถูกเขียน ทำให้ build ช้าลง 2 ถึง 3 เท่า ผมเลยสั่งให้ข้ามสามโฟลเดอร์ที่เป็นของ build โดยเฉพาะ คำสั่งนี้ต้องใช้ admin

Add-MpPreference -ExclusionPath "C:\apm-build\build","C:\apm-build\src","C:\apm-build\toolchain"

โฟลเดอร์ทั้งสามยังไม่มีในตอนนี้ ไม่ต้องสร้างก่อน สคริปต์จะสร้างให้ตอน build ถ้าคุณวาง kit ไว้ที่อื่น ให้เปลี่ยน path ในคำสั่งให้ตรง

นี่คือการแลกความปลอดภัยกับความเร็ว

โฟลเดอร์ที่ถูกยกเว้นจะไม่ถูกสแกน ผมเลือกยกเว้นเฉพาะสามโฟลเดอร์ที่มีแค่ source ที่ดาวน์โหลดและของที่ compile เอง ไม่ใช่ทั้งไดรฟ์ ถ้าไม่สบายใจ ข้ามข้อนี้ได้ ผลคือ build ช้าลง ไม่ใช่ล้ม เมื่อทำซีรีส์เสร็จและไม่ build บ่อย ให้ถอนออกด้วย Remove-MpPreference -ExclusionPath ตามด้วยสามโฟลเดอร์เดิม ถ้าเครื่องถูกคุมด้วยนโยบายองค์กร คำสั่งนี้อาจถูกปฏิเสธ ก็ข้ามไปได้เช่นกัน

ข้อ 14 ตรวจว่า Defender จดโฟลเดอร์แล้ว

(Get-MpPreference).ExclusionPath

ในรายการที่แสดง ต้องมีสามบรรทัดที่เราเพิ่งใส่ (ถ้าเครื่องมีรายการอื่นอยู่ก่อนก็จะเห็นปนกัน)

C:\apm-build\build
C:\apm-build\src
C:\apm-build\toolchain

ข้อ 15 ปิด Terminal (Admin)

exit

ปิดหน้าต่างนี้ทิ้งเลย ข้อต่อไปทั้งหมดไม่ใช้ admin และต้องเปิด terminal ใหม่เพราะ PATH ที่เพิ่มจากการติดตั้งจะไม่เข้าหน้าต่างที่เปิดค้างไว้ก่อนหน้า

เปิด pwsh ปกติ ตรวจเครื่องมือ และแตก build kit

ตั้งแต่ตรงนี้ไปเป็น user ปกติ ไม่มี admin

ข้อ 16 เปิด pwsh ปกติ

กดปุ่ม Start พิมพ์ pwsh เลือก PowerShell 7 (ไอคอนสีดำ ไม่ใช่ Windows PowerShell สีน้ำเงิน) แล้วเปิดแบบธรรมดา อย่าเลือก Run as administrator

ข้อ 17 ยืนยันว่าไม่ใช่ admin

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

คราวนี้ต้องได้ False ถ้าได้ True แปลว่าเปิดผิดหน้าต่าง

ข้อ 18 ตรวจเครื่องมือทั้งสี่ตัว

git --version; cmake --version; ninja --version; pwsh --version

ผลที่ผมได้ตอนทดสอบ (เลขของคุณอาจใหม่กว่านี้ ขอให้ตรงเงื่อนไข cmake 3.24 ขึ้นไป และ pwsh 7.5 ขึ้นไป)

git version 2.54.0.windows.1
cmake version 4.1.2
1.13.1
PowerShell 7.6.1

ถ้าบรรทัดไหนขึ้น "is not recognized" แปลว่า terminal นี้ยังไม่เห็น PATH ใหม่ ให้ปิดแล้วเปิดใหม่อีกครั้ง ถ้าเป็นแค่ ninja ให้ดูข้อ 11

ข้อ 19 ตรวจว่า Git มี bash.exe

Test-Path "C:\Program Files\Git\bin\bash.exe"

ต้องได้ True ตัวนี้ ImageMagick ใช้รัน clone-repositories.sh ในตอนที่ 5

ข้อ 20 ดาวน์โหลดและตรวจ build kit

ถ้าคุณทำตามสารบัญและดาวน์โหลดไว้แล้ว ข้ามไปข้อ 21 ได้ ถ้ายังไม่ได้ทำ รันสามบรรทัดนี้ใน pwsh ปกติ ที่ไหนก็ได้

curl.exe -L -o "$env:USERPROFILE\Downloads\apm-build-kit.zip" https://linuxthai.org/files/apm-build-kit.zip
(Get-Item "$env:USERPROFILE\Downloads\apm-build-kit.zip").Length
(Get-FileHash "$env:USERPROFILE\Downloads\apm-build-kit.zip" -Algorithm SHA256).Hash -eq '24BA604D8EE0F355F14C61C948C616FBDB9F97A0A75FC4955BCC64CD939D6206'

บรรทัดที่สองต้องพิมพ์ 48142 (ราว 47 KB) และบรรทัดที่สามต้องพิมพ์ True ถ้าไม่ตรง ให้ลบไฟล์แล้วโหลดใหม่ อย่าแตกไฟล์ที่ hash ไม่ตรง

ข้อ 21 แตกไฟล์ลงรากของไดรฟ์ C

Expand-Archive -Path "$env:USERPROFILE\Downloads\apm-build-kit.zip" -DestinationPath C:\

ใน zip มีโฟลเดอร์ชั้นนอกชื่อ apm-build-kit อยู่ ผลของคำสั่งนี้เลยเป็น C:\apm-build-kit ไม่ใช่ C:\apm-build ที่ซีรีส์นี้ใช้ ถ้าเจอ error ว่าไม่มีสิทธิ์สร้างโฟลเดอร์ที่ราก C:\ ให้แตกไปไดรฟ์อื่นแทน แล้วใช้ path นั้นตลอดซีรีส์

ข้อ 22 เปลี่ยนชื่อโฟลเดอร์

Rename-Item C:\apm-build-kit apm-build

ข้อ 23 ตรวจว่าไฟล์ครบ

Get-ChildItem C:\apm-build -Force | Select-Object Mode, Name, Length
(Get-ChildItem C:\apm-build -Recurse -File -Force).Count

คำสั่งแรกต้องเห็นรายการนี้ (ลำดับอาจต่างกัน) และคำสั่งที่สองต้องได้ 47

Mode  Name               Length
----  ----               ------
d---- deps
d---- ports-overlay
d---- scripts
d---- templates
d---- tools
-a--- build.cmd             507
-a--- deploy.cmd            610
-a--- .gitignore             53
-a--- LICENSE              2725
-a--- README.txt           1118
-a--- versions.json        2780
-a--- versions.lock.json   1083

ถ้าเห็นโฟลเดอร์ apm-build-kit ซ้อนอยู่ข้างใน C:\apm-build อีกชั้น แปลว่าแตกซ้อน ให้ลบ C:\apm-build แล้วทำข้อ 21 ถึงข้อ 22 ใหม่ เป้าหมายคือไฟล์ C:\apm-build\build.cmd ต้องมีอยู่จริง

ข้อ 24 ทดสอบว่าสคริปต์โหลด environment ของ compiler ได้

นี่คือการซ้อมสั้น ๆ ก่อนของจริง รันใน pwsh ปกติ โดยเข้าโฟลเดอร์ kit ก่อน

cd C:\apm-build
. .\scripts\lib.ps1
Enter-VsEnv
cl.exe 2>&1 | Select-String "Version"
(Get-Command cmake, ninja, git, cl | Select-Object -ExpandProperty Source)

บรรทัด . .\scripts\lib.ps1 (มีจุดนำหน้า เว้นวรรค แล้วตามด้วย path) คือการ dot-source เพื่อโหลดฟังก์ชันของ kit เข้ามาใน terminal นี้ และตอนโหลดนี้เองที่ Get-VsPath ถูกเรียกครั้งแรก ถ้าหา Visual Studio ไม่เจอ error จะโผล่ที่บรรทัดนี้เลย ไม่ต้องรอถึง Enter-VsEnv ผลที่ผมได้บนเครื่องผมเอง เลขเวอร์ชันของคุณอาจต่างเล็กน้อย

Microsoft (R) C/C++ Optimizing Compiler Version 19.44.35217 for x64

และคำสั่งสุดท้ายต้องแสดงตำแหน่งของ cmake, ninja, git และ cl.exe ครบทั้งสี่ ถ้า cl.exe อยู่ใต้ <path จากข้อ 6>\VC\Tools\MSVC\14.4x...\bin\HostX64\x64\ และ Enter-VsEnv ไม่พ่น error แปลว่าเครื่องพร้อมแล้ว

เมื่อทำข้อ 24 ผ่าน ปิด terminal นี้ได้ หรือเปิดไว้ใช้ต่อในตอนที่ 2 ก็ได้

ทัวร์โฟลเดอร์ของ kit และไฟล์ versions.json

kit ที่แตกแล้วมี 47 ไฟล์ ขนาดรวมราว 95 KB (zip ราว 47 KB) ประกอบด้วยไฟล์ที่ผมเขียนเองทั้งหมด ไม่มี source ของซอฟต์แวร์ใดอยู่ข้างใน สคริปต์จะไปดาวน์โหลดของจริงจากต้นทางเอง

ไฟล์หรือโฟลเดอร์ หน้าที่
build.cmd ทางเข้าหลัก เรียก scripts\build-all.ps1 แล้ว build ทั้งระบบลง stage\ (-From เริ่มกลางทาง -To หยุดหลังขั้นที่ต้องการ)
deploy.cmd เรียก scripts\90-deploy.ps1 ติดตั้ง stage\ ลง C:\APM (ไม่ start อะไร) มีสวิตช์ -ResetConfig กับ -Lan (ตอนที่ 7)
LICENSE สัญญาอนุญาตของสคริปต์ใน kit (MIT + Commons Clause) deploy คัดลอกเป็น C:\APM\LICENSE.txt
versions.json เวอร์ชัน url และ sha256 ของทุกอย่าง ไฟล์ที่ต้องแก้เมื่อมี security release
versions.lock.json hash ของแต่ละรายการที่ผมบันทึกไว้จากการ build รอบทดสอบ
scripts\ สคริปต์ PowerShell 13 ตัว เก้าตัวหลักที่ใช้ build (lib.ps1, build-all.ps1, 00-fetch, 10-deps-vcpkg, 20-apache, 25-imagemagick, 30-php, 40-mariadb, 90-deploy) กับสคริปต์ช่วยอีกสี่ตัวด้านล่าง
scripts\trust-ca.ps1 ให้ Windows ของ user นี้เชื่อ CA ของ APM จะได้ไม่มีคำเตือนใน browser (ไม่ใช้ admin)
scripts\new-cert.ps1 ออก cert เพิ่มให้ชื่อโฮสต์อื่น เช่น -Hosts myapp.localhost
scripts\firewall-lan.ps1 เปิด firewall ให้เครื่องในวง LAN เข้า Apache ได้ (ใช้ admin)
scripts\set-path.ps1 ใส่ php กับ mariadb client ของ APM เข้า PATH
templates\ ไฟล์ตั้งค่าต้นแบบ 5 ไฟล์ (httpd.conf, apm-ssl.conf, php.ini, my.ini, index.php)
deps\apache\vcpkg.json รายชื่อ library ที่ Apache ใช้ (manifest ของ vcpkg) พร้อม baseline
ports-overlay\openssl\ สูตร build OpenSSL 3.5 LTS ที่ใช้แทนตัว 3.6 ของ vcpkg
tools\mkcert.php ออก CA และ cert ของเครื่องด้วย extension openssl ของ PHP ที่เพิ่ง build

สี่สคริปต์ช่วยกับสวิตช์ของ deploy.cmd ใช้หลัง build เสร็จ ผมอธิบายวิธีใช้ทั้งหมดในตอนที่ 7 ตอนนี้แค่รู้ว่ามีอยู่ก็พอ

ส่วนโฟลเดอร์ต่อไปนี้ สคริปต์สร้างขึ้นเอง ตอนรัน และถูกกันออกจาก git ด้วย .gitignore

โฟลเดอร์ใต้ C:\apm-buildมากับ kit (ประมาณ 95 KB)build.cmdทางเข้า builddeploy.cmdทางเข้า deployversions.jsonเวอร์ชัน + sha256versions.lock.jsonhash ที่บันทึกไว้scripts\สคริปต์ 13 ตัวtemplates\ไฟล์ config 5 ไฟล์deps\รายชื่อ lib ของ vcpkgports-overlay\OpenSSL 3.5 LTStools\mkcert.phpสคริปต์สร้างให้ (รวมประมาณ 36 GB)downloads\600 MBtarball, ziptoolchain\3 GBphp-sdk, perl, nasmsrc\6 GBsource ที่แตกแล้วbuild\25 GBไฟล์ระหว่าง buildstage\1.5 GBผลลัพธ์deploy.cmdC:\APM (ประมาณ 650 MB)
kit เล็กมาก ส่วนที่ใหญ่คือสิ่งที่สคริปต์ดาวน์โหลดและ build ผลลัพธ์จริงมีแค่ stage\ ราว 1.5 GB ซึ่งเป็นสิ่งเดียวที่ deploy นำไปใช้

ขนาดที่เขียนไว้เป็นค่าโดยประมาณที่วัดหลัง build เสร็จ ถ้า build หลายรอบ build\ จะโตกว่านี้ ที่ว่างขั้นต่ำ 60 GB ที่ผมแนะนำเผื่อส่วนนี้ไว้แล้ว

อ่าน versions.json ให้เข้าใจก่อนแตะ

ไฟล์นี้ตัดสินว่าจะ build อะไรเวอร์ชันไหน ผมวางไฟล์ไว้ด้านล่างโดยย่อค่า sha256 ให้สั้นลงด้วยจุดสามจุดเพื่อให้อ่านง่าย ในไฟล์จริงของคุณทุกค่ายาวครบ 64 ตัวอักษร ห้าม copy บล็อกนี้ไปทับไฟล์จริง

{
  "apm_version": "1.0.0",
  "toolchain": {
    "php-sdk":      { "version": "2.8.4", "url": "https://github.com/php/php-sdk-binary-tools/archive/refs/tags/php-sdk-2.8.4.zip", "sha256": null, "dest": "toolchain/php-sdk", "strip": 1 },
    "strawberry":   { "version": "5.42.3.1", "url": "https://github.com/StrawberryPerl/...portable.zip", "sha256": null, "dest": "toolchain/strawberry", "strip": 0 },
    "nasm":         { "version": "3.01", "url": "https://www.nasm.us/pub/nasm/releasebuilds/3.01/win64/nasm-3.01-win64.zip", "sha256": null, "dest": "toolchain/nasm", "strip": 1 },
    "winflexbison": { "version": "2.5.25", "url": "https://github.com/lexxmark/winflexbison/...zip", "sha256": null, "dest": "toolchain/winflexbison", "strip": 0 }
  },
  "sources": {
    "php":       { "version": "8.4.27", "url": "https://www.php.net/distributions/php-8.4.27.tar.xz", "sha256": "dcf93923...d3f0" },
    "httpd":     { "version": "2.4.69", "url": "https://downloads.apache.org/httpd/httpd-2.4.69.tar.bz2", "sha256": "c5e6ebc6...c73d" },
    "apr":       { "version": "1.7.6",  "url": "https://downloads.apache.org/apr/apr-1.7.6.tar.bz2", "sha256": "49030d92...eb32" },
    "apr-util":  { "version": "1.6.5",  "url": "https://downloads.apache.org/apr/apr-util-1.6.5.tar.bz2", "sha256": "96de1dd6...92e2" },
    "mod_fcgid": { "version": "2.3.9",  "url": "https://archive.apache.org/dist/httpd/mod_fcgid/mod_fcgid-2.3.9.tar.bz2", "sha256": null, "sha1": "f0b6d87d...3945" },
    "mariadb":   { "version": "11.8.9", "url": "https://archive.mariadb.org/mariadb-11.8.9/source/mariadb-11.8.9.tar.gz", "sha256": "2e015b7e...6fc6" },
    "pecl-redis":    { "version": "6.3.0",  "url": "https://pecl.php.net/get/redis-6.3.0.tgz", "sha256": null },
    "pecl-igbinary": { "version": "3.2.16", "url": "https://pecl.php.net/get/igbinary-3.2.16.tgz", "sha256": null },
    "pecl-imagick":  { "version": "3.8.1",  "url": "https://pecl.php.net/get/imagick-3.8.1.tgz", "sha256": null },
    "imagemagick":   { "version": "7.1.2-34", "url": null, "sha256": null }
  },
  "php_deps_series": "8.4",
  "vs_toolset": "vs17",
  "arch": "x64"
}

ฟิลด์ที่ต้องรู้จักมีไม่กี่ตัว

  • apm_version: เลขรุ่นของชุด kit/APM เอง (ตอนนี้ 1.0.0) ไม่เกี่ยวกับเวอร์ชันของ Apache PHP หรือ MariaDB ที่ build ออกมา ใช้ระบุว่ากำลังใช้ kit รุ่นไหน ไม่ต้องแก้เมื่อมี security release
  • version และ url: เวอร์ชันและที่ดาวน์โหลด เปลี่ยนสองค่านี้พร้อม sha256 คือวิธีอัปเดตซอฟต์แวร์ตัวนั้น
  • sha256: ถ้าเป็นค่า hash สคริปต์จะบังคับให้ไฟล์ที่โหลดมาตรงกับค่านี้ ถ้าเป็น null แปลว่าต้นทางไม่ได้ประกาศ hash ไว้ จะใช้วิธี trust-on-first-use (ตอนที่ 2 เล่าละเอียด)
  • sha1 (เฉพาะ mod_fcgid): ต้นทางประกาศแค่ sha1 สคริปต์ตรวจให้อีกชั้น
  • dest และ strip: โฟลเดอร์ปลายทางของ toolchain กับจำนวนชั้นโฟลเดอร์นอกสุดที่ตัดทิ้งตอนแตกไฟล์ (เป็นค่าเดียวกับ tar --strip-components)
  • imagemagick มี url เป็น null เพราะไม่ได้โหลดเป็น tarball แต่ clone จาก git ที่ tag 7.1.2-34 (ตอนที่ 5)
  • php_deps_series และ vs_toolset: บอกชุด dependency ของ PHP team (8.4) กับ toolset ของ Visual Studio (vs17 คือ v143)

ส่วนไฟล์ versions.lock.json เก็บ hash ของทั้ง 13 รายการที่ผมบันทึกไว้จากการ build รอบทดสอบ ถ้าไฟล์ที่คุณโหลดมาไม่ตรงกับที่ผมโหลดไว้ สคริปต์จะหยุดทันที ตอนที่ 2 อธิบายกลไกนี้ ตอนนี้ยังไม่ต้องแก้อะไรทั้งสองไฟล์

lib.ps1, build-all.ps1 และ build.cmd ทำอะไร

สามไฟล์นี้เป็นโครงของทั้งระบบ ที่เหลือคือสคริปต์ของแต่ละขั้นซึ่งจะอ่านในตอนที่ 2 ถึง 7 ผมแสดงโค้ดครบทุกบรรทัดและเดินไปตามลำดับที่มันรัน

ลำดับการเรียกเมื่อสั่ง .\build.cmdbuild.cmdเช็กว่ามี pwshbuild-all.ps1-From / -To เลือกช่วงสคริปต์แต่ละขั้น ตามลำดับfetch vcpkg apache mariadb ...เรียกใช้ก่อน buildlib.ps1Enter-VsEnvvcvars64.batตั้ง PATH INCLUDE LIBcl.exe link.exeพร้อมใช้ใน processทุกอย่างอยู่ใน process pwsh เดียว ไม่แตะ PATH ของระบบ และตัด path ที่มีคำว่า xampp ออกจาก PATH ของ process
ไม่ต้องเปิด Developer Prompt เพราะ lib.ps1 โหลด environment ของ MSVC เข้า PowerShell ให้เอง

build.cmd

@echo off
rem build.cmd - build the whole APM stack (Apache, PHP 8.4, MariaDB, ImageMagick, libs) into stage\
rem   build.cmd                 full build
rem   build.cmd -From php       resume from a step: fetch vcpkg apache mariadb imagemagick php
setlocal
where pwsh >nul 2>&1 || (echo [ERR] PowerShell 7 ^(pwsh^) not found - see https://linuxthai.org/article/apm-build-windows-1-prepare-tools & exit /b 1)
pwsh -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\build-all.ps1" %*
exit /b %ERRORLEVEL%

ไฟล์นี้เล็กมาก มีสามอย่างที่ควรรู้ อย่างแรก where pwsh เช็กว่ามี PowerShell 7 ในเครื่องหรือไม่ ถ้าไม่มีจะพิมพ์ [ERR] PowerShell 7 (pwsh) not found พร้อมลิงก์ชี้มาที่บทความนี้ แล้วจบ (ให้ทำข้อ 12) อย่างที่สอง %~dp0 คือโฟลเดอร์ที่ไฟล์ build.cmd อยู่ ทำให้สั่งจากโฟลเดอร์ไหนก็ได้ อย่างที่สาม %* ส่ง argument ที่พิมพ์ตามหลัง เช่น -From php หรือ -To apache ต่อให้ build-all.ps1 และ -ExecutionPolicy Bypass ทำให้สคริปต์รันได้แม้ policy ของเครื่องจะห้ามสคริปต์ที่โหลดมาจากอินเทอร์เน็ต เฉพาะใน process นั้น

lib.ps1

# lib.ps1 - shared helpers (dot-source from build scripts)
# Any VS 2022 edition with the C++ x64 tools (Build Tools here, Enterprise on GitHub runners)
function Get-VsPath {
    $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
    $p = & $vswhere -latest -products * -version '[17.0,18.0)' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
    if (-not $p) { throw '[ERR] Visual Studio 2022 with C++ x64 tools not found (see https://linuxthai.org/article/apm-build-windows-1-prepare-tools)' }
    return $p
}
$Script:VcVars = "$(Get-VsPath)\VC\Auxiliary\Build\vcvars64.bat"

# Import the MSVC x64 developer environment into this PowerShell process (once).
function Enter-VsEnv {
    if ($env:VSCMD_ARG_TGT_ARCH -eq 'x64') { return }
    $vswhereDir = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"
    cmd /c "set `"PATH=$vswhereDir;%PATH%`" && `"$Script:VcVars`" >nul && set" | ForEach-Object {
        if ($_ -match '^([^=]+)=(.*)$') { [Environment]::SetEnvironmentVariable($Matches[1], $Matches[2]) }
    }
    # never let XAMPP binaries leak into a build
    $env:Path = ($env:Path -split ';' | Where-Object { $_ -and $_ -notmatch '(?i)xampp' }) -join ';'
    if (-not (Get-Command cl.exe -ErrorAction SilentlyContinue)) { throw '[ERR] MSVC environment not loaded' }
}

function Invoke-Step([string]$Name, [scriptblock]$Block, [string]$Log) {
    Write-Host "[..] $Name"
    & $Block *>> $Log
    if ($LASTEXITCODE) { Get-Content $Log -Tail 30; throw "[ERR] $Name failed rc=$LASTEXITCODE (log: $Log)" }
    Write-Host "[OK] $Name"
}

ฟังก์ชัน Get-VsPath (บรรทัดที่ 4 ถึง 9) เป็นส่วนที่หา Visual Studio ให้ มันเรียก vswhere.exe ซึ่ง Visual Studio Installer ติดตั้งไว้ที่ path ตายตัวใต้ Program Files (x86) ธงแต่ละตัวมีหน้าที่ดังนี้

ธงของ vswhere ความหมาย
-latest ถ้าเจอหลายตัว เอาตัวที่ใหม่สุด
-products * นับทุก edition (Build Tools, Community, Professional, Enterprise)
-version '[17.0,18.0)' เฉพาะ Visual Studio 2022 (รุ่น 17.x) ตัดรุ่น 18 ขึ้นไปทิ้ง
-requires ...VC.Tools.x86.x64 ต้องมี component คอมไพเลอร์ C++ x64 ติดตั้งอยู่จริง
-property installationPath พิมพ์เฉพาะ path ที่ติดตั้ง

ถ้า query ไม่ได้อะไรกลับมา (-not $p) ฟังก์ชัน throw ข้อความ [ERR] Visual Studio 2022 with C++ x64 tools not found พร้อมลิงก์มาที่บทความนี้ ถ้าเจอก็คืน path ออกไป

บรรทัดที่ 10 เอา path ที่ได้ไปต่อท้ายด้วย \VC\Auxiliary\Build\vcvars64.bat เก็บใน $Script:VcVars จุดที่ควรรู้คือบรรทัดนี้ทำงานตอน dot-source lib.ps1 ไม่ใช่ตอนเรียก Enter-VsEnv ดังนั้นถ้าไม่มี Visual Studio ที่ใช้ได้ error จะโผล่ทันทีที่โหลดสคริปต์ และนี่คือเหตุผลที่ข้อ 6 ให้รัน query เดียวกันนี้ตรวจก่อน ผลของมันคือ path เดียวกับที่สคริปต์จะใช้

ฟังก์ชัน Enter-VsEnv ทำงานเป็นขั้น ๆ ตามนี้

  1. ถ้าตัวแปร VSCMD_ARG_TGT_ARCH เป็น x64 อยู่แล้ว แปลว่าเคยโหลดไว้ใน process นี้ เลยออกทันที ทำให้เรียกซ้ำได้หลายรอบโดยไม่เสียเวลา
  2. รันคำสั่ง cmd /c ที่เรียก vcvars64.bat (path จาก $Script:VcVars) แล้วต่อด้วย set ซึ่งพิมพ์ตัวแปร environment ทั้งหมดที่ได้ออกมาเป็นบรรทัด NAME=VALUE (ที่ต้องทำผ่าน cmd เพราะ vcvars64.bat เป็น batch ที่ตั้งตัวแปรได้เฉพาะใน cmd ที่เรียกมัน ไม่ส่งผลกลับมาที่ PowerShell เอง) มีการเอา path ของ vswhere นำหน้า PATH ชั่วคราวเพราะ batch ของ VS ต้องใช้มัน
  3. PowerShell อ่านแต่ละบรรทัดด้วย regex ^([^=]+)=(.*)$ แล้วตั้งตัวแปรนั้นให้ process ของตัวเองด้วย SetEnvironmentVariable ผลคือ PATH, INCLUDE, LIB ของ MSVC ย้ายเข้ามาอยู่ใน pwsh นี้ ไม่แตะ environment ของระบบ
  4. ตัด path ใดก็ตามที่มีคำว่า xampp ออกจาก PATH ของ process เพื่อไม่ให้ php.exe, perl, หรือ DLL ของ XAMPP ถูกเรียกเข้ามาปนใน build โดยบังเอิญ
  5. สุดท้ายเช็กว่าหา cl.exe เจอ ถ้าไม่เจอ throw '[ERR] MSVC environment not loaded' ซึ่งเป็นข้อความที่คุณจะเห็นถ้าเจอ Visual Studio แต่โหลด environment แล้วยังไม่มี compiler เช่น ติดตั้งค้างครึ่งทาง

ฟังก์ชัน Invoke-Step ห่อคำสั่งที่ใช้เวลานานทุกคำสั่ง มันพิมพ์ [..] ชื่อขั้น แล้วรัน script block โดย *>> $Log ซึ่งต่อท้ายผลลัพธ์ ทุก stream (output, error, warning) ลงไฟล์ log แทนการพ่นเต็มจอ จากนั้นเช็ก $LASTEXITCODE ถ้าไม่ใช่ศูนย์ จะแสดง 30 บรรทัดสุดท้ายของ log แล้ว throw พร้อมบอก path ของ log ถ้าผ่านก็พิมพ์ [OK] ชื่อขั้น เลยตอน build คุณจะเห็นจอเงียบมาก มีแต่ [..] กับ [OK] เป็นช่วง ๆ รายละเอียดอยู่ใน build\logs\

build-all.ps1

# build-all.ps1 - full APM build in dependency order. Each step can also be run on its own.
#   pwsh -File scripts\build-all.ps1                  # everything into stage\
#   pwsh -File scripts\build-all.ps1 -From php        # resume from a step
#   pwsh -File scripts\build-all.ps1 -To apache       # stop after a step
param(
    [ValidateSet('fetch','vcpkg','apache','mariadb','imagemagick','php')][string]$From = 'fetch',
    [ValidateSet('fetch','vcpkg','apache','mariadb','imagemagick','php')][string]$To = 'php'
)
$ErrorActionPreference = 'Stop'
$steps = [ordered]@{
    fetch       = { & "$PSScriptRoot\00-fetch.ps1" }
    vcpkg       = { & "$PSScriptRoot\10-deps-vcpkg.ps1" }
    apache      = { & "$PSScriptRoot\20-apache.ps1" }
    mariadb     = { & "$PSScriptRoot\40-mariadb.ps1" }
    imagemagick = { & "$PSScriptRoot\25-imagemagick.ps1" }
    php         = { & "$PSScriptRoot\30-php.ps1" -Step all }   # after imagemagick: needs build\im-dev
}
$run = $false
foreach ($k in $steps.Keys) {
    if ($k -eq $From) { $run = $true }
    if (-not $run) { continue }
    $t = [Diagnostics.Stopwatch]::StartNew()
    Write-Host "==== $k ===="
    & $steps[$k]
    Write-Host ("==== {0} done in {1:N1} min ====" -f $k, $t.Elapsed.TotalMinutes)
    if ($k -eq $To) { break }
}

อ่านตามลำดับดังนี้

  1. param(...) รับพารามิเตอร์สองตัว คือ -From (ขั้นที่เริ่ม ค่าเริ่มต้น fetch คือเริ่มจากต้น) กับ -To (ขั้นที่หยุด ค่าเริ่มต้น php คือขั้นสุดท้าย) ทั้งสองรับได้เฉพาะหกชื่อในวงเล็บ (ValidateSet) พิมพ์ผิดจะ error ทันที
  2. $ErrorActionPreference = 'Stop' ทำให้ error ใด ๆ หยุดสคริปต์ทันที ถ้าสคริปต์ของขั้นไหน throw (อย่างที่ Invoke-Step ทำเมื่อคำสั่งล้ม) ทั้ง build-all จะหยุดตรงนั้น ไม่เดินต่อไปขั้นถัดไป
  3. $steps เป็น [ordered] hashtable ลำดับของหกขั้นเลยคงที่ ลำดับนี้เรียงตาม dependency ไม่ใช่ตามเลขไฟล์ ดูเอาเอง mariadb (40) มาก่อน imagemagick (25) เพราะ MariaDB ไม่พึ่งใคร ส่วน PHP อยู่หลัง ImageMagick เพราะต้องใช้ build\im-dev จากขั้นนั้นตามคอมเมนต์ในโค้ด
  4. ลูป foreach เดินทีละขั้น พอเจอชื่อที่ตรงกับ -From ก็ตั้ง $run = $true ขั้นก่อนหน้านั้นถูกข้ามด้วย continue ที่เหลือรันตามลำดับ
  5. แต่ละขั้นมี stopwatch จับเวลา พิมพ์ ==== ชื่อ ==== ตอนเริ่ม และ ==== ชื่อ done in X.X min ==== ตอนจบ ตัวเลขนาทีนี้คือที่มาของตารางเวลาในสารบัญ
  6. บรรทัดสุดท้ายในลูป if ($k -eq $To) { break } อยู่หลังจากขั้นนั้นรันจบแล้ว พอชื่อขั้นตรงกับ -To ลูปหยุดโดยขั้นนั้นรันครบก่อน เช่น -To apache รัน fetch vcpkg apache แล้วหยุด

ผลในทางปฏิบัติ ถ้าขั้นใดล้ม แก้ปัญหาแล้วรันต่อจากขั้นนั้นโดยไม่ต้องเริ่มใหม่ และถ้าอยากแบ่ง build เป็นช่วง (เช่น คืนนี้จบแค่ Apache) ใช้ -To หยุดหลังขั้นที่ต้องการ สองสวิตช์ใช้ร่วมกันได้

.\build.cmd -From php
.\build.cmd -To apache
.\build.cmd -From vcpkg -To mariadb

ข้อควรระวังหนึ่งอย่างเรื่อง PowerShell: การรันไฟล์ที่อยู่ในโฟลเดอร์ปัจจุบัน ต้องมี .\ นำหน้าเสมอ เพราะ pwsh ไม่ค้นโฟลเดอร์ปัจจุบันเป็นค่าเริ่มต้น และเครื่องที่ตั้งตัวแปร NoDefaultCurrentDirectoryInExePath=1 ไว้ cmd ก็ไม่ค้นเหมือนกัน

ถ้าพังตรงนี้

เป็นปัญหาของขั้นเตรียมเครื่องที่ผมไล่เจอ เรียงตามความน่าจะเป็น

อาการ สาเหตุ วิธีแก้
. .\scripts\lib.ps1 (หรือ build.cmd) พ่น [ERR] Visual Studio 2022 with C++ x64 tools not found vswhere หา Visual Studio 2022 ที่มี component VC.Tools.x86.x64 ไม่เจอ เช่น ยังไม่ได้ลง ลงไม่จบ ลง Visual Studio 2022 แต่ไม่ได้เลือก C++ หรือมีแค่รุ่น 2019 หรือรุ่น 18 ขึ้นไป ทำข้อ 3 หรือ Modify ใน Visual Studio Installer ให้มี MSVC v143 แล้วทำข้อ 6 ให้ได้ path ออกมา
Enter-VsEnv พ่น [ERR] MSVC environment not loaded เจอ Visual Studio แล้ว แต่โหลด vcvars64.bat แล้วยังไม่มี cl.exe เช่น ติดตั้งค้างครึ่งทาง ใช้ Repair หรือ Modify ใน Visual Studio Installer แล้วทำข้อ 24 ใหม่ ผมไม่ได้เจอกรณีนี้เองรอบนี้
ข้อ 6 ได้บรรทัดว่าง ไม่มี Visual Studio 2022 ที่มี C++ x64 tools ในเครื่อง หรือติดตั้งไม่จบ ทำข้อ 3 ซ้ำ หรือ Modify ผ่าน Visual Studio Installer
ข้อ 7 ได้ False ไม่ได้เลือก ATL/MFC component (หรือ $vs ว่างเพราะยังไม่ได้ทำข้อ 6 ในหน้าต่างนี้) Modify ใน Visual Studio Installer แล้วติ๊ก ATL กับ MFC ถ้าปล่อยไว้ จะมาล้มที่ขั้น ImageMagick ซึ่งอยู่ท้าย ๆ ผมไม่ได้เก็บข้อความ error ของกรณีนี้ไว้
winget ไม่รู้จักคำสั่ง ไม่มี App Installer ติดตั้ง App Installer จาก Microsoft Store แล้วเปิด terminal ใหม่
cmake, git หรือ pwsh ขึ้น "is not recognized" หลังลงแล้ว terminal ที่เปิดอยู่ไม่เห็น PATH ใหม่ ปิดแล้วเปิด terminal ใหม่ (ข้อ 15)
ninja ไม่พบ ทั้งที่ลงใน Terminal (Admin) แล้ว บัญชี admin เป็นคนละบัญชีกับบัญชีทำงาน ninja ไปอยู่ในโปรไฟล์ของบัญชี admin รัน winget install --id Ninja-build.Ninja --exact ซ้ำใน pwsh ปกติของบัญชีทำงาน
build.cmd ขึ้นว่า not recognized ใน pwsh ลืม .\ นำหน้า พิมพ์ .\build.cmd
build.cmd พิมพ์ [ERR] PowerShell 7 (pwsh) not found พร้อมลิงก์มาที่บทความนี้ ไม่มี pwsh ใน PATH ของ terminal นี้ ทำข้อ 12 แล้วเปิด terminal ใหม่
Add-MpPreference ถูกปฏิเสธ ไม่ใช่ admin หรือเครื่องถูกคุมด้วยนโยบายองค์กร ข้ามข้อ 13 ได้ build แค่ช้าลง
ไม่พบ C:\apm-build\build.cmd ทั้งที่แตกไฟล์แล้ว แตกซ้อนโฟลเดอร์ (C:\apm-build\apm-build-kit\...) ลบแล้วทำข้อ 21 ถึง 22 ใหม่
สคริปต์ขึ้นว่าห้ามรันสคริปต์ (execution policy) ตอนรัน .ps1 ตรง ๆ policy ของเครื่อง รันผ่าน .\build.cmd ซึ่งใส่ Bypass ให้ หรือต่อท้าย -ExecutionPolicy Bypass ใน pwsh ผมไม่ได้เจอกรณีนี้เองรอบนี้ ใส่ไว้เพราะ build.cmd ถูกเขียนมาเพื่อกันเรื่องนี้

มีอีกข้อหนึ่งที่ไม่ใช่ error แต่ควรรู้ ถ้าเครื่องคุณมี XAMPP อยู่ ไม่ต้องถอนก่อน Enter-VsEnv ตัด path ของ XAMPP ออกจาก PATH เฉพาะใน process ที่ build เอง และ APM ใช้พอร์ต 8080, 8443 และ 3307 เลยรันคู่กับ XAMPP ได้

เช็กลิสต์ก่อนไปตอนที่ 2

ทุกข้อต้องผ่านก่อนไปต่อ ถ้าข้อใดไม่ผ่าน ย้อนไปทำข้อที่อ้างถึง

  1. ข้อ 4 ถึง 8: vswhere แสดง path ของ Visual Studio 2022, มีโฟลเดอร์ MSVC 14.4x, ข้อ 6 ได้ path ออกมา (ไม่ว่าง), afx.h ได้ True และมี Windows SDK 10.0.26100.0
  2. ข้อ 9 ถึง 12: ติดตั้ง Git, CMake, Ninja, PowerShell 7 ครบ
  3. ข้อ 14: (Get-MpPreference).ExclusionPath มีสามโฟลเดอร์ (หรือผมเลือกข้ามข้อนี้โดยตั้งใจ)
  4. ข้อ 17 ถึง 19: pwsh ปกติได้ False ที่ตรวจ admin, git cmake ninja pwsh แสดงเวอร์ชันครบ และ bash.exe ของ Git ได้ True
  5. ข้อ 20 ถึง 23: zip ขนาด 48142 ไบต์ hash ตรง แตกแล้วมี C:\apm-build\build.cmd และนับไฟล์ได้ 47
  6. ข้อ 24: Enter-VsEnv ไม่ error, cl.exe รายงานเวอร์ชัน 19.44 สำหรับ x64 และ Get-Command เจอทั้งสี่โปรแกรม
  7. ยังไม่ได้รัน build.cmd เลย ตอนที่ 2 จะเริ่มรันขั้นแรกด้วยกัน
ไม่อยาก build เอง

ใครอยากได้ APM ไปใช้เลยโดยไม่ต้องคอมไพล์ ผมปล่อยตัวที่ build เสร็จแล้วไว้ที่ github.com/ChonLaWan/APM-Server โหลด APM-1.0.0-win64.zip (ราว 140 MB) จากหน้า Releases เทียบ sha256 กับไฟล์ .sha256 ที่แนบไว้ แตกไว้ที่ไหนก็ได้ แล้วเปิด manager\APMManager.exe ตัว Manager จะเลือกพอร์ต เขียน config ออก cert และสร้างฐานข้อมูลให้เอง มีปุ่ม Check for updates ที่โหลดรุ่นใหม่จาก Releases มาตรวจ sha256 แล้วแทน binary ให้ โดยไม่แตะ config ฐานข้อมูล และเว็บของเรา

ตอนที่ 2 จะรัน 00-fetch.ps1 กับ 10-deps-vcpkg.ps1 เป็นครั้งแรก ซึ่งเป็นช่วงที่เครื่องเริ่มทำงานหนักจริง ถ้าติดตรงไหนของตอนนี้ บอกได้เลยว่าข้อไหนและเห็น error อะไร เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ

อยากให้เราทำให้ไหม?

ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า

คุยเรื่องงานกับเรา

เคยเจองานแบบนี้ไหม? ติดตรงไหน?

มาแลกวิธีกันต่อในบอร์ด LinuxThai

→ คุยต่อในบอร์ด

ความคิดเห็น 0

ยังไม่มีความคิดเห็น — เป็นคนแรกเลย