c - Unix:使用 Make 进行项目管理

标签 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。 (这通常会产生有关额外 token 的警告消息。忽略它。)

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

编写一个 makefile 来执行这些步骤。当此过程的任何输入文件发生更改时,您的 makefile 应仅生成所需的最少步骤。 (注意:您可能无法像作业的前面部分那样将此 makefile 建立在我的 self 更新 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: error: ld returned 1 exit status
make: *** [cpp2html.o] Error 1

Your makefile does not build 'cpp2html' when invoked:
gcc -g -DDEBUG cpp2html.c

这是今晚到期的,所以任何建议将不胜感激。

最佳答案

它提示以下内容:

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.c< 重复相同的命令lex.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了解更多详情。

关于c - Unix:使用 Make 进行项目管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31886844/

相关文章:

bash - BASH 中 && 和 -a 的区别

使用 sprintf() 将文本复制到字符数组中 - C/Atmel studio 7

c - 交换 8 个字母的字符数组。没有正确交换

java - Install4J linux 安装程序失败并出现 "no server JVM at"错误,除非您使用 -J-client

linux - 为什么 CLOCKS_PER_SECOND 总是设置为 100 万?

linux - bash 文件中的单词列表

c - 需要有关 C 语言方法的帮助

c - 指向结构指针内字符串中的字符

c - 为什么 readdir 在第一次调用目录后下次调用 readdir 时返回 null 和 I/O 错误

c - scanf 后变量重置