Help with Resources Directory

63 views
Skip to first unread message

Matt Martin

unread,
Oct 15, 2013, 5:39:02 PM10/15/13
to cava-p...@googlegroups.com
Hello All,

Operating System: Windows XP Professional
    Cava Packager: Version 2.0.80.693
         Perl Version: Version 5.14.4

*FYI, this is my first project with CavaPackager.

I was wondering if there was a way to chose where the resource files I include in my project get installed to when I run the Installer created from the "Build".
Currently, after I run the installer (*which is pretty awesome BTW, seeing my program in an Windows Installer, I'm used to running my Apps from a CLI in Linux) the resources get installed to:
         C:\Program Files\MyApp\res\*

In that resources directory I also have another directory (*One sub directory) , and they all contain images and .ico files. If I don't have to modify my script to accommodate this new directory instead, that would be best since I have a ton of lines where I specify images to use, etc... I use relative paths so I can be as portable as possible with the script so instead of having the path to my image being something like "C:/Program Files/MyProgram/icons/my_image.png", I use this instead --> "./icons/my_image.png"

I tried the example on this page --> http://www.cavapackager.com/appdocs/topicoverview-resources.htm

And here is what I added to my script:
             *I tried both of these methods below and then rebuilt and tested after each one, but neither changed anything.

----------------------------- 1st -----------------------------
          use Cava::Packager;
          Cava::Packager::SetResourcePath('C:\CSRTicker_src\icons');

----------------------------- 2nd -----------------------------
          use Cava::Packager;
          Cava::Packager::SetResourcePath('./icons');


I wasn't sure if I was supposed to manually add the resource dir too from the "Resources" branch of the project tree, so I tried both with and without... Still no luck.

Is what I'm trying to do possible? According to the documentation the purpose of the SetResourcePath is to:

                     "Cava Packager provides a simple method of accessing files and resources from your scripts in the perl environment
                      that will work unchanged in your packaged executables.

                      You can achieve this by using a single resource directory in your development environment for all your resource files.
                      For example, you could store all of the images that a script requires in a single directory.
"

Which sounds exactly what I'm trying to do...
Does anyone have any idea what I'm doing wrong here? Any thoughts or suggestions would be greatly appreciated.

Thanks in Advance,
Matt

Matt Martin

unread,
Oct 17, 2013, 1:38:47 PM10/17/13
to cava-p...@googlegroups.com
Hey There,

So I think I figured it out thanks to this post below and the reply by Mark. Sorry, I didn't see that post until after I submitted mine.
              https://groups.google.com/d/topic/cava-packager/zDu9Ar79giU/discussion

I added the following lines and the images are working now:
        ### Added this to the start of my Script:
        #    Within the dir "./icons", there is one other Dir --> "./icons/StartMenu_Icons/"
        use Cava::Packager qw( CRF );

        Cava::Packager::SetResourcePath('./icons');

        ### Then used these lines at different parts of my Gtk2 GUI and replaced the current:
        #   *I realized we didn't need to specify the "icons" dir at all again, we just assume
        #    we're already in that dir so to access a Sub-directory of "icons" I do:
        my $icon1 = Gtk2::Gdk::Pixbuf->new_from_file( CRF( 'StartMenu_Icons/Icon_Set/Icon_1-16x16.png' ) );

        #    *And to get a file directly under the "icons" directory we just use the file name, like this:
        my $LOGO = CRF( 'NEW_Logo_3.png' );
        my $logo_image = Gtk2::Image->new_from_file( $LOGO );


And that's it...
Pretty simple now that I think about it, but luckily I only had about 10-15 images to convert to use the CRF('...') syntax from the Cava::Packager Module.

If your reading this, thanks Mark for your post in that topic I posted the link for above...


Thanks,
Matt

Matt Martin

unread,
Oct 17, 2013, 2:04:00 PM10/17/13
to cava-p...@googlegroups.com
I did have another question if someone could help me out.

This one is about calling another script that was included as a "script" in my Project's Build.

Previously, when I would execute my Main Gtk2 Script from the command line, I would call another perl script from within that one. I always had both scripts in the same directory so I would call it like this:
      my $background_script = "./bg_script.pl"

Then I would use that to run it as a background job. Using the "Proc::Background" Perl Module.

Now after I built the project I get a No such file or Directory error when running the Main executable file. After the build completed I noticed it would place that file in the ./bin directory. So I edited my script to use:
      my $background_script = "./bin/bg_script.pl"

But I still get a similar error for that too --> "Can't open Perl Script './bin/bg_script.pl': No such File or Directory".

I chose to place my Main Executable in the Root directory and NOT the /bin dir. Is that ok to do in my case?
How should I be calling this script (*which is also a .exe after the build)?

Any thoughts or suggestions would e greatly appreciated.

Thanks in Advance,
Matt

Johan Vromans

unread,
Oct 17, 2013, 5:10:38 PM10/17/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> Any thoughts or suggestions would e greatly appreciated.

Is Cava::Packager::GetScriptCommand what you'r elooking for?

( http://www.cavapackager.com/appdocs/utilities-utility.htm )

-- Johan

Matt Martin

unread,
Oct 17, 2013, 5:42:39 PM10/17/13
to cava-p...@googlegroups.com
Hey Johan, thanks for the reply!

I'm not sure, does that 'GetScriptCommand' actually execute the script? If so I'm using the "Proc::Background" Module to execute the script in the background, which is something I need to have.

I was also somewhat confused if I need to change my code to look for the file "bg_script.exe" instead of "bg_script.pl".
I tried both ways anyway and I still get the file missing error every time.

######################################################################################
What my original code was to execute the Background job/script:

    use Proc::Background;
    .........tons of other lines of code..........
    ......more.......
    ......more......
    ...................
    my $background_script = "./bg_script";
    .......more code to execute script based on a condition.......
    .....................................................................................
    $proc = Proc::Background->new("$background_script $ARG $ARG $ARG $ARG $ARG $ARG");
    my $PID = $proc->pid;
    my $start_time = $proc->start_time;
    my $alive = $proc->alive;
    ......................................
    ....code to loop and check if the process is done....
    ....exit based on return code from background script.....
######################################################################################

So do you know if that Function executes the script or does it just prepare it to be executed? I read the documentation you posted but I really didn't get it..?


Thanks Again for the reply, much appreciated!

Thanks,
Matt

Johan Vromans

unread,
Oct 18, 2013, 2:17:21 AM10/18/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> I'm not sure, does that *'GetScriptCommand'* actually execute the
> script?

No, it gives you the command line to execute the script, from the
perspective of the packaged application.

It is intended for executable scripts that are packaged within the
package (you know you can package more than one executable script in a
package?).

For example, in one of my packages, I have a menu script menu.pl that
invokes action1.pl or action2.pl and so on.

From menu.pl:

system( App::Packager::GetScriptCommand
( "action1.pl", [],
$fullscreen ? "--fullscreen" : (),
$geometry ? ( "--geometry", $geometry ) : (),
"--standard",
) );

I assume this works similar for Proc::Background.

-- Johan

Matt Martin

unread,
Oct 18, 2013, 10:44:33 AM10/18/13
to cava-p...@googlegroups.com
Hey Johan, thanks again for the reply!

Ok, that makes sense. Thanks for the example too, I'll give that a try.

With your "secondary" scripts (now executables..?) where do your's get stored after you run the build? I see in your example you just use the script name with no Path, does that mean you have them built into the same directory as your Main Executable (*i.e. the "root" dir), which for example, calls "action1.pl"..?

Also, did you make your "action1.pl" and "action2.pl" scripts into executables? I was wondering if you left them as Perl scripts or if you built them into exe's, because I was confused about needing to use either ".pl" or ".exe" in MY code?

Thanks again for the reply!

Thanks,
Matt

Matt Martin

unread,
Oct 18, 2013, 10:51:54 AM10/18/13
to cava-p...@googlegroups.com
One other thing that I forgot to ask in my last post.

What are the extra symbols, square brackets, question marks, parenthesis, colons, etc in you line of code? I was just a bit confused about that...

For example, the stuff I put in bold below...?


     system( App::Packager::GetScriptCommand
             ( "action1.pl", [],
               $fullscreen ? "--fullscreen" : (),
               $geometry ? ( "--geometry", $geometry ) : (),
               "--standard",
            ) );


Thanks in Advance,
Matt

Johan Vromans

unread,
Oct 18, 2013, 3:39:06 PM10/18/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> With your "secondary" scripts *(now executables..?)* where do your's
> get stored after you run the build?

I don't know -- and don't care, as long as GetScriptCommand returns the
actual path.

> I see in your example you just use the script name with no Path, does
> that mean you have them *built* into the same directory as your Main
> Executable *(*i.e. the "root" dir)*, which for example, calls
> *"action1.pl"*..?

No the scripts are not built individually, but packaged together in a
single executable.

In the 'Scripts' section I have "menu.pl", "action1.pl" and so on. In
the 'Executables' section I have executables "menu", "action1" and so
on, corresponding to the scripts.

> Also, did you make your "action1.pl" and "action2.pl" scripts into
> executables?

No, Cava Packager packages everything into one single executable that
has entry points "menu", "action1", and so on.

> I was wondering if you left them as Perl scripts or if you built them
> into exe's, because I was confused about needing to use either *
> ".pl"* or *".exe"* in MY code?

Major advantage is when the scripts are (more or less) related and share
libraries and modules. Instead of having multiple executables of 80MB,
each requiring significant startup overhead, you now have one single
81Mb executable, and a one-time startup overhead.

-- Johan

Johan Vromans

unread,
Oct 18, 2013, 3:43:06 PM10/18/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> For example, the stuff I put in bold below...?*

I only see stars... Please refrain from doing this.

> system( App::Packager::GetScriptCommand
> ( "action1.pl", [],

Second argument is an array ref of perl options, which is empty in my
case.

> $fullscreen ? "--fullscreen" : (),

Perl's ternary ?: operator.
<expr> ? <true-part> : <false-part>

> $geometry ? ( "--geometry", $geometry ) : (),

Same here.

-- Johan

Matt Martin

unread,
Oct 18, 2013, 4:02:07 PM10/18/13
to cava-p...@googlegroups.com
Hey, thanks again for the reply!

Humm... Ok, I'm starting to think now that I don't have my stuff configured correctly in the CavaPackager GUI.

My Perl program works like this:
I have my main "GUI" program which uses Gtk2. I then only have ONE other Perl script which gets executed in the background, getting called from within the Main GUI script. The background Perl script will write errors to a log file (*i.e. a txt file). Then lastly I have Images, but I got the images part working finally the other day.

So pretending CavaPackager doesn't exist my Program has the following pieces:
   Perl Script: Main_GUI.pl     --->   This is the main GUI.
   Perl Script: bg_script.pl      --->   This is a Background script that gets called from inside the main GUI script at some point. It write errors to the log file below
 Txt Log File: ./log/output.log  --->   This is a log file I set as a Mapped File using "my $LOG_FILE = CMF( './log/output.log' );"
       Images: ./icons/*            --->   These are use inside the Main GUI script

And I setup CavaPackager like so:
   - Under the "Executables" Tree:
         1. Main_GUI.exe
         2. bg_script.exe
   - Under the Scripts Tree:
         1. Main_GUI.pl
         2. bg_script.pl


Did I not do that correctly?

Thanks Again,
Matt



Matt Martin

unread,
Oct 18, 2013, 4:17:36 PM10/18/13
to cava-p...@googlegroups.com
This is in reply to you explanation of the "App::Packager::GetScriptCommand" command.

Ok so basically all those extra symbols and what not are really just for your case there. For me the background script takes 5 arguments
like these:

       ARGs to Background Script:
                --speed=INTEGER
                --message="QUOTED_STRING"
                --start-time=STRING
                --end-time=STRING
                --color=HEX_STRING

So how would I do that given those are the CLI Arguments, and BTW my background script will ALWAYS receive ALL of the arguments, there will never be a case where say only one is passed...

If my current command to execute the background script it this:
$proc = Proc::Background->new("bg_script.pl $speed_ARG \"$msg_ARG\" $start_ARG $end_ARG $color_ARG")

How would I incorpoprate that into the  "App::Packager::GetScriptCommand"  Command..?

Thanks Again,
Matt

Johan Vromans

unread,
Oct 19, 2013, 8:16:53 AM10/19/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> If my current command to execute the background script it this:
> $proc = Proc::Background->new("bg_script.pl $speed_ARG \"$msg_ARG\"
> $start_ARG $end_ARG $color_ARG")
>
> How would I incorpoprate that into the "App::Packager::GetScriptCommand"
> Command..?

$proc = Proc::Background->new
( App::Packager::GetScriptCommand
( "bg_script.pl", [],
$speed_ARG, $msg_ARG, $start_ARG, $end_ARG, $color_ARG ) );

-- Johan

Johan Vromans

unread,
Oct 19, 2013, 8:22:58 AM10/19/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> And I setup CavaPackager like so:
> - Under the "Executables" Tree:
> 1. Main_GUI.exe
> 2. bg_script.exe

Executable Name Type Packaged Script
Main_GUI GUI Main_GUI.pl
bg_script Console bg_script.pl

> - Under the Scripts Tree:
> 1. Main_GUI.pl
> 2. bg_script.pl

Looks correct to me.

-- Johan
Message has been deleted

Matt Martin

unread,
Oct 21, 2013, 1:38:11 PM10/21/13
to cava-p...@googlegroups.com
Hey Johan, thanks for the reply!

Not sure if you read my previous post, I posted about hour ago or so, but I deleted it because the questions were answered...

It seems that the command you posted in your last reply seemed to work for me, so it looks like it's now executing my bg_script.pl script so were good on that... Thanks again for that post, much appreciated!

One last thing (*hopefully), Since the bg_script.pl is a background script I write STDERR out to a log file. I wasn't quite sure how to handle the log file so I attempted to use the Mapped Files function of the "Cava::Packager" Module. But I am getting an error for "uninitialized value $LOG_FILE...".

My line that declares the log file was this:
    my $LOG_FILE = CMF( './log/CSRTicker.log' );
And also just tried this one:
    my $LOG_FILE = "./log/CSRTicker.log";


As you can see the log file is located under the root directory, inside a sub dir called "log". How should I declare this log file? Is there another Utility function that I need to use for this as well?

Thanks in Advance,
Matt

Johan Vromans

unread,
Oct 21, 2013, 4:52:32 PM10/21/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> I know you said that you have multiple .pl scripts that get "built"
> into a single executable file. So should I have multiple .exe files?
> Right now I have 2 Perl scripts included in my project as you saw, but
> I also have 2 executables that get created when I build the project.
> Is that correct, or should I only have one .exe file after it builds
> the project like you said your project is, For example, you said you
> have multiple scripts in one executable file..?

After installation you have multiple .exe files, one for each script.
When you inspect these you'll notice they are rather small. That's
because they are some kind of 'loader' that just loads the real code --
and that is shared between te scripts.

HTH,
Johan

Johan Vromans

unread,
Oct 21, 2013, 4:58:40 PM10/21/13
to cava-p...@googlegroups.com
Matt Martin <mrm...@gmail.com> writes:

> *My line that declares the log file was this:*
> my $LOG_FILE = CMF( './log/CSRTicker.log' );
> *And also just tried this one:
> * my $LOG_FILE = "./log/CSRTicker.log";*
> *
>
> As you can see the log file is located under the root directory, inside a
> sub dir called "log". How should I declare this log file? Is there another
> Utility function that I need to use for this as well?

I'm not sure. You can always put the log file in /tmp or /var/tmp to be
sure.

But I have the feeling that you are trying to set up some sort of
communication between the foreground and background process. If so,
there are much better alternatives, e.g. Wx::Perl::ProcessStream.

-- Johan

Matt Martin

unread,
Oct 21, 2013, 5:08:14 PM10/21/13
to cava-p...@googlegroups.com
Johan, thanks again for the reply.

Ok that makes sense, thanks for the explanation..!

Yes, you are right about the log file. Since the background script won't be able to print stuff to STDOUT I forward all output to STDERR and print it to a log file. Then in my Main script, if the bg_script returned with anything other then zero, it will read the log file and print that out in a pop-up window. All that stuff works just fine, so if it's something as simple as manually adding the log dir myself after the build/installation, I will just do that to save myself from having to change up alot of code in the Main and background scripts...

I was just about to attempt to build my project again using this code below to access the log file:

From within the Background Script:
################################################
    use Cava::Packager qw( CRF CMF );
    Cava::Packager::SetProjectPath('C:\MyApp_Project');
    ....................
    ........etc........
    ....................
    my $LOG_FILE = CMF('./log/MyApp.log');
################################################

Then I was assuming I would manually add the "log" dir to the root directory of the project path. I haven't tried this yet in any of my other builds I attempted, but hopefully it will work.

I'll give this a try (*probably tomorrow), and then post back and let you know what happened.
Thanks again for the help, much appreciated!

Thanks Again,
Matt

Matt Martin

unread,
Oct 24, 2013, 11:10:36 AM10/24/13
to cava-p...@googlegroups.com
Ok, so I tried everything I could do to get that Log file working, but couldn't get it to work correctly.

For some reason, it seemed like the background script successfully wrote to the log file, but when the Main GUI script attempted to read it I would get this error below... And I have no idea why since the variable was defined a few lines above the line with the error:
       "Use of uninitialized value $LOG_FILE in string at C:/path/to/release/dir/Main_script.pl line xxxx.
         *** unhandled exception in callback:
         ***     Error opening File: No such file or directory
         ***    ignoring at C:/path/to/release/dir/Main_script.pl"


As you can see, I got an error that "$LOG_FILE" was not defined, which was while attempting to execute this line below.

         open (ERRLOG, "<", "$LOG_FILE") or die "Error Opening File: $!\n";

But about 20+ lines or so before this one I had:

         my $LOG_FILE = CMF('bg_script.log');

So I have no idea why it would be giving this error for being undefined, even though it clearly is defined....

But I decided enough is enough and just tried to include the log file as a resource along with my images, since I had no problems accessing the image files I set with the "SetResourcePath" function and the "CRF" function, which is the short alias for "Cava::Packager::GetResource".


use Cava::Packager qw( CRF CMF );
Cava::Packager::SetProjectPath('C:\MyApp_Project');
Cava::Packager::SetResourcePath('./resources');
.........code...........
....
my $LOG_FILE = CRF('bg_script.log');

I then rebuilt my project and it now works for reading AND writing to the log file..!!!

Thanks again for the help!

Thanks,
Matt
Reply all
Reply to author
Forward
0 new messages