为 C++ 程序创建健壮的 Makefile
Posted
技术标签:
【中文标题】为 C++ 程序创建健壮的 Makefile【英文标题】:Creating a robust Makefile for C++ program 【发布时间】:2016-03-21 22:00:34 【问题描述】:考虑以下微不足道的 Makefile。请注意,有两个类,每个类都有对应的 .h 和 .cpp 文件。
output: main.o class1.o class2.o
g++ main.o class1.o class2.o -o output
main.o: main.cpp
g++ -c main.cpp
class1.o: class1.cpp class1.h
g++ -c class1.cpp
class2.o: class2.cpp class2.h
g++ -c class2.cpp
clean:
rm *.o output
这个 Makefile 是否健壮?我怎样才能使它更健壮?有人可以提供这个 Makefile 的更强大的版本吗?它将在 64 位 Red Hat Linux 或 CentOS 机器上运行。
如果重要,我正在使用:
-gcc --version 4.8.4(来自 GNU 编译器集合)
-GDB版本:GNU gdb (Ubuntu 7.7.1 -0ubuntu5~14.04.2) 7.7.1
【问题讨论】:
您对“健壮”的理解是什么? Makefile 有一些缺陷(例如,无法设置强制和可选标志,没有自动依赖跟踪,没有 VPATH 构建)。 如果你使用 CMake,为什么还要有 Makefile?! @Biffen - 我必须在没有 CMake 的情况下将应用程序发送给其他人。 @ensc - 更强大 == 将在我的教授 Linux 机器上正常工作。我不知道这些东西是什么意思,但这个任务很快就要到期了。你能用这些更改编辑我的代码吗? 你的头文件不会被包含在多个地方吗? 【参考方案1】:我不认为你原来的 makefile 离题太远了。我刚刚做了一些补充:
-
添加了一个默认的
all
目标 - 最好是明确的
在所有对 g++ 的调用中使用 CXXFLAGS
环境变量
如上所述,使 main.o
依赖于 class1.h
和 class2.h
指定clean
是PHONY
目标只是为了安全起见,如果您添加名为clean
的构建工件
ALL := output
all : $(ALL)
output: main.o class1.o class2.o
g++ $(CXXFLAGS) main.o class1.o class2.o -o output
main.o: main.cpp class1.h class2.h
g++ $(CXXFLAGS) -c main.cpp
class1.o: class1.cpp class1.h
g++ $(CXXFLAGS) -c class1.cpp
class2.o: class2.cpp class2.h
g++ $(CXXFLAGS) -c class2.cpp
.PHONY : clean
clean:
rm *.o output
【讨论】:
【参考方案2】:我会写一些类似的东西
CXX = g++
# mandatory build flags
AM_CXXFLAGS = -Wall -W -std=gnu++11
# optional build flags
CXXFLAGS = -O2 -Werror
# mandatory link flags
AM_LDFLAGS = -Wl,-as-neeeded
output: main.o class1.o class2.o
$CXX $AM_LDFLAGS $LDFLAGS $(filter %.o,$^) -o $@
%: %.cpp
$CXX $AM_CXXFLAGS $CXXFLAGS $< -c -o $@
class1.o: class1.cpp class1.h
class2.o: class2.cpp class2.h
*FLAGS
遵循 automake 表示法:AM_*
表示强制标志,普通标志包含本地设置(例如调试或优化)。
通常也应该使用带有预处理器标志 (-I ...
) 的 AM_CPPFLAGS
和 CPPFLAGS
,但我在这里省略了它们
output
目标可能也需要 $LIBS
,此处已省略
依赖跟踪更加棘手,没有实现;您将不得不在这里使用-dM
编译器选项...
当您的程序仅包含列出的 5 个文件时,您可以编写
output_SOURCES = main.c class1.c class2.c class1.h class2.h
output: $output_SOURCES
$CXX $AM_CXXFLAGS $CXXFLAGS $AM_LDFLAGS $LDFLAGS $(filter %.cpp,$^) -o $@ $LIBS
直接。
编辑:
对于自动依赖跟踪,你可以写
DEPGENFLAGS = \
-MD -MF $@D/.$@F.d -MT '$@'
%: %.cpp
$CXX $DEPGENFLAGS $AM_CXXFLAGS $CXXFLAGS $< -c -o $@
-include .deps.main.o.d
-include .deps.class1.o.d
-include .deps.class2.o.d
【讨论】:
【参考方案3】:我怎样才能使它更健壮?
使用隐式规则,保持简单。
LDLIBS+=-lstdc++
output: main.o class1.o class2.o
clean:
rm *.o output
【讨论】:
这太短了!与给出的其他解决方案相比,此实现有什么缺点吗?以上是关于为 C++ 程序创建健壮的 Makefile的主要内容,如果未能解决你的问题,请参考以下文章