Приклад проекту з декількох файлів, бібліотека Лінуксцентра http

Приклад проекту з декількох файлів

Напишемо тепер програму, що складається з двох вихідних файлів і одного заголовки. Для цього візьмемо наш калькулятор і переробимо його. Тепер після введення першого числа треба відразу вводити дію. Якщо дію оперує тільки з одним числом (як у випадку синуса, косинуса, тангенса, квадратного кореня), результат відразу буде виведений. Якщо знадобиться друге число, воно буде спеціально запитуватися.

Створимо каталог проекту kalkul2. У ньому створимо три файли: calculate.h, calculate.c, main.c.

float Calculate (float Numeral, char Operation [4]);

float Calculate (float Numeral, char Operation [4])

if (strncmp (Operation, "+", 1) == 0)

printf ( "Другий доданок.");

else if (strncmp (Operation, "-", 1) == 0)

printf ( "Від'ємник.");

else if (strncmp (Operation, "*", 1) == 0)

printf ( "Множник.");

else if (strncmp (Operation, "/", 1) == 0)

printf ( "Дільник.");

printf ( "Помилка. поділ на нуль.");

else if (strncmp (Operation, "pow", 3) == 0)

printf ( "Ступінь.");

else if (strncmp (Operation, "sqrt", 4) == 0)

else if (strncmp (Operation, "sin", 3) == 0)

else if (strncmp (Operation, "cos", 3) == 0)

else if (strncmp (Operation, "tan", 3) == 0)

У нас є два файли вихідного коду (c-файли) і один заголовний (h-файл). Заголовний включається в обидва c-файлу.

gcc -c calculate.c

Отримали calculate.o. Потім main.c.

І ось він main.o перед нами! Тепер, як вам уже, напевно, підказує інтуїція, треба з цих двох об'єктних файлів зробити запускається.

gcc calculate.o main.o -o kalkul

Упс. і не вийшло. Замість настільки бажаного запускається файлу, в консолі з'явилася якась лайка:

calculate.o (.text + 0x1b5): In function `Calculate ':

calculate.c: undefined reference to `pow '

calculate.o (.text + 0x21e): calculate.c: undefined reference to `sqrt '

calculate.o (.text + 0x274): calculate.c: undefined reference to `sin '

calculate.o (.text + 0x2c4): calculate.c: undefined reference to `cos '

calculate.o (.text + 0x311): calculate.c: undefined reference to `tan '

collect2: ld returned 1 exit status

Давайте розберемося, за що нас так насварили. Undefined reference означає посилання на функцію, яка не визначена. В даному випадку gcc не знайшов визначення функцій pow, sqrt, sin, cos, tan. Де ж їх знайти?

Коли ми писали програму hello, ми використовували функцію printf для виведення текстового рядка. Однак, як ви пам'ятаєте, ми ніде не писали визначення цієї функції. Звідки ж вона тоді викликається?

Просто при компонуванні будь-якої програми компілятор gcc за замовчуванням включає в файл, що запускається бібліотеку libc. Це стандартна бібліотека мови C. Вона містить рутинні функції, необхідні абсолютно у всіх програмах, написаних на C, в тому числі і функцію printf. Оскільки бібліотека libc потрібна у всіх програмах, вона включається за замовчуванням, без необхідності давати окреме зазначення на її включення.

Решта бібліотеки треба вимагати включати явно. Адже не можна ж в усі програми поміщати абсолютно все бібліотеки. Тоді виконуваний файл роздується до немислимо великих розмірів. Одним програмами потрібні одні функції, іншим - інші. Навіщо ж засмічувати їх непотрібним кодом! Нехай залишається тільки те, що реально необхідно.

Нам в даному випадку потрібна бібліотека libm. Саме вона містить всі основні математичні функції. Вона вимагає включення в текст програми заголовки .

Крім цього дистрибутиви Linux містять і інші бібліотеки, наприклад:

libGL Висновок тривимірної графіки в стандарті OpenGL. Потрібно заголовки .

libcrypt Криптографічні функції. Потрібно заголовки .

libcurses псевдографіка в символьному режимі. Потрібно заголовки .

libform Створення екранних форм в текстовому режимі. Потрібно заголовки .

libgthread Підтримка багатопотокового режиму. Потрібно заголовки .

libgtk Графічна бібліотека в режимі X Window. Потрібно заголовки .

libhistory Роботи з журналами. Потрібно заголовки .

libjpeg Робота з зображенням у форматі JPEG. Потрібно заголовки .

libncurses Робота з псевдографікою в символьному режимі. Потрібно заголовки .

libpng Робота з графікою в форматі PNG. Потрібно заголовки .

libpthread Багатопотокова бібліотека POSIX. Стандартна многопоточная бібліотека для Linux. Потрібно заголовки .

libreadline Робота з командним рядком. Потрібно заголовки .

libtiff Робота з графікою в форматі TIFF. Потрібно заголовки .

libvga Низькорівнева робота з VGA і SVGA. Потрібно заголовки .

А також багато-багато інших.

Зверніть увагу, що назви всіх цих бібліотек починаються з буквосполучення lib-. Для їх явного включення в виконуваний файл, потрібно додати до команди gcc опцію -l, до якої разом додати назву бібліотеки без lib-. Наприклад, щоб включити бібліотеку libvga треба вказати опцію -lvga.

Нам потрібні математичні функції pow, sqrt, sin, cos, tan. Вони, як уже було сказано, знаходяться в математичній бібліотеці libm. Отже, щоб підключити цю бібліотеку, ми повинні вказати опцію -lm.

gcc calculate.o main.o -o kalkul -lm

Ура! Нарешті наш файл, що запускається створений!