Compile Scheme using Gambit-C

1.3k views Asked by At

I am running Ubuntu 18.04 and I installed gambc to execute Scheme scripts. gsi works fine and can interprete any file I provide, and the REPL is also working as expected.

Unfortunately, I can't figure out how to use gsc.

http://gambitscheme.org/wiki/index.php/A_Tour_of_Scheme_in_Gambit gives little information on how to use gsc to compile a program, man gsc is more about gsi and doesn't cover all the available options (options -o and -c for example are not mentioned in the man page), and all other sources I could find didn't work for me.

Let me elaborate on that last part:

$ cat hello.scm
;#!/usr/local/bin/gsi-script -:d0
;
(define hello-world
        (lambda ()
                (begin (write `Hello-World) (newline) (hello-world))))

(define (main)
        (hello-world))

Then

$ gsc hello.scm
$ ls
hello.o1  hello.scm
$ ./hello.o1
Segmentation fault (core dumped)

Fails, and so does

$ gsc -c hello.scm
$ ls
hello.c hello.scm
$ gcc -o hello hello.c
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o : In function « _start » :
(.text+0x20) : Undefined reference to « main »
/tmp/ccnDUVi0.o : [30 more lines]
collect2: error: ld returned 1 exit status
  • Doing
/* File: "m1.c" */
int power_of_2 (int x) { return 1<<x; }

; File: "m2.scm"
(c-declare "extern int power_of_2 ();")
(define pow2 (c-lambda (int) int "power_of_2"))
(define (twice x) (cons x x))

; File: "m3.scm"
(write (map twice (map pow2 '(1 2 3 4)))) (newline)

$ gsc -c m2.scm        # create m2.c (note: .scm is optional)
$ gsc -c m3.scm        # create m3.c (note: .scm is optional)
$ gsc -link m2.c m3.c  # create the incremental link file m3_.c

$ gsc -obj m1.c m2.c m3.c m3_.c
m1.c:
m2.c:
m3.c:
m3_.c:
$ gcc m1.o m2.o m3.o m3_.o -lgambit -lm -ldl -lutil
$ ./a.out
((2 . 2) (4 . 4) (8 . 8) (16 . 16))

as suggested by http://www.iro.umontreal.ca/~gambit/doc/gambit.html failed at $ gsc -obj m1.c m2.c m3.c m3_.c saying m3_.c was not defined, and even ignoring that, it failed again at $ gcc m1.o m2.o m3.o m3_.o -lgambit -lm -ldl -lutil complaining that -lgambit was not defined. That document did however explain the usage of -o and -c options.

I'll stop here, but I did attempt to follow two other tutorials, neither worked and I can't find them anymore.

If any of the above methods can be modified to work for me, or if any other process allows for scripts to be compiled to executable (even simple 1-file programs will be enough for now), I'd be thankful.

2

There are 2 answers

5
rsm On BEST ANSWER

In part 3. The Gambit Scheme compiler of the Gambit Manual you mentioned, there is very informative description of the compiler and all the options it takes.

If you want to compile Scheme source file hello.scm into an executable program, try:

gsc -exe hello

You don't have to provide file extention. Resulting executable file will have the same name as a source file, without extention (so hello.scm -> hello).

0
Neven V. On

Here's what I figured out, in case someone else encounters the same problem.

  • Despite not appearing in the man page, the -exe option does enable the creation of an executable.
$ gsc -exe hello.scm
$ ./hello
Hello, World!

Its use is explained in Gambit, a portable implementation of scheme, but not in the "The Gambit Scheme Compiler" section! Instead you'll have to scroll back up to the paragraph before.

  • As @rsm pointed out, $ gsc -exe hello works as well: even if hello is already compiled the .scm is not needed, but there is a specific sequence of commands that will cause this command to fail.

This works (h is correctly compiled):

$ ls
hello.scm
$ gsc -exe -o h hello
$ ls
h  hello.scm

This works (h is correctly compiled from hello.scm and not from hello):

$ ls
hello  hello.scm
$ gsc -exe -o h hello
$ ls
h  hello  hello.scm

But this fails:

$ ls
hello.scm
$ gsc -c hello.scm
$ ls
hello.c  hello.scm
$ gsc -exe -o h hello
hello_.o:(.data.rel+0x110) : undefined reference to « ____20_hello »
collect2: error: ld returned 1 exit status
*** ERROR IN ##main -- C link failed while linking "/home/hello_.o"
$ ls
hello_.c  hello.c  hello_.o  hello.scm

In the case when a .c file with the same name already exists, the .scm extension should be used. While the message suggests a linker error, the root of the problem is -- as far as I can tell -- that C files take precedence over Scheme files when extension is unspecified, which is unexpected for a Scheme compiler...