2015-07-24 4 views
1

Добрый день, я бегу через учебник, чтобы написать свои собственные мейкфайлы, я нашел учебник здесь:C++ Makefile ошибка - Нет правила, чтобы сделать цели «% .cpp»

http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

Я знаю, что это Учебник предназначен для C-файлов, но я считаю, что аналогия между C и C++ означают, что мало что влияет на функцию make-файлов (например, я использую g ++, а не gcc). Надеюсь, мое предположение в этом вопросе не является фактором, так как каждый из предыдущих 4 учебников, похоже, работал нормально.

При работе через Makefile 5 в учебнике, я получаю сообщение об ошибке относительно построения объектных файлов из файлов .cpp: Я не могу показаться, чтобы выяснить, почему это происходит

make: *** No rule to make target '%.cpp', needed by 'obj'. Stop.

, очень запутанный и расстраивающий, поскольку я чувствую, что этого не должно происходить. Я включил мой полный Makefile ниже, любая помощь будет принята с благодарностью:

# Example Makefile                                                
# ---------------- 
# Please remember to turn off the vim option: 'expandtab' so that tabs are 
# actually displayed as tabs (do so like this - :set noexpandtab) 
# 

# This file specifies dependencies, which means that the two c++ files must 
# be compiled before the executable is built 

# ------------------ 
# Makefile Constants 
# ------------------ 

# Directory constants 
IDIR =../include # Specifies location of include directory 
ODIR =obj  # Specifies location of object directory 
LDIR =../lib  # Specifies location of library directory 

LIBS=-lm # ? 

# Options constants 
CC=g++   # Specifies the specific C compiler to use, g++ specifies C++ compiler 
CFLAGS=-I$(IDIR) # List of flags to pass to compilation command 

# Dependency Constants 
DEP_FILES=helloMake.h      # Specifies dependency files 
DEPS=$(patsubst %,$(IDIR)/%,$(DEP_FILES)) # Specifies path to dependencies and dependency files 

# Object constants 
OBJ_FILES=helloMake.o helloFunc.o   # Specify object files 
OBJ=$(patsubst %,$(ODIR)/%,$(OBJ_FILES)) # Specifies path to objects and object files 


# ----------- 
# Compilation 
# ----------- 

# Specify rules to make object files 
$(ODIR)/%.o: %.cpp $(DEPS)  # Specifies that .o files depend on the .cpp version of the file and the .h files included in the DEPS macro 
    $(CC) -c -o [email protected] $< $(CFLAGS) # The -c flag says to generate the object file, the -o [email protected] says to put the output of the compilation in the 
            # file named on the left side of the : the $< is the first item in the dependencies list 

# Specify rules to make target executable 
helloMake: $(OBJ)      # Target : Dependencies 
    $(CC) -o [email protected] $^ $(CFLAGS) $(LIBS) # This is the actual compilation command 

.PHONY: clean # Prevent the make command from attempting to do something with a file named 'clean' 

# Specify rules to clean the object files 
clean: 
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ # Removes all compiled object files 

ответ

1

Этот «простой» учебник, к сожалению, способствует плохой практике.

В принципе, сначала нужно правильно Makefile C:

# Specify the final target name 
EXE := helloMake 

# Specify the source files 
# Effectively list all source files in the current directory 
SRC := $(wildcard *.c) 

# From the source file list, get the corresponding object file list 
# This is a clearer syntax for $(patsubst %.c,%.o,$(SRC)) 
OBJ := $(SRC:.c=.o) 

# From the object file list, get the dependency file list to handle automatic 
# recompilation when a header file is modified 
DEP := $(OBJ:.o=.d) 

# Specify preprocessor flags (this is a built-in variable) 
CPPFLAGS := -I../include 
# Required flags to enable the automatic dependency generation by the compiler 
CPPFLAGS += -MMD -MP 

# Specify compiler flags (this is a built-in variable) 
# Here some basic warning flags 
CFLAGS := -Wall -W -pedantic 

# Specify linker flags (this is a built-in variable) 
LDFLAGS := -L../lib 

# Specify linker libraries (this is a built-in variable) 
# m is the maths library 
LDLIBS := -lm 

# Tell make that these target are not real files 
.PHONY: all clean 

# Now the standard primary rule 
all: $(EXE) 

# How do we make $(EXE) ? Remember the recipe describe the linking phase 
$(EXE): $(OBJ) 
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o [email protected] 

# Let's clean up the mess 
clean: 
    $(RM) $(EXE) $(OBJ) $(DEP) 

# Don't forget to include the dependency files to let make know when to recompile 
-include $(DEP) 

Тогда вы должны знать разницу между C Makefile и ++ Makefile C:

  • Использование $(CXX) вместо $(CC) ,
  • Использование $(CXXFLAGS) вместо $(CFLAGS),
  • Использовать .cpp вместо .c.

И все готово.

# Specify the final target name 
EXE := helloMake 

# Specify the source files 
# Effectively list all source files in the current directory 
SRC := $(wildcard *.cpp) 

# From the source file list, get the corresponding object file list 
# This is a clearer syntax for $(patsubst %.cpp,%.o,$(SRC)) 
OBJ := $(SRC:.cpp=.o) 

# From the object file list, get the dependency file list to handle automatic 
# recompilation when a header file is modified 
DEP := $(OBJ:.o=.d) 

# Specify preprocessor flags (this is a built-in variable) 
CPPFLAGS := -I../include 
# Required flags to enable the automatic dependency generation by the compiler 
CPPFLAGS += -MMD -MP 

# Specify compiler flags (this is a built-in variable) 
# Here some basic warning flags 
CXXFLAGS := -Wall -W -pedantic 

# Specify linker flags (this is a built-in variable) 
LDFLAGS := -L../lib 

# Specify linker libraries (this is a built-in variable) 
# m is the maths library 
LDLIBS := -lm 

# Tell make that these target are not real files 
.PHONY: all clean 

# Now the standard primary rule 
all: $(EXE) 

# How do we make $(EXE) ? Remember the recipe describe the linking phase 
$(EXE): $(OBJ) 
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o [email protected] 

# Let's clean up the mess 
clean: 
    $(RM) $(EXE) $(OBJ) $(DEP) 

# Don't forget to include the dependency files to let make know when to recompile 
-include $(DEP) 

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

# Specify the final target name 
EXE := helloMake 

# Specify the source files 
# Effectively list all source files in the current directory 
SRC := $(wildcard *.cpp) 

# Specify where to put the build temporary files 
BLD := obj 

# From the source file list, get the corresponding object file list 
# This is a clearer syntax for $(patsubst %.cpp,$(BLD)/%.o,$(SRC)) 
OBJ := $(SRC:%.cpp=$(BLD)/%.o) 

# From the object file list, get the dependency file list to handle automatic 
# recompilation when a header file is modified 
DEP := $(OBJ:.o=.d) 

# Specify preprocessor flags (this is a built-in variable) 
CPPFLAGS := -I../include 
# Required flags to enable the automatic dependency generation by the compiler 
CPPFLAGS += -MMD -MP 

# Specify compiler flags (this is a built-in variable) 
# Here some basic warning flags 
CXXFLAGS := -Wall -W -pedantic 

# Specify linker flags (this is a built-in variable) 
LDFLAGS := -L../lib 

# Specify linker libraries (this is a built-in variable) 
# m is the maths library 
LDLIBS := -lm 

# Tell make that these target are not real files 
.PHONY: all clean 

# Now the standard primary rule 
all: $(EXE) 

# How do we make $(EXE) ? Remember the recipe describe the linking phase 
$(EXE): $(OBJ) 
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o [email protected] 

# The build directory is custom so we need to tell make how to do it 
# The build directory must exist before trying to compile 
$(BLD)/%.o: %.cpp | $(BLD) 
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o [email protected] -c $< 

# Simple rule to create the build directory if needed 
$(BLD): 
    mkdir [email protected] 

# Let's clean up the mess, we can just remove the build directory alonside the executable 
clean: 
    $(RM) -r $(BLD) $(EXE) 

# Don't forget to include the dependency files to let make know when to recompile 
-include $(DEP) 
+0

Спасибо за ответ, я попробовал Makefile, который вы предложили, но когда я попытаюсь это сделать, теперь я получаю другую ошибку: g ++: ошибка: arm-linux-androideabi: Нет такого файла или каталога – chris2oph

+0

Кажется, ваша настройка компилятора isn Правильно ли, какова ваша среда (ОС, версия компилятора, сделать версию)? – Chnossos

+0

ОС: Linux (с использованием виртуальной машины VMWare vSphere Client) Версия компилятора: g ++ (GCC) 4.9.3 20141101 для GNAT Pro 7.3.1 (20150118) сделать версию: не полностью, что вы имеете в виду tbh! – chris2oph

0

Синтаксис % не является стандартным make, но расширенная функция обеспечивается, например, GNU make (в противном случае вам нужно написать конкретные правила для каждого исходного файла или использовать что-то вроде autotools, которые генерируют огромный (но портативный) Makefile s). Таким образом, вы должны убедиться, что используете утилиту make, поддерживающую это. Если это не проблема, вы уверены, что у вас есть файлы *.cpp в вашем текущем каталоге?

+0

Я действительно есть файлы .cpp в правильном каталог, я также обеспечил размещение моего файла .h в каталоге inlcude. Я начинаю думать, что веб-страница учебника, которую я использовал, возможно, не была лучшей для меня ... – chris2oph

+0

Есть ли у вас примеры каких-либо make-реализаций в общем использовании, где шаблонные правила ('' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' поддерживается? – PeterSW

+0

.'nmake' не поддерживает это и заменяет собой менее гибкие правила вывода *. –