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 ครั้งแรก
| รายการ | ขั้นต่ำ | ที่ผมใช้ทดสอบ |
|---|---|---|
| ระบบปฏิบัติการ | 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 แล้วมีอะไรผิดปกติ ความเสียหายจะกว้างกว่ามาก
เรื่องตำแหน่งโฟลเดอร์ ซีรีส์นี้ใช้ 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) ผมเลยใช้ตัวเดียวทั้งชุด และแนะนำให้ลงตามนี้
สคริปต์ 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
ขนาดที่เขียนไว้เป็นค่าโดยประมาณที่วัดหลัง 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 releaseversionและ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 ที่ tag7.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.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 ทำงานเป็นขั้น ๆ ตามนี้
- ถ้าตัวแปร
VSCMD_ARG_TGT_ARCHเป็นx64อยู่แล้ว แปลว่าเคยโหลดไว้ใน process นี้ เลยออกทันที ทำให้เรียกซ้ำได้หลายรอบโดยไม่เสียเวลา - รันคำสั่ง
cmd /cที่เรียกvcvars64.bat(path จาก$Script:VcVars) แล้วต่อด้วยsetซึ่งพิมพ์ตัวแปร environment ทั้งหมดที่ได้ออกมาเป็นบรรทัดNAME=VALUE(ที่ต้องทำผ่าน cmd เพราะvcvars64.batเป็น batch ที่ตั้งตัวแปรได้เฉพาะใน cmd ที่เรียกมัน ไม่ส่งผลกลับมาที่ PowerShell เอง) มีการเอา path ของvswhereนำหน้า PATH ชั่วคราวเพราะ batch ของ VS ต้องใช้มัน - PowerShell อ่านแต่ละบรรทัดด้วย regex
^([^=]+)=(.*)$แล้วตั้งตัวแปรนั้นให้ process ของตัวเองด้วยSetEnvironmentVariableผลคือ PATH, INCLUDE, LIB ของ MSVC ย้ายเข้ามาอยู่ใน pwsh นี้ ไม่แตะ environment ของระบบ - ตัด path ใดก็ตามที่มีคำว่า
xamppออกจาก PATH ของ process เพื่อไม่ให้ php.exe, perl, หรือ DLL ของ XAMPP ถูกเรียกเข้ามาปนใน build โดยบังเอิญ - สุดท้ายเช็กว่าหา
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 }
}
อ่านตามลำดับดังนี้
param(...)รับพารามิเตอร์สองตัว คือ-From(ขั้นที่เริ่ม ค่าเริ่มต้นfetchคือเริ่มจากต้น) กับ-To(ขั้นที่หยุด ค่าเริ่มต้นphpคือขั้นสุดท้าย) ทั้งสองรับได้เฉพาะหกชื่อในวงเล็บ (ValidateSet) พิมพ์ผิดจะ error ทันที$ErrorActionPreference = 'Stop'ทำให้ error ใด ๆ หยุดสคริปต์ทันที ถ้าสคริปต์ของขั้นไหนthrow(อย่างที่Invoke-Stepทำเมื่อคำสั่งล้ม) ทั้ง build-all จะหยุดตรงนั้น ไม่เดินต่อไปขั้นถัดไป$stepsเป็น[ordered]hashtable ลำดับของหกขั้นเลยคงที่ ลำดับนี้เรียงตาม dependency ไม่ใช่ตามเลขไฟล์ ดูเอาเองmariadb(40) มาก่อนimagemagick(25) เพราะ MariaDB ไม่พึ่งใคร ส่วน PHP อยู่หลัง ImageMagick เพราะต้องใช้build\im-devจากขั้นนั้นตามคอมเมนต์ในโค้ด- ลูป
foreachเดินทีละขั้น พอเจอชื่อที่ตรงกับ-Fromก็ตั้ง$run = $trueขั้นก่อนหน้านั้นถูกข้ามด้วยcontinueที่เหลือรันตามลำดับ - แต่ละขั้นมี stopwatch จับเวลา พิมพ์
==== ชื่อ ====ตอนเริ่ม และ==== ชื่อ done in X.X min ====ตอนจบ ตัวเลขนาทีนี้คือที่มาของตารางเวลาในสารบัญ - บรรทัดสุดท้ายในลูป
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
ทุกข้อต้องผ่านก่อนไปต่อ ถ้าข้อใดไม่ผ่าน ย้อนไปทำข้อที่อ้างถึง
- ข้อ 4 ถึง 8:
vswhereแสดง path ของ Visual Studio 2022, มีโฟลเดอร์ MSVC 14.4x, ข้อ 6 ได้ path ออกมา (ไม่ว่าง),afx.hได้ True และมี Windows SDK 10.0.26100.0 - ข้อ 9 ถึง 12: ติดตั้ง Git, CMake, Ninja, PowerShell 7 ครบ
- ข้อ 14:
(Get-MpPreference).ExclusionPathมีสามโฟลเดอร์ (หรือผมเลือกข้ามข้อนี้โดยตั้งใจ) - ข้อ 17 ถึง 19: pwsh ปกติได้
Falseที่ตรวจ admin,gitcmakeninjapwshแสดงเวอร์ชันครบ และbash.exeของ Git ได้ True - ข้อ 20 ถึง 23: zip ขนาด 48142 ไบต์ hash ตรง แตกแล้วมี
C:\apm-build\build.cmdและนับไฟล์ได้ 47 - ข้อ 24:
Enter-VsEnvไม่ error,cl.exeรายงานเวอร์ชัน 19.44 สำหรับ x64 และGet-Commandเจอทั้งสี่โปรแกรม - ยังไม่ได้รัน
build.cmdเลย ตอนที่ 2 จะเริ่มรันขั้นแรกด้วยกัน
ใครอยากได้ 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 ดาวน์โหลด source และ build lib ของ Apache ด้วย vcpkg
ตอนที่ 2 จะรัน 00-fetch.ps1 กับ 10-deps-vcpkg.ps1 เป็นครั้งแรก ซึ่งเป็นช่วงที่เครื่องเริ่มทำงานหนักจริง ถ้าติดตรงไหนของตอนนี้ บอกได้เลยว่าข้อไหนและเห็น error อะไร เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ
อยากให้เราทำให้ไหม?
ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



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