将-M标志添加到g ++会导致文件格式无法识别错误

时间:2016-09-17 18:39:38

标签: c++ gcc g++

-m标志添加到g ++会导致file format not recognized; treating as linker script,这会在链接时导致语法错误。

我正在使用这个makefile:

# Compilers
CXX = g++
#CXX = clang++
CC = gcc

UNAME := $(shell uname)

# Directories used for input and output
SRCDIR = src/src
BUILDDIR = build
EXEDIR = bin
INCLUDEDIR = src/include
VERBOSE = 0

# Debug flags
ifeq ($(VERBOSE), 1)
    CXX_FLAGS += -M
endif

# Enable all warnings but format and unused variables
CXX_FLAGS += -Wall -Wno-format -Wno-unused-variable -Wno-varargs -c -g -O0 -fbuiltin -fpermissive -std=c++14 -I include -I $(INCLUDEDIR)

OUTPUT_NAME = Test

# Where the sources are located
SRCS = $(wildcard $(SRCDIR)/*.cpp)
SRCS += $(wildcard $(SRCDIR)/*/*.cpp)

CSRCS = $(wildcard $(SRCDIR)/*.c)

# Where the compiled objects are located
OBJS = $(patsubst $(SRCDIR)/%.cpp, $(BUILDDIR)/%.o, $(SRCS))
COBJS = $(patsubst $(SRCDIR)/%.c, $(BUILDDIR)/%.o, $(CSRCS))

# Linking all the .o files and with the libs
build: $(OBJS) $(COBJS)
    $(CXX) $^ $(LINKER_FLAGS) -o ./bin/$(OUTPUT_NAME)

# Compiling all the .cpp files into .o files
$(OBJS): $(BUILDDIR)/%.o : $(SRCDIR)/%.cpp
    $(CXX) $(CXX_FLAGS) -o "$@" "$<"

$(COBJS): $(BUILDDIRT)/%.o : $(SRCDIR)/%.c
    $(CC) $(CC_FLAGS) -o "$@" "$<"

# Running the created exe
.PHONY: run
run:
    ./$(EXEDIR)/$(OUTPUT_NAME)

src/src我有两个文件,test.cppfoo.cpp

test.cpp

#include "foo.h"
#include "cstdio"

int main(int argc, char* argv[]) {
    Foo f;
    int b = f.bar(2);

    printf("%d", b);
    return 0;
}   

foo.cpp

#include "foo.h"

Foo::Foo() {

}

Foo::~Foo() {

}

int Foo::bar(int c) {
    return c + c;
}   

.h的{​​{1}}文件位于foo.cpp

src/include

foo.h

调用#ifndef _FOO_H #define _FOO_H class Foo { public: Foo(); ~Foo(); int bar(int c); }; #endif 编译代码很好,我得到了我期望的输出,但是通过调用make build(打开g ++的-M标志)我得到了

make VERBOSE=1 build

/usr/bin/ls:build/foo.o: file format not recognized; treating as linker script

我很困惑为什么启用usr/bin/ld:build/foo.o:1: syntax error标志会导致这种情况,因为我认为-M输出程序的依赖关系。如果有人能指出我正确的方向,我会非常感激。

2 个答案:

答案 0 :(得分:2)

嗯,当然!你是对的-M将gcc的输出从目标文件更改为可以导入的规则文件。但是你将那些结果文件而不是用作依赖文件-include到你的makefile中,但作为目标文件!

简而言之,你正在做这样的事情:

g++ -c foo.cxx -o foo.o
g++ -c bar.cxx -o bar.o
g++ -o exe foo.o bar.o

哪个有效。然后将其更改为:

g++ -M -c foo.cxx -o foo.o
g++ -M -c bar.cxx -o bar.o
g++ -o exe foo.o bar.o

您正在命名这些操作foo.obar.o的结果,但它们不是目标文件,当您尝试将它们链接在一起时,链接器将失败,因为......它们'不是目标文件。如果您尝试cat“详细”构建对象文件并查看它们的实际外观,则应该非常清楚。

答案 1 :(得分:2)

正如Barry在他的回答中所解释的那样,-M标志使编译器输出依赖到其他方式放置其目标文件的位置。它不会在屏幕上打印依赖项。此外,它完全禁用C / C ++编译 - 仅执行预处理。

如果您使用make选项生成依赖项文件作为.d的输入,则可以使用-MD选项使编译器输出依赖项为foo.d文件与目标文件一起。 (例如,在您的情况下,这会使它生成foo.o文件以及目标文件-MF。)

因为您只是想将依赖项打印到屏幕上,所以可以使用-M -MF /dev/stdout 选项重定向依赖项输出,例如

{{1}}