【问题标题】:Makefile using mixed versions of gcc使用混合版本的 gcc 的 Makefile
【发布时间】:2013-10-08 17:55:55
【问题描述】:

我刚刚在我的 OSX(雪豹)机器上通过 brew 安装了 gcc 4.8。

当我运行 make 时,它​​使用旧版本的 g++ 作为目标文件和新版本的可执行文件。

$ make
g++    -c -o myprogram.o myprogram.cc
g++-4.8 -g -Wall -o myprogram myprogram.o

我确定这在我的 Makefile 中很简单,谁能帮我纠正这个问题?

生成文件:

CC        := g++-4.8
CFLAGS    := -g -Wall

SRCS      := myprogram.cc
OBJS      := ${SRCS:.cc=.o}
TARGET    := ${SRCS:.cc=}

default: all

all: $(OBJS)
    $(CC) $(CFLAGS) -o $(TARGET) $(OBJS)

这是版本信息:

$ g++ --version
i686-apple-darwin10-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Copyright (C) 2007 Free Software Foundation, Inc.

$ g++-4.8 --version
g++-4.8 (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.

【问题讨论】:

    标签: c++ gcc makefile


    【解决方案1】:

    您正在使用make 的默认规则来构建您的目标文件。由于您的源文件是 C++(如 .cc 扩展名所示),除了用于链接步骤的 CCCFLAGS 变量之外,您还需要覆盖 CXXCXXFLAGS 变量.像这样的东西应该这样做:

    CXX := $(CC)
    CXXFLAGS := $(CFLAGS)
    

    【讨论】:

    • 正是我想要的!谢谢。
    【解决方案2】:

    首先,您的 make 文件似乎不正确,并且仅在您有一个源文件时才有效。当您尝试向 SRCS 添加更多文件时,它将中断(在 -o 之后将传递多个参数)。通常您将 TARGET 明确指定为程序名称,而不是没有扩展名的源文件。 您只指定了一条规则来链接您的可执行文件:

    all: $(OBJS)
        $(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
    

    这也不完全正确,应该是:

    $(TARGET): $(OBJS)
        $(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
    

    你可以添加对所有的依赖:

    all: $(TARGET)
    

    现在您没有指定如何从 .cc 构建 .o 文件的规则,但 make 足够聪明,可以为您提供隐式规则。但是对于 c++ 程序,make 使用 CXX 变量,而不是 CC(你也应该遵循它)这就是为什么你没有 g++-4.8 编译的原因。所以更合适的文件可能如下所示:

    CXX       := g++-4.8
    CXXFLAGS  := -g -Wall
    
    SRCS      := myprogram.cc
    OBJS      := ${SRCS:.cc=.o}
    TARGET    := myprogram
    
    .PHONY: default all
    
    default: all
    
    all: $(TARGET)
    
    $(TARGET): $(OBJS)
        $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS)
    
    %.o: %.cc
        $(CXX) $(CXXFLAGS) -c -o $@ $<
    

    %.o: %.c 可能不是必需的,但可以显示隐式规则的工作原理。明确地提供它不会有什么坏处。

    PS 我在最后一条规则中添加了显式 -o 参数。我只是使用了 g++ 默认会生成 .o 文件的事实,并且可以省略“-o filename.o”,结果相同。

    【讨论】:

    • 拥有default 规则有什么意义?你不能把all 作为第一条规则吗?
    • 谢谢,我用你的例子来清理我的makefile。
    • @Slava 一个问题,在您的更改之前(但在修复 CXX 问题之后)make 将为目标文件执行此操作:$ make g++-4.8 -g -Wall -c -o myprogram.o myprogram.cc g++-4.8 -g -Wall -o myprogram myprogram.o 现在它可以:$ make g++-4.8 -g -Wall -c myprogram.cc g++-4.8 -g -Wall -o myprogram myprogram.o [好吧我不知道如何格式化它以便换行符起作用]
    • @DanielKO 我只是遵循了 OP 的模式,他需要这样做可能有多种原因。
    • @MERM 修改了答案,因此 make 将生成带有 -o 参数的类似命令。
    猜你喜欢
    • 2011-07-08
    • 1970-01-01
    • 2012-05-15
    • 2013-11-27
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多