LINUX.ORG.RU

Makefile не обнаруживает заданную цель

 , ,


0

1

Пишу реализацию HashMap. Makefile писал вручную.

SHELL		:= /bin/bash
PROJ_ROOT 	= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
MAKEFILE      	= Makefile
DEL_FILE      	= rm -f
SRC_DIR		= $(PROJ_ROOT)src
CITYHASH_SRC_DIR = $(SRC_DIR)/cityhash
TESTS_SRC_DIR 	= $(PROJ_ROOT)test
BUILD_DIR	= $(PROJ_ROOT)build
LIB_BUILD_DIR	= $(BUILD_DIR)/lib
TESTS_BUILD_DIR = $(PROJ_ROOT)build/test

LIB_SOURCES	= $(wildcard $(SRC_DIR)/*.cpp)
LIB_OBJS	= $(patsubst $(SRC_DIR)/%.cpp, $(LIB_BUILD_DIR)/.cpp.o%, $(LIB_SOURCES))
LIB		= $(LIB_BUILD_DIR)/libhashmap.so

TEST_SOURCES	= $(wildcard $(TESTS_SRC_DIR)/*.cpp)
TESTS_OBJS	= $(patsubst $(TESTS_SRC_DIR)/%.cpp, $(TESTS_BUILD_DIR)/.cpp.o%, $(TEST_SOURCES))
TESTS 		= $(patsubst $(TESTS_SRC_DIR)/%.cpp, $(TESTS_BUILD_DIR)/%, $(TEST_SOURCES))

CITYHASH_OBJ 	= $(TESTS_BUILD_DIR)/city.cc.o

CXX		= g++
INCLUDE_DIRS    = $(SRC_DIR)
CXX_FLAGS	= -std=c++14 -I$(INCLUDE_DIRS) -Wall -g -O3
CXX_LFLAGS	= -std=c++14 -Wall -g -O3 -L$(LIB_BUILD_DIR)

lib: $(LIB)

tests: tests_clean $(CITYHASH_OBJ) lib $(TESTS)
	
#$(CITYHASH_OBJ):
$(TESTS_BUILD_DIR)/city.cc.o: $(CITYHASH_SRC_DIR)/city.cc
	$(CXX) -c $(CXX_FLAGS) -o $@ $<

#$(LIB):
$(LIB_BUILD_DIR)/libhashmap.so: $(LIB_BUILD_DIR)/%.cpp.o $(TESTS_BUILD_DIR)/city.cc.o
	$(CXX) -shared $(CXX_LFLAGS) -o $@ $^
	
#$(LIB_OBJS):  - Не может найти эту цель.
$(LIB_BUILD_DIR)/%.cpp.o: $(SRC_DIR)/%.cpp
	$(CXX) -c $(CXX_FLAGS) -o $@ $<
	
#$(TESTS_OBJS):
$(TESTS_BUILD_DIR)/%.cpp.o: $(TESTS_SRC_DIR)/%.cpp
	$(CXX) -c $(CXX_FLAGS) -o $@ $<

#$(TESTS):	
$(TESTS_BUILD_DIR)/%: $(TESTS_BUILD_DIR)/%.cpp.o $(TESTS_BUILD_DIR)/city.cc.o
	$(CXX) $(CXX_FLAGS) -o $@ $^
	@echo 'run a test: ' $@ 
	@$@
	@if [[ $$? == 0 ]]; then \
		echo "Test: '`basename $@`' Completed Succesfully!"; \
	else \
		echo "Test: '`basename $@`' Failed!"; \
	fi
	
tests_clean:
	$(DEL_FILE) $(TESTS_BUILD_DIR)/*
	
clean: tests_clean
	$(DEL_FILE) $(LIB_BUILD_DIR)/*

watch:
	$(foreach v, $(.VARIABLES), $(info $(v) = $($(v))))

При попытке выполнить .make tests make выводит ошибку:

make: *** Нет правила для сборки цели «/home/r2d2/proj/cpp_c/hashmap/cpp_hashmap/build/lib/%.cpp.o», 
требуемой для «/home/r2d2/proj/cpp_c/hashmap/cpp_hashmap/build/lib/libhashmap.so».  Останов.

Хотя цель задана:

$(LIB_BUILD_DIR)/%.cpp.o: $(SRC_DIR)/%.cpp
	$(CXX) -c $(CXX_FLAGS) -o $@ $<

Куда копать и что делать?

Есть репозиторий на github . Только перед сборкой создайте директории в корне - mkdir -p build/{test,lib}



Последнее исправление: OlegUP (всего исправлений: 1)

$(LIB_BUILD_DIR)/libhashmap.so: $(LIB_BUILD_DIR)/%.cpp.o ...

Вот чем оно по-твоему должно % заменить? Hint: из имени цели оно не выводиться, там % нет

anonymous
()

Ошибка здесь

#$(LIB):
$(LIB_BUILD_DIR)/libhashmap.so: $(LIB_BUILD_DIR)/%.cpp.o $(TESTS_BUILD_DIR)/city.cc.o
	$(CXX) -shared $(CXX_LFLAGS) -o $@ $^

Чем заменять %? Задай список объектников вместо $(LIB_BUILD_DIR)/%.cpp.o

anonymous
()

BTW, для создания каталогов в GNU make можно использовать order-only dependencies:

build/%.o: %.c | build ; gcc -o $@ $<

build: ; mkdir $@

anonymous
()
Ответ на: комментарий от anonymous

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

Заменил на

$(LIB_BUILD_DIR)/libhashmap.so: $(LIB_OBJS) $(LIB_BUILD_DIR)/city.cc.pic.o 
	$(CXX) -shared $(CXX_LFLAGS) -o $@ $^

Заработало, спасибо.

OlegUP
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.