Я разбираюсь с Ofront, пытаюсь собрать консольный транслятор-компилятор для Линукса и для Виндоуса и решил написать об этом на форум.
Что я сделал:
1) Зашёл на
software-templ.com и скачал
бинарную версию Ofront для Линукса.
2) Прочёл, что
исходный код линуксовской версии Ofront'а находится на Google code. Долго копался на этом сайте (кажется, проект Google Code закрыт?) и наконец-то на этой странице посередине нашёл кнопку
Download, скачал исходники.
3) Зашёл в терминале в каталог «ofront/V4_ofront/linux386» и запустил команду «make», которая вылетела с ошибкой. Оказалось, что для того, чтобы собрать из исходников исполняемый файл, необходимо уже иметь исполняемый файл «ofront», поэтому я взял его из архива, скачанного на пункте №1. В архивах находится как компилятор (траслятор), так и система Oberon V4, запускающаяся в линуксовском окне через «X», но нас пока интересует только компилятор.
4) Отредактировал 15-ю строчку в файле «ofront/V4_ofront/linux386/makefile»:
Код: "OBERON"
Было:
OFRONT = $(SETPATH) ofront -s
Стало:
OFRONT = $(SETPATH) ../../../linbin/bin/ofront -s
То есть я просто указал путь к исполняемому файлу «ofront». Наверное, можно было скопировать этот файл в текущий каталог, но я решил этого не делать, чтобы он не был перезаписан одноимённым откомпилрованным файлом.
Снова запустил «make», на этот раз всё сработало. Помимо компилятора и нескольких исполняемых файлов, появилась ещё и библиотека OberonV4 в двух видах: libOberonV4.a (статическая) и libOberonV4.so (динамическая). Проверил «make install» - ничего не происходит, такой секции в makefil'е нет.
5) Пришло время проверить получившийся компилятор. Отдельно от всего этого создал отдельный каталог, в нём создал «MyMod.Mod»:
Код: "OBERON"
MODULE MyMod;
IMPORT Console;
BEGIN
Console.String('Hello MyMod!'); Console.Ln
END MyMod.
Модуль «Console» подглядел в файлах, поставляемых с компилятором.
6) После долгих разбирательств подобрал вот такой вот bash-скрипт:
Код: "OBERON"
#!/bin/bash
OFRONTPATH=/home/...путь.../ofront/V4_ofront/linux386
OFRONT=$OFRONTPATH/ofront
OBERON=.:$OFRONTPATH $OFRONT -s MyMod.Mod -m
cc MyMod.c -o MyMod -I$OFRONTPATH -L$OFRONTPATH -lOberonV4 -lm -lX11
Запуск транслятора весьма непривычный. Остановимся на нём поподробнее:
Код: "OBERON"
OBERON=.:$OFRONTPATH $OFRONT -s MyMod.Mod -m
После того, как это разворачивается (подставляются значения переменных, начинающихся с $), получается примерно следующее:
Код: "OBERON"
OBERON=.:/home/user/ofront /home/user/ofront/ofront -s MyMod.Mod -m
Тут на самом деле запускается файл «/home/user/ofront/ofront», а «OBERON=...» - это, передающаяся этому файлу, переменная окружения с именем «OBERON». Если её задать непосредственно перед запуском «ofront» на отдельной строчке или вообще не задавать, то «ofront» не найдёт файла с модулем «Console». Ту же самую команду можно выполнить в более привычном виде, через «env»:
Код: "OBERON"
env OBERON=.:$OFRONTPATH $OFRONT -s MyMod.Mod -m
Скрипт я назвал «x» и выполнил команды:
Код: "OBERON"
7) Но появившийся исполняемый файл «MyMod» не работает:
Код: "OBERON"
$ ./MyMod
./MyMod: error while loading shared libraries: libOberonV4.so: cannot open shared object file: No such file or directory
Это происходит потому, что он скомпонован с библиотекой OberonV4 динамически, а не статически и при запуске не может найти эту самую динамическую библиотеку (то есть файл «libOberonV4.so»). В свою очередь, это произошло потому, что файлы libOberonV4.so и libOberonV4.a находятся рядом и GCC молча взял тот, который *.SO. Поэтому либо переименовываем/перемещаем файл libOberonV4.so, чтобы он не мешался, либо редактируем одну строчку в скрипте компиляции:
Код: "OBERON"
cc MyMod.c -o MyMod -I$OFRONTPATH -L$OFRONTPATH -lOberonV4 -static
Теперь всё работает, а «MyMod» весит не 6, а 639 килобайт (т. к. внутри себя содержит libOberonV4.a). Наверняка его можно почистить какой-нибудь утилиткой - убрать лишнее, но я этим никогда не занимался.
8) А ещё можно не компоновать программу статически, а вместо этого сделать так, чтобы она успешно находила этот «libOberonV4.so». Тут есть три варианта:
8.1) Запускаем программу не по-обыкновенному, а вот так:
Код: "OBERON"
LD_LIBRARY_PATH=...путь.../ofront/V4_ofront/linux386 ./MyMod
8.2) Копируем libOberonV4.so в каталог с программой и запускаем вот так:
Код: "OBERON"
LD_LIBRARY_PATH=. ./MyMod
(Линукс, в отличие от Виндоуса, не берёт динамический библиотечный файл по умолчанию из того же каталога, где находится программа)
8.3) Копируем файл «libOberonV4.so» в каталог «/usr/lib» и запускаем программу по-обыкновенному.