skeeto / w64devkit

Portable C and C++ Development Kit for x64 (and x86) Windows
The Unlicense
3k stars 211 forks source link

Update w64devkit.c #83

Closed grable0 closed 1 year ago

grable0 commented 1 year ago

Fixes fatal() to use ExitProcess() instead. Passes any arguments received to onto the shell login (i use this together with ConEmu-Here to change the working directory and even execute files from .profile) Adds a terminal title. Increases stack size for the passing of arguments.

skeeto commented 1 year ago

Thanks, I missed that return. I'd rather keep everything flowing to one exit, so fixed it differently (42d0a17), following what I did in alias.c.

I like your idea for SetConsoleTitle, too! I've been doing that in my .profile, but it ought to be the norm. I also plucked that out (0a652a6).

As for passing arguments through to the shell, I'm unsure. w64devkit.exe may eventually accept flags, but a policy of passing the command string through to the login shell eliminates that option. At the very least I'd delimit shell arguments behind, say, "--". What's your angle on this? Your commit message says something about the working directory, but I want to better understand the need you're filling. I see you also added "-s". Does that solve some problem?

Revisiting w64devkit.c, I'm probably going to overhaul it. I wrote it over two and a half years ago, and I've had a lot more practice and learned a whole lot since. I can easily eliminate the custom stack configuration, as well as simplify the fiddly string manipulation. I'll keep in mind the login shell argument passthrough while I do.

grable0 commented 1 year ago

I only use it for one thing, namely to start a ConEmu terminal from anywhere in Explorer and optionally run executables/scripts. With some registry tweaks adding items to the right click menu which then passes the file or directory referenced in Explorer over to w64devkit.exe.

The real deal happens in the profile where the argument is checked to determine if its a file or directory and then use the directory component to set the current directory. Additionally i can then check if its an executable file or script and run it directly in the new terminal.

This is already something supported by ConEmu, but since w64devkit.exe sets the current directory it overrides the one set by ConEmu prior to launching w64devkit.exe. Also i belive this ConEmu feature may interfere with where w64devkit.exe is started from, which may prevent it from finding its /bin directory etc.

Note that all this can be done without ConEmu too, and just use w64devkit.exe directly from those registry tweaks.

Using -s is just to guarantee the argument end up as $1 in sh, which is is to say i currently only use one argument. Though i admit my familiarity with sh is low, so i dont know if this is required or not. So the passing of arguments does not have to be verbatim like i did but could be under something similar like for example an --args option or just -- as you prefer, which would still allow you to add other options in the future.

I know this probably isnt something used by most people and in that it defers all processing to the profile may not be to peoples liking.

For more information about this i added 2 files to my fork, w64devkit-here-profile and w64devkit-here.reg which is where the meat and potatoes are ;)

skeeto commented 1 year ago

Thanks for the detailed explanation. I understand better now.

You looked at the launcher source, so you've seen it barely does anything. It's a glorified shell script, except without a decent system shell to run it, it must itself be a standalone executable. The original launcher was a batch script, activate.bat, but cmd.exe turned out to be too inflexible even for this simple task.

Well-behaved alias commands on Windows https://nullprogram.com/blog/2021/02/08/

activate.bat was just a couple of lines to prepend the adjacent "bin" to $PATH, then run "busybox sh -l". If whatever you're launching from can do that much, which it sounds like it can, then you don't need w64devkit.exe at all. Set $PATH then invoke the shell directly in whatever way you need.

$W64DEVKIT{,_HOME} are for use in your in own scripts and .profile, and w64devkit itself doesn't use or need them. It sets $HOME according to w64devkit.ini, but again, that's just a convenience feature.

since w64devkit.exe sets the current directory

It might seem odd that w64devkit.exe changes the working directory without attempting to go back when it's done, but the login shell itself changes to $HOME on start. If you don't ask ash to be a login shell, it leaves the working directory alone. It seems you perhaps don't want it to be a login shell anyway. If so then don't pass "-l". (In fact, the shell itself is optional, and you really only need bin/ in you $PATH to use the tools.)

Does that make sense? Am I missing a detail that makes launching through w64devkit.exe important? I see you even have an entry in your .reg that lets you even keep using the nice icon without running it!

If it turns out invoking the shell directly is the right solution for you, it should probably be captured in documentation since you're probably not alone.

grable0 commented 1 year ago

Indeed that is what i initially did, have a batch file that did virtually the same thing as w64devkit.exe, but i didnt like having that superfluous cmd.exe hanging around either and i thought if ever there was changes to how w64devkit.exe operated id have to keep up with it.

In short w64devkit.exe just felt more clean ;)

I replicated that batch script at the top of my .profile instead and then using C:\w64devkit\bin\sh.exe -l -s directly and yes that does work just fine (i prefer the -l since then it will automatically run my profile).

So i guess there really is no need for this specific use case inside w64devkit.exe even if it is technically cleaner.

What i added to that profile:

title() {
    echo -ne "\x1b]0;$1\a"
}
PATH="C:/w64devkit/bin;$PATH"
W64DEVKIT="$(cat C:/w64devkit/VERSION.txt)"
W64DEVKIT_HOME="$USERPROFILE"
title "w64devkit"