美好的一天。我在目录中,在其中Makefile和文件夹src和bin。如何将目标文件编译到bin文件夹中,然后构建可执行文件?
我阅读了一些说明,并在%.o之前添加了$(BIN),但没有帮助,目标文件与makefile一起出现在文件夹中。问题出在哪里?
CC = arm-linux-gnueabihf-gcc
CXX = arm-linux-gnueabihf-g++
CPPFLAGS = -I .
CFLAGS =-g -std=gnu99 -O1 -Wall
CXXFLAGS = -g -std=gnu++11 -O1 -Wall
LDFLAGS = -lrt -lpthread
SRCDIR = src
BIN = bin
SOURCES = $(wildcard $(SRCDIR)/*.cpp) $(wildcard $(SRCDIR)/*.c)*
...
OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o))
OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o))
#$(warning OBJECTS=$(OBJECTS))
ifeq ($(filter %.cpp,$(SOURCES)),)
LINKER = $(CC)
LDFLAGS += $(CFLAGS) $(CPPFLAGS)
else
LINKER = $(CXX)
LDFLAGS += $(CXXFLAGS) $(CPPFLAGS)
endif
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
all: $(TARGET_EXE)
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $@
.PHONY : dep all run copy-executable debug
dep: depend
depend: $(SOURCES) *.h
echo '# autogenerat`enter code here`ed dependencies' > depend
ifneq ($(filter %.c,$(SOURCES)),)
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \
>> depend
endif
ifneq ($(filter %.cpp,$(SOURCES)),)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \
>> depend
endif
clean:
rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) connect.gdb depend
...
答案 0 :(得分:0)
由于您尚未告知Makefile在哪里可以找到源文件(除非您在省略的部分之一中这样做),因此我不清楚此makefile的工作方式如何。
在这些规则中:
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $<
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $<
您告诉编译器生成目标文件,但没有指定 where 来生成它们,默认是在工作目录中生成它们。您可以使用-o option来覆盖它:
$(BIN)/%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
$(BIN)/%.o:%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
一旦将目标文件放在想要的位置(bin/
),则必须确保链接规则:
$(TARGET_EXE):$(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $@
可以找到它们。最好的方法是确保OBJECTS
包含目标文件的正确路径。我不确定如何建议您这样做,因为从makefile的外观来看,该变量可能不包含您认为的内容。
编辑:
让我们分阶段进行。
假设我们在源文件src/foo.c
上。我们想要的是:
src/foo.c -> bin/foo.o
bin/foo.o -> foo
这需要两个规则,我们可以这样写:
$(BIN)/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(TARGET_EXE): bin/foo.o
$(LINKER) $(LDFLAGS) -L. $^ -o $@
我们实际上有很多源文件,其中一些是C ++文件。因此,我们必须为他们制定规则:
$(BIN)/%.o: src/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
并构造更长的对象列表:
OBJECTS := bin/foo.o bin/bar.o bin/baz.o bin/quartz.o...
$(TARGET_EXE): $(OBJECTS)
$(LINKER) $(LDFLAGS) -L. $^ -o $@
(混合C和C ++对我来说似乎很不健康,但没关系。)
我们如何构造对象列表?我们必须从wildcard
可以产生的来源列表开始:
SRC := src
C_SOURCES := $(wildcard $(SRC/*.c)
# this is src/foo.c src/bar.c
SRC := src
CPP_SOURCES := $(wildcard $(SRC/*.cpp)
# this is src/baz.cpp src/quartz.cpp
,然后将它们转换为我们实际想要的目标文件名:
BIN := bin
OBJECTS := $(patsubst $(SRC)/%.cpp,$(BIN)/%.o, $(CPP_SOURCES))
OBJECTS += $(patsubst $(SRC)/%.c,$(BIN)/%.o, $(C_SOURCES))
# this is bin/foo.o bin/bar.o bin/baz.o bin/quartz.o
这应该可以给您想要的效果,如果您了解它,您就会明白为什么旧的makefile没有。