Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 20 июн 2025, 20:37

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
 Заголовок сообщения: "Умная" линковка (smart linking) в ZXDev/SDCC
СообщениеДобавлено: 14 сен 2012, 21:19 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
С некоторыми ограничениями решена следующая проблема ZXDev.

Текущая стратегия компоновщика: прилинковывать все указанные в командной строке .rel-файлы. Из указанных библиотек линковать только .rel-файлы, необходимые для разрешения зависимостей.

На практике это значит, что экономия кода может быть достигнута если при разработке библиотек они вручную разделены на атомарные сущности (и представляют в итоге набор .rel-файлов, которые могут быть зависимыми друг от друга и от других библиотек). Для не-библиотек (и сгенерированных Ofront'ом сишных исходников), из которых порождается один .rel-файл, поведение линкера остаётся консервативным, со следующими "если":

Мёртвый код вида "IF FALSE THEN ... END" Ofront не добавляет к целевому Си-коду.

SDCC и сам не включает:
    a) мёртвый код вида if(0)... (выдаётся warning 126: unreachable code).
    b) проверка вида if(1)... тоже осуществляется на этапе компиляции.
    c) отбрасываются неиспользованные переменные (если они описаны внутри функций, то выдаётся warning 85: in function ... unreferenced local variable : 'i')

Но неиспользованные символьные строки, пустые, неэкспортированные и неиспользованные процедуры будут по-прежнему добавлены целиком. Увы, это ограничение SDCC. Не идеально конечно, но вполне терпимо. Главное знать эти вещи и умело ими пользоваться.

В терминологии SDCC включаемые в один .rel-файл по одному сишные файлы называются модулями, хотя я бы предпочёл для большей ясности называть их атомарными (неделимыми) сущностями линковки, которые включаются в целевой код полностью. Логично, что чем меньше атомарность, тем потенциально компактнее будет целевой код. Так что практически всегда есть смысл включать каждую функцию (или переменную) в отдельный .rel — только так будет достигаться "умная" линковка с отбрасыванием неиспользуемых библиотечных функций. А модули это всё-таки несколько иные сущности (я понимаю желание называть любую часть чего-либо модулем, например, как это принято в языках, эмулирующих понятие модуля через классы; но желающим разобраться, почему я упорно предпочитаю не называть модулями .rel-файлы или сишные исходники, советую вдумчиво познакомиться с концепцией модульности, реализованной в языках Модула-2 и Оберон).

Для облегчения разбивки исходных сишных текстов на "модули" (в терминологии SDCC), а на деле просто на фрагменты с отдельными функциями, я написал утилиту smartlib, облегчающую подготовку библиотек. Она автоматически делит сишный исходник на несколько (по отдельным функциям или как-либо ещё). Заголовок и "линии отреза" задаются с помощью специального вида комментариев:
Код: "EMPTY"
Header for copying to all parts ...
/*========= Header ==================*/
Function1 ...
/*-------- Cut here -----------------*/
Function2 ...
/*-------- Cut here -----------------*/
Function3 ...

Подобным образом доработана библиотека Basic. Теперь она готова для "умной" линковки. Добавлен модуль TinyHello, который демонстрирует возможность сборки крошечной программы — размер бинарника после компиляции составляет 45 байт. Для программы на языке высокого уровня это вполне близко к идеалу. А можно ли меньше? Да, возможность сделать TinyHello ещё меньше появится когда Филипп Краузе реализует передачу параметров в регистрах.

Теперь, когда найден способ смартлинковать сущности из библиотек, среда ZXDev стала ещё привлекательнее в качестве высокоуровневого клея между ассемблерными подпрограммами и исходниками на ЯВУ, в качестве средства для накопления и наработки библиотек. Я надеюсь, те спектрумисты (MSX-шники и т.д.), которые давно хотели сформировать свой набор библиотек, но не решались начать эту работу, будут рассматривать ZXDev как стержень, на который нанижутся асмовые библиотеки для использования их из Си/Оберона, как повод наконец приступить к задуманному делу.

Трёхуровневая система разработки, в которой умелый программист может извлечь пользу из любого уровня (низкий-асм, средний-Си и высокий-Оберон), — идеальный на данный момент структурно-модульный клей между всеми тремя уровнями (без оверхеда на каждом из них). Поэтому утверждаю, что ZXDev — это не "игрушечная" среда. Это серьёзный инструмент, предназначенный как для начинающих, так и для профессионалов, позволяющий выполнить разработку софта практически любой сложности. И в то же время идеологически он выполнен в духе SDCC, которому не чужды промежуточные уровни представления кода.

P.S. В принципе, sdcclib и sdar аналогичны по функциональности. Так что перешёл на sdar без труда. Как использовать sdar и smartlib — смотрите ZXDev/Lib/Bin/*.bat


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 12 окт 2012, 11:40 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
С удивлением узнал, что такое поведение Си-компилятора, как описано выше, оказывается типично для многих Си-компиляторов. Например, абсолютно такая же стратегия у компилятора Tiny C: нет "умной" линковки при добавлении сущностей из объектных файлов (добавляется всё целиком) и даже из библиотек, если перед добавлением в библиотеку исходник не разрезать на кусочки и не компилировать в отдельные объектники, как это помогает делать утилита smartlib.

Рассылка разработчиков Tiny C, тема «[Tinycc-devel] TCC and "smart" linking»


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 04 июл 2014, 14:37 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Чтобы разрабатывать на Обероне библиотеки без выхода на уровень Си добавил в smartlib новую функциональность: ключи -noinit и -nocut.
Цитата:
Командная строка для вызова smartlib:

smartlib.exe src.c [partname] [-noinit] [-nocut]

Здесь:

src.c - обрабатываемый утилитой сишный исходник.

partname - имя части (было добавлено чтобы иметь возможность использовать короткие имена DOS для длинного имени исходника). Например: smartlib.exe longname.c lnam

Ключи для использования утилиты в XDev/Ofront:

-nocut - не разрезать исходник (если не нужна "умная" линковка).

-noinit - отрезать (не включать в библиотеку) инициализатор модуля вида:

Код: "C"
               export void *GRAPH0__init(void)
{
__DEFMOD;
__IMPORT(Asm__init);
__REGMOD("GRAPH0", 0);
__REGCMD("CLS2", GRAPH0_CLS2);
__REGCMD("GCLS", GRAPH0_GCLS);
__REGCMD("SCRDOT", GRAPH0_SCRDOT);
__REGCMD("SCRNAD", GRAPH0_SCRNAD);
/* BEGIN */
__ENDMOD;
}

а фактически последний фрагмент. Нужно для сборки Оберон-библиотек (чтобы повысить эффективность кода).


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club