Post

[Techris] 7. Techris의 배포

Techris 개발기 — 지옥의 배포를 경험하며

[Techris] 7. Techris의 배포

들어가며

Techris를 완성했으니 이제 다른 사람들이 플레이할 수 있도록 배포해야 한다. 하지만 Pharo의 이미지 기반 개발 방식과 VM의 특성 때문에 배포가 생각보다 훨씬 복잡했다. 이 과정에서 겪은 시행착오와 해결 방법을 공유해보려 한다.

Pharo의 빌드 방식

일단 Pharo는 개발했던 이미지의 마지막 저장된 스냅샷을 바탕으로 Pharo의 VM위에서 동작하는 방식이다. 예를들어서 Java의 바이트 코드가 JVM위에서 돌아가는 것 처럼 말이다. 따라서 exe나 .app과 같은 파일로 export 하려면 vm과 이미지를 함께 빌드해서 export하는 방식 밖에 없다. 하지만 pharo 공식 홈페이지에서는 이 방법이 되게 모호하게 나와있어서 사용중인 오픈소스를 찾아보았다.

PharoApplicationGenerator

alt text 다행히도 PharoApplicationGenerator라는 오픈소스를 발견해서 이를 활용해서 배포하면 끝나겠구나라고 “쉽게” 단정지었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash

set -x 
set -e

IMAGE_DIR=/Users/apple/Documents/Pharo/images/Woowahan-Techris-deploy
IMAGE_NAME=Woowahan-Techris-deploy.image
CHANGES_NAME=Woowahan-Techris-deploy.changes
APP_NAME=Techris
APP_BUNDLE=$APP_NAME.app
DMG_NAME=$APP_NAME-Installer.dmg
VM_TYPE=Spur

# To create the DMG we need the create-dmg tool, you can get it from brew
# brew install create-dmg

#Clean Up previous build
rm -f -R dmg
mkdir -p dmg
rm -f $DMG_NAME

mkdir -p $APP_BUNDLE/Contents/Resources/

cp -f $IMAGE_DIR/*.sources $APP_BUNDLE/Contents/Resources/
cp -f $IMAGE_DIR/$CHANGES_NAME $APP_BUNDLE/Contents/Resources/
cp -f $IMAGE_DIR/$IMAGE_NAME $APP_BUNDLE/Contents/Resources/

#Downloading Pharo VM
if [ ! -d "./pharo-vm" ] 
then
    mkdir pharo-vm
    pushd pharo-vm

    if [ "$VM_TYPE" = "headless" ]; then
      curl --output vm.zip https://files.pharo.org/vm/pharo-spur64-headless/Darwin-arm64/latest.zip
    else
      curl --output vm.zip https://files.pharo.org/vm/pharo-spur64/Darwin-arm64/stable10.zip
    fi

    unzip vm.zip
    popd
fi

mkdir -p $APP_BUNDLE/Contents/MacOS
cp -Rf pharo-vm/Pharo.app/Contents/MacOS/* $APP_BUNDLE/Contents/MacOS/

#codesign -dv -r- $APP_BUNDLE

#Ad Hoc Signing.
codesign --force --deep -s - $APP_BUNDLE

#Creating DMG
cp -r $APP_BUNDLE ./dmg/

#Setting DPI for the background image
sips --setProperty dpiWidth 144 --setProperty dpiHeight 144 installer-background.png

create-dmg \
  --volname "$APP_NAME Installer" \
  --volicon "installer.icns" \
  --background "installer-background.png" \
  --window-pos 200 120 \
  --window-size 600 400 \
  --icon-size 100 \
  --icon "$APP_BUNDLE" 120 120 \
  --hide-extension "$APP_BUNDLE" \
  --app-drop-link 450 120 \
  "$DMG_NAME" \
  "dmg/"

사용 방법은 그다지 어렵지 않다 마지막으로 작업했던 image의 이미지 파일을 이 sh 스크립트로 돌려주면 pharo 공식 홈페이지에서 제공하는 VM을 다운받고, 이를 함께 빌드해서 .app과 .dmg파일이 나오게끔 되어있다. 빌드를 마치고 집에 있던 다른 맥북에서 돌려보았지만 여기서 두 가지 문제가 발생하였다.

1. 확인되지 않은 개발자의 문제

macOS Gatekeeper의 보안 검사에 걸렸다. Apple 개발자 인증서로 서명하지 않은 앱은 기본적으로 실행이 차단된다. 따라서 어플 자체가 바로 열리지 않아서 바로 다른 exe나 .app처럼 이용할 수가 없었다. 이번에 .app을 처음 만들다보니 정확히는 몰랐는데 apple에서는 Apple Developer Program 가입하여 개발자 인승서로 앱 서명을 받아야 완전하게 배포를 할 수 있다고 한다. 하지만 시간도 없고 일회성에 돈을 부담하기에는 무리가 있어서 이 방법은 제외했다.

를 해결하기 위한 두 가지 방식이 있는데

첫번째는 사용자가 직접 보안설정에서 이를 허용시키게끔 하는것이다. 하지만 이 방법은 꽤나 사용자 경험에 치명적일 것 같아서 이 방법은 일단 배제했다.

두번째는 해당하는 파일만 GateKeeper 을 해제하는 방식이다. 기본적으로 터미널에서 이루어지는 것이기 떄문에 이게 그나마 개발자의 결과물로서는 더 좋은 방안이라고 생각했다. 대신 리드미에 정확한 동작 방식을 기입하는 걸로 대체하기로 결정했다.

2. 폰트를 찾을 수 없는 문제

이제는 .app파일이 열리지만 화면 자체가 뜨지 않는 문제가 발생했다. 다행히도 내장된 Pharo VM에 접속하여 도커 컨테이너 처럼 로그를 볼 수 있게끔 해놨는데 에러는 다음과 같았다. 폰트를 찾을 수 없어 랜더링 과정에서 충돌이 나서 발생하는 것이었다. 그렇다면 사용중인 배민 한나체를 내부에 두고 이를 load하게끔 하면 되지 않을까 생각해보았고 Pharo VM에서 폰트를 어떻게 불러오는지 확인해보았다.

FT2Error: Error reading new face from file [error 1][cannot open resource]

1
2
3
4
5
6
macOSXFolderDirectories
    | tmp1 |
    tmp1 := FileLocator home / 'Library' / 'Fonts'.
    ^ { tmp1 } , #( '/System/Library/Fonts' '/Network/Library/Fonts/' '/Library/Fonts' )
          collect: [ :arg1 | arg1 asFileReference ]
          thenSelect: [ :arg2 | arg2 exists ]

일단 기본적으로 System에 있는 라이브러리와 폰트들을 적용시키는건데 내가 이미지에 사용중인 배민 한나체는 다른 컴퓨터의 로컬에 저장되지 않았기 때문에 ttf를 직접 설치하게끔 하거나 경로를 맞춰주는 것으로 해결해야했다. 하지만 ttf를 다른 맥에 깔아보았을때 Apple 기기의 이름 즉 choi’s 맥북 이렇게 되어있으면 저 경로는 틀린 경로로 떠서 사용자마다 app이 켜질수도있고 아닐수도있다는 위험함이 있다. 따라서 경로를 바꾸는 방법으로 결정해야했는데

정말 모든 경로를 바꿔봐도 게임이 켜지지 않았다. 시간이 너무 촉박하고 작성해야할 문서도 남아있는 상황이라 눈물을 머금고 다른 폰트로 대체하기로 하였다. Pharo 내부에 있는 font는 전에 언급했다시피 CJK를 지원하지 않아 모든 텍스트들을 영문으로 바꿔야했다.

3. VM 버전 불일치

위에 방법들을 해봤지만 또 안켜지는 상황이 발생했다. 이번에도 내부 로그를 보는데 폰트 관련된 에러는 없었고 이번엔 VM 버전이 불일치하다는 것을 확인했다. 일단 PharoApplicationGenerator 오픈소스가 기본적으로 내가 지금 사용하는 버전의 VM을 받는 것이 아닌 과거의 VM을 받는 것이라서 버전의 불일치 문제가 발생한 것이었다. 하지만 이 또한 github issue에서도 아직 해결중인 문제라고 하고있고 제기가 되었던 문제여서 쉽게 해결할 수 없었다.

마지막 대안

정말 마지막 대안이었다. 일단 VM을 직접 받고 이미지 스냅샷을 직접 .zip으로 묶은 다음에 이를 다른 로컬에서 실행시키는 방법밖에 없었다. alt text

결국 처음 받은 VM을 직접 받아서 이미지를 함께 압축하고 게이트 키퍼를 우회하기 위한 .command 파일을 함께 넣기로 하였다.

1
2
3
4
5
6
7
8
APP_DIR="$(cd "$(dirname "$0")" && pwd)"

xattr -d com.apple.quarantine "$APP_DIR/Pharo.app" 2>/dev/null
xattr -dr com.apple.quarantine "$APP_DIR" 2>/dev/null

"$APP_DIR/Pharo.app/Contents/MacOS/Pharo" \
    "$APP_DIR/Woowahan-Techris-deploy.image" \
    techris --embedded

결국은 됐다. 이상없이 실행되지만 분명히 사용자 경험에 좋지 않다. 하지만 더 나은 대안이 없어 내가 찾은 최선의 방법이라고 생각하여 이렇게 배포하기로 결정했다.

마치며

그래도 빌드 방식을 제대로 지킨다면 다른 컴퓨터에서도 잘 열리는 것을 확인하였고 조금은 불편하지만 이에 만족해야할 것 같다. 만약 안됐으면 Pharo를 선택한 내 자신이 미워질 것 같았지만 그나마 다행이다.

This post is licensed under CC BY 4.0 by the author.