Я прочитал хороший учебник по make-файлам, но немного запутался, когда все стало сложнее.
Я реструктурировал папку своего рабочего пространства и добавил подпапку: Вот изображение папки моего рабочего пространства:
Я попытался отредактировать make-файл, но все равно не смог заставить его скомпилировать мои файлы.
Нужно ли мне объявлять только заголовочные файлы в make-файлах или мне нужны и заголовочные, и cxx-файлы?
В make-файле я указал, как создавать релизную и отладочную сборки. Я попытался сказать: создайте файлы отладки .o в папке отладки и свяжите их вместе в отладке с исполняемым файлом с именем exefile. Так как я добавил подпапки include и src, это запуталось, и я не знаю, как теперь правильно редактировать make-файл.
Вот код make-файла:
#Compiler Flags#
CC = g++
CFLAGS = -Wall -Werror -Wextra
HDIR = include
#Project Files#
SRCS = src/main.cxx src/ex05_01.cxx src/ex05_02.cxx
OBJS = $(SRCS:.cxx=.o)
EXE = exefile
#Debug Build Settings#
DBGDIR = debug
DBGEXE = $(DBGDIR)/$(EXE)
DBGOBJS = $(addprefix $(DBGDIR)/, $(OBJS))
DBGCFLAGS = -g -O0 -DDEBUG
#Release Build Settings#
RELDIR = Release
RELEXE = $(RELDIR)/$(EXE)
RELOBJS = $(addprefix $(RELDIR)/, $(OBJS))
RELFLAGS = -g -O0 -DNDEBUG
.PHONY: all clean debug prep release remake
#default build
debug: $(DBGEXE)
$(DBGEXE): $(DBGOBJS)
$(CC) $(CFLAGS) $(DBGCFLAGS) -o $(DBGEXE) $^
$(DBGDIR)/%.o: %.cxx
$(CC) -c $(CFLAGS) $(DBGCFLAGS) -o $@ $<
# Release rules
release: $(RELEXE)
$(RELEXE): $(RELOBJS)
$(CC) $(CFLAGS) $(RELCFLAGS) -o $(RELEXE) $^
$(RELDIR)/%.o: %.cxx
$(CC) -c $(CFLAGS) $(RELCFLAGS) -o $@ $<
# Other rules
prep: mkdir -p $(DBGDIR) $(RELDIR)
remake:
clean all
clean:
rm -f $(RELEXE) $(RELOBJS) $(DBGEXE) $(DBGOBJS)
Спасибо за помощь!
Обновлено: я забыл опубликовать сообщение об ошибке make:
*** No rule to make target
debug/main.o', needed bydebug/exefile'. Stop.
хорошо, но это то, что я сделал здесь: SRCS = src/main.cxx src/ex05_01.cxx src/ex05_02.cxx
Ваше сообщение об ошибке говорит вам, что фактическая ошибка находится где-то еще. Проверьте, есть ли на самом деле файл с именем main.o в /debug/
@DavidC.Rankin: но itzFlubby сказал, что нет необходимости объявлять путь включения, только файлы cxx? теперь я запутался
@itzFlubby: нет файлов в отладке
И вот проблема: Ошибка говорит именно об этом -> а именно о том, что файл main.o нужен, но не может быть найден. Иногда помогает удаление папки отладки и повторная попытка
@HardCodedCoder - вы правы, если ваши источники могут видеть и включать ваши заголовки в include. Тогда я согласен, что ваша проблема в другом.
@DavidC.Rankin: теперь я отредактировал строку: $(DBGDIR)/%.o: src/%.cxx $(CC) -c $(CFLAGS) $(DBGCFLAGS) -o $@ $< я добавил src/ в %.cxx и теперь он не находит файлы h
@DavidC.Rankin, как я могу это исправить?
@DavidC.Rankin: g++ -c -Wall -Werror -Wextra -g -O0 -DDEBUG -o debug/main.o src/main.cxx src/main.cxx:2:10: фатальная ошибка: 'ex05_01.h' файл не найден #include "ex05_01.h" ^~~~~~~~~~~ Произошла 1 ошибка. make: *** [debug/main.o] Ошибка 1
На самом деле это не имеет ничего общего с Makefiles. Сначала вам нужно выяснить, как скомпилировать ваши файлы вручную (запустить g++ напрямую и т. д.). Затем вы можете приступить к автоматизации процесса, поместив нужные команды в Makefile.
Я смотрю, и трудно сказать со вставленными make-файлами, но у вас есть символы табуляции '\t' (не пробелы), следующие за вашими целями, верно? Между таргерами и рецептами? Нравится "debug:\t$(DBGEXE)", а затем перед каждой оставшейся строкой в мишени?
Какие команды вы используете для компиляции кода без Makefile?
@DavidC.Rankin: да, я использую только табуляции и без пробелов!
@DavidC.Rankin: Я думаю, проблема именно в том, о чем вы сейчас сказали: он не может найти файлы заголовков во включенных путях! Что мне нужно добавить, чтобы он теперь видел файлы .h?
Добавление -I/path/to/includes (здесь просто -I./include) в качестве параметра компилятора должно сделать это.
@DavidC.Rankin: да!!!! Работаю сейчас!!!! Спасибо!!!!
Рад, что это помогло. Иногда это просто мелочи :)





Вы также должны включить правила для зависимостей файла заголовка. Предполагая, что main.cxx зависит от ex05_01.h, при изменении ex05_01.h вы захотите перекомпилировать main.cxx. Что-то вроде этого выполнит эту работу:
main.o: ex05_01.h ... (add more headers if you have)
(повторить для всех файлов .o)
Ваши сборки отладки и выпуска отличаются только несколькими вещами: выходной папкой DIR и флагом определения DEBUG/NDEBUG в FLAGS. Чтобы избежать дублирования всех настроек, вы можете провести рефакторинг и создать общие цели, а затем переключаться между настройками с помощью условного оператора над переменной, например, если вы запустите make следующим образом:
make BUILD=REL <target>
вы получите переменную BUILD, определенную со значением «REL», затем вы можете использовать ifeq (см. https://www.gnu.org/software/make/manual/html_node/Conditional-Example.html#Conditional-Example), чтобы установить DIR и FLAGS соответственно.
Большинство компиляторов могут выводить эти зависимости включаемых файлов при компиляции. И они могут быть автоматически включены в make-файл для дальнейших запусков.
Вам не нужно объявлять заголовочные файлы в make-файле, но вы должны назвать все используемые кодовые файлы (в вашем случае cxx).