Вы пытаетесь написать сложный 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 $@ $^
Пока этого достаточно.