Один Makefile для источников в нескольких подкаталогах - PullRequest
0 голосов
/ 20 февраля 2019

В моем C ++ проекте исходные тексты организованы в каталоге src.Внутри каталога src находятся подкаталоги, которые содержат заголовки и исходные файлы, например,

project
├── Makefile
│
├── MyBinary
│
├── src
│    │
│    ├── main.cpp
│    │
│    ├── Application
│    │      │
│    │      ├── Application.h
│    │      └── Application.cpp
│    │      
│    │
│    └── Tasks
│           ├── BackgroundWorker.h
│           └── BackgroundWorker.cpp
│
└── obj
     ├── Application.o
     └── BackgroungWorker.o

Я пытаюсь создать Makefile, чтобы все объектные файлы создавались внутри каталога obj иисполняемый файл MyBinary создается над каталогом src на том же уровне, что и Makefile.

Он не должен быть слишком сложным или автоматизированным.Я не против вручную указать каждый файл .cpp и .h в Makefile.

Но я новичок в Makefiles и, к сожалению, я борюсь с этой попыткой:

CXX=c++
CXXFLAGS=-Wall -Os -g0

# Name of the output binary
APPNAME=MyBinary

# Source root directory
SRC_ROOT=src

# Object file directory
OBJ_DIR=obj

DEPS=$(SRC_ROOT)/Application/Application.h \
     $(SRC_ROOT)/Tasks/BackgroundWorker.h

_OBJ=$(SRC_ROOT)/Application/Application.o \
    $(SRC_ROOT)/Tasks/BackgroundWorker.o\
    $(SRC_ROOT)/main.o

OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ))

# This rule says that the .o file depends upon the .c version of the 
# file and the .h files included in the DEPS macro.
$(OBJ_DIR)/%.o: %.cpp $(DEPS)
  $(CXX) -c -o $@ $< $(CXXFLAGS)

# Build the application.
# NOTE: The $@ represents the left side of the colon, here $(APPNAME)
#       The $^ represents the right side of the colon, here $(OBJ)
$(APPNAME): $(OBJ)
  $(CXX) -o $@ $^ $(CXXFLAGS)

clean:
  rm -f $(OBJ_DIR)/*.o $(APPNAME)

Ошибка при вызове make: Неустранимая ошибка: невозможно создать obj / src / Application.o: файл или каталог не найдены.

Может кто-нибудь помочь?

1 Ответ

0 голосов
/ 20 февраля 2019

OBJ=$(patsubst %,$(OBJ_DIR)/%,$(_OBJ)) добавляет obj/ к словам _OBJ.Вы хотите заменить src на obj что-то, что вы можете сделать с

OBJ=$(patsubst $(SRC_ROOT)/%,$(OBJ_DIR)/%,$(_OBJ))

Обратите внимание, что структура каталогов, которую вы получаете, предполагает наличие подкаталогов Application и Tasks до obj, которые у вас естьчтобы создать их вручную перед вызовом make или обновлением Makefile для их создания.

Вот что-то, что ведет себя так, как я ожидаю, когда структура каталогов предварительно создана.

APPNAME=MyBinary
SRC_ROOT=src
OBJ_DIR=obj

DEPS=$(SRC_ROOT)/Application/Application.h \
     $(SRC_ROOT)/Tasks/BackgroundWorker.h

_OBJ=$(SRC_ROOT)/Application/Application.o \
    $(SRC_ROOT)/Tasks/BackgroundWorker.o\
    $(SRC_ROOT)/main.o

OBJ=$(patsubst $(SRC_ROOT)/%,$(OBJ_DIR)/%,$(_OBJ))

$(OBJ_DIR)/%.o: $(SRC_ROOT)/%.cpp $(DEPS)
    echo Making $@ from $<
    touch $@ 

$(APPNAME): $(OBJ)
    echo Making $@ from $^
    touch $@

Примечаниечто на практике вы должны быть лучше с зависимостями и, вероятно, иметь их для генерации компилятором (см. -MM и аналогичные опции для g ++), здесь вы перекомпилируете все, когда вы изменяете заголовок.

...