Avatar ·

В чем разница между Makefile и CMake для сборки C++ кода?

Всем привет! Я только начал изучать C++ и пытаюсь разобраться с инструментами сборки. У меня есть простой проект: main.cpp, какой-то класс myclass.cpp и myclass.h. Сейчас я компилирую всё ручками в терминале: g++ -c myclass.cpp -o myclass.o g++ -c main.cpp -o main.o g++ main.o myclass.o -o myprogram Это жутко неудобно, особенно когда файлов становится много. Все говорят про Makefile и CMake, но я не понимаю, в чем между ними разница. Makefile — это что-то вроде скрипта для make, где я вручную прописываю команды компиляции? А CMake — это тоже самое, но через какой-то конфиг? Или это вообще разные вещи? Какой инструмент стоит учить новичку? Буду благодарен за объяснение с примерами! Мне нужно понять, какой из них решает мою проблему сборки проекта проще и эффективнее. Заранее спасибо! <<>>

Ключевое различие: Makefile — это рецепт, CMake — это генератор рецептов

Представьте, что вы пекарь. Makefile — это ваш рукописный рецепт: "взять 200 г муки, 100 мл воды, замесить тесто, выпекать 30 минут". Вы сами пишете каждый шаг, указываете точные команды и зависимости. CMake — это не рецепт, а программа, которая сама генерирует рецепт (Makefile, а также проекты для Visual Studio, Xcode, Ninja и др.) под вашу конкретную кухню (операционную систему, компилятор).

Пример: ваш проект с Makefile

Вот как выглядит Makefile для вашей задачи (файл Makefile в корне проекта):

# Makefile
CXX = g++
CXXFLAGS = -std=c++17 -Wall

# Цель по умолчанию
all: myprogram

# Правило сборки исполняемого файла
myprogram: main.o myclass.o
	$(CXX) $(CXXFLAGS) main.o myclass.o -o myprogram

# Правила сборки объектных файлов
main.o: main.cpp myclass.h
	$(CXX) $(CXXFLAGS) -c main.cpp -o main.o

myclass.o: myclass.cpp myclass.h
	$(CXX) $(CXXFLAGS) -c myclass.cpp -o myclass.o

# Очистка
clean:
	rm -f *.o myprogram

Теперь сборка: make. Очистка: make clean. Makefile работает на Linux/macOS (с GNU Make). На Windows нужен MinGW или NMake — и ваш Makefile, скорее всего, придётся переписывать.

Пример: тот же проект с CMake

Создаём файл CMakeLists.txt в корне:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyProject)

set(CMAKE_CXX_STANDARD 17)

# Собираем исполняемый файл из исходников
add_executable(myprogram main.cpp myclass.cpp)

Процесс сборки:

  1. mkdir build && cd build — создаём отдельную папку для сборки.
  2. cmake .. — CMake анализирует систему и генерирует Makefile (или другой файл сборки).
  3. make — собственно компиляция.

Преимущество: на Windows с Visual Studio вы делаете cmake .. -G "Visual Studio 17 2022" — и получаете готовый .sln файл. Код не меняется!

Итоговое сравнение

  • Makefile:
    • Платформозависим (разный синтаксис для GNU Make, NMake, BSD Make).
    • Требует ручного прописывания зависимостей (каждый .cpp → .o).
    • Сложен для больших проектов (сотни файлов).
    • Не умеет автоматически находить библиотеки.
  • CMake:
    • Кроссплатформенный (один CMakeLists.txt работает везде).
    • Автоматически отслеживает зависимости (достаточно перечислить .cpp файлы).
    • Умеет находить внешние библиотеки (FindBoost, find_package).
    • Генерирует не только Makefile, но и проекты для IDE.

Что учить новичку?

Начните с Makefile для маленьких учебных проектов (до 5-10 файлов) — это поможет понять, как работает компиляция и линковка. Как только проект разрастается или появляется необходимость собрать его на Windows/Linux/macOS — переходите на CMake. Это стандарт де-факто в современном C++.

<<>>

Дополнение: CMake как "make-генератор" и альтернативы

Важно понимать, что CMake не заменяет make — он генерирует для него файлы. Если вам не нравится сам make (например, из-за медленной работы на больших проектах), CMake может генерировать файлы для Ninja — более быстрой и современной системы сборки. Просто укажите: cmake .. -G Ninja и затем ninja.

Есть и другие генераторы: Meson (синтаксис похож на Python), Bazel (от Google), Premake. Но CMake остаётся самым популярным благодаря огромному сообществу и поддержке практически всех IDE (CLion, Qt Creator, VS Code, Visual Studio).

Совет: не пишите Makefile вручную для проектов, которые планируете развивать. Даже если вы используете make — пусть CMake генерирует его за вас. Это сэкономит часы отладки "магических" ошибок make.