Свои библиотеки (в исходном тексте)

PS>   С неиспользуемыми кусками кода все понятно — это свойство компилятора, а
PS> не линковщика. С lib-модулями — тоже. Например, в Borland C++ lib-файлы
PS> (библиотеки) собираются из obj-файлов с помощью специальной программы.
PS>   А вот с obj-файлами — непонятно. Копирую их другого своего письма:
PS>   Может ли obj-файл, созданный компилятором при
PS> компилировании одной программы, использоваться в другой? Если не может —
PS> тогда понятно (он — «собственность» этого проекта). Если может — что
PS> наиболее вероятно (компилятор пишет что-то вроде «Создан qwe.obj (qwe.clw
PS> был изменен)») — то что, собственно говоря, помещать в этот obj-файл —
PS> процедуры, используемые в одном проекте, или процедуры, используемые в
PS> другом проекте? А если я создам один exe-файл, потом — другой, а потом
PS> вернусь к первому, что делать компилятору с obj-файлами? Как он узнает, что
PS> они были созданы для другого проекта?
PS>   А откуда Вы знаете про SmartLink? Наверное, там это объясняется.

Честно говоря, я этим делом специально не занимался. Но по опыту использования SOURСE — библиотек типа тех, что мы обсуждали по данной теме, могу сказать, что проблем никогда не было. Т.е., когда я собираю приложение, никогда не задумываюсь, а как у меня там с obj-модулями общих библиотек?

Стало интересно — посмотрел. Оказывается — все несколько не так, как мы все думали.
Короче:

  • компилятор компилирует ВСЁ, за исключением кода, заключенного в директиву OMIT().
  • компилятор включает в OBJ-файл ВСЁ, ЧТО СКОМПИЛИРОВАЛ, за исключением кода, который никогда не будет выполнен по условиям ТОЛЬКО ДАННОГО МОДУЛЯ.

Т.е., в OBJ-файл включаются ВСЕ процедуры, но не включается код типа:

Tst PROCEDURE
  Code
    OMIT('***')
  ля-ля-ля     ! не компилируется вообще
    ***
  Return
  A = B        !
  B = A        ! компилируется, но в OBJ-файл не включается
  Return       !

Из данной процедуры в OBJ-файл будет включен ТОЛЬКО код «RET NEAR».

  • при сборке приложения из OBJ-файла линкер берет ТОЛЬКО те процедуры, которые ИСПОЛЬЗУЮТСЯ в данном приложении. При этом, естественно, линкер берет ВЕСЬ ТОТ код процедуры, который компилятор поместил в OBJ-файл по условиям первых двух пунктов. Включение объявления процедуры в MAP-секции не означает ее использования.

(!)Под использованием процедуры подразумевается ТОЛЬКО прямой ее вызов или получение ее адреса в коде, который попадает в OBJ-файл по условиям первых двух пунктов.

Т.е. в MAP-секции могут быть объявлены хоть все процедуры из всех модулей и библиотек, но в приложение будут включены ТОЛЬКО те, которые отвечают условию (!).

Таким образом, как видно, нет необходимости производить контроль, какое приложение дало команду скомпилировать какой-либо модуль. Т.е. автономный модуль компилируется ТОЛЬКО на основании информации, заключенной в данном модуле. Контроль, обычно, нужен только для режимов компиляции: 16/32-bit, отладка и пр.

Думаю, что этого вполне достаточно для правильного понимания взаимодействия компилятора и линкера?