【问题标题】:Makefile : select files by extension, from a variableMakefile :从变量中按扩展名选择文件
【发布时间】:2017-01-27 11:37:45
【问题描述】:

是否可以从与特定扩展名匹配的变量中选择文件,然后丢弃其余文件?

SRCS = file1.c file2.c file3.cpp

OBJS = $(SRCS:%.c=%.o)
OBJS += $(SRCS:%.cpp=%.o)

问题在于 $(SRCS:%.c=%.o) 将 .c 文件转换为 .o 文件,保留 .cpp 文件。

在这种情况下,OBJS 变量将等于

file1.o file2.o file3.cpp file1.c file2.c file3.o

而我想要的是

file1.o file2.o file3.o

那么,有可能吗?或者唯一干净的方法是拥有SRCS_CSRCS_CPP 变量?

【问题讨论】:

    标签: c++ c makefile


    【解决方案1】:

    使用 GNU make,有几个text processing functions 可用。你可以试试这个:

    CSRCS = $(filter %.c,$(SRCS))
    CPPSRCS = $(filter %.cpp,$(SRCS))
    

    这会将对象列表一分为二。然后您可以单独处理每个:

    OBJS = $(CSRCS:%.c=%.o)
    OBJS += %(CPPSRCS:%.cpp=%.o)
    

    另一种选择是一次性应用两个过滤器:

    OBJS = $($(SRCS:%.c=%.o):%.cpp=%.o)
    

    虽然这不太可读。

    【讨论】:

    • 我也喜欢你的第二个建议,我不认为它很难阅读
    【解决方案2】:

    我可以看到两种可能的解决方法(但它们会给您带来稍微不同的 项目组织)。首先是要有:

    SRCS := file1 file2 file3
    OBJS := $(SRCS:%=%.o)
    

    然后您可以使用依赖项定义目标以检查 源文件是 C 或 C++ 文件:

    %.o: %.cpp
        g++ $< [...]
    
    %.o: %.c
        gcc $< [...]
    

    或者您可以拥有像file1.c.o/file3.cpp.o 这样的目标文件。这意味着 您可以拥有同名的 C 和 C++ 文件,这可能很有用。 那么你只需要这样做:

    SRCS := file1.c file2.c file3.cpp
    OBJS := $(SRCS:%=%.o)
    
    %.cpp.o: %.cpp
        g++ $< [...]
    
    %.c.o: %.c
        gcc $< [...]
    

    希望我能帮上忙:)

    【讨论】:

    • 好极了。第二种解决方案正是我想要的。谢谢!
    • 我也认为@Cakeisalie5 的回答是更好的方法。
    【解决方案3】:
    set_o_suffix=$(addsuffix .o,$(basename $1))
    set_o_suffix_for_cxx=$(addsuffix .o,$(basename $(filter %.c %.cpp,$1)))
    
    SRCS := foo.c buz/bar.cpp main.js
    $(info set_o_suffix=$(call set_o_suffix,$(SRCS)))
    $(info set_o_suffix_for_cxx=$(call set_o_suffix_for_cxx,$(SRCS)))
    all:
    

    输出:

    set_o_suffix=foo.o buz/bar.o main.o
    set_o_suffix_for_cxx=foo.o buz/bar.o
    

    【讨论】:

      【解决方案4】:

      首先你有什么样的操作系统?

      如果是 Linux 风格的,那么你可以使用 | grep 分机

      如果是窗口则使用 find |而是..

      如果您使用文件选择,那么在构建文件选择器时,您可以填写所需的扩展名并确保其他扩展名将被丢弃...

      如果您从命令行运行 C++/C 程序,则选择上述。

      如果您希望变量具有特定扩展名,请使用正则表达式 在 . 之后指定字符数。 (点)并且只允许 1 个分机。

      更多信息: 访问https://msdn.microsoft.com/en-us/library/bb982727.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多