2015-11-02 43 views
0

目前我PyInstaller規格如下所示:我可以告訴PyInstaller打包我的整個源代碼樹嗎?

 
import sys 
import os 
import re 
from pathlib import Path 

DEBUG = True 

lib = Path("lib/alpha") 

hidden_imports = [] 
hidden_imports += lib.glob("processes/**/*.py") 
hidden_imports += lib.glob("ui/config_panels/**/*.py") 
hidden_imports += lib.glob("ui/logic/**/*.py") 
hidden_imports = list(str(x) for x in hidden_imports) 

for index, path in enumerate(hidden_imports): 
    path = re.sub(r"lib(\\|\/)", "", path) 

    if "__init__.py" in path: 
     path = re.sub(r"(\\|\/)__init__.py", "", path) 
    else: 
     path = re.sub(r"\.py", "", path) 

    hidden_imports[index] = ".".join(re.split(r"\\|\/", path)) 

block_cipher = None 

a = Analysis(
    ["app.pyw"], 
    pathex=["lib"], 
    binaries=None, 
    datas=[ 
     ("icons/*", "icons") 
    ], 
    hiddenimports=hidden_imports, 
    hookspath=None, 
    runtime_hooks=None, 
    excludes=None, 
    win_no_prefer_redirects=None, 
    win_private_assemblies=None, 
    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="alpha", 
    debug=DEBUG, 
    strip=None, 
    upx=True, 
    console=DEBUG, 
    icon="icons\\foo.ico" 
) 

醜得要命,對不對?

我在源代碼樹中有一些目錄,文件名遵循特定的命名約定,並使用importlib按需導入。我不想將所有這些模塊的名稱硬編碼到我的規範中,原因很明顯。

當使用「hiddenimports」選項,參數必須是模塊名稱的列表,所以我必須glob文件名,遍歷結果列表和「modulify」的文件名,考慮到Windows和Linux支持。

必須有更好的方法。有什麼辦法可以告訴PyInstaller只包括我的整個源碼樹,即每個文件在lib/alpha下?

回答

0

您可以使用Tree() function包括一個完整的目錄樹,但這不會完全符合您的要求。由於您要添加源文件,因此您需要PyInstaller遞歸分析它們以確保其所有依賴項都包含在內。最好的方法是通過隱藏式導入。

我不會詳細解釋,我只是從我自己的spec文件中分享一段代碼,我用它來包含不是由我的應用程序直接包含的模塊,而是提供給用戶創建的插件使用。這非常適合您的使用案例。

# Files under mcedit2.synth are used only by plugins and not internally. 
support_modules = [] 
for root, dirnames, filenames in os.walk(os.path.join('src', 'mcedit2', 'synth')): 
    for filename in fnmatch.filter(filenames, '*.py'): 
     if filename == "__init__.py": 
      filepath = root 
     else: 
      filepath = os.path.join(root, filename) 
      filepath = filepath[:-3] # discard ".py" 

     components = filepath.split(os.path.sep) 
     components = components[1:] # discard 'src/' 

     if "test" in components or components == ["mcedit2", "main"]: 
      continue 

     modulename = ".".join(components) # dotted modulename 
     support_modules.append(modulename) 

hiddenimports.extend(support_modules) 
+1

等一下。我想我可以只爲此使用'collect_submodules'。它通常被hookfiles用來收集導入庫的子模塊,但它也應該可以在spec文件中使用。 – codewarrior

相關問題