any easy way to re-use what pyinstaller has created?

20 views
Skip to first unread message

进陆

unread,
Jul 6, 2020, 7:06:01 AM7/6/20
to PyInstaller
the question is at the end of this post which is labeled in strong, underlined style

1. I have pyd and main.py
1.1 the pyd is created as the README.md( from https://github.com/yglukhov/nimpy) says, but of cause we can use C to create it as well
```nim
# mymodule.nim - which I put in R:\test
import nimpy

proc greet(name: string): string {.exportpy.} =
  return "Hello, " & name & "!"
```

```bash
# Compile on Windows:
nim c --threads:on --app:lib --out:mymodule.pyd mymodule
```

1.2 the `main.py` is a simple one to test `mymodule.pyd`
```python
# main.py
import mymodule
print(mymodule.greet("world"))
```

2. build EXE file with pyinstaller
```
pyinstaller.exe main.py
```

now we have the `EXE` file and other `pyd/dll` under `R:\test\dist\main`. The `main.exe` can run under windows without python installation. And we can read that `sys.path` is
```
['R:\\test\\dist\\main\\base_library.zip', 'R:\\test\\dist\\main']
```
which is what I wrote in `main_nim.nim`

3. I try to re-use( for example make the GUI in nimlang but call the module in Python) the self-contained pyinstaller-released `main.exe`
```python
# main_nim.nim
import os
putEnv("PYTHONPATH", getAppDir() & ";" & joinPath(getAppDir(), "base_library.zip"))
putEnv("PATH", getAppDir())

import nimpy
let mymodule = pyImport("mymodule")
echo mymodule.greet("world")
```

I compiled and put `main_nim.exe` to `R:\test\dist\main`, then run it

```
R:\test\dist\main>main_nim.exe
PYTHONPATH = R:\test\dist\main;R:\test\dist\main\base_library.zip
Failed to import the site module
ModuleNotFoundError: No module named 'site'
```

so I copy `python\lib\site.py` and run `main_nim.exe` again

```
R:\test\dist\main>main_nim.exe
PYTHONPATH = R:\test\dist\main;R:\test\dist\main\base_library.zip
Failed to import the site module
Traceback (most recent call last):
  File "R:\test\dist\main\site.py", line 73, in <module>
    import os
ModuleNotFoundError: No module named 'os'
```

<u>***<font color=red>I repeated the above test-copy-test again and again, and find that I have to copy 10 files( i.e. contextlib.py, genericpath.py, ntpath.py, os.py, site.py, stat.py, sysconfig.py, token.py, tokenize.py, _sitebuiltins.py), copy 1 directory( i.e. importlib)</font></u>*** and make 1 dumb `python.exe`, then

```
R:\test\dist\main>main_nim.exe
PYTHONPATH = R:\test\dist\main;R:\test\dist\main\base_library.zip
Hello, world!
```

So my question is, is there any easy way to re-use application released by pyinstaller without do what ***<u>**<font color=red>I have done by hand</font>***</u>** before?


Thanks

bwoodsend

unread,
Jul 6, 2020, 8:18:37 AM7/6/20
to PyInstaller

Hello,

Firstly you certainly shouldn’t need to copy those files about. It looks like the problem is nimpy can’t read the standard lib files from the base_library.zip archive and you’re extracting them manually. You can tell PyInstaller not to use the zip by adding the kwarg noarchive=True to the a = Analysis(...) section of the main.spec file. (If you’re new to spec files - it’s just a Python script containing all the build code.) If you edit the spec you must use PyInstaller main.spec instead of PyInstaller main.py or you will lose your changes.

Assuming the above doesn’t fix your problem: You can’t reuse bits of a build in the way you’re suggesting but you can still automate them. Again, use the spec file. You could append code to the end of your spec (such as code to copy those files in) and it will run that code after every build.

Also, I recommend Markdown Here for using markdown in Google Groups.

Brénainn

Message has been deleted

进陆

unread,
Jul 6, 2020, 10:32:21 AM7/6/20
to PyInstaller


在 2020年7月6日星期一 UTC+8下午8:18:37,bwoodsend写道:

Hello,

Firstly you certainly shouldn’t need to copy those files about. It looks like the problem is nimpy can’t read the standard lib files from the base_library.zip archive and you’re extracting them manually.

if I copy pyc files(i.e. contextlib.pyc, genericpath.pyc, ntpath.pyc, os.pyc, site.pyc, stat.pyc, sysconfig.pyc, token.pyc, tokenize.pyc, _sitebuiltins.pyc) into `base_library.zip`, `main_nim.exe` can run which means `nimpy` can read modules from `base_library.zip`
 

You can tell PyInstaller not to use the zip by adding the kwarg noarchive=True to the a = Analysis(...) section of the main.spec file. (If you’re new to spec files - it’s just a Python script containing all the build code.) If you edit the spec you must use PyInstaller main.spec instead of PyInstaller main.py or you will lose your changes.

I found I can use `pyinstaller  -d noarchive main.py` to tell pyinstaller not to create `base_library.zip`. Then pyinstaller can produce run-able `main.exe` from `main.py`

but I still need to copy 3 files(site.py,  _sitebuiltins.py and sysconfig.py) to ensure `main_nim.exe`(just as the name suggested, which is created by nim code) can run 

so that is not so-automatic yet.
Reply all
Reply to author
Forward
0 new messages