С некоторыми ограничениями решена следующая проблема 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