Я решил опробовать CPCC (консольный компилятор Компонентного Паскаля для Линукса, подсистема Блэкбокса).
https://sourceforge.net/projects/cp-dev/
Тут я расписываю всё очень подробно в надежде на то, что кому-то в будущем эта писанина поможет разобраться, как пользоваться CPCC. Документация, увы, практически отсутствует.

Долго пытался понять, почему не компилируется проект с тремя файлами, один из которых - внешний модуль. Оказалось, что достаточно этот внешний модуль просто включить в список IMPORT (в другом модуле, где это нужно), а я ещё дописывал его в список LinkedMods в prj-файле:## Код:
```
LinkedMods=Kernel$+ Math ... Init Out GraphSdl GraphLib GraphTest#
```
(GraphSdl у меня - это внешний модуль.)

Чтобы скомпилировать этот компонент из трёх файлов, мне потребовалось три PRJ-файла. Иначе оно ругается: "Error #152: symbol file of imported module not found". Порядок сборки такой:## Код:
```
./cpcc GraphSdl.prj # Тут оно ругается в конце, но без этой строчки никак.
./cpcc GraphLib.prj # Создаётся лишний файл - libgraphlib.so, но без этого тоже никак.
./cpcc GraphTest.prj
```
Прилагаю к сообщению все 6 файлов (3 cp и 3 prj). Вообще, всё это ненормально. Может, доделаем компилятор-то? Такой компилятор, но доведённый до ума, оказал бы незаменимую помощь при продвижении Оберона в массы.

В итоге, я смог без каких либо дополнительных проблем из линуксовской консоли собрать динамическую библиотеку (SO-файл), экспортирующую процедуру Do модуля GraphTest (кстати, она так и называется - "Do", а не, например, "GraphTest_Do", как было бы в VOC или OO2C, но это, пожалуй, хорошо). Список экспортируемых SO-файлом процедур можно получить командой:## Код:
```
nm -d libgraphtest.so
```

Затем я создал файл "prog.c":## Код:
```
extern void Do();
int main() {
  Do();
  return 0;
}
```
и скомпилировал его командой:## Код:
```
gcc -o prog -lgraphtest -L. prog.c
```
(-lgraphtest добавляет файл libgraphtest.so, а -L. указывает, что этот файл следует искать также и в текущем каталоге.)

Появился исполняемый файл prog, который замечательно работает, но только запускать его надо вот так:## Код:
```
env LD_LIBRARY_PATH=. ./prog
```
или вот так:## Код:
```
export LD_LIBRARY_PATH=.
./prog
```
иначе он ругается:## Код:
```
./prog: error while loading shared libraries: libgraphtest.so: cannot open shared object file: No such file or directory
```
что очень тупо

Дальше я сделал следующее: в модуль GraphTest (Graph/Mod/Test.cp) добавил секцию BEGIN:## Код:
```
MODULE GraphTest;
  ...
BEGIN
  Do
END GraphTest.
```
а из файла "prog.c" убрал всё лишнее, оставив только:## Код:
```
int main() {
  return 0;
}
```

Это работает, то есть после точно такой же сборки исполняемого файла через GCC программа работает также. Получается, что SO-файл сам запускает процедуру Do внутри себя.

Внимание вопрос. Как сделать так, чтобы SO-файл можно было запускать непосредственно? Или как сделать так, чтобы получался не SO, а ".a"-файл, то есть статическая библиотека?
Или ещё один вариант вопроса: как дописать ElfLinker или LinLinker или что-то ещё и где его взять? Вроде бы, линуксовский SO-файл (имеющий формат ELF) не очень отличается от исполняемого бинарника формата ELF. Пока искал в интернете информацию по этому поводу, с удивлением обнаружил, что некоторые SO-файлы можно даже запускать из консоли после chmod +x и тогда запускается процедура с определённым названием, что-то вроде __ldd_main...