in reply to Re: problem with par as other user in thread problem with par as other user
PS. I am replying to Ace128 who asked quite essential question, so it do not fit in CB.
But this could be useful in general, I hope.
explanation on how redistributable perl is done with only in-memory unpacks
First of all, previous (lost, but easily recoverable) archive previously located at http://www.vkonovalov.ru/perl-for-cd.zip was perl-5.6.1 + perl/Tk
Currently I placed newer at http://www.vkonovalov.ru/files-exchange/perl58tk84-for-cd.zip which is based on perl-5.8.? and Tk GUI with Tcl/Tk, which is better than perl/Tk. (looks similar but more powerful)
How that works.
start.exe is a tiny C program (explain later) which uses perl58.dll and searches for file './modules/modules.pm' and feeds it to perl interpreter. This bootstraps in such a way that required modules are unzipped and loaded so 'modules/perl58.zip' becomes available to @INC.
Unlike PAR, perl58.zip is not unzipped entirely, only used what is used. Also, just not using filesystem at all could be beneficial in some cases.
How can I make file set even smaller
If I'll go further this easy way, (which probably was the way of all commercial packers), then:
- incorporate files "modules/modules.pm", "modules/redo.pm" into mentioned small C program, as C string, and eval it later.
- "start.pl" could be placed inside "perllib.zip"
- Use famous technique on appending "perllib.zip" to executable, which is perfectly possible.
- All required extensions could be built into perl58.dll, now this possible, see http://perldoc.perl.org/perl588delta.html#Installation-and-Configuration-Improvements. This requires compilation of perl, (but I'll better place required DLLs near around)
So this ends in 2 files: 1 EXE + 1 DLL, including Tcl/Tk.
start.exe, a tiny C program
Its trivial. It loads perl58.dll, calls RunPerl. Dead simple.
The only trick used (and its not my invention of course) it checks its name to have an idea on what script to run.
So I compiled the stub once, and then I just copy with different name to make engine to start "name.pl" script.
Same as busybox.
// a simple program which executes a perl script at
// one of following locations, whichever comes first:
// modules/[name].pl
// perl/[name].pl
// ./[name].pl
// modules/executor-resolver.pl
// perl/executor-resolver.pl
// ./executor-resolver.pl
//? modules/[name]
//? perl/[name]
//? ./[name]
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include "EXTERN.h"
#include "perl.h"
int main(int argc, char *argv[], char **env)
{
char bufstr[2048];
char fullpath[2048];
char name[2048];
char **xargv = (char**)malloc(sizeof(char*)*(argc+2));
char *script[] = // how to search for script to run
{
"modules\\",
"perl\\",
"",
0
};
char history[2048];
int i=0, j, k, rc;
bufstr[0]=0;
strcpy(history,"tried:\n ");
GetModuleFileName(NULL,fullpath,2048);
j = strlen(fullpath);
while (j && fullpath[j]!='\\')
j--;
j++;
strcpy(name,fullpath+j);
k = strlen(name);
if (stricmp(name+k-4,".exe")==0) {
//okay
name[k-4] = 0;
}
else {
MessageBox(0,name,"bad: not able to parse",0);
return 1;
}
//MessageBox(0,name,"good:",0);
fullpath[j] = 0;
strcpy(bufstr,fullpath);
// try with 'name' first
for (k=0;script[k];k++) {
strcpy(bufstr+j,script[k]);
strcat(bufstr+j,name);
strcat(bufstr+j,".pl");
strcat(history,bufstr);
strcat(history,"\n ");
#undef access
if (!access(bufstr,0)) {
//found it!
goto found;
}
}
// try with "executor-resolver.pl" at second set of tries
for (k=0;script[k];k++) {
strcpy(bufstr+j,script[k]);
strcat(bufstr+j,"executor-resolver.pl");
strcat(history,bufstr);
strcat(history,"\n ");
#undef access
if (!access(bufstr,0)) {
//found it!
//but here script name should be inserted
xargv = (char**)malloc(sizeof(char*)*(argc+4));
for (k=0; k<argc; k++)
xargv[k+2] = argv[k];
xargv[2] = name;
xargv[1] = bufstr;
xargv[0] = "perl";
argc += 2;
goto run;
}
}
MessageBox(0,history,"Did not found.",0);
return -1;
found:;
//MessageBox(0,name,"!found!",0);
xargv = (char**)malloc(sizeof(char*)*(argc+3));
for (k=0; k<argc; k++)
xargv[k+1] = argv[k];
xargv[1] = bufstr;
xargv[0] = "perl";
argc += 1;
run:;
rc = RunPerl(argc, xargv, env);
free(xargv);
return rc;
}
Very same could be ported to Linux, of course, I just didn't this...
Re^3: problem with par as other user
by Ace128 (Hermit) on Jun 29, 2006 at 12:20 UTC
|
Hey!
Well, since this may be of more interest to more, I ask it here.
What do I have to do minimum to get this start.c to compile properly? I've downloaded the source from Activestate and setup Dev-C++ to find the headers and libs. Now, when I compile I get this:
I was hoping I wouldn't have to install M$ Visual Studio X. It seems that I have to do "configure" (to create the config.h file that is missing), but how to do this in windows? Would be damn cool if I could compile this start.c, since this little project seems really cool to me :) And besides, I need to add a pause in there to make it pause, and not close the terminal window when some tk script Im runing doesnt work. :) I get some error, but the window closes and I cant see the error. (Probably some module missing in this package that I use). Oh, and maybe somehow to get rid of the terminal window aswell when the tk script actually works!
But, I suppose the Perl interpreter is boundled into this start.c, and thus I need to be able to compile the whole Perl source aswell?
Thanks,
Ace | [reply] [d/l] |
|
why you need to compile start.c, in the first place?
Regarding compiling perl shipped with activestate with mingv, or free MS compiler, or else - please seek monastery, I remember many articles here.
Regarding
C:/perl-5.8.8/perl.h:37:23: config.h: No such file or directory
You do not have to create config.h with configure. Config.h shipped with Perl and is inside its directory ./lib/CORE/*.h
To get rid of terminal window - thats easy. Also, it should not show in the package that I've sent. On which step do you see them?
Did you succeeded running perl-cd-blablabla, BTW??
BR,
Vadim. | [reply] [d/l] |
|
Well well, interesting.. didn't know about those header files with the standard installable!
Running like "start tktest.pl" with this code:
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
my $mw = MainWindow->new;
#centers window
CenterWindow($mw, 300, 200);
MainLoop;
sub CenterWindow {
my($window, $width, $height) = @_;
#$window->idletasks;
$width = $window->reqwidth unless $width;
$height = $window->reqheight unless $height;
my $x = int(($window->screenwidth / 2) - ($width / 2));
my $y = int(($window->screenheight / 2) - ($height / 2));
$window->geometry("=${width}x${height}+${x}+${y}");
}
displays the terminal aswell. I just unzipped your package and ran this. Else I love this solution! :)
And now I compiled but linking seems to give me:
...Temp/ccARbaaa.o(.text+0x44):start.c: undefined reference to `_imp__
+win32_malloc'
...Temp/ccARbaaa.o(.text+0x35a):start.c: undefined reference to `_imp_
+_win32_malloc'
...Temp/ccARbaaa.o(.text+0x435):start.c: undefined reference to `_imp_
+_win32_malloc'
...Temp/ccARbaaa.o(.text+0x4bf):start.c: undefined reference to `_imp_
+_RunPerl'
...Temp/ccARbaaa.o(.text+0x4d5):start.c: undefined reference to `imp(w
+char_t, int, int, int, int, int, int, int, int, int, int, int, int, i
+nt, int, int, int, int, int, int, int, int, int, int, int, int, int,
+int, int, int, int, int, int, int, float, long double,...)(...)'
collect2: ld returned 1 exit status
Execution terminated
Ideas on this? :)
/ Ace | [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
|
|