构建 main.c 和 main.cpp 的单个 Makefile
Single Makefile to build both main.c and main.cpp
我想 make main-c
从 main.c
构建 main-c
。
和 make main-cpp
从 main.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-c
和 main-cpp
这两个规则都需要创建 main.o
才能完成,但您没有创建 main.o
的规则。
您正在使用 make's implicit object file creation,这是从源文件创建“.o”文件的内置规则。它可以使用“.c”或“.cpp/cc/C”文件,并将使用适当的变量进行构建。但是,由于您同时拥有 main.c
和 main.cpp
,看起来它默认使用 C 版本。
您可能需要为每个规则创建明确的规则(并且可能使用不同的名称)。
I was expecting make main-cpp to use $(CXX) $^ $(LDLIBS) -o $@ and build from .cpp.
是的。 make main-cpp --debug
将帮助您了解发生了什么。
问题是您依赖默认规则来制作 main-cpp
和 main-c
目标所需的 main.o
,但是当 make-cpp
目标被调用。在这种情况下,您需要定义不同的非默认规则来构建 .o 文件。如果您只是让 make-cpp
和 main-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)
我想 make main-c
从 main.c
构建 main-c
。
和 make main-cpp
从 main.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-c
和 main-cpp
这两个规则都需要创建 main.o
才能完成,但您没有创建 main.o
的规则。
您正在使用 make's implicit object file creation,这是从源文件创建“.o”文件的内置规则。它可以使用“.c”或“.cpp/cc/C”文件,并将使用适当的变量进行构建。但是,由于您同时拥有 main.c
和 main.cpp
,看起来它默认使用 C 版本。
您可能需要为每个规则创建明确的规则(并且可能使用不同的名称)。
I was expecting make main-cpp to use $(CXX) $^ $(LDLIBS) -o $@ and build from .cpp.
是的。 make main-cpp --debug
将帮助您了解发生了什么。
问题是您依赖默认规则来制作 main-cpp
和 main-c
目标所需的 main.o
,但是当 make-cpp
目标被调用。在这种情况下,您需要定义不同的非默认规则来构建 .o 文件。如果您只是让 make-cpp
和 main-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)