                    ПРИНЦИП РАЗДЕЛЬНОЙ КОМПИЛЯЦИИ


   При разработке больших программ исходный текст разделен на несколько файлов.
После того, как они отдельно друг от друга откомпилированы, их нужно скомпоно-
вать в единую программу. Здесь описан метод раздельной компиляции и отмечены
основные моменты, на которые следует обращать внимание при разработке исходного
текста.


                  1. Замечания к исходной программе

   Имеются две серьезные проблемы раздельной компиляции и сборки больших
программ:

        - ссылки на функции из других файлов
        - возможность получения общих данных

   Ниже дана попытка освещения этих вопросов с параллельным показом на приме-
рах. Рассмотрим следующую программу.

#include <stdio.h>
int  a[10];
char b[4];

char main()
{
        char sub1(),sub2();
        sub1();
        sub2();
        printf("%d,%d,%d\n",a[0],a[3],a[9]);
        printf("%c,%c,%c\n",b[0],b[1],b[2]);
}

char sub1()
{
        a[0]=1;
        a[3]=2;
        a[9]=3;
}

char sub2()
{
        b[0]='a';
        b[1]='b';
        b[2]='c';
}

   Текст данной программы размещен в трех файлах с именами PROG1, PROG2 и
PROG3 - соответственно содержащих главную функцию и функции 1 и 2.
Точнее, в каждом из этих файлов содержатся:

PROG1.C:
        #include <stdio.h>
        int a[10];
        char b[4];
        char main()
        {
              :
              :
        }

PROG2.C:
        extern int a[10];
        char sub1()
        {
              :
              :
        }

PROG3.C:
        extern char b[4];
        char sub2()
        {
              :
              :
        }

   Функция main вызывает функции sub1 и sub2, поэтому их определения необхо-
димы. Так как функции sub1 и sub2 в свою очередь никакие другие функции не
вызывают - никаких других описаний не требуется. Использование массивов "a"
и "b" также является проблемой. На идентификатор "а" ссылаются программа main
и sub1. На массив "b" ссылаются функции main и sub2. В любом из этих вариантов
между файлами должна быть установлена связь.
   Для этой цели используется описатель "extern" (внешний). В первом из файлов
- PROG1.C, этот описатель отсутствует, однако в двух других файлах этот описа-
тель введен. Этот факт отражает то обстоятельство, что массивы "a" и "b" содер-
жатся в файле PROG1.C, а в других файлах этих массивов нет. Если в двух или
большем числе файлов будут стоять определения без описателей "extern", то при
сборке единой программы появятся сообщения о дублировании имен массивов. С
другой стороны, при добавлении описателя "extern" во все определения, они мо-
гут диагностироваться как неопределенные.
   Следовательно, в случае организации общих данных для нескольких файлов необ-
ходимо дать определение без описателя "extern" только в одном из файлов с
текстом исходной программы. Во все другие файлы нужно поставить "extern".


              2. Процедура компиляции и сборки программы

   Для описанных выше текстовых файлов с исходной программой последователь-
ность команд компиляции и сборки модулей выглядит следующим образом:

        cc1 prog1
        cc1 prog2
        cc1 prog3
        cc2 prog1
        cc2 prog2
        cc2 prog3
        as prog1
        as prog2
        as prog3
        ld prog=prog1,prog2,prog3,clib/l/gXMAIN

   В том случае, когда все части программы (все файлы) уже откомпилированы и
требуется лишь перекомпилировать одни из них (например файл PROG2.C), следует
выполнить приведенную ниже группу команд:

        cc1 prog2
        cc2 prog2
        as prog2
        ld prog=prog1,prog2,prog3,clib/l/gXMAIN
