Makefile с другой исходной папкой для тестовой цели - PullRequest
0 голосов
/ 21 февраля 2020

Я очень новичок в make-файлах C ++, и ниже у меня есть make-файл, который я в основном скопировал откуда-то на inte rnet. Мой вклад в make-файл - это цель "test", которая является проблемой.

Мой код организован в , включая (для заголовков), sr c (для источников) и test (для тестовых источников) каталогов. Для стандартной цели я хочу собрать все файлы в папке sr c, которая также включает основной файл. cpp. Чтобы создать тестовую сборку, я хочу собрать все файлы в папке sr c , кроме main. cpp и дополнительно все файлы в папке test, Я надеялся, что моя цель теста достигнет этого, но это не удается. Он просто строит файлы из стандартной цели.

Как я могу исправить свои ошибки.

Спасибо

Makefile, который я использую:

APP=myappname

SRC_DIR=src
INC_DIR=include
OBJ_DIR=obj
BIN_DIR=bin
TEST_SRC_DIR=test
MAIN_CPP_NAME=main.cpp

CC=g++
LD=g++
CFLAGS=-O2 -c -Wall -std=c++17
LFLGAS=
DFLAGS=-g3 -O0 -DDEBUG
INCFLAGS=-I$(INC_DIR)

SOURCES=$(wildcard $(SRC_DIR)/*.cpp)
HEADERS=$(wildcard $(INC_DIR)/*.hpp)
OBJECTS=$(SOURCES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
DEPENDS=$(OBJ_DIR)/.depends


.PHONY: all
all: $(BIN_DIR)/$(APP)

.PHONY: debug
debug: CFLAGS+=$(DFLAGS)
debug: all

.PHONY: test
test:   SOURCES=$(wildcard $(SRC_DIR)/*.cpp)
test: SOURCES=$(filter-out $(SRC_DIR)/$(MAIN_CPP_NAME), $(SOURCES))
test: OBJECTS=$(SOURCES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
test: TEST_SOURCES=$(wildcard $(TEST_SRC_DIR)/*.cpp)
test: OBJECTS+=$(TEST_SOURCES:$(TEST_SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
test: all

$(BIN_DIR)/$(APP): $(OBJECTS) | $(BIN_DIR)
$(LD) $(LFLGAS) -o $@ $^

$(OBJ_DIR)/%.o: | $(OBJ_DIR)
$(CC) $(CFLAGS) $(INCFLAGS) -o $@ $<

$(DEPENDS): $(SOURCES) | $(OBJ_DIR)
$(CC) $(INCFLAGS) -MM $(SOURCES) | sed -e 's!^!$(OBJ_DIR)/!' >$@

ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDS)
endif


$(BIN_DIR):
    mkdir -p $@
$(OBJ_DIR):
    mkdir -p $@

.PHONY: clean
clean:
    rm -rf $(BIN_DIR) $(OBJ_DIR)

1 Ответ

2 голосов
/ 22 февраля 2020

Вы пытаетесь написать сложный make-файл без понимания основ, что практически невозможно. Давайте попробуем очень простой подход.

Сначала предположим, что исходные файлы

src/main.cpp
src/func.cpp
test/unit.cpp
test/global.cpp

Теперь нам нужен список объектных файлов, которые понадобятся test.

SOURCES:=$(wildcard $(SRC_DIR)/*.cpp) # this will be src/main.cpp src/func.cpp
NON_MAIN_SOURCES:=$(filter-out $(SRC_DIR)/$(MAIN_CPP_NAME), $(SOURCES)) # this will be src/func.cpp
TEST_DIR_SOURCES:=$(wildcard $(TEST_SRC_DIR)/*.cpp) # this will be test/unit.cpp test/global.cpp
TEST_SOURCES:=$(notdir $(NON_MAIN_SOURCES) $(TEST_DIR_SOURCES)) # this will be func.cpp unit.cpp global.cpp
TEST_OBJECTS:=$(patsubst %.cpp,$(OBJ_DIR)/%.o,$(TEST_SOURCES)) # this will be obj/func.o obj/unit.o obj/global.o

(Обратите внимание, что вы должны избегать конфликтов имен между src/ и test/, например, иметь src/func.cpp, а также test/func.cpp. Это является следствием вашей структуры каталогов; для make-файла нет способа обойти это.)

Теперь мы должны сказать Make, как построить эти объектные файлы. Мы можем начать с правила для источников в src:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
    $(CC) $(CFLAGS) $(INCFLAGS) -o $@ $<

(я упустил обязательное условие $(OBJ_DIR) для простоты. На данный момент вы будете нести ответственность за обеспечение существования obj/ .)

Теперь об источниках в test. Грубый, но эффективный подход состоит в том, чтобы добавить для них правило:

$(OBJ_DIR)/%.o: $(TEST_DIR)/%.cpp
    $(CC) $(CFLAGS) $(INCFLAGS) -o $@ $<

Существуют более сложные способы, но сначала вы должны освоить основы.

Наконец, правило для сборки bin/mytestname:

$(BIN_DIR)/mytestname: $(TEST_OBJECTS)
    $(LD) $(LFLAGS) -o $@ $^

Пока этого достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...