Скомпилируйте схему с помощью Gambit-C

Я использую Ubuntu 18.04 и установил gambc для выполнения сценариев Scheme. gsi отлично работает и может интерпретировать любой файл, который я предоставляю, и REPL также работает, как и ожидалось.

К сожалению, я не могу понять, как использовать gsc.

http://gambitscheme.org/wiki/index.php/A_Tour_of_Scheme_in_Gambit дает мало информации о том, как использовать gsc для компиляции программы, man gsc больше относится к gsi и не охватывает все доступные параметры (например, параметры -o и -c не упоминаются на странице man), и все другие источники, которые я смог найти, не работай на меня.

Позвольте мне уточнить последнюю часть:

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

(define (main)
        (hello-world))

потом

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

Не получается и так

$ 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
  • Делает
/* 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))

как предложено http://www.iro.umontreal.ca/~gambit/doc/gambit.html не удалось выполнить $ gsc -obj m1.c m2.c m3.c m3_.c, заявив, что m3_.c не определено, и даже проигнорировав это, снова произошел сбой в $ gcc m1.o m2.o m3.o m3_.o -lgambit -lm -ldl -lutil, сообщив, что -lgambit не определено. Однако в этом документе объясняется использование опций -o и -c.

Я остановлюсь здесь, но я пытался следовать двум другим учебникам, ни один из них не работал, и я больше не могу их найти.

Если какой-либо из вышеперечисленных методов можно изменить, чтобы он работал у меня, или если какой-либо другой процесс позволяет компилировать скрипты в исполняемый файл (на данный момент будет достаточно даже простых однофайловых программ), я был бы благодарен.


person Neven V.    schedule 06.11.2019    source источник


Ответы (2)


В части 3. Компилятор Gambit Scheme из Руководства по Gambit, о котором вы упомянули, содержит очень информативное описание компилятора и всех параметров, которые он использует.

Если вы хотите скомпилировать исходный файл схемы hello.scm в исполняемую программу, попробуйте:

gsc -exe hello

Вам не нужно указывать расширение файла. Результирующий исполняемый файл будет иметь то же имя, что и исходный файл, без расширения (так что hello.scm -> hello).

person rsm    schedule 06.11.2019
comment
Я сделал $ gsc -exe hello, и мой терминал ответил hello_.o:(.data.rel+0x150) : référence indéfinie vers « ____20_hello » collect2: error: ld returned 1 exit status *** ERROR IN ##main -- C link failed while linking "/home/vanille/ALGO/Scheme/hello_.o" - person Neven V.; 07.11.2019
comment
О, .scm требуется, когда hello уже скомпилирован. Получил выходной файл, надо разобраться, почему его запуск ничего не дал. - person Neven V.; 07.11.2019
comment
Это должно работать на всех платформах. Ошибка, которую вы получаете, исходит от компоновщика, не связанного с Gambit. Возможно, что-то не так с версией (пакетом) Gambit для Ubuntu, но я предполагаю, что здесь. Важно то, что вы ничего не можете сделать с некоторыми переключателями на gsc и т. д., вы должны проверить, почему компоновщик в вашей системе не работает. - person rsm; 07.11.2019
comment
@NevenV. Я предлагаю связаться с сопровождающим пакета Ubuntu Gambit. Информация (включая адрес электронной почты) должна быть указана в описании пакета. Скорее всего, он не знает о проблеме (или уже знает, как ее решить). - person rsm; 07.11.2019
comment
Я подожду, пока немного посплю, и тогда, если я не смогу решить проблему, я сделаю это. - person Neven V.; 07.11.2019

Вот что я понял, если кто-то еще столкнется с той же проблемой.

  • Несмотря на то, что параметр -exe не отображается на странице man, он позволяет создать исполняемый файл.
$ gsc -exe hello.scm
$ ./hello
Hello, World!

Его использование объясняется в Gambit, портативной реализации схемы, но не в разделе "Компилятор схемы Gambit"! Вместо этого вам придется вернуться к предыдущему абзацу.

  • Как указал @rsm, $ gsc -exe hello тоже работает: даже если hello уже скомпилирован, .scm не нужен, но есть определенная последовательность команд, которая приведет к сбою этой команды.

Это работает (h правильно скомпилировано):

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

Это работает (h правильно скомпилирован из hello.scm, а не из hello):

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

Но это не удается:

$ 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

В случае, когда файл .c с таким именем уже существует, следует использовать расширение .scm. Хотя сообщение указывает на ошибку компоновщика, корень проблемы, насколько я могу судить, заключается в том, что файлы C имеют приоритет над файлами Scheme, когда расширение не указано, что неожиданно для Scheme. компилятор...

person Neven V.    schedule 07.11.2019