我正在尝试创建一个makefile,它将找到所有现有的.c和.cpp文件,然后编译它们。
我使用How to place object files in separate subdirectory作为模板,并将其与How to make a makefile for C and C++, with sources in subdirectories相结合。假设我已经定义了所有变量(因为它们是不必要的,所以我只是忽略了它们)。
我一直收到的错误是make: *** No rule to make target 'obj/<randoCfile>.c', needed by '<target>'. Stop.
SOURCES := $(call rwildcard,$(SRCDIR),*.c)
SOURCES += $(call rwildcard,$(SRCDIR),*.cpp)
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:%.c=%.c.o))
OBJECTS += $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:%.cpp=%.cpp.o))
#Default Make
all: $(TARGET)
#Remake
remake: cleaner all
#Make the Directories
directories:
@mkdir -p $(TARGETDIR)
@mkdir -p $(BUILDDIR)
#Clean only Objecst
clean:
@$(RM) -rf $(BUILDDIR)
#Full Clean, Objects and Binaries
cleaner: clean
@$(RM) -rf $(TARGETDIR)
#Link
$(TARGET): $(OBJECTS)
$(CC) -o $(TARGETDIR)/$(TARGET) $^ $(LIB)
$(BUILDDIR)/%.c.o:
$(CC) $(INC) $(CFLAGS) -c -o $@ $<
$(BUILDDIR)/%.cpp.o:
$(CXX) $(INC) $(CXXFLAGS) -c -o $@ $<
#Non-File Targets
.PHONY: all remake clean cleaner resources关于如何解决我的问题,有什么建议吗?我在Windows上运行(这就是为什么我使用通配符,而不是我找到的一个例子中的shell(find...) )。
发布于 2020-02-21 00:11:58
你有几个问题。最重要的是:
SOURCES := $(call rwildcard,$(SRCDIR),*.c)
SOURCES += $(call rwildcard,$(SRCDIR),*.cpp)让我们假设这将导致SOURCES的以下值
SOURCES := src/foo.c src/bar/bar.c src/biz/biz.cpp src/boz.cpp接下来,OBJECTS将是什么呢?
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:%.c=%.c.o))
OBJECTS += $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:%.cpp=%.cpp.o))它将是(假设BUILDDIR是obj):
OBJECTS := obj/foo.c.o obj/bar/bar.c.o obj/biz/biz.cpp obj/boz.cpp \
obj/foo.c obj/bar/bar.c obj/biz/biz.cpp.o obj/boz.cpp.o为什么?因为像$(SOURCES:%.c=%.c.o)这样的翻译并不只返回与模式匹配的单词.它返回所有的单词,并且只翻译与模式匹配的单词。
由于您只是将.o添加到后缀,而不是替换后缀,所以可以将其简化为:
SOURCES := $(call rwildcard,$(SRCDIR),*.c)
SOURCES += $(call rwildcard,$(SRCDIR),*.cpp)
OBJECTS := $(SOURCES:$(SRCDIR)/%=$(BUILDDIR)/%.o))此外,这一规则也不正确:
$(BUILDDIR)/%.c.o:
$(CC) $(INC) $(CFLAGS) -c -o $@ $<在这里,您还没有声明任何先决条件。也许你会在其他地方做你没有给我们看的事情,但最好是这样做:
$(BUILDDIR)/%.c.o: $(SRCDIR)/%.c
$(CC) $(INC) $(CFLAGS) -c -o $@ $<当然,.cpp文件也是如此。
发布于 2020-02-21 20:11:58
Make (任意风味)是一个从目标(可执行文件)到源的程序,所以通常从可执行文件开始(需要构建一个对象文件列表),而这些对象取决于它们所依赖的源文件。你在想相反的方向..。搜索源文件,然后朝相反的方向走。虽然它更动态,但它并不是make工作的方式,所以解决方案很可能需要使用另一个程序来编译所有的源代码,并最终以一些您可能无法指定的东西结束,而make只会在那里执行搜索和编译程序。
因此,make的不同口味(例如gnu make或berkely make)开发了每一种不兼容的方法来实现可能的返回方式,使用gnu make中的函数,并在berkeley Make中具有强大的宏功能。我只想说,所有这些都不是标准的,都需要一些培训才能有效地处理。
https://stackoverflow.com/questions/60329676
复制相似问题