resource directories

22 views
Skip to first unread message

aardvarkman

unread,
Nov 23, 2007, 12:52:47 AM11/23/07
to Cava Packager
Hi,

I have a number of resources which are in two diff directories:

root dir
myscript.pl
more scripts.pl
application dir
a bunch of other dirs
user dir
a bunch of other dirs

Should I change the dir structure so that the app and user dirs are
under a single res dir? By choosing the root dir as the resource dir,
the package includes the raw .pl files in the final package. Seems
like I need to change my dir structure so that the right thing happens
automatically.

true?

tia,

b

Cava Support

unread,
Nov 23, 2007, 6:36:21 AM11/23/07
to Cava Packager
Hi,

Yes.

Everything in your resource dir will get included. So if that includes
your source scripts they get included too.

You need a separate dir for your resources.

Regards

Mark

aardv...@gmail.com

unread,
Nov 25, 2007, 1:35:50 AM11/25/07
to Cava Packager
Ok. . . I'm getting closer:

1: I rearranged all dirs I need under one res dir.
2: I now have:

res
subdir
a file
a file
a file
subdir
a file
a file

3: when I package, I get a res dir with everything in it.

However, when I run the exe . . .the main pl file can't find the
resources. The path the resources has changed because the exe is now
in a bin directory. The path is ../res instead of /res.

Reading the help, it looks like I may have to do something like:
Cava::Pack::SetResourcePath('c:/myscripts/resourcedir');

Yet I have a 3000 line program and I find that I"m rearchitecting it
to use Cava. Am I missing something? Is there an easier way?

tia,

ben


Cava Support

unread,
Nov 25, 2007, 8:17:22 AM11/25/07
to Cava Packager
Hi,

For example, the file you want is at

'c:/myscripts/resourcedir/images/exit.png'

So.

Cava::Pack::SetResourcePath('c:/myscripts/resourcedir');

And when you want the file:

my $filepath = Cava::Pack::Resource('images/exit.png');

works both in myscript.pl and myscript.exe.

When packed as an executable, Cava::Pack::SetResourcePath is a noop -
so the 'root' path of your resources is already set. You don't need to
bother with relative paths etc.


Regards

Mark



On Nov 25, 6:35 am, "aardvark...@gmail.com" <aardvark...@gmail.com>
wrote:

aardv...@gmail.com

unread,
Nov 25, 2007, 7:03:17 PM11/25/07
to Cava Packager
Thanks again.

I have a hundred resource files. My script is already working of
course; it gets resources via relative paths from the main pl script.
Is there any way to use Cava packager without adding
Cava::Pack::SetResourcePath in the hundred places I call those files?

It's not that much work, but I'd rather not 1) add code only for
packaging reasons 2) add code that I don't need when I"m not using
Cava 3) change something that's already working so that I can
package. . .

I am wondering if there should be a way to specify the res path during
packaging rather than during coding. That would be more portable. At
packaging time, the default path would be whatever you decide as the
Cava author, but the user could customize it prior to packaging. In my
case, it would just be ../res.

ben

Cava Support

unread,
Nov 25, 2007, 8:19:28 PM11/25/07
to Cava Packager
Hi,

I think I may be getting confused over what you are asking, so
apologies if the following doesn't answer your questions.

To use Cava::Pack::Resource.

put all the files you want to use under one folder. You can have as
complicated a directory structure under that folder as you wish. It
will all get packaged.

The changes you must make in your script are:

use Cava::Pack;
Cava::Pack::SetResourcePath('E:/Path/To/My/resource/Folder/anywhere/on/
filesystem');

you only have to do this once.

Then, to access the files, if you have a file
'E:/Path/To/My/resource/Folder/toolbar8/images/open.png'

you would do

my $filename = Cava::Pack::Resource('toolbar8/images/open.png');

This means your code will work both as a perl script or as a packaged
executable.

When packaging, just select 'E:/Path/To/My/resource/Folder' as the
resource directory.

Your current code may do:
my $filename = 'E:/Path/To/My/resource/Folder/toolbar8/images/
open.png';

or maybe you have a relative path because you always run the script
from within the directory where your script resides:
my $filename = '../toolbar8/images/open.png';

Neither is in any way portable.

The relative path assumes you always run the script from within the
directory where your script resides
So, if you do
perl.exe c:/full/path/to/my/perl/script.pl
from anywhere but the directory that contains script.pl, your relative
paths will fail.

Being lazy, I always create a package along the lines of:

package MyAppExport;
require Exporter;
use Cava::Pack;
Cava::Pack::SetResourcePath('E:/Path/To/My/resource/Folder/anywhere/on/
filesystem');
use base qw(Exporter);
our @EXPORT = qw( RF );
sub RF { Cava::Pack::Resource( shift ); }


This means that all I have to do at the top of my script is
use MyAppExport;

then, for file access

my $filename = RF('toolbar8/images/open.png');

There is nothing that says you are limited to using
Cava::Pack::Resource for packaging additional files.

All Cava::Packager does is create a directory structure.
Once Cava Packager has 'built' the dir structure, there's nothing to
stop you adding extra folders.
You could ignore Cava::Pack::Resource completely and add copies of all
your existing folders with your 'resource' files in at the right
relative location, and then

my $filename = '../myfolder/filename.ext';

would work with a packaged executable exactly as it does within your
perl script.
That is to say, so long as the current working directory is where the
executable or your script is when the executable or perl.exe is
executed, then all will be fine.

For the precise case you cite, just copy your res folder to the 'bin'
directory.

I'd have to say that I don't think this is practically useful.
I think that with any method of packaging a perl script you are going
to be faced with needing to change lines like
my $filename = '../myfolder/filename.ext';


Best Regards

Mark


On Nov 26, 12:03 am, "aardvark...@gmail.com" <aardvark...@gmail.com>
wrote:

aardvarkman

unread,
Dec 1, 2007, 3:46:37 AM12/1/07
to Cava Packager
Hi Mark,

I'm still having fun with this, and I'm sure I'll get things working
great. . .

I guess I'm having a hard time understanding the big picture. My
script will always run on any machine anywhere because I have relative
paths. I imagine distributing zips or some other kind of package so
that when a user installs everything, all the directories are created
and the relative paths all work. There will never be a path issue in
that scenario. I've put all my resources in a res dir and it all
works. My "current code" has no absolute paths.

Where I get a tad lost, is that your first example shows this:
Cava::Pack::SetResourcePath('E:/Path/To/My/resource/Folder/anywhere/
on/
filesystem');

Ok. That's specifies a resource dir. But then I have to do this: my
$filename = Cava::Pack::Resource('toolbar8/images/open.png'); whereas
before I just had 'res/config/strings_enu.txt';

I don't see why having relative paths is not portable. You say:

or maybe you have a relative path because you always run the script
from within the directory where your script resides: my $filename =
'../toolbar8/images/open.png'; Neither is in any way portable. The
relative path assumes you always run the script from within the
directory where your script resides" . . . .

I think any installed application expects its resources to be in some
constant place relative to the caller. You wouldn't unzip a bunch of
app files and then rearrange the dir structure. You wouldn't install a
Windows app and then move its dll's either.

I'm pretty sure that I'm not understanding something that's obvious to
you. I am a tech writer and not a programmer. But I sure would like to
say"

'res/config/strings_enu.txt';

or

"$res/config/strings_enu.txt";

rather than

Cava::Pack::Resource('toolbar8/images/open.png'); in 50 different
places.

What am I missing?

Thanks again!

ben



Cava Support

unread,
Dec 1, 2007, 6:55:42 AM12/1/07
to Cava Packager
Hi,

Thanks for persevering!

I think the problem is that you have assumed that by 'relative path'
you are getting something relative to the location of your script(or
indeed executable). This is wrong. You are getting a location relative
to the current working directory which has nothing to do with the
location of your script / executable.

So, "res/path/to/my/file.pl" could point anywhere, depending on what
the current working directory is when you call it.

It happens to be the case that when you transfer your perl code to
another machine, you then launch it from the identical directory so
all works.

Assuming you have a script at c:\myscripts\test.pl.

IF you do the following:

cd C:\myscripts
perl test.pl

all those relative paths work fine.

Now do:
cd C:\Windows
c:\perl\bin\perl.exe c:/myscripts/test.pl

all the relative paths are broken.

You can't distribute an executable and assume that the user is going
to change working directory before running it. Nor, in the vast
majority of cases would you want them to.


Regards


Mark




















Best Regards


Mark
Reply all
Reply to author
Forward
0 new messages