makefile链接不起作用(虽然没有错误消息)

时间:2015-06-24 13:00:16

标签: c++ linux makefile linker

我遇到了我制作的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

4 个答案:

答案 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您要构建allall取决于MyExecutableMyExecutable并不依赖于任何内容,因此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更灵活:

  1. 从源开始 - 你也应该有一个变量;在向项目中添加/删除源文件时,它非常有用:

    SOURCES = STutorial.cpp
    
  2. 为您的目标文件定义一个变量(这在链接时会派上用场):

    OBJ = $(SOURCES:.cpp=.o)
    
  3. 将所有源文件编译为目标文件:

    .cpp.o:
        $(C++) $(CFLAGS) -o $@ $<
    
  4. 使用编译的目标文件链接您的二进制文件:

    $(MyExecutable): $(OBJ)
       $(C++) $(LDFLAGS) $(OBJ) -o $@ 
    
  5. 为完整性添加一个干净的命令(删除二进制文件和目标文件):

    clean:
        $(RM) $(EXECUTABLE) $(OBJ) 
    
  6. 现在,把它们放在一起:

    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