Best practice for embedding files in a GHC-compiled tool?

What is the best way to embed an arbitrary file in a Haskell program? I would like to use GHC to compile command-line tools to be used with OS X. I want the tool to be a single file, not a package or a directory, that makes no assumptions about what else is present. For example, it should be able to run as part of an OS X install disk. I want this tool to be "self reproducing" in the sense that one of its options causes it to output its own documentation and source code. I want this data to be stored as a compressed file within the tool binary itself. The distribution model I'm imagining here is where one writes a program anonymously, that isn't hosted anywhere but is passed from user to user because it is useful, and eventually reaches another user who wants to modify the code. Assume that intermediate users will care less about this, and will try to delete anything that they can. That rules out storing the data in a separate file. Think of the M.I.T. game "Core Wars" from the dawn of the computer age. I'm looking for a strategy here that will be evolutionarily successful in a fairly hostile environment. In other words, I want to be able to write in Haskell, without losing the automatic distribution of source code enjoyed by interpreted languages. No one deletes the source code for a Perl script, because by doing so they're killing the program. There must be some library I'm overlooking that would make this very easy. All I can think of is to use Template Haskell to read a compressed tar file into a Haskell variable. Is that what one does, or is there a better way? Thanks in advance, Dave

Dave Bayer wrote:
What is the best way to embed an arbitrary file in a Haskell program?
I don't know the best way. I'd probably use FFI. main.hs: {-# LANGUAGE ForeignFunctionInterface #-} module Main where import Foreign import Foreign.ForeignPtr import qualified Data.ByteString as B import qualified Data.ByteString.Internal as BI foreign import ccall "& hello" hello :: Ptr Word8 foreign import ccall "& hello_size" helloSize :: Ptr Int main = do helloSize' <- peek helloSize hello' <- newForeignPtr_ hello let helloBS = BI.PS hello' 0 helloSize' B.putStr helloBS hello.c: char hello[] = "Hello, world!\n"; int hello_size = sizeof(hello); Test: # ghc -O -o main main.hs hello.c -package bytestring # ./main Hello, world! The idea is then to use some existing tool that embeds binary data in C programs. Bertram

On Feb 9, 2008, at 8:03 AM, Bertram Felgenhauer wrote:
Dave Bayer wrote:
What is the best way to embed an arbitrary file in a Haskell program?
I don't know the best way. I'd probably use FFI.
<snip>
The idea is then to use some existing tool that embeds binary data in C programs.
Since you're specifically interested in OS X, I'd follow this advice, and then look at /usr/include/mach-o/getsect.h. This header declares a function extern char *getsectdata( const char *segname, const char *sectname, unsigned long *size); which seems like it'll give you all of the data in one of the sections of the executable file for the currently running program. I haven't used it, though, so I'm not positive about how it works. I think it's then fairly straightforward to tell the linker to just include an arbitrary file into a section with a name of your choice. Aaron

A bit late, sorry, but you could use this:
http://www.wellquite.org/hinstaller/
On Thu, Feb 7, 2008 at 5:29 AM, Dave Bayer
What is the best way to embed an arbitrary file in a Haskell program?
I would like to use GHC to compile command-line tools to be used with OS X. I want the tool to be a single file, not a package or a directory, that makes no assumptions about what else is present. For example, it should be able to run as part of an OS X install disk.
I want this tool to be "self reproducing" in the sense that one of its options causes it to output its own documentation and source code. I want this data to be stored as a compressed file within the tool binary itself.
The distribution model I'm imagining here is where one writes a program anonymously, that isn't hosted anywhere but is passed from user to user because it is useful, and eventually reaches another user who wants to modify the code. Assume that intermediate users will care less about this, and will try to delete anything that they can. That rules out storing the data in a separate file. Think of the M.I.T. game "Core Wars" from the dawn of the computer age. I'm looking for a strategy here that will be evolutionarily successful in a fairly hostile environment.
In other words, I want to be able to write in Haskell, without losing the automatic distribution of source code enjoyed by interpreted languages. No one deletes the source code for a Perl script, because by doing so they're killing the program.
There must be some library I'm overlooking that would make this very easy. All I can think of is to use Template Haskell to read a compressed tar file into a Haskell variable. Is that what one does, or is there a better way?
Thanks in advance, Dave
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Aaron Tomb
-
Alfonso Acosta
-
Bertram Felgenhauer
-
Dave Bayer