Unix:使用Make进行项目管理

时间:2015-08-07 21:23:22

标签: c linux unix gcc makefile

我的指示是:<​​/ p>

制作此计划所需的步骤如下:

编译cpp2html.c以生成cpp2html.o。 (重要:此项目中的源代码是C,而不是C ++,因此必须使用gcc编译和链接,而不是g ++。)

运行命令

flex cppscanner.l 从cppscanner.l中的语言描述生成文件lex.yy.c。

编译lex.yy.c以生成lex.yy.o. (这通常会产生关于额外令牌的警告信息。忽略它。)

链接.o文件以生成名为cpp2html的可执行程序

编写将执行这些步骤的makefile。当更改此进程的任何输入文件时,makefile应仅导致所需的最小步骤量。 (注意:您可能无法将此makefile基于我自我更新的makefile,就像在作业的前面部分一样。相反,您可能会发现有必要从头开始编写这个。

这是我的makefile:

cpp2html: cpp2html.o lex.yy.o
        gcc -g -DDEBUG cpp2html.o lex.yy.o
        mv a.out cpp2html

lex.yy.o: lex.yy.c
        gcc -g -DDEBUG lex.yy.c

lex.yy.c:
        flex cppscanner.l

cpp2html.o: cpp2html.c
        gcc -g -DDEBUG cpp2html.c

我在这里做错了什么?我收到一条错误消息:

  

collect2:错误:ld返回1退出状态
  make:*** [cpp2html.o]错误1

     

你的makefile在调用时不会构建'cpp2html':
  gcc -g -DDEBUG cpp2html.c

今晚即将到期,所以我们将非常感谢任何建议。

1 个答案:

答案 0 :(得分:3)

它抱怨以下内容:

cpp2html.o: cpp2html.c
        gcc -g -DDEBUG cpp2html.c

这一行正在尝试将cpp2html.c编译为a.out

将其更改为

cpp2html.o: cpp2html.c
        gcc -g -DDEBUG -c cpp2html.c

对于将lex.yy.c编译为lex.yy.o的行执行相同的操作。 -c选项告诉gcc仅生成目标文件并将其写入.o文件。

您可以利用其他选项和一些内置变量。这是一个建议:

cpp2html: cpp2html.o lex.yy.o
        gcc -g -DDEBUG -o $@ $?

$@评估目标的名称。 $?计算依赖项列表(.o文件)。 -o选项告诉gcc将结果二进制文件写入指定的文件名而不是a.out

您还可以利用隐式规则:

%.o : %.c
        gcc -g -DDEBUG -c $<

这会将任何.c文件构建到相应的.o文件,因此您无需为cpp2html.clex.yy.c重复相同的命令。

修改

FWIW,这是我如何构建makefile(带注释;假设Gnu make):

# Variables used by implicit rules
CFLAGS=-g -DDEBUG -Wall -Werror  # flags for gcc
LFLAGS=                          # flags for flex, currently none
LEX=flex                         # lexer     
CC=gcc                           # C compiler

# Variables to make life easier
LSRCS=cppscanner.l                            # All of our flex source files
SRCS=cpp2html.c $(patsubst %.l,%.c,${LSRCS})  # All of our C source files
OBJS=$(patsubst %.c,%.o,${SRCS})              # All of our object files
TARGET=cpp2html                               # Final target name

${TARGET} : ${OBJS}              
        ${CC} ${CFLAGS} -o $@ $^ # Explicit rule to build target
                                 # $@ expands to target name
                                 # $^ expands to list of all prerequisites

clean:
        rm -rf *.o $(patsubst %.l,%.c,${LSRCS})

就是这样。我们依靠隐式规则将.l文件构建到.c文件,并将.c文件构建为.o个文件。隐式规则使用LEXCCLFLAGSCFLAGS变量来使用正确的选项运行正确的命令。我们只需要单一的显式规则来构建我们的最终可执行文件。

构造像这样的makefile的好处是你可以在不必添加新规则的情况下将文件添加到项目中。

认为以上所有都是正确的;我的主盒子此刻关闭,所以我无法测试它。有关详细信息,请参阅Gnu Make manual