为C ++程序创建健壮的Makefile

时间:2016-03-21 22:00:35

标签: c++ linux gcc makefile

考虑以下简单的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

3 个答案:

答案 0 :(得分: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_*表示强制标记,普通标记包含本地设置(例如调试或优化)。

    通常,AM_CPPFLAGSCPPFLAGS也应使用预处理程序标志(-I ...),但我在此处省略了它们

  • 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

答案 1 :(得分:2)

我认为您的原始makefile远远不够。我刚刚做了一些补充:

  1. 添加了默认的all目标 - 明确
  2. 在对g ++
  3. 的所有调用中使用CXXFLAGS环境变量
  4. main.o依赖于所讨论的class1.hclass2.h
  5. 如果您添加名为clean
  6. 的构建工件,请指定PHONYclean目标只是为了安全起见
    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 :(得分:0)

  

如何让它更健壮?

使用隐式规则,保持简单。

LDLIBS+=-lstdc++
output: main.o class1.o class2.o

clean:
    rm *.o output