【问题标题】:substituting folder path in $(SOURCES) of a makefile在makefile的$(SOURCES)中替换文件夹路径
【发布时间】:2015-12-10 14:42:59
【问题描述】:

我正在寻找一种方法来替换 makefile 中源文件变量列表中的文件夹。

这里有什么有用的吗?

我从查找源文件开始

program_C_SRCS := $(wildcard  $(SRCDIR)/*.c)
program_CXX_SRCS := $(wildcard $(SRCDIR)/*.cpp)

结果(如果我正确理解 GNU makefile)通常看起来像

src/main.cpp
src/sensor.cpp

然后我通过目标文件构建

program_C_OBJS := ${program_C_SRCS:.c=.o}
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.opp}

这将按照预期替换我的源文件的扩展名。

最后,我想将“src/”替换为“obj/”

program_C_OBJPATH := ${subst $(SRCDIR) , $(OBJDIR) , $(program_C_OBJS)}
program_CXX_OBJPATH := ${subst $(SRCDIR) , $(OBJDIR) , $(program_CXX_OBJS)}

但是,这不起作用。

我浏览了 GNU makefile 网站,但无济于事。这个解决方案Makefile to put object files from source files different directories into a single, separate directory? 很接近,但对象目录必须明确包含在任何地方,并且源目录不包含源路径信息。

在我的 makefile 中,源文件列表包含路径,我希望目标文件列表也包含相应的目标目录。

makefile 的其余部分也尝试使用变量

链接阶段

$(program_NAME): $(program_OBJS)
    $(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(program_OBJS) -o "$(program_NAME)"

编译阶段

%.opp : %.cpp | mkdirobjdir
    $(CXX) $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -o "$@" "$<"

最后是规则

main_enose.opp : main_enose.cpp core_enose.cpp core_enose.h
$(OBJDIR)/core_enose.opp : core_enose.cpp core_enose.h
$(OBJDIR)/core_enose.h :

【问题讨论】:

    标签: makefile


    【解决方案1】:

    您的问题是$(subst) 调用中逗号周围的空格。 make 不会像您期望的那样忽略它们。它将它们视为要查找的字符串中的文字值、要替换的字符串以及要在其中进行替换的字符串。

    删除它们。

    program_C_OBJPATH := ${subst $(SRCDIR),$(OBJDIR),$(program_C_OBJS)}
    program_CXX_OBJPATH := ${subst $(SRCDIR),$(OBJDIR),$(program_CXX_OBJS)}
    

    也就是说,您可能想使用$(patsubst) 来限制替换发生的位置:

    program_C_OBJPATH := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(program_C_OBJS))
    program_CXX_OBJPATH := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(program_CXX_OBJS))
    

    或者您想使用$(notdir)$(addprefix) 来处理剥离所有目录信息并将其添加回来:

    program_C_OBJPATH := $(addprefix $(OBJDIR)/,$(notdir $(program_C_OBJS)))
    program_CXX_OBJPATH := $(addprefix $(OBJDIR)/,$(notdir $(program_CXX_OBJS)))
    

    【讨论】:

    • 谢谢!这可以正常工作。不过,它似乎并没有解决我的问题。发生的情况是以下规则不起作用。 $(program_NAME): $(program_OBJS) 。它说make: *** No rule to make target 'obj_dbg/core_enose.opp', needed by 'program'. Stop.似乎链接规则是失败的
    • obj_dbg/core_enose.opp 的规则在哪里定义?你没有显示你的makefile的那部分。
    • 确实,现在请看一下。我意识到规则现在不能没有路径,所以我在它们前面加上了如下前缀:$(OBJDIR)/core_enose.opp : $(SRCDIR)/core_enose.cpp $(SRCDIR)/core_enose.h。但这也失败了。
    • ok 添加$(OBJDIR)/%.opp : $(SRCDIR)/%.cpp 终于成功了。但我不明白为什么。我的意思是“%.opp”中的“%”应该包括所有的路径+文件名(没有扩展名)。此外,我现在必须在我的所有规则中包含 $(objdir) 和 $(srcdir)。有没有办法避免这种情况?
    • %.o: %.c 确实有 % 匹配任何路径组件,但它需要它们是您的案例所没有的两侧的 相同 组件。在这里编辑问题可能是错误的做法(因为这里的问题被问到并得到了回答)。我很乐意帮助您解决其他问题,但您应该将它们作为一个新问题提出(如果您愿意,请在此处的评论中链接它,这样我一定会看到它)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    • 2017-12-17
    相关资源
    最近更新 更多