将-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.cpp
和foo.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
输出程序的依赖关系。如果有人能指出我正确的方向,我会非常感激。
答案 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.o
和bar.o
的结果,但它们不是目标文件,当您尝试将它们链接在一起时,链接器将失败,因为......它们'不是目标文件。如果您尝试cat
“详细”构建对象文件并查看它们的实际外观,则应该非常清楚。
答案 1 :(得分:2)
正如Barry在他的回答中所解释的那样,-M
标志使编译器输出依赖到其他方式放置其目标文件的位置。它不会在屏幕上打印依赖项。此外,它完全禁用C / C ++编译 - 仅执行预处理。
如果您使用make
选项生成依赖项文件作为.d
的输入,则可以使用-MD
选项使编译器输出依赖项为foo.d
文件与目标文件一起。 (例如,在您的情况下,这会使它生成foo.o
文件以及目标文件-MF
。)
因为您只是想将依赖项打印到屏幕上,所以可以使用-M -MF /dev/stdout
选项重定向依赖项输出,例如
{{1}}