我遇到了我制作的Makefile问题。它由一个内置main()的.cpp文件组成,我想从中创建可执行文件。在输入终端 make 命令时,我得到以下信息:
g++ STutorial.o -o MyExecutable
g++: error: STutorial.o: No such file or directory
g++: fatal error: no input files
在第一次制作STutorial.o (.o创建)然后制作的同时获取此信息:
g++ STutorial.o -o MyExecutable
STutorial.o: In function `main':
STutorial.cpp:(.text+0x47a): undefined reference to `alcOpenDevice'
首先,为什么 make 从一开始就没有? 其次,为什么这个引用未定义,好像我没有包含库,我在Makefile以及STutorial.cpp文件中做了。 你能帮帮我吗?我正在读我能做错的事情并且没有任何线索。 (我是初学者,也许错误是一个菜鸟,我提前道歉,但不能单独理解) 生成文件:
FLAGS += -std=c++11
CCX=g++
FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL
all: MyExecutable
MyExecutable:
$(CXX) STutorial.o -o MyExecutable
STutorial.o: STutorial.cpp
$(CXX) $(FLAGS) STutorial.cpp
答案 0 :(得分:2)
你的makefile应该是这样的:
CCX=g++
FLAGS +=-c -Wall #for compilation, for warning
LINK_FLAGS += -lopenal -lSDL
all: MyExecutable
MyExecutable: Stutorial.o
$(CXX) STutorial.o -o MyExecutable $(LINK_FLAGS)
STutorial.o: STutorial.cpp
$(CXX) $(FLAGS) STutorial.cpp
说明:
您的MyExecutable
取决于Stutorial.o
,其取决于Stutorial.cpp
现在-c
标志只能用于.cpp
文件来创建目标文件而不是已经创建的.o
文件。
因此,您应该有两个标志:FLAGS
用于编译,LINK_FLAGS
用于在制作可执行文件期间链接库。
答案 1 :(得分:2)
您的可执行规则是问题:
MyExecutable:
$(CXX) STutorial.o -o MyExecutable
它有一个目标(MyExecutable
),它有一个配方($(CXX) ...)
,看起来都很好。但它的先决条件是什么? MyExecutable
确实有先决条件 - 它需要STutorial.o
才能生成二进制文件!你需要明确告诉make:
MyExecutable: STutorial.o
$(CXX) STutorial.o -o MyExecutable
否则,您告诉make您要构建all
。 all
取决于MyExecutable
。 MyExecutable
并不依赖于任何内容,因此STutorial.o
的规则永远不会被运行。
至于链接器错误,您没有在所需的库中进行链接,因此您应该定义如下内容:
LFLAGS += -lopenal -lSDL
MyExecutable: STutorial.o
$(CXX) STutorial.o $(LFLAGS) -o MyExecutable
答案 2 :(得分:1)
Makefile中有一些问题,从:
开始FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL
您正在重新定义FLAGS变量。 所以你应该拥有的是编译器和链接器标志的不同变量:
CFLAGS +=-c -Wall #for compilation, for warning
LDFLAGS += -lopenal -lSDL
现在,为了给出一个完整的答案,而不是解决您的直接问题,我将尝试展示如何使Makefile更灵活:
从源开始 - 你也应该有一个变量;在向项目中添加/删除源文件时,它非常有用:
SOURCES = STutorial.cpp
为您的目标文件定义一个变量(这在链接时会派上用场):
OBJ = $(SOURCES:.cpp=.o)
将所有源文件编译为目标文件:
.cpp.o:
$(C++) $(CFLAGS) -o $@ $<
使用编译的目标文件链接您的二进制文件:
$(MyExecutable): $(OBJ)
$(C++) $(LDFLAGS) $(OBJ) -o $@
为完整性添加一个干净的命令(删除二进制文件和目标文件):
clean:
$(RM) $(EXECUTABLE) $(OBJ)
现在,把它们放在一起:
CCX=g++
CFLAGS +=-c -Wall -std=c++11#for compilation, for warning
LDFLAGS += -lopenal -lSDL
SOURCES = STutorial.cpp
OBJ = $(SOURCES:.cpp=.o)
all: $(MyExecutable)
$(MyExecutable): $(OBJ)
$(CCX) $(LDFLAGS) $(OBJ) -o $@
.cpp.o:
$(CCx) $(CFLAGS) -o $@ $<
clean:
$(RM) $(EXECUTABLE) $(OBJ)
这应该允许您灵活地构建,重建,清理项目。
答案 3 :(得分:0)
这是你应该做的:
g++ -std=c++11 -Wall -lopenal -lSDL STutorial.cpp -o MyExecutable