makefile 链接不起作用(尽管没有错误消息)

makefile linking does not work (although no error message)

我生成的 Makefile 有问题。它由一个 .cpp 文件组成,里面有 main() ,我想从中创建可执行文件。在输入终端 make 命令时,我得到以下信息:

g++ STutorial.o -o MyExecutable
g++: error: STutorial.o: No such file or directory
g++: fatal error: no input files

make STutorial.o (.o 创建)然后 make 得到这个:

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

你应该这样做:

g++ -std=c++11 -Wall  -lopenal -lSDL STutorial.cpp -o MyExecutable

你的 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 用于在制作可执行文件期间链接库。

您的可执行规则是问题所在:

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

您的 Makefile 开头有一些问题:

FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL

您正在重新定义 FLAGS 变量。 所以你应该有一个不同的编译器变量和linker flags:

CFLAGS +=-c -Wall #for compilation, for warning
LDFLAGS += -lopenal -lSDL

现在,为了给出一个完整的答案,而不仅仅是解决您眼前的问题,我将尝试展示如何使 Makefile 更加灵活:

  1. 从源开始——你也应该有一个变量;当 adding/removing 源文件 to/from 项目时很有用:

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

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

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

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

    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) 

这应该允许您灵活地构建、重建、清理您的项目。