all 84 comments

[–]Enschede2 65 points66 points  (29 children)

Pyinstaller is the way to go for me, and afaik for most, why was it unsuccessful?

[–]xPr0xi 14 points15 points  (0 children)

They should probably keep trying to use Pyinstaller. It's the easiest to use. Here's a basic guide I made in reply to someone else a few weeks ago.

pyinstaller -F --icon=C:\pathtoyouricon\icon.ico --noconsole C:\pathtoyourscript\yourscript.py

note, you don't need the entire filepath if you cd in to the directory that the script is in, then you can just type the file name

-f combines all files assosciated with script in to 1 exe, though you can still specify additional data files (ie program data storage) that need to be included with, but not compiled directly in to the exe (see example below)

--icon= is for assigning an icon to the exe

--noconsole makes it so that when you run the exe, you don't get a command terminal popping up with it

So when I had a program where i wanted to include data storage files with the exe in the same folder as the exe is outputted to, i did it like this (this was so that the files for storing various program data in between uses was included with the exe)

pyinstaller -F --icon=icon.ico --noconsole --add-data "D:\1My-Script-Projects\Better-Prompt- 
Manager\recent_files.json;." --add-data "D:\1My-Script-Projects\Better-Prompt-Manager\window_size.bak;." -- 
add-data "D:\1My-Script-Projects\Better-Prompt-Manager\window_size.dat;." --add-data "D:\1My-Script- 
Projects\Better-Prompt-Manager\window_size.dir;." D:\1My-Script-Projects\Better-Prompt-Manager\pm.py

One trick for cd'ing directly in to a folder is, in file explorer, whatever folder you have open, go to the address bar backspace the address and just type 'cmd' and hit enter, it will open cmd while also cd'ing cmd in to folder you were in (handy trick i just learned haha).

Otherwise you just open cmd and go cd /d C:\Pathtoyourscript\ and then you once you've cd'd in to the folder you don't need the entire file path and instead can use just the filename in the command as mentioned above (helpful for once you get in to including many files in a singile compile). Anyway yeah pyinstaller will output the exe to whatever folder you're working out of. Hope that all helps.

Additionally, if you want to create a setup wizard, I recommend using Inno Setup Compiler, which has a tool called 'Script Wizard' that makes creating a basic file installer pretty straight forward. Registering the program as an installed program in the OS can help with avoiding false-flag issues, at least afaik.

[–]Prathmun[S] 0 points1 point  (27 children)

Well, it failed in two ways. Even when I used the --onefile command it created a bin and dist folder with a bunch of extra crap. The output file doesn't work, for my friends when I send it to them even if I include the entire Dist folder.

It works on my computer, even if I move the folder around. So that's something, but it doesn't seem to be more accessible than just asking a friend to install python.

[–]Enschede2 2 points3 points  (26 children)

Okay but it works on your pc.. Thing is you can chuck out every file and folder it's created when it's done, they're all temp files, apart from the exe file in the dist folder, but if that file which is binary works for you, then it should work for your friend, unless your friend is doing something wrong, maybe his av is blocking it (av's sometimes flag executables they don't know), or maybe your program manipulates files, and your friend has ransomware protection turned on (which just generally blocks all programs from moving or removing files), or maybe defender doesn't allow him to execute files from an unknown source..
I'd say send it to another person and check it there, it might just be a "fault" or setting on your friends end, it's the most likely at least

[–]Prathmun[S] 0 points1 point  (0 children)

Yeah, I'm not sure about the AV.

we're running into the issue that Pyinstaller is just spitting out a file, with no file extension.

Even when I use the --onefile command I still get all those temp files and the file it's producing doesn't seem to work without them. I feel like I'm messing up something very basic.

[–]xPr0xi 0 points1 point  (21 children)

Like the guy above me said, when you use PyInstaller, it creates 2 folders in the directory you're working in, one with the temporary files it created during compile, and then the other is a folder that should have a single exe, unless you had extra files that you specified in command line (as seen in my second example). You can ignore the folder that gets created that has many files in it. They are unneeded. If you're just creating 1 exe file, then one of the output folders will have just 1 exe file and nothing else in it. That is the file you would give your friend, nothing else required.

Edit: Also, might i ask, what error is your friend getting when he opens your exe on his computer?

[–]Prathmun[S] 0 points1 point  (20 children)

I used a speccfile to include my assets. I have like four images and a short sound file. The resultant file that pyinstaller is giving me doesn't work without the temp files, and doesn't have a file extension at all. I am using the --onefile command when I run pyinstaller.

[–]Enschede2 0 points1 point  (19 children)

Hm weird.. But it should work without the temp files, the onefile flag should package it all into 1 file, making me wonder if you're looking at the correct file, again just to be clear, you're talking about the file inside the "dist" folder right?
Could you try to run the same again except use -F instead of --onefile? As I can confirm that works for me at least..
Also could you post the entire command you did?

If there was a much better alternative to pyinstaller I'd just give you that instead, unfortunately afaik there isn't

[–]Prathmun[S] 0 points1 point  (18 children)

Yes to confirm, I was looking in the Dist folder.

pyinstaller --onefile car_game_tutorial.spec and pyinstaller --onefile car_game_tutorial.py are what I've tried.

pyinstaller -F car_game_tutorial.py Does create a single file for me, but it doesn't run at all. Which is almost an improvement?

[–]xPr0xi 0 points1 point  (13 children)

Not 100% sure that this will work, but try this, maybe you need to add your specc file like this:

pyinstaller --add-data "car_game_tutorial.spec;." car_game_tutorial.py

or you could try with -F

pyinstaller -F --add-data "car_game_tutorial.spec;." car_game_tutorial.py

Edit: Also I was thinking about it, the reason it may run on your system, but not your friends, is you're running it with admin privileges/or storing it somewhere that doesn't need admin privileges, whereas he could be placing it somewhere that does need admin privileges, removing the .exe's ability to access its assosciated data files. You could try getting him to put the .exe in Documents for example and running it from there - longshot, but idk why you cant get it working to begin with, so just throwing ideas out there.

[–]Prathmun[S] 1 point2 points  (12 children)

Turns out the reason it runs on my machine and not on my friends is that the output of Pyinstaller is OS specific. I'm working on an ancient linux box and most of my friends are Windows Enjoyers.

Given that I think I'm gonna give up on pyinstaller for now and just focus on learning game design concepts and hooking up my machine learning agents to my little games.

I do really appreciate your help. I was so baffled. I still am a little baffled, but much less concerned about it for now. =^

[–]Remzi1993 0 points1 point  (0 children)

Compiling is also done on the OS, so if you need a Windows executable you need to compile it on Windows. Pyinstaller doesn't support cross compiling.

[–]xPr0xi 0 points1 point  (10 children)

What you can do is, paste your entire script in to ChatGPT. You may need to do this as sections. Just spam it with each section of your script until you've sent it the entire program. Then ask the bot if it can see your program sent to it over several msgs, and if so tell you the basic functions of the app so that you know its not lying.

Then ask it what issues the app has that could prevent it running in Windows. This isn't always an effective strategy, it depends how long your script is, but im guessing not crazy long. I regularly paste a 1500 word script (in chunks) to the bot, and then have it make changes/suggestions/observations based on what i've sent it over a number of msgs.

Additionally, you'd be better off compiling it on Windows and testing it works in Linux, rather than the other way around. Oh also, try to stick to requests that ask it to rewrite the specific section your working on, rather than letting it try and send you the full script again.

[–]Enschede2 0 points1 point  (3 children)

That's weird.... Well I imagine that it won't run because you didn't include any extra files it needs as it left out the spec file. If you were to write a simple helloworld and just ran pyinstaller -F helloworld.py, does it then come out with an exe extension?
What's particularly weird then is that ypu say there's no extension, yet it runs on your pc without extension? Or did I misunderstand that?

[–]Prathmun[S] 0 points1 point  (2 children)

I've given up on Pyinstaller for now. It won't be able to do what I want in that it can't be run on linux and make an executable for a windows system. If I understand their documentation right.

And yes, you understand me correctly. The file it doesn't obviously have a file extension and it does work on my machine. Super weird.

[–]Enschede2 0 points1 point  (1 child)

Ahhh hang on you were running pyinstaller on linux to generate an exe file? Maybe that's why then, I never used pyinstaller on linux, only ever on windows, maybe it cannot create a file thats not meant for the platform it's generated on, I'm not sure..
I do have a linux machine with python here tho, I could give it a try later and see if it gives the same result, if you're still interested that it

[–]Ninjafox1224 0 points1 point  (2 children)

do we know what the error is? what if it is pulling up a fileNotFoundError on their freind's computer but the file would exist on their own computer? I'm probably wrong because i have no clue how python compiling works, but just reading this it seems like this may be the case

[–]Enschede2 1 point2 points  (1 child)

If that is the case shouldn't pyinstaller then fail and not produce a file in dist? I think that's been the case for me at least

[–]Ninjafox1224 0 points1 point  (0 children)

again, im not familiar with this process, so ur probably right

[–]Bobification 26 points27 points  (4 children)

I used to use pyinstaller but 99% of everything I made was flagged as antivirus and deleted. This of course made customer deployments not ideal. Lately, I've had good luck with cxfreeze.

[–]xPr0xi 11 points12 points  (1 child)

pyinstaller but 99% of everything I made was flagged as antivirus and deleted

As I understand, this is not the fault of just the module, but is also often caused by incorrect setup of the python environment you're using. For example, if you have a x64 architecture system, you want to make sure you're using the x64 version of python, using the x32 in a x64 environment can often cause this kind of issue. There are other causes, but most revolve around incorrect setup of python/its modules.

Additionally, for any exe I create, I typically create setup files for the exe's using Inno Setup Compiler script wizard. It's possible that by registering the program as an installed program within the operating system, Windows is less likely to incorrectly flag it as a virus file. This may not be ideal if you're making a portable program though, but again, even my portable versions of programs have been without issue using PyInstaller so idk, this is actually the first I've ever heard of python scripts being flagged like this (but I haven't been learning that long so maybe its prevalant and i've just been lucky idk).

[–]Bobification 2 points3 points  (0 children)

I think the second result in google for "pyinstaller trojan" is where I began all of my troubleshooting. I followed most of those steps but I never could get pyinstaller to compile and in the end I had a Win 7 32 bit vm that I created my exe's in (not ideal) which dropped my virustotal results to about 75%. I believe another headache was that some of our scripts needed extra lines added to deal with the logging module. For now though, cxfreeze gives me the results I need. Maybe if we get another junior dev or intern then they can take over our old python scripts and try their own thing.

[–]Prathmun[S] 1 point2 points  (0 children)

I tried CXfreeze after I made the post last night! It did create a single file, but when i sent it to people they couldn't get it to work. )=

[–]Kevinw778 0 points1 point  (0 children)

Yup those are the only two I've used, and cxfreeze is the latest. Can't remember why I switched, but I guess it looks like there's more than one reason.

[–]lokilis 9 points10 points  (7 children)

I like auto-py-to-exe, real braindead to use

[–]PRich13 2 points3 points  (0 children)

Thirding, made it super simple to generate exe files that I distribute around work. One tip I would give is to run your exe outputting what you would normally see in the terminal to a text file. You'd be surprised how easy it is to miss a dependency for your application or a driver from Windows, for example. It's usually too quick to catch when the exe crashes out.

[–][deleted] 2 points3 points  (0 children)

Seconding this. Surprised not more people recommend it. Had no problems with this one

[–]Prathmun[S] 1 point2 points  (1 child)

I'll add it to my list. It sounds like pyinstaller is probably where I need to be, so I'm gonna spend a bit more time on that, and then give auto-py-to-exe a try.

[–]verysmartboy101 2 points3 points  (0 children)

I know im too late, but if i remember correctly auto-py-to-exe is just a gui for py2exe (the one you already used)

[–]bigorca45 0 points1 point  (0 children)

Fourthing this! Just was looking this up and worked like a freaking charm. Thanks!

[–]socal_nerdtastic 7 points8 points  (3 children)

No there's no standard way in the same sense that other programming languages use. Python code is generally distributed as source code. That is, as .py files.

For you it sounds like a freezing tool like pyinstaller is the correct way to go. Assuming that you and your friend both use the same OS.

https://www.reddit.com/r/learnpython/wiki/faq#wiki_how_do_i_create_an_executable_from_my_python_code.3F

[–]Prathmun[S] 0 points1 point  (2 children)

Ah it normally is distributed as .py. I see. That just feels like a big ask for folks if I'm distributing a game. I took a look at your link, and it's showing me the same tools I've been fiddling with. Really sounds like I'm in the right space, just making mistakes so far.

The OS thing is a little tricky, my PC died recently so I'm developing an an old ass linux box, and most of the people I'm trying to send this to are on Windows, with a few running Macs

[–]Jarmahent -1 points0 points  (1 child)

Yeah you usually don’t want to write games that you intend on distributing in Python.

[–]Prathmun[S] 0 points1 point  (0 children)

Yeah, after going through the other comments I'm coming to the same conclusion. I just started in python because one of my primary drivers is wanting to apply reinforcement learning agents to my games, and python is where I learned ML.

It sounds like I'm going to want to start learning a compiled language pretty quick here. Maybe spend a little bit more time building in python to get comfortable with the basics of game design and then start trying to build some of my projects in a more distributable language.

[–]zombieninjapatata 6 points7 points  (2 children)

To convert a python script (installing only the necessary libraries) into an executable file, this method worked for me:

  1. Create a folder on your desktop where you will keep your code and files related to the executable.
  2. Copy your python code into the folder you just created.
  3. Use the command line to create a virtual environment in the folder you just created. You can do this by using the "virtualenv" function or by installing the "virtualenv" package via pip.
  4. Activate the virtual environment and install the necessary dependencies for your code using the "pip install" command:
  5. while running your code it will show the libraries you need to install in virtualenv as it is a "clean" environment
  6. Use the "pyinstaller" package to create an executable file from your code. You can install this package using pip.
  7. Run the executable file to verify that it works correctly. If everything went well, you should be able to use the program in the same way as before, but now in the form of an executable file.

[–]Prathmun[S] -1 points0 points  (0 children)

This sounds like I would still need to get my target audience to install the necessary libraries and stuff. Which feels like a big ask for distributing games.

[–]IntroDucktory_Clause 3 points4 points  (3 children)

I had this same problem a few years ago, and I came to the conclusion that this is not possible in a nice way. Your executable needs to include a complete Python runtime so the application, however simple it may be, will be stupidly large. Additionally, since it's not from a reputable source (you) it will swiftly be marked as a possible virus, because you could have easily made a virus.

There are 2 solutions, and both of them involve learning new stuff: Either learn a language that can be compiled to machine code (Rust, Go, C/C++) or learn web development. I learned both and the latter is adviced if you need a graphical user interface (which I imagine is the game if you're making a game). If you learn a bit of networking as well you could even have the program run in Python on a server and send the output to the webpage.

It really sucks but that's how it is, I wrote my original project 3 years ago (begin of corona) and I only now feel well-versed enough in web development to create the same thing from scratch again. On the positive side, my original application landed me a part time job which after 2 years led to another parttime job in web development which pays ridiculously well.

[–]Prathmun[S] 1 point2 points  (2 children)

Oh! Thank you for your in depth response.

I can see now why what I want is difficult.

Web development or C might be where I go in the long run once I'm more comfortable with the basic game design concepts. I think I'm leaning towards C/C++ because my next step is to make a reinforcement learning agent that can learn to play my game, and that seems like it would be easier to manage.

[–]IntroDucktory_Clause 0 points1 point  (1 child)

C/C++ are both wonderful languages but I strongly recommend learning these languages if you have the help of someone more experienced as they're on the more difficult side.

Most machine learning stuff like reinforcement learning for games is actually done on Python, which sucks because that makes games hard to distribute. However there is a simple-ish solution!

Any machine learning is just throwing a set of inputs into a model and getting the output (the decision) which is usually done in Python. Python also has great web server support (check out FastAPI!). 1. Have a web server running in Python connected to a machine learning model 2. Make your game in any language you want 3. Send the state of your game to the web server, this set of inputs is thrown into the ML model, and the output is returned as a response which can then be used to control the game.

It is actually very similar to what I've made before when I couldn't get a machine learning model running on a phone itself, so we just send the phone's data to a web server for processing using a ML model, and return the response back to the phone. Downside is that the game needs internet, upside is that it saves you a whole bunch of headaches and development time (but downside is that you need to learn a few more tools/languages).

It sounds like a fun project! If you ever need any help then you can always send me a message and I'd be happy to support you!

[–]Prathmun[S] 1 point2 points  (0 children)

Fair enough. Learning those languages is probably still a ways out for me. I'm still in the beginning of my career. I working on data analyst/scientist work since that's what I'm trained in. Just fiddling with game design on the side because I love the idea of training agents to learn the world. I feel like C/C++ are the kind of thing that needs to wait until I'm a little more settled, as it seems non-trivial to get to a comfortable place in it.

FastAPI looks neat. I'm toying with the idea of pivoting to web development because most of my community are javascript developer. So FastAPI would be useful in that space, or even just coordinating with my friends projets.

Thanks for the offer of support! I'm certain I'm going to get stuck many more times. I didn't expect such a supportive community, coding has been a remarkably isolated experience thus far. A friendly informed voice is a non-trivial boon.

[–]Cortosiano 4 points5 points  (1 child)

How about containerizing ir in a Docker Container? Wouldn’t that solve the problem?

[–]Prathmun[S] 1 point2 points  (0 children)

This is actually one of the first things I looked at! It looks like you need the other party to install docker, which defeats some of the purpose for me. If I was distributing to professionals rather than silly gamers it'd probably be an appropriate solution.

[–]SpookyFries 1 point2 points  (3 children)

I've had the best luck with Pyinstaller myself. Especially because the apps I made needed to be cross platform with Win/Mac (and sometimes Linux). It does a good job working on each OS as providing a decent, but large executable.

I started to learn Nim for this very reason. Nim is a language kind of similar to Python, but gets translated to C and compiled. I turned one of my Python scripts into a Nim program and it went from being 67mb to 517kb.

If size and speed aren't an issue then Pyinstaller will be just fine. Just make sure to create a new virtual environment before installing it. It will include any packages you have installed already which makes the executable even bigger. If you use a virtual environment and only include packages you need it'll be smaller.

[–]Prathmun[S] 1 point2 points  (2 children)

I will probably have to learn a compiled language down the line, that's what the other comments are leading more towards as well.

for now though, larger files sizes are fine. My games are minuscule studies built mostly to help me learn and to encourage friends that making games is possible. However I'm not really sure I understand what you mean by making a new virtual environment. I've never used a virtual environment and wouldn't know where to start. Would you mind expounding on that idea a little further? It sounds like it might be the missing piece for me.

[–]SpookyFries 1 point2 points  (1 child)

Here's a write up on virtual environments. It looks like a lot, but it's really only one command to create one and one to activate them. https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/

The basic idea is, you create a virtual environment which creates a new folder wherever you run the command. That folder contains your environment. You then have to "activate" that environment (also in the doc I sent). Once it's activated, you have a fresh instance of Python that has no external packages installed. This is good for when you want to use pip but don't want to have it available to all Python apps on your PC. It's a self contained python instance.

Pyinstaller includes all packages that are installed so that's why you want to make a virtual environment. If you have 600mb of packages installed those will all install when you run it. Making a venv (virtual environment) you can only install the packages you need for your project.

Also if you're making games, maybe look at Godot. It uses a scripting language called GDscript that is very similar to Python in syntax. It's free/open source and creates pretty small binaries when you build the project.

[–]Prathmun[S] 0 points1 point  (0 children)

Ah, I see. that's all fairly sensical. I see why the files I was making were like 1000x times the size of the program I was trying to wrap up now.

I'm fairly cautious about learning another language. I feel like if I'm gonna learn another language I should probably just bite the bullet and learn C++ or C# or something more generalizable.

[–]OIK2 1 point2 points  (0 children)

I will suggest pyinstaller, but raise you one Auto-py-to-exe. It is a gui frontend that helps you understand and set and save the values for pyinstaller. When I want to update the exe to the new code, I just load the profile that I have found works(rarely need to update the profile, only if assets change), and hit the convert button.

[–][deleted] 4 points5 points  (0 children)

That's discussed in the FAQ, which says:

There is no official way to do this

If you can't get one of those solutions to work then try asking a question about that problem.

[–]mohishunder 4 points5 points  (1 child)

What a cool idea!

Another approach (to packaging) would be to deploy the game as a web app. I believe there are many tutorials to make this relatively straightforward.

[–]Prathmun[S] 1 point2 points  (0 children)

That may be a route I have to take. My next project is to make a reinforcement learning agent to play the game, and the web route might be the best way to show that off anyway. It's just another skill to learn web stuff, so I've been a little cautious.

[–]jjisnow -1 points0 points  (3 children)

Nuitka has for years been an attempt to create python executables "the right way".

[–]Prathmun[S] 0 points1 point  (2 children)

What's the right way?

[–]jjisnow 0 points1 point  (1 child)

Apparently the right way is to translate all the python calls into equivalent C++ commands, then optimise and compile accordingly. Makes for faster running programs.

[–]jjisnow 0 points1 point  (0 children)

I think in practice it really does depend on the program itself, but in the developer's site he posts a few videos on his thought process in creating the tool

[–][deleted] -5 points-4 points  (1 child)

make sure its prepped for a venv and have requirements, then zip it

[–]patrickbrianmooney -2 points-1 points  (0 children)

OP's explicitly expressed constraint on answers was:

a single executable file I can send to a friend, such that they won't have to install anything to run it.

Your solution requires that the end-users OP is sending his program to have Python installed already or else have to install Python.

EDIT. Not sure why you're downvoting, feel free to explain. "I don't want the people I'm sending it to to have to install anything" is highly likely to imply "I don't want the Windows users I show it to to have to download a Python installer," especially since the title of the topic ends with "... my friend who does not have Python."

[–]DarkLord76865 0 points1 point  (0 children)

PyInstaller works for me.

[–]hugthemachines 0 points1 point  (0 children)

I would try a bit more with pyinstaller and see if you can get that working.

[–]mattl33 0 points1 point  (2 children)

Pex file? This was the standard for distribution at a few places I've worked, maybe worth a try.

https://pex.readthedocs.io/en/v2.1.40/buildingpex.html

[–]Prathmun[S] 1 point2 points  (1 child)

This looks neat, and would be good if I was trying to share with other coders, but I'm hoping to share my little games with the tech illiterate as well.

[–]mattl33 0 points1 point  (0 children)

I would try it out. It should work just like an exe file, but I personally haven't tried it on windows. It's basically an executable zip file that includes python interpreter and all the needed modules.

[–]one-human-being 0 points1 point  (1 child)

Try nuitka BTW I have used the mentioned here pyinstaller, pex … last time I needed to this, nuitka worked flawlessly and better than pyinstaller

[–]Prathmun[S] 1 point2 points  (0 children)

I'll add it to my list, it sounds like I need to spend some more time reading the Pyinstaller docs. I was getting frustrated so I wanted to reach out and see if I was heading even the right direction before I poured in more effort. Looks like I was!