简体   繁体   English

Allegro5 Makefile错误

[英]Allegro5 makefile error

note: this is the final exercise in the Head First C book. 注意:这是《 Head First C》书中的最后练习。

I have the following problem. 我有以下问题。 I am trying to make a game using the allegro5.2 libraries. 我正在尝试使用allegro5.2库制作游戏。 I want to use multiple .c files in order to organize everything neatly. 我想使用多个.c文件来整理所有内容。 However, I have problems compiling my programs using a makefile. 但是,我在使用makefile编译程序时遇到问题。 I am trying to compile this easy program: 我正在尝试编译这个简单的程序:

#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;
}

The makefile is: 生成文件为:

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

Now, when I use the terminal this compiles fine, but now I seem to have a problem. 现在,当我使用终端时,这可以正常编译,但是现在我似乎遇到了问题。 The error given by the terminal (using the command make Blasteroids) is: 终端给出的错误(使用命令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

I don't know what I am doing wrong and I am very new to these things. 我不知道自己在做什么错,对这些事情我很陌生。 I have searched for examples in makefiles, but they give me code like I am using now. 我已经在makefiles中搜索了示例,但是它们给了我现在正在使用的代码。 I now I can just use a single line for the above program, but the idea is that I want to make my own .c files, make them into .o files and then link them together. 现在,我可以在上面的程序中使用一行,但是我的想法是要创建自己的.c文件,将它们创建为.o文件,然后将它们链接在一起。 Hence the makefile. 因此,makefile。

something like the following makefile contents should do the job 像下面的makefile内容应该做的事情

Notes: 笔记:

  1. header files are only needed during the compile step 头文件仅在编译步骤中需要
  2. library files are only needed during the link step 库文件仅在链接步骤中需要
  3. best to have the first 'target' be 'all' so the makefile can be successfully executed without have to include a 'Blasteroids' parameter 最好将第一个“目标”设置为“全部”,以便可以成功执行makefile,而不必包含“ Blasteroids”参数
  4. having a 'target' 'clean' makes it easy to clear away the items that will be rebuilt 拥有“目标”“干净”,可以轻松清除将要重建的项目
  5. any 'target' that does not produce a file of the same name should be listed in a '.PSEUDO' operator 没有产生同名文件的任何“目标”都应在“ .PSEUDO”运算符中列出
  6. the linker processes the linker command line items in the order listed on the command line. 链接器按命令行上列出的顺序处理链接器命令行项。 Therefore, list the objects, then the directories, then the library 'short' names 因此,列出对象,然后列出目录,然后列出库“短”名称
  7. list the header files at the end of the compile command line 在编译命令行末尾列出头文件
  8. use macros (like CC and RM) that contain the full path to the executables so the correct executable is used, other wise the first item found in the $PATH that matches the name will be used. 使用包含可执行文件完整路径的宏(例如CC和RM),以便使用正确的可执行文件,否则,将使用$ PATH中与名称匹配的第一项。
  9. $^ is a built in macro that expands to the recipe dependencies $ ^是一个内置宏,可扩展为配方依赖项
  10. $< is a built in macro that expands to the first dependency $ <是一个内置宏,可扩展为第一个依赖项
  11. $@ is a built in macro that expands to the recipe 'target' $ @是一个内置宏,可扩展为配方“目标”
  12. the $(SRC:.c=?) statements do character replacement on the extension of the file names contained in the $(SRC) macro $(SRC:.c=?)语句对$(SRC)宏中包含的文件名的扩展名执行字符替换
  13. the %.o:%.c recipe says for each source file to be compiled into a object file, use this recipe %.o:%.c配方表示对于要编译为目标文件的每个源文件,请使用此配方
  14. the '-ggdb' is so the maximum debug information will be available to the 'gdb' debugger. “ -ggdb”是这样,因此最大的调试信息将提供给“ gdb”调试器。
  15. this pattern of 'makefile' can be extensively used for other projects with only minor variations. 这种“ makefile”模式可以广泛用于其他项目,而只需稍作改动即可。 For more flexibility could also insert a recipe for automatically generating the header file dependencies, so would not need to list them individually in the compile recipe, but for now, the following makefile contents will do what you are currently trying to perform 为了获得更大的灵活性,还可以插入一个配方来自动生成头文件依赖项,因此不需要在编译配方中单独列出它们,但是就目前而言,以下makefile内容将执行您当前要执行的操作

and now the makefile 现在是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)

The make program looks for files named makefile or Makefile , with no extension. make程序将查找没有扩展名的名为makefileMakefile If you name your makefile something else, such as makefile.txt , then make can't find it and it will just use its own built-in rules which don't know anything about extra flags ro libraries that may be needed. 如果您将makefile命名为其他名称,例如makefile.txt ,则make找不到它,它将仅使用自己的内置规则,这些规则对可能需要的额外标志ro库一无所知。

So either rename your makefile to makefile or Makefile , or else specify the name of your makefile explicitly on the command line when you run make, such as make -f makefile.txt Blasteroids . 因此,可以将makefile重命名为makefileMakefile ,或者在运行make时在命令行上显式指定makefile的名称,例如make -f makefile.txt Blasteroids

Secondarily, if you don't specify a target on the command line then make will always build the first target. 其次,如果您未在命令行上指定目标,那么make将始终构建第一个目标。 So, if you re-order your targets so that the one you usually want to build (in this case Blasteroids ) is first, then you can just run make with no arguments and it will build that target. 因此,如果您对目标进行重新排序以使通常要构建的目标(在本例中为Blasteroids )首先出现,则可以不带任何参数运行make ,它将构建该目标。

Unlike a programming language, the order of target definition doesn't matter to make: eg, you don't have to define rules for all the object files first before the link line. 与编程语言不同,目标定义的顺序无关紧要:例如,您不必在链接行之前先为所有目标文件定义规则。 Make reads the entire file and constructs an internal graph of prerequisite relationships, and nodes and edges in this graph can be added in any order. Make会读取整个文件并构造一个内部的前提条件关系图,并且可以按任何顺序添加该图中的节点和边。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM