【问题标题】:Proper method for wildcard targets in GNU MakeGNU Make 中通配符目标的正确方法
【发布时间】:2023-03-05 17:30:01
【问题描述】:

我正在尝试编写一个将源文件和目标文件分开的 Makefile,但我似乎无法找出完成此任务的正确方法。我有两种可行的方法,但我希望有人能指出“正确”的方法。

我的项目分为srcobj 文件夹,Makefile 与这些文件夹处于同一级别。

第一种方法使用通配符函数在src中查找源文件,然后使用文本替换确定对应的目标文件。

SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)

prog: $(OBJ)
       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(patsubst src/,obj/,$(OBJ))

%.o: %.cpp
     $(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)  

这似乎有效,但是,每次我运行make prog 时,它都会重新编译所有目标文件。 OBJ 变量必须在所有对象前面都有src/,否则我会得到“没有规则来制作目标”。从好的方面来说,我可以轻松地使用 prog 目标中的 patsubst 来指定目标文件。

第二种方法类似,但在 OBJ 变量上使用 vpath 和文本替换:

 vpath = %.cpp src
 vpath = %.o obj

 SRC = $(wildcard src/*.cpp)
 OBJ = $(subst src/,,$(SRC:.cpp=.o))
 POBJ = $(patsubst src/,obj/$(SRC:.cpp=.o))

 prog: $(OBJ)
       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(POBJ)

 %.o: %.cpp
     $(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)  

这消除了目标文件的重新编译,但需要我为 prog 目标添加另一个变量 POJB(因为我不能只对没有 basedir 的目标文件执行任何 patsubst)。

这两种方法都有效,并且各有优势,但哪一种是“正确”的方法,如果都不是,实现这种类型的建筑的正确方法是什么?

【问题讨论】:

    标签: makefile wildcard gnu-make target


    【解决方案1】:

    你的第一个例子差不多了:

    SRC = $(wildcard src/*.cpp)
    OBJ = $(patsubst src/%.cpp, obj/%.o, $(SRC))
    
    prog: $(OBJ)
      $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) $(OBJ) -o prog 
    
    obj/%.o: src/%.cpp
      $(CC) $(CFLAGS) -c $< -o $@
    

    【讨论】:

    • SRC = $(wildcard src/**/*.cpp) 获取位于src 子目录中的源代码
    猜你喜欢
    • 2011-01-29
    • 2014-07-08
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多