Makefile 循环源文件

问题描述 投票:0回答:1

我目前正在尝试在 Windows 中为简单的 C++ 项目设置我的第一个 Makefile,以便能够将它用于我创建的每个项目,只需要做一些更改。 在这里,我从所有文件夹中获取源文件:

sources := $(wildcard src/*.cpp) $(wildcard src/*/*.cpp) $(wildcard include/*.cpp) $(wildcard include/*/*.cpp)

这给了我以下输出:

src/main.cpp src/core/console.cpp src/core/filehandler.cpp src/core/framework.cpp src/core/globals.cpp src/core/textureeditor.cpp src/ui/buttonfuncs.cpp src/ui/interface.cpp src/ui/userinterfaces.cpp

现在我想将我的文件编译成目标文件,如下所示:

$(OBJDIR)%.o: $(sources)
    @echo compiling $< to $@
    @$(CC) -c $< -o $@ $(FLAGS)

它输出:

compiling src/main.cpp to obj/main.o
compiling src/main.cpp to obj/console.o
compiling src/main.cpp to obj/filehandler.o
compiling src/main.cpp to obj/framework.o
compiling src/main.cpp to obj/globals.o
compiling src/main.cpp to obj/textureeditor.o
compiling src/main.cpp to obj/buttonfuncs.o
compiling src/main.cpp to obj/interface.o
compiling src/main.cpp to obj/userinterfaces.o

这清楚地表明它获取了正确的目标文件,但没有从源中获取正确的文件。

是否有解决方案可以迭代源或每次运行时删除源的第一个元素?或者也许有更好的解决方案?

旁注:.o 文件始终与列表中的 .cpp 文件匹配,因为 .o 名称是从源列表生成的。

我尝试将文件夹名称放入 srcs_dir:

srcs_dir = $(foreach wrd,$(sources),$(dir $(wrd)))

并像这样运行它:

$(OBJDIR)%.o: $(srcs_dir)%.cpp
    @echo compiling $< to $@
    @$(CC) -c $< -o $@ $(FLAGS)

输出如下:

make: *** No rule to make target 
obj/main.o',
debug'.  Stop.

需要

整个 Makefile:

#defining project settings
project_name := Nimble
version := 0.0.1

#defining compiler settings
INCLUDE_PATHS := $(foreach wrd,$(wildcard src/*/),-I $(dir $(wrd))) \
    $(foreach wrd,$(wildcard include/*/),-I $(dir $(wrd)))
LIBS := -lraylib -lopengl32 -lgdi32 -lwinmm -llua54
CC := g++
CPP := c++20
DEBUGFLAGS_O := -std=$(CPP) -Wno-missing-braces -w -g -Wall -m64 $(INCLUDE_PATHS)
RELEASEFLAGS_O := -std=$(CPP) -Wno-missing-braces -w -O3 -Wall -m64 $(INCLUDE_PATHS)

#defining paths
OUTPATH_DEBUG := bin/debug/$(project_name)
OUTPATH_RELEASE := bin/release/$(project_name)
OBJDIR := obj/
SRCDIR := src/

#getting headers
headers := $(wildcard src/*.h) $(wildcard src/*/*.h) $(wildcard include/*.h) $(wildcard include/*/*.h)
#getting sourcefiles
sources := $(wildcard src/*.cpp) $(wildcard src/*/*.cpp) $(wildcard include/*.cpp) $(wildcard include/*/*.cpp)
srcs_dir = $(foreach wrd,$(sources),$(dir $(wrd)))
#object_files := $(sources:.cpp=.o)
srcs = $(foreach wrd,$(sources),$(notdir $(wrd)))
object_files := $(foreach wrd,$(srcs:.cpp=.o),$(OBJDIR)$(wrd))


print:
    @echo Object Files:
    @echo $(object_files)
    @echo Sources:
    @echo $(sources)
    @echo srcs:
    @echo $(srcs)
    @echo include paths:
    @echo $(INCLUDE_PATHS)
    @echo headers:
    @echo $(headers)
    @echo srcs_dir:
    @echo $(srcs_dir)

debug: FLAGS := $(DEBUGFLAGS_O)

release: FLAGS := $(RELEASEFLAGS_O)

release: $(object_files)
    @$(CC) obj/*.o -o $(OUTPATH_RELEASE) -s -L lib/ $(LIBS)
    @xcopy graphics\\ bin\\release\\graphics\\ /s /Y

debug: $(object_files)
    @$(CC) obj/*.o -o $(OUTPATH_DEBUG) -L lib/ $(LIBS)
    @xcopy graphics\\ bin\\debug\\graphics\\ /s /Y

$(OBJDIR)%.o: $(sources)
    @$(CC) -c $< -o $@ $(FLAGS)

clean:
    @echo > Cleaning Object files
    @cd obj/ && del *.o
    @echo > Cleaning 
makefile gnu-make
1个回答
0
投票

作为总经理建议您想要 使用

VPATH
vpath
。在模式规则中,词干(与
%
匹配的部分)必须与目标和先决条件中的相同字符串匹配。没有办法说“这个,加上随机的其他子目录”。

要使用 VPATH,您需要执行以下操作:

sources := $(wildcard src/*.cpp) $(wildcard src/*/*.cpp) $(wildcard include/*.cpp) $(wildcard include/*/*.cpp)
object_files := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(sources)))

VPATH := $(sort $(dir $(sources)))

  ...

$(OBJDIR)%.o: %.c
        $(CC) -c $< -o $@ $(FLAGS)

大多数 make 函数,如

$(dir ...)
$(notdir ...)
,接受要操作的单词列表,因此您不需要使用循环并一次传递一个单词。

此外,请不要在您的配方中添加

@
前缀,直到它们完全起作用,否则您只是丢弃重要的调试信息。

© www.soinside.com 2019 - 2024. All rights reserved.