Многофайловая сборка
Зачем нужна многофайловая сборка?
До сих пор на курсе мы писали программы в одном файле: один main.cpp, в котором находится весь код. Для небольших задач этого достаточно, но в реальных проектах код разбивают на несколько файлов. Причины:
Разделение ответственности. Каждый файл отвечает за свою часть логики. Это упрощает чтение и поддержку кода.
Повторное использование. Написав, например, библиотеку для работы с функциями, можно подключить её к любому проекту, не копируя код заново.
Совместная работа. Несколько разработчиков могут одновременно работать над разными файлами, не мешая друг другу.
В домашнем задании по численным методам вам предоставляется готовая библиотека fparser — парсер математических функций. Она позволяет считать строку вида "x^2 + sin(x)" из ввода и вычислить значение этой функции в любой точке. Вам не нужно писать парсер самостоятельно — только подключить библиотеку к своей программе.
Файлы в C++: исходные и заголовочные
В C++ принято разделять код на два типа файлов:
Заголовочные файлы (.h, .hpp)
Заголовочный файл содержит объявления: какие функции, классы и структуры существуют, какие у них сигнатуры (имена, аргументы, типы возврата). Он не содержит реализацию — только «обещание», что где-то эти функции определены.
Пример (упрощённо):
// fparser.hh — заголовочный файл библиотеки fparser
struct FunctionParser {
int Parse(const std::string& function, const std::string& vars);
double Eval(const double* vars);
// ...
};Заголовочные файлы подключаются директивой #include:
#include "fparser.hh"При компиляции #include буквально вставляет содержимое заголовочного файла в то место, где он подключён. Благодаря этому компилятор знает, какие функции и типы существуют, даже если их реализация находится в другом файле.
Исходные файлы (.cpp, .cc)
Исходный файл содержит реализацию — собственно код функций. Например, fparser.cc содержит код всех методов класса FunctionParser.
Ваш main.cpp — тоже исходный файл. В нём вы подключаете заголовок (#include "fparser.hh"), а значит, можете использовать FunctionParser, хотя его реализация находится в другом файле.
Как работает сборка
Сборка многофайловой программы состоит из двух этапов:
1. Компиляция. Каждый исходный .cpp-файл компилируется отдельно. Компилятор проверяет синтаксис, подставляет содержимое #include и создаёт промежуточный объектный файл (.o):
g++ -c main.cpp → main.o
g++ -c fparser/fparser.cc → fparser.o
2. Линковка. Все объектные файлы объединяются (линкуются) в один исполняемый файл:
g++ main.o fparser.o -o output_solution
На практике оба этапа часто записывают одной командой:
g++ -g -O3 -Ifparser main.cpp fparser/fparser.cc fparser/fpoptimizer.cc -o output_solutionЗдесь:
-g— включает отладочную информацию-O3— уровень оптимизации-Ifparser— указывает компилятору, где искать заголовочные файлы (папкаfparser)- в конце перечислены все
.cpp/.cc-файлы, которые нужно скомпилировать и слинковать -o output_solution— имя выходного исполняемого файла
Makefile
Набирать длинную команду компиляции каждый раз неудобно. Для этого существует Makefile — специальный файл с правилами сборки. В предоставленном шаблоне он уже написан: достаточно выполнить одну команду:
make allУтилита make прочитает Makefile, выполнит нужные команды компиляции и линковки, и вы получите готовый исполняемый файл. Если вы изменили только main.cpp, make перекомпилирует только его, не трогая файлы библиотеки — это экономит время.
Локальная сборка
Рекомендуемый способ работы — на своём компьютере. Так вы освоите инструменты, которыми пользуются профессиональные разработчики: терминал, компилятор, систему сборки.
Шаг 1. Склонируйте репозиторий
Если у вас установлен git, откройте терминал и выполните:
git clone https://github.com/dfbakin/hw-approx-template.git
cd hw-approx-templateЕсли git не установлен, можно скачать репозиторий как ZIP-архив со страницы на GitHub (кнопка Code → Download ZIP) и распаковать.
Шаг 2. Убедитесь, что компилятор установлен
В терминале выполните:
g++ --versionЕсли команда не найдена, установите компилятор — см. гайд «С чего начать?».
Шаг 3. Напишите решение
Откройте main.cpp в любом редакторе (VS Code, CLion или даже блокнот). Шаблон уже содержит подключение библиотеки fparser и базовую структуру — вам нужно дописать логику решения задачи.
Шаг 4. Скомпилируйте и запустите
В терминале из папки проекта выполните:
make allВы увидите строку компиляции, начинающуюся с g++ — это значит, что компилятор работает. Если ошибок нет, будет создан исполняемый файл.
После успешной компиляции программа запустится автоматически. Введите входные данные задачи и проверьте, совпадает ли вывод с ожидаемым.
Если вы изменили код, повторите make all — программа перекомпилируется и запустится заново.
Сборка без Makefile
Если по какой-то причине make недоступен, можно собрать вручную:
g++ -g -O3 -Ifparser main.cpp fparser/fparser.cc fparser/fpoptimizer.cc -o output_solution
./output_solutionИспользование fparser отдельно от шаблона
Если вы хотите подключить библиотеку к собственному проекту (без шаблонного репозитория):
Скачайте библиотеку: fparser4.5.2.zip
Распакуйте архив в папку
fparserрядом с вашим.cpp-файломСкомпилируйте:
g++ -g -O3 -Ifparser main.cpp fparser/fparser.cc fparser/fpoptimizer.cc -o output_solutionАльтернатива: Replit
Если у вас не получается настроить локальную среду, можно воспользоваться онлайн-платформой Replit. Она позволяет писать, компилировать и запускать код прямо в браузере.
Шаг 1. Вход в Replit
Откройте replit.com и войдите в аккаунт. Можно использовать Google-аккаунт или логин и пароль.
Шаг 2. Импорт репозитория
Нажмите кнопку Import (или Create Repl → Import from GitHub). В поле для URL вставьте:
https://github.com/dfbakin/hw-approx-template.git
Нажмите Import from GitHub и дождитесь завершения импорта.
Шаг 3. Остановите AI-агента
После импорта Replit может автоматически запустить AI-агента, который попытается что-то сделать с вашим проектом. Его нужно остановить:
- Напишите ему команду stop
- Нажмите кнопку Stop
- Закройте панель агента
Шаг 4. Откройте файлы
Нажмите кнопку + в верхней части экрана и откройте main.cpp — в нём вы будете писать решения. Нажмите + ещё раз и выберите Shell — это терминал для сборки и запуска.
Шаг 5. Соберите и запустите
В терминале введите:
make allРаботает точно так же, как при локальной сборке: компиляция, линковка, запуск. Введите входные данные и проверьте результат.