Нужно ли объявлять файлы заголовков, файлы cxx или и то, и другое в файле make?

Я прочитал хороший учебник по make-файлам, но немного запутался, когда все стало сложнее.

Я реструктурировал папку своего рабочего пространства и добавил подпапку: Вот изображение папки моего рабочего пространства:

Нужно ли объявлять файлы заголовков, файлы cxx или и то, и другое в файле 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.

Вам не нужно объявлять заголовочные файлы в make-файле, но вы должны назвать все используемые кодовые файлы (в вашем случае cxx).

itzFlubby 24.02.2019 10:17

хорошо, но это то, что я сделал здесь: SRCS = src/main.cxx src/ex05_01.cxx src/ex05_02.cxx

Gino Pensuni 24.02.2019 10:18

Ваше сообщение об ошибке говорит вам, что фактическая ошибка находится где-то еще. Проверьте, есть ли на самом деле файл с именем main.o в /debug/

itzFlubby 24.02.2019 10:20

@DavidC.Rankin: но itzFlubby сказал, что нет необходимости объявлять путь включения, только файлы cxx? теперь я запутался

Gino Pensuni 24.02.2019 10:20

@itzFlubby: нет файлов в отладке

Gino Pensuni 24.02.2019 10:20

И вот проблема: Ошибка говорит именно об этом -> а именно о том, что файл main.o нужен, но не может быть найден. Иногда помогает удаление папки отладки и повторная попытка

itzFlubby 24.02.2019 10:22

@HardCodedCoder - вы правы, если ваши источники могут видеть и включать ваши заголовки в include. Тогда я согласен, что ваша проблема в другом.

David C. Rankin 24.02.2019 10:22

@DavidC.Rankin: теперь я отредактировал строку: $(DBGDIR)/%.o: src/%.cxx $(CC) -c $(CFLAGS) $(DBGCFLAGS) -o $@ $< я добавил src/ в %.cxx и теперь он не находит файлы h

Gino Pensuni 24.02.2019 10:26

@DavidC.Rankin, как я могу это исправить?

Gino Pensuni 24.02.2019 10:27

@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

Gino Pensuni 24.02.2019 10:27

На самом деле это не имеет ничего общего с Makefiles. Сначала вам нужно выяснить, как скомпилировать ваши файлы вручную (запустить g++ напрямую и т. д.). Затем вы можете приступить к автоматизации процесса, поместив нужные команды в Makefile.

melpomene 24.02.2019 10:31

Я смотрю, и трудно сказать со вставленными make-файлами, но у вас есть символы табуляции '\t' (не пробелы), следующие за вашими целями, верно? Между таргерами и рецептами? Нравится "debug:\t$(DBGEXE)", а затем перед каждой оставшейся строкой в ​​мишени?

David C. Rankin 24.02.2019 10:31

Какие команды вы используете для компиляции кода без Makefile?

melpomene 24.02.2019 10:35

@DavidC.Rankin: да, я использую только табуляции и без пробелов!

Gino Pensuni 24.02.2019 10:35

@DavidC.Rankin: Я думаю, проблема именно в том, о чем вы сейчас сказали: он не может найти файлы заголовков во включенных путях! Что мне нужно добавить, чтобы он теперь видел файлы .h?

Gino Pensuni 24.02.2019 10:37

Добавление -I/path/to/includes (здесь просто -I./include) в качестве параметра компилятора должно сделать это.

David C. Rankin 24.02.2019 10:38

@DavidC.Rankin: да!!!! Работаю сейчас!!!! Спасибо!!!!

Gino Pensuni 24.02.2019 10:39

Рад, что это помогло. Иногда это просто мелочи :)

David C. Rankin 24.02.2019 11:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
18
219
1

Ответы 1

  1. Вы также должны включить правила для зависимостей файла заголовка. Предполагая, что main.cxx зависит от ex05_01.h, при изменении ex05_01.h вы захотите перекомпилировать main.cxx. Что-то вроде этого выполнит эту работу:

    main.o: ex05_01.h ... (add more headers if you have)
    

    (повторить для всех файлов .o)

  2. Ваши сборки отладки и выпуска отличаются только несколькими вещами: выходной папкой 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-файл для дальнейших запусков.

Deduplicator 24.02.2019 23:29

Другие вопросы по теме