Приклад проекту з декількох файлів, бібліотека Лінуксцентра 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
Ура! Нарешті наш файл, що запускається створений!