9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

macOS 上でポータブルな Python 環境を作成する

Last updated at Posted at 2025-04-09

数年前、次のような記事を書きました。

上記記事を最新状況を踏まえて更新した、新バージョンの記事が本記事です。

最新の macOS には Python 環境はデフォルトでは同梱されていない

2022年の macOS Monterey 12.3 Update より、macOS には標準で同梱されないようになりました。よって、Pythonを使用するアプリケーションやスクリプトを配布する開発者は、

  • ユーザが各自で Python 環境をインストールすることを要求する
  • Python環境を丸ごと添付して配布する

といういずれかの手段を選ぶ必要があります。

ユーザにインストールさせる場合

ユーザが Python をインストールする方法としては、

などの手が考えられます。このうち、最も簡便なのは Xcode Command Line Tools でしょう。

xcode-select --install

としてインストールすると、

/Library/Developer/CommandLineTools/usr/bin/python3

が使えるようになります。

初回起動時の自動インストール

実は、現在の macOS でも

/usr/bin/python3

というコマンドはデフォルトで用意されていますが、これは“スタブ”と呼ぶべきもので、

  • Xcode Command Line Tools がインストールされていなければインストールを促すダイアログを表示する
  • インストールされていれば /Library/Developer/CommandLineTools/usr/bin/python3 を起動する

という挙動をします。

ポータブルな Python 環境を用意したい!

ユーザにターミナル操作をさせることは避けたい

上記の「ユーザ各自にPython環境をインストールさせる」という方法の場合、「ユーザにターミナル操作をさせる」という手間が生じます。ですが、これはユーザ側にとって大きな負担になります。一般ユーザにとって「ターミナルにコマンドを打ち込む」という操作は、プログラマが想像するよりもはるかに忌避感の強い行為であり、猛烈に嫌がられます。「ターミナルにコマンドを打ち込む」ことを要求するアプリは、それが普及の妨げとなりえます。自分はアプリ作成において 「ユーザにターミナル操作を要求したら負け」 と考え、ターミナル操作を要求しない形で配布するように心がけています。

ポータブルな Python 環境を同梱して配布すると受け入れられやすい

そこで、Python環境を丸ごとパッケージ化して、それをアプリに同梱して配布する方法が使えます。.app バンドルのアプリの場合、そのバンドル内にPython環境を封じ込めて(APPNAME.app/Contents/Frameworks/Python.framework)配布し、アプリ内からはその中の Python バイナリ (APPNAME.app/Contents/Frameworks/Python.framework/Versions/Current/bin/python3) を起動する、という形で使えば、ユーザにPython環境を用意させる手間が省けます。

ポータブルな Python 環境のビルド法

macOSで配布するためのポータブルな Python 環境のビルドには、relocatable-pythonというツールを使うのが便利です。

Step 0: Xcode Command Line Tools のインストール(確認)

まず、開発者自身のMac環境には、Xcode Command Line Tools がインストールされている必要があります。

xcode-select --install

Step 1: relocatable-python レポジトリの clone

mkdir ~/WORKDIR
cd ~/WORKDIR
git clone https://github.com/gregneagle/relocatable-python
cd relocatable-python

Step 2: Python の最新バージョンを確認

Pythonの最新の正式リリースバージョンを確認します。本記事執筆時点では 3.13.3 でした。そこで、https://www.python.org/ftp/python/3.13.3/ にアクセスします。すると、その中に python-3.13.3-macos11.pkg というファイル名が確認できます。この 3.13.311 という数値を記録しておきます。

Step 3: requirements.txt を用意

これから作成する Portable Python Framework にデフォルトで同梱する pip ライブラリを記載した requirements.txt を作成します。

なお、relocatable-python レポジトリにはデフォルトで requirements_python3_recommended.txt というファイルが用意されていますが、これには古い pyobjc が指定されており、これを同梱しようとするとビルドが失敗してしまいます。よって、用意されている requirements_python3_recommended.txt は使わず、自分で必要な requirements.txt を用意しましょう。

例えば次のように指定します。

requirements.txt
numpy             # 配列・行列計算の基盤
scipy             # 数値解析・統計・最適化
matplotlib        # 可視化
pandas            # データフレームによるデータ処理
requests          # HTTP通信の標準的ライブラリ

Step 4: ビルド

次のようにビルドコマンドを実行します。オプションは以下の通りです。

  • --python-version: Step 2 で確認したPythonのバージョン番号を指定
  • --os-version: Step 2 で確認したOSのバージョン番号を指定
  • --pip-requirements: Step 3 で作成したファイルを指定
./make_relocatable_python_framework.py --python-version 3.13.3 --os-version 11 --upgrade-pip --pip-requirements=requirements.txt

これにより、Python.framework が生成されます。

Step 5: 署名

配布するには、Apple Developer Program に登録された正当な署名をしておくことが望ましいです。

codesign --force -s "Developer ID Application: <キーチェーンに登録した証明書名>" Python.framework

署名を終えたら、その署名が有効かどうか、

codesign --verify --verbose=4 Python.framework

として確認しましょう。

Step 6: バイナリの対応CPUアーキテクチャ確認

この方法で生成された Python バイナリ自体は、Intel Mac (x86_64) / Apple Silicon (arm64) の両方に対応した Universal Binary となっています。しかし、pip でインストールされる周辺ライブラリは、ホストマシンのネイティブなバイナリしかインストールされないことが普通です。それでは、完全なポータビリティが実現できたとは言えません。

どのバイナリが Universal Binary になっているか否かを確認するには、

./python_universal_tester.sh 3.13.3

とするとよいです。Python.framework 内の各バイナリが、x86_64 / arm64 のどちらに対応しているかを確認できます。

Pythonそのものだけではなく pip ライブラリを添付して配布する場合、完全なポータビリティを実現するには、Intel Mac と Apple Silicon Mac の両方で Python.framework を生成して両方を同梱し、自分のアプリからは、uname -m の実行結果に応じてどちらを呼び出すかを切り替える、などといった措置を講じる必要があるでしょう。

Step 7: 配布

app bundle として配布する場合、APPNAME.app/Contents/Frameworks/Python.framework に同梱しておき、APPNAME.app/Contents/Frameworks/Python.framework/Versions/Current/bin/python3 を起動させるとよいでしょう。シェルスクリプトから Python インタプリタを起動させる場合、

export PATH=/path/to/APPNAME.app/Contents/Frameworks/Python.framework/Versions/Current/bin:$PATH

と冒頭で宣言して起動させるとよいでしょう。

zipで包む場合の注意

生成された Python.framework を zip 圧縮して配布する場合、内部のシンボリックリンク構造を保って zip 化するため,-y オプションを付けることを忘れぬようご注意ください。

zip -rqy PythonFramework.zip Python.framework
9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?