From: Thien-Thi Nguyen <ttn@gnuvola.org>
To: guile-user@gnu.org
Subject: Re: Modules
Date: Sun, 30 Jan 2011 11:13:56 +0100 [thread overview]
Message-ID: <87vd164s2j.fsf@ambire.localdomain> (raw)
In-Reply-To: <87tygrcnbf.fsf@ossau.uklinux.net> (Neil Jerram's message of "Sat, 29 Jan 2011 23:17:08 +0000")
() Neil Jerram <neil@ossau.uklinux.net>
() Sat, 29 Jan 2011 23:17:08 +0000
If the modules are installed, that's true. What if they are not?
[...]
For scripts that use uninstalled modules, then, some kind of
solution is needed; ideally one that works for both 1.8 and
1.9/2.0, allows the code needed to live in a single common
file, rather than duplicated at the top of each script; and
continues to work if the script+module tree as a whole is moved
to a different place in the filesystem.
This is what "module catalogs" from Guile 1.4.x provides.
[verbose explanation follows, skip to end for summary]
Basically, you associate with each element in ‘%load-path’ a
sub-association between module name (list of symbols) and
implementation resolution method. For Guile 1.4.x, there are two
types of modules supported:
- scheme source (text)
- shared object library
Of course the implementation must provide the appropriate
interface (as defined by the support in ‘resolve-module’) for
loading; this system cannot be used for arbitrary scheme source or
shared object libraries.
At load-time, the interpreter consults these catalogs
preferentially, falling back to old-style filesystem groping on
lookup failure. A module (of any form) need not include its
location information.
To see how this helps, i use two small scripts:
st:
#!/bin/sh
exec strace -f -e open "$@" 2>&1 | grep -v o.such.file
sta:
#!/bin/sh
exec strace -f -e open "$@" 2>&1
Here is a run of loading (database postgres-table) [scheme code]
from the Guile-PG build tree. Note that it in turn requires
(database postgres) [shared object library]. Also note ‘-L .’
which is explained further down.
$ cd ~/build/guile-pg/.b
$ st guile -L . -c '(use-modules (database postgres-table))'
open("/home/ttn/local/lib/libguile.so.9", O_RDONLY) = 3
open("/home/ttn/local/lib/libltdl.so.7", O_RDONLY) = 3
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/i686/cmov/libm.so.6", O_RDONLY) = 3
open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3
open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
open("/home/ttn/local/lib/guile/site/.module-catalog", O_RDONLY) = 3
open("/home/ttn/local/share/guile/site/.module-catalog", O_RDONLY) = 3
open("/home/ttn/local/lib/guile/1.4.1.122/.module-catalog", O_RDONLY) = 3
open("/home/ttn/local/lib/guile/site/init.scm", O_RDONLY) = 3
open("./.module-catalog", O_RDONLY) = 3
open("/home/ttn/build/guile-pg/src/postgres-table.scm", O_RDONLY) = 3
open("/home/ttn/local/lib/guile/1.4.1.122/ice-9/common-list.scm", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/.b/src/.libs/postgres.so.0.0.0", O_RDONLY) = 4
open("/home/ttn/local/lib/libpq.so.3", O_RDONLY) = 4
open("/etc/ld.so.cache", O_RDONLY) = 4
open("/lib/i686/cmov/libcrypt.so.1", O_RDONLY) = 4
open("/lib/i686/cmov/libresolv.so.2", O_RDONLY) = 4
open("/lib/i686/cmov/libnsl.so.1", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/src/postgres-types.scm", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/src/postgres-col-defs.scm", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/src/postgres-qcons.scm", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/src/postgres-resx.scm", O_RDONLY) = 4
If i use ‘sta’, there are many "no such file" messages, but NOT
with the modules. Strictly speaking, open(2) savings proves
improvement only for shared object libraries, so you'll have to
trust me (or confirm by looking at the source code) that the
scheme source modules are treated analogously (i.e., no probing).
$ cd ~/build/guile-pg/.b
$ st guile -L . -c '(use-modules (database postgres-table))' > A
$ sta guile -L . -c '(use-modules (database postgres-table))' > B
$ diff -u A B | uniq
--- A 2011-01-30 10:41:25.000000000 +0100
+++ B 2011-01-30 10:41:32.000000000 +0100
@@ -1,8 +1,29 @@
+open("/home/ttn/local/lib/tls/i686/sse2/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/i686/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/i686/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/i686/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/sse2/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/tls/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/i686/sse2/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/i686/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/i686/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/i686/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/sse2/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/sse2/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
+open("/home/ttn/local/lib/cmov/libguile.so.9", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/ttn/local/lib/libguile.so.9", O_RDONLY) = 3
open("/home/ttn/local/lib/libltdl.so.7", O_RDONLY) = 3
+open("/home/ttn/local/lib/libm.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/i686/cmov/libm.so.6", O_RDONLY) = 3
+open("/home/ttn/local/lib/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/cmov/libdl.so.2", O_RDONLY) = 3
+open("/home/ttn/local/lib/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3
open("/home/ttn/local/lib/guile/site/.module-catalog", O_RDONLY) = 3
open("/home/ttn/local/share/guile/site/.module-catalog", O_RDONLY) = 3
@@ -13,9 +34,21 @@
open("/home/ttn/local/lib/guile/1.4.1.122/ice-9/common-list.scm", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/.b/src/.libs/postgres.so.0.0.0", O_RDONLY) = 4
open("/home/ttn/local/lib/libpq.so.3", O_RDONLY) = 4
+open("/home/ttn/local/lib/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 4
open("/lib/i686/cmov/libcrypt.so.1", O_RDONLY) = 4
+open("/home/ttn/local/lib/libresolv.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/cmov/libresolv.so.2", O_RDONLY) = 4
+open("/home/ttn/local/lib/libnsl.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/i686/cmov/libnsl.so.1", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/src/postgres-types.scm", O_RDONLY) = 4
open("/home/ttn/build/guile-pg/src/postgres-col-defs.scm", O_RDONLY) = 4
The ‘-L .’ means that ~/build/guile-pg/.b/.module-catalog is
consulted:
;;; .module-catalog
;;; generated 2010-12-18 20:35:15 UTC -- do not edit!
(
((database postgres-resdisp) . "/home/ttn/build/guile-pg/src/postgres-resdisp.scm")
((database postgres-col-defs) . "/home/ttn/build/guile-pg/src/postgres-col-defs.scm")
((database postgres-table) . "/home/ttn/build/guile-pg/src/postgres-table.scm")
((database postgres-meta) . "/home/ttn/build/guile-pg/src/postgres-meta.scm")
((database postgres-gxrepl) . "/home/ttn/build/guile-pg/src/postgres-gxrepl.scm")
((database postgres) scm_init_module "scm_init_database_postgres_module" () . "/home/ttn/build/guile-pg/.b/src/.libs/postgres.so.0.0.0")
((database postgres-types) . "/home/ttn/build/guile-pg/src/postgres-types.scm")
((database postgres-qcons) . "/home/ttn/build/guile-pg/src/postgres-qcons.scm")
((database postgres-resx) . "/home/ttn/build/guile-pg/src/postgres-resx.scm")
)
;;; .module-catalog ends here
This (version 1) format is not very compact. For version 2, we
add a magic number, factor the root and all intervening parent
directories, provide other meta info in a "header" section, and
include other meta info (exports list being the most interesting)
in the body. In some sense version 2 is like /etc/ld.so.cache.
I imagine Guile 2.x could adopt module catalogs, extending to
handle also compiled scheme (.go) and the (future) JIT files as
well, but perhaps it's too late. I wonder how module catalogs
would fit w/ name canonicalization, which IIUC is specific to
compiled scheme.
In sum, build-time caching plus run-time indirection as a means to
facile module relocatability (plus some performance gain).
next prev parent reply other threads:[~2011-01-30 10:13 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-08 11:45 Modules Marek Kubica
2010-12-08 18:11 ` Modules Andreas Rottmann
2010-12-09 1:19 ` Modules Nala Ginrut
2011-01-28 16:26 ` Modules Andy Wingo
2011-01-29 12:13 ` Modules Marek Kubica
2011-01-29 13:08 ` Modules Neil Jerram
2011-01-29 13:18 ` Modules Neil Jerram
2011-01-29 17:04 ` Modules Andy Wingo
2011-01-29 18:37 ` Modules Marek Kubica
2011-01-29 23:17 ` Modules Neil Jerram
2011-01-30 10:13 ` Thien-Thi Nguyen [this message]
2011-01-30 11:42 ` Modules Andy Wingo
2011-02-13 19:05 ` Modules Andy Wingo
2011-01-29 17:07 ` Modules Andy Wingo
2011-01-29 18:40 ` Modules Marek Kubica
2011-01-29 23:35 ` Modules Neil Jerram
2011-02-01 21:43 ` Modules Andy Wingo
2011-02-02 14:43 ` Modules Jon Wilson
-- strict thread matches above, loose matches on Subject: below --
2004-03-21 5:40 modules Ian Zimmerman
2004-03-21 14:47 ` modules Andreas Rottmann
2004-03-22 18:05 ` modules Ian Zimmerman
2004-03-23 16:05 ` modules Robert Uhl
2004-03-21 21:29 ` modules Thien-Thi Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87vd164s2j.fsf@ambire.localdomain \
--to=ttn@gnuvola.org \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).