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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

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

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
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

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

Dave Bayer
On Feb 7, 2008, at 12:27 AM, [hidden email] wrote:

> Are you assuming that the various users have GHC/Hugs installed? You  
> know about scripting through the 'runhaskell' binary, right?


I do, and I've used this. I don't want to do that here.

Let me say this again: I am making no assumptions whatsoever about  
various users, other than platform. Haskell is not a niche language,  
with the right compile options, it CAN be used in this way.

Here's the extreme case: When one is installing Mac OS X, one has  
access to a command line via a terminal application, but the operating  
system is otherwise very stripped down. Nevertheless, if one  
customizes an install DVD by adding a single command-line tool, one  
can execute that tool in this environment.

I'd rather use Haskell than C for such applications.

With C, we can introduce one file to an alien environment, and it will  
run. I've linked GHC Haskell programs that can be used in this way.  
Such programs can be used by anyone on a given platform. Assuming that  
GHC/Hugs is installed divides the potential audience by a large factor.

Under this extreme hypothesis, how do I embed a compressed tar file  
into a single file command line tool written in Haskell and compiled  
by GHC?

Thanks,
Dave
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

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

Reinier Lamers-2

Op 7-feb-2008, om 13:53 heeft Dave Bayer het volgende geschreven:
>
> Under this extreme hypothesis, how do I embed a compressed tar file  
> into a single file command line tool written in Haskell and  
> compiled by GHC?
Hack up a shell script or a small Haskell program to automatically  
generate a Haskell file of the form:

 > module TarFile where
 >
 > import Data.ByteString as B
 >
 > myTarFile = B.pack [<tar file as list of Word8s here>]

You could also do that using Template Haskell, as you already hinted,  
but this sounds less like rocket science :-)

Reinier
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

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

Bertram Felgenhauer-2
In reply to this post by Dave Bayer
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
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

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

Aaron Tomb-3

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
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

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

Bugzilla from alfonso.acosta@gmail.com
In reply to this post by Dave Bayer
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 <[hidden email]> wrote:

> 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
>  [hidden email]
>  http://www.haskell.org/mailman/listinfo/haskell-cafe
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe