로그인
KO

내 러너에서 PHP micro 빌드하기 (standalone 워크플로)

bin/jumphp export:standalone과 app:export는 게임이나 앱을 micro에 붙여요. micro는 JumPHP에 필요한 확장을 넣어 정적으로 빌드한 PHP(StaticPHP)예요. micro는 워크플로 .github/workflows/standalone.yml이 빌드하고 릴리스 standalone-<key>로 게시해요 (key는 PHP 버전, 확장 목록, StaticPHP의 커밋, JumPHP의 레지스트리와 패치의 지문이에요: tools/standalone-key.sh). 그래서 micro는 이 중 하나가 바뀔 때만 다시 빌드돼요. 이 페이지에서는 이 워크플로를 내 러너에서 실행하는 방법(러너 설치는 ci-runner.md)과, GitHub의 머신이 공짜로 주던 것 중 내 머신에는 없을 수 있는 것을 설명해요.

실행하기

포지 > 저장소 > Actions > standalone > Run workflow, 또는 터미널에서(JumPHP 프로젝트에서 gh는 포지용이에요):

gh workflow run standalone.yml -f extensions=tools/app-extensions.txt -f macos=false -f linux=false
입력 값
extensions tools/standalone-extensions.txt(게임: SDL, OpenGL, OpenAL), tools/app-extensions.txt(데스크톱 앱, IDE), tools/hybrid-extensions.txt 빌드되는 micro = 자체 key
linux true / false false: Linux micro 없음(아래 "Docker" 참고). 이 경우 export:standalone이 사용자의 컴퓨터에서 Linux용을 빌드해요
macos true / false false: Mac micro 없음(데스크톱 앱만 해당). macOS 러너가 없으면 작업이 끝없이 기다려요

Windows 작업은 다운로드가 캐시돼 있으면 약 10분, 맨 처음에는 30~60분 걸려요. 결과물: https://<forge>/<소유자>/<저장소>/releases/download/standalone-<key>/micro-windows-x86_64.sfx.

GitHub의 머신에는 있었지만 내 머신에는 없을 수 있는 것

GitHub에서는 같은 워크플로가 "저절로 돌았는데", windows-latest와 ubuntu-latest가 GitHub가 미리 준비한 이미지이기 때문이에요. 내 러너는 아무것도 없는 머신이에요. 아래 항목은 워크플로가 처리하거나 여기서 안내해요.

GitHub의 이미지 내 러너 워크플로가 하는 일 / 내가 할 일
PowerShell 7(pwsh), PHP, Composer, Git 흔히 Windows PowerShell 5.1과 Git뿐 단계는 Windows PowerShell에서 실행돼요. PHP 8.4와 Composer가 없으면 내려받아요(php.net, getcomposer.org, 지문 확인). Git의 usr\bin이 PATH에 들어가요
영어 Windows 내 Windows의 언어(프랑스어 등) VSLANG=1033이 Visual Studio 도구가 영어로 출력하게 해요. PHP의 configure.js가 링커의 출력을 읽기 때문에, 그렇지 않으면 JScript 오류로 멈춰요
Visual Studio 2022 직접 설치해야 해요: Build Tools 2022, "C++를 사용한 데스크톱 개발" 워크로드 Windows 러너가 반드시 갖춰야 하는 유일한 것이에요(Git for Windows와 함께). install-windows-runner.ps1이 둘 다 설치해요
api.github.com에 빠르게 접근, 제한은 드묾 같은 API가 504나 "rate limit exceeded"를 반환 StaticPHP 다운로드는 4번 재시도하고 실행 사이에 %USERPROFILE%\.spc-downloads에 보관돼요. Composer는 소스에서 설치해요(--prefer-source)
actions/upload-artifact@v4, download-artifact@v4 Forgejo는 지원하지 않아요("not currently supported on GHES") 포지에서는 Windows 작업이 직접 micro를 릴리스에 게시해요(작업의 github.token, 포지의 API). release 작업은 GitHub에서만 돌아요
Linux 작업의 Docker 작업이 Docker 없는 컨테이너에서 실행돼요 아래 참고
LF 줄 바꿈 Git for Windows가 CRLF로 변환 StaticPHP를 클론하기 전에 git config --global core.autocrlf false(파일에 대한 패치가 그 텍스트에 의존해요)

Docker: 필요한 곳과 필요 없는 곳

  • Windows 작업은 Visual Studio로 네이티브 컴파일해요. Docker를 쓰지 않고, Windows 러너는 쓸 수도 없어요(Windows의 Linux 컨테이너는 WSL2를 거쳐요). 이를 위해 설치할 것은 없어요.
  • Linux 작업은 docker build docker/standalone을 실행한 뒤 StaticPHP의 docker run을 실행해요. 작업 컨테이너 안에는 Docker가 없어요. 러너가 제공하지 않는 한 말이죠. 호스트(또는 러너의 dind)의 Docker 소켓을 작업에 마운트하거나(러너 config.yml의 container.options / valid_volumes), WSL2 Linux 러너(ci-runner.md 4절)를 쓰세요. Docker가 있는 진짜 Linux예요. 그렇지 않으면 linux=false로 실행하세요. bin/jumphp export:standalone <id> --linux가 내보내는 컴퓨터에서 Linux micro를 빌드해요 (약 15분, 이후 ~/.jumphp/standalone/에 보관돼요).
  • 어떤 러너든 micro를 다른 key로 복사하거나 이름을 바꾸지 마세요. 올바른 확장이 없는 PHP가 되어 사용자의 실행 파일이 충돌해요(Call to undefined function SDL_Init()). key가 바뀌었다면 micro를 다시 빌드해야 해요.

문제 해결

작업 로그는 포지의 실행 페이지(작업 > 빨간 단계)에서 볼 수 있어요. 포지의 API는 로그를 돌려주지 않아요.

증상 원인 / 해결
key 작업이 "Fetching the repository" 직후 30초 만에 실패 작업 컨테이너가 포지의 이름을 해석하지 못해요. 러너의 Docker-in-Docker에 외부로 나가는 DNS가 없어요. 러너의 compose 파일에서 dind 서비스에 dns: [1.1.1.1, 9.9.9.9]를 지정해 주세요. 테스트: docker run --network <새 네트워크> node:20-bookworm getent hosts <forge>
Cannot find: pwsh in PATH 워크플로는 Windows PowerShell(shell: powershell)을 요구해요. 예전 사본은 pwsh를 요구했어요. 업데이트하세요
"Checking for link.exe" 다음에 configure.js ... Erreur d'exécution Microsoft JScript Visual Studio 도구가 Windows의 언어로 출력해요. VSLANG=1033(이 페이지 이후 워크플로에 들어 있어요)
ERROR: bison is required 같은 폴더에서 빌드가 중간까지만 된 뒤에 나타나요. StaticPHP가 msys2 도구는 남기지만 PATH에는 다시 넣지 않아요. 작업 공간의 spc/pkgroot, spc/source, spc/buildroot를 지우고 다시 실행하세요(새 작업처럼 깨끗한 작업 공간이면 돼요)
StaticPHP 패치 "not patched (StaticPHP changed)" 또는 "Failed patch module" CRLF 줄 바꿈(core.autocrlf false로 설정하고 다시 클론), 또는 이전 시도에서 이미 패치된 소스 폴더(spc/source/php-src를 지우세요)
Failed to get GitHub release API info for madler/zlib / HTTP/2 504 api.github.com이 내 주소에 대해 제한하거나 실패해요. 워크플로가 재시도해요. 새 머신에서 첫 실행은 한 번 더 시도해야 할 수 있어요. 다운로드는 보관되므로 시도할 때마다 더 멀리 가요
GHESNotSupportedError: upload-artifact@v4 ... not currently supported Forgejo를 쓰고 있어요. 이 저장소의 워크플로를 쓰세요(아티팩트 없이 게시해요)
macOS 작업이 "waiting"에 머물고 실행이 끝나지 않음 macOS 러너가 없어요: -f macos=false
Cannot find path ...\buildroot\bin\micro.sfx 빌드가 앞에서 실패했어요. 위쪽 줄을 읽어 보세요(그게 원인이에요)

AI 에이전트에게

"내 러너에서 standalone 워크플로가 동작하게 해 줘"라는 요청을 받을 수 있어요. 실행 페이지에서 실패한 단계를 읽고(접근할 수 없으면 사용자에게 붙여 넣어 달라고 하세요), 사용자의 머신이 아니라 워크플로를 수정하세요(GitHub에서도 계속 유효해야 해요: github.server_url을 테스트하세요). 단, 빠져 있는 것이 위의 전제 조건(Git, Visual Studio Build Tools, Linux 작업용 Docker)이라면 사용자에게 알리고, 사용자가 승낙할 때만 설치하세요. 러너를 등록하지 말고, 토큰을 파일에 쓰지 말고, 이 워크플로의 명령으로 현재 파일에서 빌드하지 않은 micro를 게시하지 말고, 릴리스를 다른 key로 옮기지 마세요. 실행에 성공한 뒤에는 파일을 확인하고 (gh release view standalone-<key>, 200으로 응답하는 다운로드), Windows micro라면 러너의 머신에서 그것으로 스크립트를 실행해 보세요 (copy /b micro.sfx + test.php test.exe, 그다음 test.exe: PHP 버전, extension_loaded('ffi')……).