Allegro5 makefile错误

时间:2017-01-25 17:49:48

标签: c makefile allegro5

注意:这是Head First C一书中的最后一次练习。

我有以下问题。我正在尝试使用allegro5.2库制作游戏。我想使用多个.c文件,以整齐地组织一切。但是,我在使用makefile编译程序时遇到问题。我正在尝试编译这个简单的程序:

#include <stdio.h>
#include <allegro5/allegro.h>

const int disp_h = 640;
const int disp_w = 480;

int main(int argc, char **argv) {

ALLEGRO_DISPLAY *display;

if(!al_init()) {
    fprintf(stderr, "failed to initialize allegro!\n");
    return -1;
}

display = al_create_display(disp_h,disp_w);
if(!display) {
    fprintf(stderr, "failed to create display!\n");
    return -1;
}

al_rest(0.4);
al_destroy_display(display);

printf("bye bye!!!\n");

return 0;
}

makefile是:

Blasteroids.o: allegro.h Blasteroids.c
    gcc -Wall -c Blasteroids.c

Blasteroids: Blasteroids.o allegro.h
    gcc -Wall -I/usr/include/allegro5 -L/usr/lib -lallegro -lallegro_main Blasteroids.o -o Blasteroids

现在,当我使用终端这个编译很好,但现在我似乎有问题。终端给出的错误(使用命令make Blasteroids)是:

cc   Blasteroids.o   -o Blasteroids
Undefined symbols for architecture x86_64:
  "_al_create_display", referenced from:
      __al_mangled_main in Blasteroids.o
  "_al_destroy_display", referenced from:
      __al_mangled_main in Blasteroids.o
  "_al_install_system", referenced from:
      __al_mangled_main in Blasteroids.o
  "_al_rest", referenced from:
      __al_mangled_main in Blasteroids.o
  "_main", referenced from:
     implicit entry/start for main executable
     (maybe you meant: __al_mangled_main)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Blasteroids] Error 1

我不知道我做错了什么,我对这些事情很陌生。我在makefile中搜索了一些例子,但它们给了我现在正在使用的代码。 我现在可以在上面的程序中使用一行,但我的想法是我想制作我自己的.c文件,将它们制作成.o文件,然后将它们链接在一起。因此makefile。

2 个答案:

答案 0 :(得分:0)

类似下面的makefile内容应该做的工作

注意:

  1. 仅在编译步骤
  2. 期间需要头文件
  3. 仅在链接步骤
  4. 期间需要库文件
  5. 最好让第一个'目标'为'all',这样makefile就可以成功执行,而不必包含'Blasteroids'参数
  6. 让'目标''干净'可以轻松清除将要重建的物品
  7. 任何不会生成同名文件的'目标'都应列在'.PSEUDO'运算符中
  8. 链接器按命令行中列出的顺序处理链接器命令行项。因此,列出对象,然后列出目录,然后列出库的“短名称”
  9. 列出编译命令行末尾的头文件
  10. 使用包含可执行文件完整路径的宏(如CC和RM),以便使用正确的可执行文件,否则将使用$ PATH中与名称匹配的第一项。
  11. $ ^是一个扩展为配方依赖项的内置宏
  12. $&LT;是一个内置宏,扩展到第一个依赖
  13. $ @是一个内置宏,可扩展到配方'target'
  14. $(SRC:.c=?)语句对$(SRC)宏中包含的文件名的扩展名进行字符替换
  15. %.o:%.c食谱说明要将每个源文件编译成目标文件,请使用此配方
  16. '-ggdb'是'gdb'调试器可用的最大调试信息。
  17. 这种'makefile'模式可以广泛用于其他项目,只有很小的变化。为了获得更大的灵活性,还可以插入一个自动生成头文件依赖关系的配方,因此不需要在编译配方中单独列出它们,但是现在,以下makefile内容将执行您当前尝试执行的操作
  18. 现在是makefile

    CC := /bin/gcc
    RM := /bin/rm
    
    CFLAGS := -Wall -Wextra -pedantic -std=gnu99 -ggdb -c
    LFLAGS := -L/usr/lib -lallegro -lallegro_main
    
    SRC    := Blasteroids.c
    #OBJ    := $(SRC:.c=.0)
    OBJ    := $(SRC:.c=.o)
    NAME   := $(SRC:.c=)
    
    .PSEUDO: all clean
    
    all: $(NAME)
    
    %.o:%.c
        #$(CC) $(CFLAGS) $^ -o $@ -I/usr/include/allegro5
        $(CC) $(CFLAGS) $< -o $@ -I/usr/include/allegro5
    
    $(NAME): $(OBJ)
        $(CC) -ggdb  $^ -o $@  $(LFLAGS)
    
    .clean:
        $(RM) -f $(NAME) $(OBJ)
    

答案 1 :(得分:0)

make程序会查找名为makefileMakefile的文件,但没有扩展名。如果你将makefile命名为其他东西,例如makefile.txt,那么make找不到它,它只会使用自己的内置规则,这些规则不知道有关额外标志的任何内容。可能需要。

因此,要么将makefile重命名为makefileMakefile,要么在运行make时在命令行中明确指定makefile的名称,例如make -f makefile.txt Blasteroids

其次,如果您没有在命令行上指定目标,那么make将始终构建第一个目标。因此,如果您重新排序目标,以便您通常要构建的目标(在本例中为Blasteroids)是第一个,那么您可以只运行make而没有参数,它将构建该目标

与编程语言不同,目标定义的顺序无关紧要:例如,您不必在链接行之前首先为所有目标文件定义规则。 Make读取整个文件并构建先决条件关系的内部图,并且可以按任何顺序添加此图中的节点和边。