Сделайте невозможным найти правило - PullRequest
0 голосов
/ 25 сентября 2019

Возможно, я что-то пропустил, но этот make-файл завершился неудачно с ошибкой (перефразирование из-за локализации активно):

there is no rule to build target ****.o

где **** - имя существующего файла .cpp.Сделайте версию 3.81, gcc 4.7.5 (если это актуально).

Вот make-файл.

program_name := librlsmatt.a
source_dirs  :=   ../src    
include_dirs := $(source_dirs)

CXX = g++
AR = ar 

WARNS := -Wall -Wno-deprecated -Wno-unused -Wno-unused-parameter
CFLAGS:= $(addprefix -I, $(include_dirs)) $(WARNS) -fstack-protector-all -g 
ARFLAGS := cru

source_files := $(wildcard $(addsuffix /*.cpp, $(source_dirs) ) )
object_files := $(notdir $(source_files:.cpp=.o) )
dep_files := $(object_files:%.o=%.d)

.PHONY :  clean

-include $(dep_files)

$(program_name): $(object_files)
    $(info Linking ...)
    @$(AR) $(ARFLAGS) $@ $(object_files)

%.o: %.cpp makefile
    $(info Compiling $< ...)
    @$(CXX) -c $(CFLAGS) $< -o $@ -MF $(@:%.o=%.d) -MT $@

clean:
    $(info Clean $(program_name)...)
    @$(RM) -f $(program_name) $(object_files) $(dep_files)

1 Ответ

1 голос
/ 25 сентября 2019

Во-первых, обратите внимание, что целью по умолчанию в Makefile является первая;следовательно, если у нас есть файлы зависимостей, и мы включаем их перед главной целью, то цель .o в первом включенном правиле зависимости будет целью по умолчанию.Как правило, включайте зависимости где-то еще ниже, например, в самый конец.

Проблема сопоставления с образцом в этом Makefile вызвана тем, что файлы .o не имеют префикса каталога из-заиспользование $(notdir ...) в расширении, которое их генерирует, но файлы .cpp делают.

make пытается создать некоторый foo.o, и правило %.o: %.cpp заставляет его искать foo.cpp.Но нет foo.cpp;существует только src/dir/foo.cpp.

Если вы действительно хотите, чтобы файлы .o находились в одном каталоге, механизм VPATH может оказаться возможным.Если src/dir находится в VPATH, то, когда make ищет foo.cpp для обновления foo.o, он найдет его в src/dir.

Если принудительно выполнить все .o файлыиз дерева в один каталог, вы должны быть уверены, что нет двух .cpp файлов с одинаковыми именами.

Если вы хотите поместить .o файлы вне дерева исходных текстов (что полезно,потому что вы можете иметь, например, исходное дерево только для чтения), вероятно, лучше всего отобразить структуру исходного дерева в выходном дереве, например:

$(OUTPUT_DIR)/%.o: %.cpp:   # where the % stem is src/dir/whatever/foo

Идея состоит в том, что объектфайл $(OUTPUT_DIR)/src/whatever/foo.o, а исходный файл src/whatever/foo.cpp.

Рецепт должен убедиться, что каталог $(OUTPUT_DIR)/src/whatever существует;поэтому где-то понадобится команда mkdir -p:

$(OUTPUT_DIR)/%.o: %.cpp:
        $(info Compiling $< ...)
        @mkdir -p $(dir $@) 
        @$(CXX) -c $(CFLAGS) $< -o $@ -MF $(@:%.o=%.d) -MT $@
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...