내 러너에서 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')……).