Pyinstaller --onefile warning pyconfig.h when importing scipy or scipy.signal

后端 未结 5 1127
梦毁少年i
梦毁少年i 2020-12-01 05:23

This is very simple to recreate. If my script foo.py is:

import scipy

Then run:

python pyinstaller.py --onefile foo.py


        
相关标签:
5条回答
  • 2020-12-01 06:02

    I ran the archive_viewer.py utility (from PyInstaller) on one of my own --onefile executables that has the same error and found that pyconfig.h is included twice:

     (31374007, 6521, 21529, 1, 'x', 'include\\pyconfig.h'),
     (31380528, 6521, 21529, 1, 'x', 'Include\\pyconfig.h'),
     (31387049, 984, 2102, 1, 'x', 'pytz\\zoneinfo\\CET'),
    

    Sadly though, I don't know how to fix it.

    PyInstaller Manual link: http://www.pyinstaller.org/export/d3398dd79b68901ae1edd761f3fe0f4ff19cfb1a/project/doc/Manual.html#archiveviewer

    0 讨论(0)
  • 2020-12-01 06:09

    The answer by wtobia@ worked for me. See https://github.com/pyinstaller/pyinstaller/issues/783

    1. Go to C:\Python27\Lib\site-packages\PyInstaller\build.py
    2. Find the def append(self, tpl): function.
    3. Change if tpl[2] == "BINARY": to if tpl[2] in ["BINARY", "DATA"]:
    0 讨论(0)
  • 2020-12-01 06:14

    I realized that the problem is that Windows is case-insensitive and these 2 statements are source directories are "duplicates: include\pyconfig.h Include\pyconfig.h

    My solution is to manually tweak the .spec file with after the a=Analysis() call:

    import platform
    if platform.system().find("Windows")>= 0:
        a.datas = [i for i in a.datas if i[0].find('Include') < 0]
    

    This worked in my 2 tests.

    A more flexible solution would be to check ALL items for case-insensitive collisions.

    0 讨论(0)
  • 2020-12-01 06:15

    You can hack the spec file to remove the second instance by adding these lines after a=Analysis:

    for d in a.datas:
        if 'pyconfig' in d[0]: 
            a.datas.remove(d)
            break
    
    0 讨论(0)
  • 2020-12-01 06:22

    Expanding upon Ilya's solution, I think this is a little bit more robust solution to modifying the spec file (again place after the a=Analysis... statement).

    a.datas = list({tuple(map(str.upper, t)) for t in a.datas})
    

    I only tested this on a small test program (one with a single import and print statement), but it seems to work. a.datas is a list of tuples of strings which contain the pyconfig.h paths. I convert them all to lowercase and then dedup. I actually found that converting all of them all to lowercase was sufficient to get it to work, which suggests to me that pyinstaller does case-sensitive deduping when it should be case-insensitive on Windows. However, I did the deduping myself for good measure.

    0 讨论(0)
提交回复
热议问题