#c #makefile
Вопрос:
Я действительно новичок в makefile и изо всех сил пытаюсь заставить его скомпилировать все файлы .cpp в папке src.
прямо сейчас файл makefile выглядит следующим образом:
SRC_DIR = src
OBJ_DIR = build/obj
INCLUDE_DIR = $(SRC_DIR)/inc
SRC_DIRS = $(wildcard $(SRC_DIR) $(SRC_DIR)/* $(INCLUDE_DIR)/*)
C_FILES = $(filter %.cpp, $(wildcard $(SRC_DIRS)/*.cpp))
OBJ_FILES = $(addprefix $(OBJ_DIR)/, $(notdir $(C_FILES:.cpp=.o)))
INCLUDE_PATH = -I$(INCLUDE_DIR)
CXXFLAGS = $(INCLUDE_PATH)
CXX = g
CFLAGS = -Wall -g
CC = gcc
$(OBJ_DIR)/%.o: $(SRC_DIRS)/%.cpp
pile: $(OBJ_FILES)
test:
@echo $(C_FILES)
@echo $(OBJ_FILES)
и чего я хочу достичь с помощью каждого правила, так это:
pile:
при вызовеmake pile
он должен проверять наличие всех файлов .o внутриbuild/obj
.$(OBJ_DIR)/%.cpp:
найдите эквивалентный.cpp
файл в исходной папке и скомпилируйте его.
Я полагаю, что с моим вторым правилом что-то не так, но я не могу точно сказать, почему, потому test
что правило печатает все файлы.. :/
заранее благодарю вас за любую помощь.
Комментарии:
1. Настоятельно рекомендуется использовать
CMake
вместо этого, и aMakefile
не следует использовать, если ваш проект имеет более одной цели (или является сложным, со многими зависимостями).2. спасибо, но это проект с учебными целями, и одна из вещей, которую я хочу изучить, — это makefile xD. Однако это не должен быть большой проект, я просто не хочу добавлять новое правило для каждого файла.
3. Все, что имеет 1 или более зависимостей, вызовет у вас сильную головную боль (если вас не попросили взять на себя существующий
Makefile
проект, не утруждайте себя обучением, вы ничего не пропустите; -))4. что ж, я посмотрю
CMake
и посмотрю, не станет ли от этого легче. спасибо вам 🙂5. Рекомендация cmake-это личное мнение, оно не отвечает на вопрос. Существует много законных способов использования make.
Ответ №1:
Похоже, что SRC_DIRS может быть массивом, который не будет доволен этой функцией сопоставления. Попробуйте изменить:
$(OBJ_DIR)/%.o: $(SRC_DIRS)/%.cpp
Для
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
Комментарии:
1. это не сработало :/ а также файл cpp может (и, вероятно, будет) находиться во вложенной папке, если я буду использовать только $(SRC_DIR), это не сработает, верно?
2. Да, сопоставитель хочет создать объект в OBJ_DIR, имя которого соответствует файлу CPP, существующему в SRC_DIR. Если make не может найти соответствующий файл cpp, правило неприменимо, и поэтому оно будет продолжать поиск, в конечном итоге оканчиваясь на «не удается найти правило».
Ответ №2:
Здесь много проблем, но самая фундаментальная заключается в том, что вы на самом деле не определяете правило, когда пишете эту строку:
$(OBJ_DIR)/%.o: $(SRC_DIRS)/%.cpp
Правило состоит из целей, предварительных условий и рецепта. Здесь вы не предоставили рецепт, поэтому вы не сказали make, как на самом деле что-либо построить.
Другая проблема, как упоминал @Ryan-Miller; вы не можете использовать несколько каталогов в одном правиле, подобном этому. Но вы все равно можете просто избежать сложностей, если все ваши исходные файлы находятся в одном каталоге.
Если это не то, чего вы хотите, пожалуйста, проясните свой вопрос относительно ВСЕХ различных вещей, которые вам нужны. Вы написали «$(OBJ_DIR)/%.cpp: найдите файл equivalente .cpp в исходной папке и скомпилируйте его«. Как именно вы определяете «эквивалентный файл .cpp»? Компьютерное программирование — это все о деталях!
Комментарии:
1. Я не добавил рецепт, потому что пытался использовать неявные правила, как указано здесь . И да, как вы упомянули, мне не очень понятно, как найти эквивалент .cpp , я сопоставляю все файлы cpp с их эквивалентом .o, когда я определяю
OBJ_FILES
, но я не могу точно сказать, как я мог бы поступить по-другому.. так что, я думаю, считайте это частью вопроса.2. Неявное правило, такое как правило шаблона, требует, чтобы вы создали для него рецепт, как я говорю в своем ответе. Вы не можете просто создать цель шаблона и предварительные условия без рецепта: это не правило. Эта строка ничего не делает (технически она отменяет это правило шаблона, но поскольку оно не существует, на самом деле оно ничего не делает).
3. Прежде чем вы сможете написать файл создания, точно так же, как и до того, как вы сможете написать программу, вам необходимо четко знать, что вы хотите, чтобы файл создания делал. Если вы можете описать словами, что должен делать файл makefile, обычно его нетрудно заставить это сделать. Точно так же, как в случае с программой, если вы не знаете, чего хотите от нее добиться, все получится не так хорошо.