Два основных вопроса о компиляции и библиотеках - PullRequest
3 голосов
/ 27 августа 2009

У меня два полусвязанных вопроса.

Мой первый вопрос: я могу вызывать функции в стандартной библиотеке, не компилируя всю библиотеку, просто:

#include <stdio.h>

Как бы я поступил так же с моими заголовочными файлами? Просто "включение" моих заголовочных файлов открытого текста, очевидно, не работает.

#include "nameofmyheader.h"

Как я могу создать библиотеку, которую могут вызывать другие файлы?

Второй вопрос. Предположим, у меня есть программа, которая разбита на файлы 50 c и заголовочный файл. Как правильно его скомпилировать, кроме того:

cc main.c 1.h 1.c 2.c 3.c 4.c 5.c 6.c 7.c   /*... and so on*/

Пожалуйста, исправьте все мои заблуждения. Я полностью потерян здесь.

Ответы [ 5 ]

14 голосов
/ 27 августа 2009

Во-первых, вы немного озадачены тем, что происходит с #include. Вы никогда не «компилируете» стандартную библиотеку. Стандартная библиотека уже скомпилирована и находится в файлах библиотеки (файлы .dll и .lib в Windows, .a и .so в Linux). Что делает #include, так это дает вам объявлений , необходимых для ссылки на стандартную библиотеку.

Первое, что нужно понять о директивах #include, это то, что они очень низкого уровня. Если вы программировали на Java или Python, #include сильно отличается от импорта. Импорт сообщает компилятору на высоком уровне «этот исходный файл требует использования этого пакета», и компилятор выясняет, как разрешить эту зависимость. Директива #include in C гласит: «возьмите все содержимое этого файла и буквально вставьте его прямо здесь при компиляции». В частности, #include <stdio.h> вводит файл, который имеет предварительные объявления для всех функций ввода / вывода в стандартной библиотеке. Затем, когда вы компилируете свой код, компилятор знает, как выполнять вызовы этих функций и проверять их на корректность типов.

Как только ваша программа скомпилирована, она связывается со стандартной библиотекой. Это означает, что ваш компоновщик (который автоматически вызывается вашим компилятором) либо заставит ваш исполняемый файл использовать общую стандартную библиотеку (.dll или .so), либо скопирует необходимые части статической стандартной библиотеки (.lib или .a) в ваш исполняемый файл. Ни в том, ни в другом случае ваш исполняемый файл не "содержит" какую-либо часть стандартной библиотеки, которую вы не используете.

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

Заголовочный файл не всегда является частью библиотеки. Кажется, что у вас есть несколько исходных файлов, и вы хотите иметь возможность использовать функции из одного исходного файла в другом исходном файле. Вы можете сделать это без создания библиотеки. Все, что вам нужно сделать, это поместить объявлений для файлов foo.c, к которым вы хотите получить доступ из других мест, в foo.h. Объявления - это такие вещи, как прототипы функций и объявления переменных "extern". Например, если foo.c содержит

int some_global;

void some_function(int a, char b)
 {
     /* Do some computation */
 }

Затем, чтобы сделать их доступными из других исходных файлов, foo.h должен содержать

extern int some_global;

void some_function(int, char);

Затем вы #include "foo.h" везде, где вы хотите использовать some_global или some_function. Поскольку заголовки могут включать в себя другие заголовки, обычно заголовки заключаются в «включить охранники», чтобы объявления не дублировались. Например, foo.h должен действительно читать:

#ifndef FOO_H
#define FOO_H

extern int some_global;

void some_function(int, char);

#endif

Это означает, что заголовок будет обрабатываться только один раз на единицу компиляции (исходный файл).

Что касается того, как их компилировать, никогда не помещайте файлы .h в командную строку компилятора, поскольку они не должны содержать какой-либо компилируемый код (только объявления). В большинстве случаев это прекрасно для компиляции как

cc main.c 1.c 2.c 3.c ... [etc]

Однако, если у вас 50 исходных файлов, возможно, будет гораздо удобнее, если вы используете систему сборки. В Linux это Makefile. От окон зависит, какую среду разработки вы используете. Вы можете зайти в Google или задать еще один вопрос, как только укажете платформу (так как этот вопрос уже достаточно широк).

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

0 голосов
/ 27 августа 2009

Стандартная библиотека уже скомпилирована и размещена на вашем компьютере, готовая к динамическому связыванию. Это означает, что библиотека динамически загружается при необходимости программой. Сравните это со статической библиотекой, которая компилируется в вашу программу при запуске компилятора / компоновщика.

Вот почему вам нужно компилировать код, а не стандартный код библиотеки. Вы можете создать динамическую (общую) библиотеку самостоятельно.

Для справки, #include <stdio.h> не ИМПОРТ стандартной библиотеки. Он позволяет компиляции и ссылке видеть открытый интерфейс библиотеки (чтобы узнать, какие функции используются, какие параметры они принимают, какие типы определены, какие у них размеры и т. Д.).

Динамическая загрузка

Общая библиотека

Вы можете разбить ваши файлы на модули и создать общие библиотеки. Но в целом, когда проекты становятся больше, вам, как правило, требуется более совершенный механизм для сборки вашей программы (и библиотек). Вместо того, чтобы напрямую вызывать компилятор, когда вам нужно выполнить перестройку, вы должны использовать программу make или полную систему сборки, такую ​​как GNU Build System .

0 голосов
/ 27 августа 2009

Если вы действительно хотите, чтобы это было так просто, как просто включение файла .h, весь ваш «библиотечный» код должен быть в файле .h. Однако в этом случае кто-то может включить ваш файл .h в один и только один файл .c. Это может быть хорошо, в зависимости от того, как кто-то будет использовать вашу «библиотеку».

0 голосов
/ 27 августа 2009

Вы можете объединить несколько файлов .c в библиотеку. Эти библиотеки можно связать с другими файлами .c, чтобы они стали исполняемыми.

Вы можете использовать make-файл для создания большого проекта.

Makefile имеет набор правил. Каждое правило описывает шаги, необходимые для создания одного фрагмента программы, и их зависимости от других фрагментов или исходных файлов.

0 голосов
/ 27 августа 2009

Вам необходимо создать разделяемую библиотеку, стандартная библиотека - это разделяемая библиотека, которая неявно связана в вашей программе.

Когда у вас есть общая библиотека, вы можете использовать файлы .h и просто скомпилировать программу с параметром -lyourlib, который подразумевается для libc

Создать, используя:

gcc -shared test.c -o libtest.so

А затем скомпилируйте вашу программу как:

gcc myprogram.c -ltest -o myprogram

Для вашего второго вопроса я советую вам использовать Makefiles http://www.gnu.org/software/make/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...