简体   繁体   中英

Including a directory using Pyinstaller

All of the documentation for Pyinstaller talks about including individual files. Is it possible to include a directory, or should I write a function to create the include array by traversing my include directory?

Paste the following after a = Analysis() in the spec file to traverse a directory recursively and add all the files in it to the distribution.

##### include mydir in distribution #######
def extra_datas(mydir):
    def rec_glob(p, files):
        import os
        import glob
        for d in glob.glob(p):
            if os.path.isfile(d):
                files.append(d)
            rec_glob("%s/*" % d, files)
    files = []
    rec_glob("%s/*" % mydir, files)
    extra_datas = []
    for f in files:
        extra_datas.append((f, f, 'DATA'))

    return extra_datas
###########################################

# append the 'data' dir
a.datas += extra_datas('data')

The problem is easier than you can imagine

try this: --add-data="path/to/folder/*;."

hope it helps !!!

Yes, you can just add directories to the Analysis object and they get copied across.

a = Analysis(['main.py'],
             datas = [('test/dir', 'test/dir')],
             ...)

What about just using glob ?

from glob import glob
datas = []
datas += glob('/path/to/filedir/*')
datas += glob('/path/to/textdir/*.txt')
...

a.datas = datas

The accepted answer works fine if your folder doesn't have any subfolders. However, if you folder does have any subfolders, all data will be collapsed into the your 'dir_to_include' path, which will mess up your imports. The below is an example, where main.py accesses music and pictures from the data folder.

.
├── data
│   ├── music
│   │   ├── music1.mp3
│   ├── pics
│   │   ├── pic1.png
│   │   ├── pic2.png
│   │   ├── numbers
│   │   │   ├── 0.png
│   │   │   ├── 1.png
│   │   │   ├── 2.png
├── main.py
├── main.spec

In this case, after we generated our main.spec file using pyinstaller main.py , we can change some arguents inside the main.spec file.

On the top of the main.spec, our we set our added_files :

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None

added_files = [
    ('./data/*.*', 'data'),
    ('./data/pics/*.*', 'data/pics'),
    ('./data/music/*.*', 'data/music'),
    ('./data/pics/numbers/*.*', 'data/pics/numbers'),
    ]
...

Then, we set datas=added_files below:

...
a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=[],
    datas=added_files,
...

We have to add the path for each individual subfolder, or else they won't get added by pyinstaller automatically. If we simply do added_files = '[(./data/*', data')] , then all the pictures and audio will be added to the 'data' directory, which is not what we want. Thus, we use path/*.* , so folders don't get added recursively, and define each subfolder manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM