[gambit-list] moving to blackhole
per.eckerdal at gmail.com
Tue Oct 6 04:58:36 EDT 2009
First of all, as previously mentioned, (import "sdl-ttf") is not at
all the same thing as (import sdl-ttf), and the latter is what you
want to do.
Also, (load "~~/lib/modules/build") should not be inside of any module
source code file. BH is designed to be loaded into the development
environment, but should not be required to be included with
distributed binaries; having that on the top of files would hinder that.
What is done instead is to fire up a gsc REPL, and then do (load "~~/
lib/modules/build") from there. (This is normally done with a script.
That's what bsc is.)
Another not-so-obvious thing is that you don't compile scheme files
from the command line like you do with gsc; you use the procedure |
module-compile!|, for instance (module-compile! 'ttf-sdl)
These are the obvious problems on the surface that I can see. The main
problem, however, is that BH is designed mainly to be used on its own.
> This what I'm trying to do:
> ../src/sdl-interface.scm is a third party library
> sdl-ttf.scm is a library i'm trying to keep independent of blackhole,
> since i want to contribute it to the sdl-interface project
> test-ttf.scm (the unnamed file above) is an attempt to get a minimal
> piece of code that uses both blackhole and sdl-ttf. i ultimately want
> to make an app that uses libraries out of blackhole, and the
> non-blackhole sdl-interface.
> Can I compile sdl-interface and sdl-ttf separately and then link them
> with ttf-test via blackhole?
As you might have understood by the other answers on the list, this is
stretching beyond normal usage of BH. Because it's Gambit however, the
answer is obviously not a no, the question is how much hackage that is
If sdl-ttf or sdl-interface exports macros, you're in trouble. That is
the biggest difficult problem that BH solves, and hacking around that
is most likely not worth the effort. If it's just a few macros, you
might get away with re-implementing them in BH, in a module that also
re-exports sdl-ttf and/or sdl-interface.
You can compile sdl-interface and sdl-ttf separately using the normal
Gambit workflow, and then use the |load| procedure to load them into
the Gambit environment. You'd have to make sure yourself that |load|
is called at the proper time, and only once, but I guess you knew that
After loading them into the Gambit environment, problem is to make
sure that BH doesn't protect you away from using the external
BH is essentially a big renaming engine. What it does is to make sure
that name clashes don't occur. One part of that is prefixing all top-
level names with unique namespaces, for instance "sdl-ttf#". So,
assuming that ttf-test.scm is assigned the namespace "ttf-test#", all
references to globals in ttf-test.scm that BH doesn't recognize to be
from another module will be prefixed with ttf-test#.
So if you just load the external libraries, a call to SDL::Delay will
be renamed to ttf-test#SDL::Delay.
There are a couple of possible workarounds:
* BH doesn't touch identifiers that contain a #. So if you use
Gambit's namespace mechanism in the non-BH libraries to add a
namespace prefix to all their names, you will be able to use it like
* Another hack that can be used is that BH doesn't touch what's inside
##let. So you can get SDL::Delay with (##let () SDL::Delay)
* And the least hacky one: Use a module loader. For this one I added
some utility functions to BH, so make sure to get the latest version
from github, and don't forget to recompile build.o1.
Either from the REPL, or in some initialization code that is run after
BH is loaded, execute something like this:
;; This is the module name. Not really important. Choose something
;; This is a list of files that BH should load when importing;
;; if you want to load the files manually, leave it
;; empty. Otherwise add the paths, as strings, here, without
;; This is a list of the identifiers that are imported.
;; Next is an optional argument. It's used if the file(s) that are
;; being imported have a namespace prefix. It's "" by default, but
;; could be something like "sdl#". Theoretically, you could pass
;; "SDL::" here, to remove the prefix so that BH modules don't need
;; to use it. Later on, you could use BH's functionality for
;; prefixing instead, for greater flexibility. For that, you should
;; remove the SDL:: prefixes in the previous argument as well.
Note that, depending on when you do it, you might need to prefix
module-resolver-add! and make-external-module-resolver with module#.
Nicola Archibald wrote a message on the gambit list not too long ago
about a neat way of loading BH by modifying /usr/local/Gambit-C/lib/
gambcext and letting bsc be a symlink. You might want to look into
that, since that would provide a natural place for you to insert the
You should then be able to do (import (sdl)). Note that this code
isn't really tested. Tell me if you choose to use it and it doesn't
More information about the Gambit-list