web-dev-qa-db-ja.com

pyinstallerで最小サイズの実行可能ファイルを作成するにはどうすればよいですか?

私はWindows 10にいます。anacondaがインストールされていますが、python 3.5を使用して、新しいクリーンな最小環境で実行可能ファイルを個別に作成したいと思います。

TEST1:フォルダーtestenvにpythonスクリプトtest1.pyを作成しました:

print('Hello World')

次に、環境を作成し、pyinstallerをインストールして実行可能ファイルを作成しました

D:\testenv> python -m venv venv_test
...
D:\testenv\venv_test\Scripts>activate.bat
...
(venv_test) D:\testenv>pip install pyinstaller
(venv_test) D:\testenv>pyinstaller --clean -F test1.py

そして、約6 Mbのtest1.exeを作成します

テスト2:test1.pyを次のように変更しました。

import pandas as pd
print('Hello World')  

環境にpandasをインストールし、新しい実行可能ファイルを作成しました。

(venv_test) D:\testenv>pip install pandas
(venv_test) D:\testenv>pyinstaller --clean -F test1.py

Antは、今では230 Mbのtest1.exeを作成します!!!

コマンドを実行した場合

(venv_test) D:\testenv>python -V
Python 3.5.2 :: Anaconda custom (64-bit)

pyinstallerを実行しているときに、理解できないメッセージが表示されます。たとえば、

INFO: site: retargeting to fake-dir 'c:\\users\\username\\appdata\\local\\continuum\\anaconda3\\lib\\site-packages\\PyInstaller\\fake-modules'

また、matplotlibや、コードとは関係のない他のモジュールに関するメッセージが表示されます。たとえば、

INFO:   Matplotlib backend "pdf": added
INFO:   Matplotlib backend "pgf": added
INFO:   Matplotlib backend "ps": added
INFO:   Matplotlib backend "svg": added

関連する質問があることを知っています: pyinstaller exeのサイズを小さくするpyinstallerとnumpyを使用した実行可能ファイルのサイズ しかし、問題を解決できず、何かをしているのではないかと心配アナコンダに関して間違っています。

だから私の質問は次のとおりです。私は何が間違っていますか?実行可能ファイルのサイズを小さくできますか?

9
esperluette

問題は、仮想環境、特にアナコンダを使用しないことです。デフォルトのpython 32ビットをダウンロードし、必要なモジュールのみを使用してください。リンクに記載されている手順に従ってください。これで確実に修正されます。

仮想環境を作成しましたが、スペックファイルが古いAnacondaエントリにリンクしていないことを確認しますか?

これがすべて失敗した場合、これは非常に奇妙なのでバグを提出してください。

3
Dragomeow

上記の答えを受け入れましたが、私は簡単に道に迷う私のような完全な初心者のために私が一歩一歩行ったことをここに投稿します。

始める前に、実際に必要なすべてのモジュールを含む完全なtest1.pyサンプルスクリプトを投稿します。元の質問よりも少し複雑な場合はおaび申し上げますが、誰かの助けになるかもしれません。

test1.pyは次のようになります。

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt
import matplotlib.image as image
import numpy as np
import os.path
import pandas as pd
import re   

from matplotlib.ticker import AutoMinorLocator 
from netCDF4 import Dataset
from time import time
from scipy.spatial import distance
from simpledbf import Dbf5
from sys import argv

print('Hello World')

Matplotlib.use( 'Agg')を追加しました(実際のコードは図を作成しているため) DISPLAYが未定義の場合にmatplotlibでPNGを生成

1)pythonの新しいバージョンをanacondaから独立してインストールします。

ダウンロードpython from: https://www.python.org/downloads/ 'add python to path'を選択し、すべてのユーザーのインストールランチャーの選択を解除する(管理者権限を持たない)CMDから同じバージョンを使用していることを確認し、単にpythonと書きます:Python 3.6.4 (v3.6.4:d48eceb、2017年12月19日、06:04:45)[MSC v.1900 32ビット(Intel)] on win32詳細については、「help」、「copyright」、「credits」または「license」と入力してください。

2)CMDから環境を作成してアクティブ化する

D:\> mkdir py36envtest
...
D:\py36envtest>python -m venv venv_py36
...
D:\py36envtest\venv_py36\Scripts>activate.bat

3)スクリプトに必要なすべてのモジュールを環境にインストールします

コマンドでpythonバージョンと互換性があることを確認:(from Pythonでのインポート時にMatplotlibがモジュールとして認識されない)

(venv_py36) D:\py36envtest> python -m pip install nameofmodule

注意:私の場合、オプション--proxy https://00.000.000.00:00 も追加する必要がありました

たとえば、pyインストーラーの開発バージョンを使用しました。

(venv_py36) D:\py36envtest> python -m pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz

モジュール:パンダ、matplolib、simpledbf、scipy、netCDF4。最後に、私の環境は次のようになります。

(venv_py36) D:\py36envtest> pip freeze
altgraph==0.15
cycler==0.10.0
future==0.16.0
macholib==1.9
matplotlib==2.1.2
netCDF4==1.3.1
numpy==1.14.0
pandas==0.22.0
pefile==2017.11.5
PyInstaller==3.4.dev0+5f9190544
pyparsing==2.2.0
pypiwin32==220
python-dateutil==2.6.1
pytz==2017.3
scipy==1.0.0
simpledbf==0.2.6
six==1.11.0
style==1.1.0
update==0.0.1

4).specファイルを作成/変更します(pyinstallerを実行すると、.specファイルが作成され、名前を変更できます)。

最初はたくさんのImportErrorがありました:DLL load failed(特にscipyの場合)およびこれらの投稿のおかげで解決したモジュールの欠落エラー:
カスタムsklearnパイプラインを永続化(ピクル)する推奨方法は何ですか?
およびこの回答へのコメント: scipy.signal ImportErrorを含むPyinstaller:DLL load failed

私のinputtest1.specは最終的に次のようになります。

# -*- mode: python -*-
options = [ ('v', None, 'OPTION')]
block_cipher = None


a = Analysis(['test1.py'],
             pathex=['D:\\py36envtest', 'D:\\py36envtest\\venv_py36\\Lib\\site-packages\\scipy\\extra-dll' ],
             binaries=[],
             datas=[],
             hiddenimports=['scipy._lib.messagestream',
                            'pandas._libs.tslibs.timedeltas'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='test1',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

5)最後に、コマンドで実行可能ファイルを作成します

(venv_py36) D:\py36envtest>pyinstaller -F --clean inputtest1.spec

私のtest1.exeは47.6 Mbです。anaconda仮想環境から作成された同じスクリプトの.exeは229 Mbです。

私は幸せです(そして、さらに提案があれば歓迎します)

27
esperluette