pyOCD: Build pyOCD into Single Executable File - file missing in pyyaml

I followed the guide https://github.com/mbedmicro/pyOCD/blob/master/docs/how_to_build.md to build an executable from pyOCD. Before diving into the problem, let’s first list my system settings.  

1. My system

  • I work on 64-bit Windows 10
  • I’ve got Python 3.8
  • I did not set up a virtual environment when starting the procedure, but work directly from my Python 3.8 installation.  

2. The procedure

I issue the following commands in a Windows console:

# We need to use upstream version of pyinstaller due to
# http://comments.gmane.org/gmane.comp.python.pyinstaller/6457
pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

# Create single-file executables
pyinstaller --onefile pyocd/tools/gdb_server.py
pyinstaller --onefile pyocd/tools/flash_tool.py
pyinstaller --onefile pyocd/tools/pyocd.py

Everything goes well until the last command:

FileNotFoundError: [Errno 2] No such file or directory:
'c:\\python38\\lib\\site-packages\\pyyaml-5.2b1-py3.8-win-amd64.egg\\EGG-INFO\\top_level.txt'

I check if I’ve got pyyaml properly installed. I run the command pip install pyyaml and everything seems okay:

C:\Seafile\EMBEETLE IDE\pyOCD>pip install pyyaml
    Requirement already satisfied:
    pyyaml in c:\python38\lib\site-packages\pyyaml-5.2b1-py3.8-win-amd64.egg (5.2b1)

 

3. Solution

I believe I found a solution. I created the file top_level.txt myself in the right place:

image

After googling the keywords yaml and top_level.txt, I discovered that this file should have only two lines:

_yaml
yaml

I issue again the failed command:

$ pyinstaller --onefile pyocd/tools/pyocd.py

Now it works! At least - the compilation works.  

4. Problem with the executable

Unfortunately, the executable itself doesn’t work. I get import errors:

C:\Seafile\EMBEETLE IDE\pyOCD\dist>pyocd.exe --version
    Traceback (most recent call last):
      File "pyocd\tools\pyocd.py", line 35, in <module>
    ImportError: attempted relative import with no known parent package
    [7508] Failed to execute script pyocd

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Comments: 17 (10 by maintainers)

Most upvoted comments

In case its useful, this is the spec file I’m currently using (you can ignore the stuff that excludes and replaces svd files, as I am doing that only to reduce the executable size): https://github.com/carlosperate/ubittool/blob/master/package/pyinstaller-cli.spec

Thanks so much for taking the time @carlosperate, That solved the issue we were having.

In the meantime, if you are still planning to use PyInstaller I’d recommend to have a look at perhaps implementing the logic from the spec file as a hook in pyOCD, since there are plans to provide a way to expose them to PyInstaller: https://github.com/pyinstaller/pyinstaller/issues/4232

Btw, also wanted to thank you @flit for that spec file in your https://github.com/flit/pyOCD/tree/feature/binary_release branch, it has certainly helped me as well.

Hi @flit and @cederom , Thanks a lot to both of you guys. It worked!

I installed capstone as suggested:

pip install capstone

Then I navigated to the cloned PyOCD folder and issued the command:

pyinstaller pyocd.spec

with ‘pyocd.spec’ being the spec-file from @flit . I get a nice pyocd.exe in the dist folder. I run it to see its version, and that works:

C:\Seafile\EMBEETLE IDE\pyOCD\dist>pyocd.exe --version
    0.23.1.dev10

Note: I just noticed the following in the error message from yesterday:

ModuleNotFoundError: No module named 'capstone'

I should have seen that before asking you guys for help. My sincere apologies.

Sorry, that how_to_build.md document is waaay out of date. It should be removed.

Take a look at my feature/binary_release branch. This has a .spec file that will correctly build pyocd using PyInstaller. The branch is a little out of date, but should still work if you rebase it.

I haven’t merged the changes from this branch because I intend to integrate it into CI.