【问题标题】:Makefile seems to ignore flags. Why?Makefile 似乎忽略了标志。为什么?
【发布时间】:2015-02-02 04:20:51
【问题描述】:

make 似乎忽略了我的 cflag 选项,因为编译器抱怨我需要将 -std=c++11 作为标志,但该选项包含在我的 makefile 中。

CC=g++
# Flags for the C compiler
CXX_FLAGS= \
    -Wall \
    -std=c++11 \
    -O2
# Linker Flags
LD_FLAGS= 

# Sources to compile
SOURCES=main.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXE=HolidayLights.out

all: $(SOURCES) $(EXE)

# Primary build target
$(EXE): $(OBJECTS)
    $(CC) $(LD_FLAGS) $(OBJECTS) -o $@

.o:
    $(CC) -c $(CXX_FLAGS) -o $@ $<

这个makefile的构建命令的输出是:

g++     -c -o main.o main.cpp

我不明白为什么它没有在输出中列出我的标志。另外,我知道它忽略了-std=c++11 标志,因为它抱怨非静态常量成员,并且不应该启用该标志。

Edit0:符号更改

【问题讨论】:

  • @RSahu 您的评论似乎只是一个符号,但是我确实进行了更改,以后阅读起来会更容易。
  • CC 和 CC_FLAGS 用于 C 编译器。将 CXX 和 CXX_FLAGS 用于 C++ 编译器。还是CXXFLAGS?我喜欢 Make。
  • 如果你依赖 GNU Make 使用的默认规则,你可以定义 CXXFLAGS 和 CFLAGS 来控制编译器标志以获得你需要的一切。
  • @n.m.这样做确实更有意义。我只是根据 C makefile 的旧教程建立了我的 makefile。我从某所大学网上找到的。

标签: c++ c++11 makefile


【解决方案1】:

您的.o: 规则未被选中,请将其改为.cpp.o:。

默认情况下(来自 GNU make doco):

n.o 由 n.cc、n.cpp 或 n.C 自动生成,配方形式为 '$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c'

您的规则在第一种情况下不起作用的原因是单后缀隐式规则应该是 源 类型而不是目标类型。因此规则将是.cpp:(同样来自make doco):

双后缀规则由一对后缀定义:目标后缀和源后缀。它匹配名称以目标后缀结尾的任何文件。相应的隐式先决条件是通过用文件名中的源后缀替换目标后缀来实现的。目标和源后缀为'.o' 和'.c' 的双后缀规则等价于模式规则'%.o : %.c'。

单后缀规则由单个后缀定义,即source后缀。它匹配任何文件名,并且通过附加源后缀来生成相应的隐式先决条件名称。源后缀为'.c' 的单后缀规则等价于模式规则'% : %.c'。

但是,请仔细阅读最后一句话。 .cpp: 规则只有在你想将XYZZY.cpp 变成XYZZY 时才有效。由于你的目标是XYZZY.o的形式,它不会被使用。

当然,另一种选择是根本不触及默认规则,而只是修改它们使用的变量:

CXX      = g++
CPPFLAGS = -Wall -std=c++11 -O2
LD_FLAGS =

SOURCES  = main.cpp
OBJECTS  = $(SOURCES:.cpp=.o)
EXE      = HolidayLights.out

all: $(SOURCES) $(EXE)

$(EXE): $(OBJECTS)
    $(CXX) $(LD_FLAGS) $(OBJECTS) -o $@

而且,如果您想使用隐式规则,您应该真正使用首选形式,即较新的模式规则。它们比后缀的要强大得多。

【讨论】:

  • 为什么需要此更改?我不明白为什么它不会被选中。
  • 现在更有意义了。所以基本上make会根据扩展名选择生成目标文件要遵循的规则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2018-11-09
  • 1970-01-01
  • 2020-05-02
相关资源
最近更新 更多