[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Making forge-packages installation relocatable
From: |
Benjamin Lindner |
Subject: |
Making forge-packages installation relocatable |
Date: |
Tue, 27 Oct 2009 22:10:47 +0100 |
User-agent: |
Thunderbird 2.0.0.22 (Windows/20090605) |
Hello all,
One item on my personal todo list for octave has long been to make the
octave forge package installation via pkg.m relocatable, i.e. allowing
an installed octave directory structure to be moved elsewhere and having
everything work as before (thus making octave a truly portable application).
Currently this works for octave itself, but not if forge packages are
installed.
This is, because installed packages are referred to by their absolute
path at the time of installation.
My idea is to remove the absolute path and store only the package's
actual subdirectory and restore the absolute path at runtime based on
OCTAVE_HOME().
Thinking about it I realised that this makes sense only for globally
installed packages - not locally installed ones.
I have attached a first attempt to achieve this.
I'm not entirely satisified by the solution, but it is a first attempt
and it does work for me for octave-3.2.3 on windows.
comments and suggestions are very welcome.
I see that the package list structure contains actually two directory paths:
.dir
.archprefix
In the attached patch I actually only deal with the .dir field, by
creating a new function getdir() (similar to getarchdir()) and replacing
all explicit references to the field .dir by a call to this new function.
The situation with .archprefix is different, as currently, this field is
not referenced directly, rather than through the function getsrchdir().
So I modified this function to generate the actual absolute path at runtime.
But actually the field .archprefix is redundant, because this directory
can be (and is) created from the package's description and version at
runtime, so couldn't it be removed anyway?
benjamin
diff -r d5ba49ddea77 scripts/pkg/pkg.m
--- a/scripts/pkg/pkg.m Sun Oct 25 19:31:34 2009 +0100
+++ b/scripts/pkg/pkg.m Tue Oct 27 21:50:50 2009 +0100
@@ -205,7 +205,7 @@
"octave_packages");
mlock ();
- global_install = issuperuser ();
+ global_install = issuperuser ()
if (prefix == -1)
if (global_install)
@@ -370,7 +370,7 @@
case "rebuild"
if (global_install)
global_packages = rebuild (prefix, archprefix, global_list, files,
- auto, verbose);
+ auto, verbose, global_install);
global_packages = save_order (global_packages);
save (global_list, "global_packages");
if (nargout > 0)
@@ -378,7 +378,7 @@
endif
else
local_packages = rebuild (prefix, archprefix, local_list, files, auto,
- verbose);
+ verbose, global_install);
local_packages = save_order (local_packages);
save (local_list, "local_packages");
if (nargout == 0)
@@ -419,7 +419,7 @@
endswitch
endfunction
-function descriptions = rebuild (prefix, archprefix, list, files, auto,
verbose)
+function descriptions = rebuild (prefix, archprefix, list, files, auto,
verbose, global_install)
if (isempty (files))
[dirlist, err, msg] = readdir (prefix);
if (err)
@@ -445,21 +445,27 @@
endif
if (exist (descfile, "file"))
desc = get_description (descfile);
- desc.dir = fullfile (prefix, dirlist{k});
+ if (global_install)
+ desc.dir = dirlist{k};
+ desc.dir_is_relative = true;
+ else
+ desc.dir = fullfile (prefix, dirlist{k});
+ desc.dir_is_relative = false;
+ endif
desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-",
desc.version));
if (auto != 0)
- if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
- unlink (fullfile (desc.dir, "packinfo", ".autoload"));
+ if (exist (fullfile (getdir (desc), "packinfo", ".autoload"), "file"))
+ unlink (fullfile (getdir (desc), "packinfo", ".autoload"));
endif
if (auto < 0)
desc.autoload = 0;
elseif (auto > 0)
desc.autoload = 1;
- fclose (fopen (fullfile (desc.dir, "packinfo", ".autoload"), "wt"));
+ fclose (fopen (fullfile (getdir (desc), "packinfo", ".autoload"),
"wt"));
endif
else
- if (exist (fullfile (desc.dir, "packinfo", ".autoload"), "file"))
+ if (exist (fullfile (getdir (desc), "packinfo", ".autoload"), "file"))
desc.autoload = 1;
else
desc.autoload = 0;
@@ -632,7 +638,13 @@
endif
## Set default installation directory.
- desc.dir = fullfile (prefix, cstrcat (desc.name, "-", desc.version));
+ if (global_install)
+ desc.dir = cstrcat (desc.name, "-", desc.version);
+ desc.dir_is_relative = true;
+ else
+ desc.dir = fullfile (prefix, cstrcat (desc.name, "-",
desc.version));
+ desc.dir_is_relative = false;
+ endif
## Set default architectire dependent installation directory.
desc.archprefix = fullfile (archprefix, cstrcat (desc.name, "-",
@@ -750,7 +762,7 @@
rm_rf (tmpdirs{i});
endfor
for i = 1:length (descriptions)
- rm_rf (descriptions{i}.dir);
+ rm_rf (getdir (descriptions{i}.dir));
rm_rf (getarchdir (descriptions{i}));
endfor
rethrow (lasterror ());
@@ -759,10 +771,11 @@
## Check if the installed directory is empty. If it is remove it
## from the list.
for i = length (descriptions):-1:1
- if (dirempty (descriptions{i}.dir, {"packinfo", "doc"}) &&
+ descriptions{i}
+ if (dirempty (getdir (descriptions{i}), {"packinfo", "doc"}) &&
dirempty (getarchdir (descriptions{i})))
warning ("package %s is empty\n", descriptions{i}.name);
- rm_rf (descriptions{i}.dir);
+ rm_rf (getdir (descriptions{i}));
rm_rf (getarchdir (descriptions{i}));
descriptions(i) = [];
endif
@@ -771,8 +784,9 @@
## If the package requested that it is autoloaded, or the installer
## requested that it is, then mark the package as autoloaded.
for i = length (descriptions):-1:1
+ disp(descriptions{i})
if (autoload > 0 || (autoload == 0 && isautoload (descriptions(i))))
- fclose (fopen (fullfile (descriptions{i}.dir, "packinfo",
+ fclose (fopen (fullfile (getdir (descriptions{i}), "packinfo",
".autoload"), "wt"));
descriptions{i}.autoload = 1;
endif
@@ -797,7 +811,7 @@
rm_rf (tmpdirs{i});
endfor
for i = 1:length (descriptions)
- rm_rf (descriptions{i}.dir);
+ rm_rf (getdir (descriptions{i}));
endfor
if (global_install)
printf ("error: couldn't append to %s\n", global_list);
@@ -910,23 +924,23 @@
for i = delete_idx
desc = installed_pkgs_lst{i};
## If an 'on_uninstall.m' exist, call it!
- if (exist (fullfile (desc.dir, "packinfo", "on_uninstall.m"), "file"))
+ if (exist (fullfile (getdir (desc), "packinfo", "on_uninstall.m"), "file"))
wd = pwd ();
- cd (fullfile (desc.dir, "packinfo"));
+ cd (fullfile (getdir (desc), "packinfo"));
on_uninstall (desc);
cd (wd);
endif
## Do the actual deletion.
if (desc.loaded)
- rmpath (desc.dir);
+ rmpath (getdir (desc));
if (exist (getarchdir (desc)))
rmpath (getarchdir (desc));
endif
endif
- if (exist (desc.dir, "dir"))
- [status, msg] = rm_rf (desc.dir);
+ if (exist (getdir (desc), "dir"))
+ [status, msg] = rm_rf (getdir (desc));
if (status != 1)
- error ("couldn't delete directory %s: %s", desc.dir, msg);
+ error ("couldn't delete directory %s: %s", getdir (desc), msg);
endif
[status, msg] = rm_rf (getarchdir (desc));
if (status != 1)
@@ -936,7 +950,7 @@
rm_rf (desc.archprefix);
endif
else
- warning ("directory %s previously lost", desc.dir);
+ warning ("directory %s previously lost", getdir (desc));
endif
endfor
@@ -995,7 +1009,7 @@
pkg_desc_list{name_pos}.name = installed_pkgs_lst{i}.name;
pkg_desc_list{name_pos}.version = installed_pkgs_lst{i}.version;
pkg_desc_list{name_pos}.description = installed_pkgs_lst{i}.description;
- pkg_desc_list{name_pos}.provides = parse_pkg_idx
(installed_pkgs_lst{i}.dir);
+ pkg_desc_list{name_pos}.provides = parse_pkg_idx (getdir
(installed_pkgs_lst{i}));
endif
endfor
@@ -1207,7 +1221,7 @@
if (! exist (inst_dir, "dir"))
[status, msg] = mkdir (inst_dir);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("the 'inst' directory did not exist and could not be created:
%s",
msg);
endif
@@ -1236,9 +1250,9 @@
flags = strcat( flags, " LDFLAGS=-L\"", fullfile(OCTAVE_HOME,"lib"),
"\"" );
flags = strcat( flags, " CPPFLAGS=-I\"",
fullfile(OCTAVE_HOME,"include"), "\"" );
[status, output] = shell (strcat ("cd '", src, "'; ./configure
--prefix=\"",
- desc.dir, "\"", flags));
+ getdir (desc), "\"", flags));
if (status != 0)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("the configure script returned the following error: %s", output);
elseif (verbose)
printf("%s", output);
@@ -1248,10 +1262,10 @@
## Make.
if (exist (fullfile (src, "Makefile"), "file"))
- [status, output] = shell (cstrcat ("export INSTALLDIR=\"", desc.dir,
+ [status, output] = shell (cstrcat ("export INSTALLDIR=\"", getdir (desc),
"\"; make -C '", src, "'"));
if (status != 0)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("'make' returned the following error: %s", output);
elseif (verbose)
printf("%s", output);
@@ -1317,7 +1331,7 @@
endif
[status, output] = copyfile (archindependent, instdir);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("Couldn't copy files from 'src' to 'inst': %s", output);
endif
endif
@@ -1332,7 +1346,7 @@
endif
[status, output] = copyfile (archdependent, archdir);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("Couldn't copy files from 'src' to 'inst': %s", output);
endif
endif
@@ -1361,7 +1375,7 @@
endfunction
function create_pkgadddel (desc, packdir, nm, global_install)
- instpkg = fullfile (desc.dir, nm);
+ instpkg = fullfile (getdir (desc), nm);
instfid = fopen (instpkg, "wt");
## If it is exists, most of the PKG_* file should go into the
## architecture dependent directory so that the autoload/mfilename
@@ -1427,11 +1441,11 @@
function copy_files (desc, packdir, global_install)
## Create the installation directory.
- if (! exist (desc.dir, "dir"))
- [status, output] = mkdir (desc.dir);
+ if (! exist (getdir (desc), "dir"))
+ [status, output] = mkdir (getdir (desc));
if (status != 1)
error ("couldn't create installation directory %s : %s",
- desc.dir, output);
+ getdir (desc), output);
endif
endif
@@ -1440,13 +1454,13 @@
## Copy the files from "inst" to installdir.
instdir = fullfile (packdir, "inst");
if (! dirempty (instdir))
- [status, output] = copyfile (fullfile (instdir, "*"), desc.dir);
+ [status, output] = copyfile (fullfile (instdir, "*"), getdir (desc));
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("couldn't copy files to the installation directory");
endif
- if (exist (fullfile (desc.dir, getarch ()), "dir") &&
- ! strcmp (fullfile (desc.dir, getarch ()), octfiledir))
+ if (exist (fullfile (getdir (desc), getarch ()), "dir") &&
+ ! strcmp (fullfile (getdir (desc), getarch ()), octfiledir))
if (! exist (octfiledir, "dir"))
## Can be required to create upto three levels of dirs.
octm1 = fileparts (octfiledir);
@@ -1457,38 +1471,38 @@
if (! exist (octm3, "dir"))
[status, output] = mkdir (octm3);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("couldn't create installation directory %s : %s",
octm3, output);
endif
endif
[status, output] = mkdir (octm2);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("couldn't create installation directory %s : %s",
octm2, output);
endif
endif
[status, output] = mkdir (octm1);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("couldn't create installation directory %s : %s",
octm1, output);
endif
endif
[status, output] = mkdir (octfiledir);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
error ("couldn't create installation directory %s : %s",
octfiledir, output);
endif
endif
- [status, output] = movefile (fullfile (desc.dir, getarch (), "*"),
+ [status, output] = movefile (fullfile (getdir (desc), getarch (), "*"),
octfiledir);
- rm_rf (fullfile (desc.dir, getarch ()));
+ rm_rf (fullfile (getdir (desc), getarch ()));
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't copy files to the installation directory");
endif
@@ -1497,10 +1511,10 @@
endif
## Create the "packinfo" directory.
- packinfo = fullfile (desc.dir, "packinfo");
+ packinfo = fullfile (getdir (desc), "packinfo");
[status, msg] = mkdir (packinfo);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't create packinfo directory: %s", msg);
endif
@@ -1508,7 +1522,7 @@
## Copy DESCRIPTION.
[status, output] = copyfile (fullfile (packdir, "DESCRIPTION"), packinfo);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't copy DESCRIPTION: %s", output);
endif
@@ -1516,7 +1530,7 @@
## Copy COPYING.
[status, output] = copyfile (fullfile (packdir, "COPYING"), packinfo);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't copy COPYING: %s", output);
endif
@@ -1526,7 +1540,7 @@
if (exist (changelog_file, "file"))
[status, output] = copyfile (changelog_file, packinfo);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't copy ChangeLog file: %s", output);
endif
@@ -1537,7 +1551,7 @@
if (exist(index_file, "file"))
[status, output] = copyfile (index_file, packinfo);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't copy INDEX file: %s", output);
endif
@@ -1546,7 +1560,7 @@
write_index (desc, fullfile (packdir, "inst"),
fullfile (packinfo, "INDEX"), global_install);
catch
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
rethrow (lasterror ());
end_try_catch
@@ -1557,7 +1571,7 @@
if (exist (fon_uninstall, "file"))
[status, output] = copyfile (fon_uninstall, packinfo);
if (status != 1)
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (octfiledir);
error ("couldn't copy on_uninstall.m: %s", output);
endif
@@ -1566,14 +1580,14 @@
## Is there a doc/ directory that needs to be installed?
docdir = fullfile (packdir, "doc");
if (exist (docdir, "dir") && ! dirempty (docdir))
- [status, output] = copyfile (docdir, desc.dir);
+ [status, output] = copyfile (docdir, getdir (desc));
endif
## Is there a bin/ directory that needs to be installed?
## FIXME: Need to treat architecture dependent files in bin/
bindir = fullfile (packdir, "bin");
if (exist (bindir, "dir") && ! dirempty (bindir))
- [status, output] = copyfile (bindir, desc.dir);
+ [status, output] = copyfile (bindir, getdir (desc));
endif
endfunction
@@ -1587,7 +1601,7 @@
cd (wd);
catch
cd (wd);
- rm_rf (desc.dir);
+ rm_rf (getdir (desc));
rm_rf (getarchdir (desc), global_install);
rethrow (lasterror ());
end_try_catch
@@ -1595,7 +1609,7 @@
endfunction
function generate_lookfor_cache (desc)
- dirs = split_by (genpath (desc.dir), pathsep ());
+ dirs = split_by (genpath (getdir (desc)), pathsep ());
for i = 1 : length (dirs)
gen_doc_cache (fullfile (dirs{i}, "doc-cache"), dirs{i});
endfor
@@ -1880,21 +1894,21 @@
## Now check if the package is loaded.
tmppath = strrep (path(), "\\", "/");
for i = 1:length (installed_pkgs_lst)
- if (findstr (tmppath, strrep (installed_pkgs_lst{i}.dir, "\\", "/")))
+ if (findstr (tmppath, strrep (getdir (installed_pkgs_lst{i}), "\\", "/")))
installed_pkgs_lst{i}.loaded = true;
else
installed_pkgs_lst{i}.loaded = false;
endif
endfor
for i = 1:length (local_packages)
- if (findstr (tmppath, strrep (local_packages{i}.dir, "\\", "/")))
+ if (findstr (tmppath, strrep (getdir (local_packages{i}), "\\", "/")))
local_packages{i}.loaded = true;
else
local_packages{i}.loaded = false;
endif
endfor
for i = 1:length (global_packages)
- if (findstr (tmppath, strrep (global_packages{i}.dir, "\\", "/")))
+ if (findstr (tmppath, strrep (getdir (global_packages{i}), "\\", "/")))
global_packages{i}.loaded = true;
else
global_packages{i}.loaded = false;
@@ -1956,7 +1970,7 @@
for i = 1:num_packages
cur_name = installed_pkgs_lst{idx(i)}.name;
cur_version = installed_pkgs_lst{idx(i)}.version;
- cur_dir = installed_pkgs_lst{idx(i)}.dir;
+ cur_dir = getdir (installed_pkgs_lst{idx(i)});
if (length (cur_dir) > max_dir_length)
first_char = length (cur_dir) - max_dir_length + 4;
first_filesep = strfind (cur_dir(first_char:end), filesep());
@@ -1984,7 +1998,7 @@
pnames = pdirs = cell (1, num_packages);
for i = 1:num_packages
pnames{i} = installed_pkgs_lst{i}.name;
- pdirs{i} = installed_pkgs_lst{i}.dir;
+ pdirs{i} = getdir (installed_pkgs_lst{i});
endfor
## Load all.
@@ -2022,7 +2036,7 @@
pnames = pdirs = cell (1, num_packages);
for i = 1:num_packages
pnames{i} = installed_pkgs_lst{i}.name;
- pdirs{i} = installed_pkgs_lst{i}.dir;
+ pdirs{i} = getdir (installed_pkgs_lst{i});
pdeps{i} = installed_pkgs_lst{i}.depends;
endfor
@@ -2135,7 +2149,15 @@
endfunction
function archdir = getarchdir (desc)
- archdir = fullfile (desc.archprefix, getarch());
+ archdir = fullfile (getarchprefix (desc), getarch());
+endfunction
+
+function d = getdir (desc)
+ if (isfield (desc, "dir_is_relative") && desc.dir_is_relative)
+ d = fullfile (OCTAVE_HOME(), "share", "octave", "packages", desc.dir);
+ else
+ d = desc.dir;
+ endif
endfunction
function s = issuperuser ()
@@ -2210,7 +2232,7 @@
dirs = {};
execpath = EXEC_PATH ();
for i = idx;
- ndir = installed_pkgs_lst{i}.dir;
+ ndir = getdir (installed_pkgs_lst{i});
dirs{end+1} = ndir;
if (exist (fullfile (dirs{end}, "bin"), "dir"))
execpath = cstrcat (fullfile (dirs{end}, "bin"), ":", execpath);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Making forge-packages installation relocatable,
Benjamin Lindner <=