构建 main.c 和 main.cpp 的单个 Makefile

Single Makefile to build both main.c and main.cpp

我想 make main-cmain.c 构建 main-c

make main-cppmain.cpp 构建 main-cpp

我有,都在同一个文件夹中:

main.c:

#include <stdio.h>

int main(int argc, char const *argv[]) {
    printf("This ic C\n");
}

main.cpp:

#include <iostream>

int main(int argc, char const *argv[]) {
    std::cout << "This is C++" << std::endl;
}

Makefile:

CFLAGS   = -std=gnu11

CXXFLAGS = -std=gnu++11 

CPPFLAGS = -g -Wall -O3
LDFLAGS  = 
LDLIBS   =  
OBJS     = main.o 

APP-C    = main-c
APP-CPP  = main-cpp

default:
    echo "Check README.txt"

main-c: $(OBJS)
    $(CC) $^ $(LDLIBS) -o $@

main-cpp: $(OBJS)
    $(CXX) $^ $(LDLIBS) -o $@

clean:
    -rm -Rf *.o 

distclean: clean
    -rm -Rf $(APP-C) $(APP-CPP) 

所以:

$ make main-c
cc -std=gnu11 -g -Wall -O3  -c -o main.o main.c
cc main.o  -o main-c

但是(也是从 .c 构建的):

$ make main-cpp
cc -std=gnu11 -g -Wall -O3  -c -o main.o main.c
c++ main.o  -o main-cpp

我期待 make main-cpp 使用 $(CXX) $^ $(LDLIBS) -o $@ 并从 .cpp 构建。我错过了什么?

main-cmain-cpp 这两个规则都需要创建 main.o 才能完成,但您没有创建 main.o 的规则。

您正在使用 make's implicit object file creation,这是从源文件创建“.o”文件的内置规则。它可以使用“.c”或“.cpp/cc/C”文件,并将使用适当的变量进行构建。但是,由于您同时拥有 main.cmain.cpp,看起来它默认使用 C 版本。

您可能需要为每个规则创建明确的规则(并且可能使用不同的名称)。

I was expecting make main-cpp to use $(CXX) $^ $(LDLIBS) -o $@ and build from .cpp.

是的。 make main-cpp --debug 将帮助您了解发生了什么。

问题是您依赖默认规则来制作 main-cppmain-c 目标所需的 main.o,但是当 make-cpp 目标被调用。在这种情况下,您需要定义不同的非默认规则来构建 .o 文件。如果您只是让 make-cppmain-c 依赖于具有不同名称的 .o,那将是最简单的。由于它们是不同的构建,因此它们应该有不同的名称:

CFLAGS   = -std=gnu11
CXXFLAGS = -std=gnu++11 
CPPFLAGS = -g -Wall -O3
LDFLAGS  = 
LDLIBS   =  
APP-C   = main-c
APP-CPP  = main-cpp

default:
    echo "Check README.txt"

main-c: %:%.o
    $(CC) $^ $(LDLIBS) -o $@

main-cpp: %:%.o
    $(CXX) $^ $(LDLIBS) -o $@

main-cpp.o: main.cpp
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $? -o $@

main-c.o: main.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $? -o $@

clean:
    -rm -Rf *.o 

distclean: clean
    -rm -Rf $(APP-C) $(APP-CPP)