繁体   English   中英

搜索所有 .c 和 .cpp 文件并在一个 makefile 中编译它们

[英]Search for all .c and .cpp files and compiling them in one makefile

我正在尝试创建一个 makefile,它将找到所有现有的 .c 和 .cpp 文件,然后编译它们。

我已经使用How to place object files in separate subdirectory作为模板并将其与How to make a makefile for C and C++, with source in subdirectories 结合使用 假设我已经定义了所有变量(我只是将它们排除在外,因为它们是不必要的)。

我不断收到的错误是make: *** No rule to make target 'obj/<randoCfile>.c', needed by '<target>'. Stop. 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...)

你有几个问题。 最重要的在这里:

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))

它将是(假设BUILDDIRobj ):

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=%.co)没有返回与模式相匹配的话......它返回的所有单词,并且与模式相匹配的人。

由于您只是将.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文件也是如此。

Make(任何风格)是一个从目标(可执行文件)到源文件的程序,因此您通常从可执行文件(需要构建目标文件列表)开始,而这些对象依赖于它们所依赖的源文件要构建.... 你在反方向思考... 搜索源文件,然后朝着相反的方向前进。 虽然它更具动态性,但它不是 make 的工作方式,所以很可能该解决方案需要使用另一个程序来完成所有工作来编译每个源并最终以您可能无法指定的内容结束,而 make 只会做在那里执行您的搜索和编译程序。

出于这个原因,不同风格的 Make(例如 gnu make 或 berkely make)开发了各种不兼容的方法来尽可能地返回,使用 gnu make 中的函数,并在 berkeley make 的情况下具有强大的宏功能。 只是说这些都不是标准的,都需要经过一些培训才能有效处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM