繁体   English   中英

使用Makefile进行构建:即使显式指定,也选择file.c而不是file.cpp

[英]Building using Makefile: picks file.c instead of file.cpp even though specified explicitly

抽象:

我在同一父文件夹中有一个具有相同名称的.c文件和.cpp文件。 我不再希望编译.c文件,但也不想从文件夹中将其删除。

即使我明确指定要编译.cpp文件,makefile仍在使用.c文件。 如何解决此问题?

file3.c重命名为另一个名称时,将编译file3.cpp

细节:

src文件夹中的文件为:

file1.c
file2.c
file3.c
file3.cpp
file4.cpp

makefile的重要摘录:

SOURCE_FILES := ./src/file1.c \
        ./src/file2.c \
        ./src/file3.cpp \
        ./src/file4.cpp

OBJS = $(patsubst %.cpp,%.o,$(filter %.cpp, $(SOURCE_FILES))) \
    $(patsubst %.c,%.o,$(filter %.c, $(SOURCE_FILES)))

all : $(OBJS)
    $(CXX) $(CFLAGS) $(INCLUDES) -o $(PROJECT).bin $(OBJS) $(LDFLAGS) $(LIBRARIES) 

.cpp.o: 
    $(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@
    @echo 'CPP FILE : ' $<

.c.o:
    $(CXX) $(CFLAGS) $(INCLUDES) -c $<  -o $@
    @echo 'C FILE : ' $<

在执行“ make”时,echo命令的日志给出:

C FILE : ./src/file1.c
C FILE : ./src/file2.c
C FILE : ./src/file3.c
CPP FILE : ./src/file4.cpp

问题:

  1. 上述问题如何解决?
  2. 有没有更简单的方法来获取我的OBJS变量的值?

make使用方法从两个可能使用的匹配规则中选择一个,具体取决于您使用的make版本。 (它在3.81和3.82之间变化,我相信4.0+会有所调整,但不确定。)

我相信make 3.81使用了最后一个匹配规则,make 3.82+使用了最短词干(与%匹配的位)的匹配规则,然后使用了具有相似词干长度的规则之间的第一个匹配规则。

因此,似乎您当前正在使用make 3.81。

在这种情况下,应该可以简单地交换两个规则的顺序来获得所需的行为(假设您始终希望.cpp文件“获胜”)。

或者,您可以尝试为file3.o目标提供明确的前提条件,而不是让其猜测。 (即file3.o: file3.cpp

就是说,您的任何明确的后缀规则都不是必需的,因为make已经包含了从.c.cpp文件构建.o文件的默认规则。 (我不知道它们之间的相对顺序,因此您可能需要明确的前提条件(假设可行)才能使内置规则正确运行。)

另外,您可能想看看使用模式规则而不是老式的后缀规则 ,这是当前实践的重点。

我可以看到,对OBJS变量的唯一改进是对结果进行过滤,因此只需过滤一次。

OBJS = $(filter %.o,$(patsubst %.cpp,%.o,$(SOURCE_FILES)) \
    $(patsubst %.c,%.o,$(SOURCE_FILES)))

也就是说,您也可以使用Substitution References代替显式调用$(patsubst)来缩短该时间。

OBJS = $(filter %.o,$(SOURCE_FILES:.cpp=.o) $(SOURCE_FILES:.c=.o))

您对.c ==> .o和.cpp ==> .o都有规则。 在您的情况下,因为现在存在新创建的file3.o文件,所以首先运行file3.c的规则。 由于目标file3.o文件存在,因此没有理由编译file3.cpp。

查看制造手册 ,如果同一目标有两个规则,则使用最后一个规则。

暂无
暂无

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

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