微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我如何为 GMP 项目制作 Makefile

如何解决我如何为 GMP 项目制作 Makefile

我在尝试为我的 C 项目生成 Makefile 时遇到问题。它包含 3 个文件 alea.c crypto.c 和 main.c。这是我的 Makefile:

SHELL = /bin/bash
CC = gcc
RM = rm -rf
TAR = tar
MKDIR = mkdir
CHMOD = chmod
CP = cp
MV = mv

PROGNAME = Crypto_ivsk
EXEC = Crypt
PACKAGE = $(PROGNAME)
VERSION = 0.3
disTDIR = $(PACKAGE)-$(VERSION)
HEADERS = alea.h crypto.h  gmp.h
SOURCES = alea.c crypto.c main.c 

LDFLAGS = -lgmp 
CFLAGS = -Wall

OBJ = $(SOURCES:.c=.o) 
disTFILES = $(SOURCES) Makefile $(HEADERS) 

all: $(EXEC)  

$(EXEC): $(OBJ)  
    $(CC) $(OBJ) -o $(LDFLAGS) $(EXEC)

%.o:%.c $(HEADERS) 
    $(CC) -c $< $(CFLAGS)

dist: distdir
    $(CHMOD) -R a+r $(disTDIR)
    $(TAR) zcvf $(disTDIR).tar.gz $(disTDIR)
    $(RM) $(disTDIR)

distdir: $(disTFILES)
    $(RM) $(disTDIR)
    $(MKDIR) $(disTDIR)
    $(CHMOD) 777 $(disTDIR)
    $(CP) -rf $(disTFILES) $(disTDIR)
clean:
    $(RM) $(PROGNAME) $(OBJ) *~ $(disTDIR).tar.gz

但是当我在 shell 中输入“make”时,会出现以下错误: “没有规则可以让 alea.o STOP 需要的目标 gmp.h”

我的水平太低了,没有办法解决这个问题,有人可以帮帮我吗?

谢谢:)

解决方法

您说过您所有的 %.o 文件都依赖于扩展名为 .c 的同名文件以及它们包含的头文件。

您已将 gmp.h 作为包含在 make 找不到的目录中(我想您指的是 GNU Multiprecision 库包含文件),这是您不应放入 $(HEADER) 的文件{1}} 变量。为什么?

很简单,因为你永远不会改变那个文件,所以依赖它的文件必须重新编译,因为它是一个系统文件。

我向您提供了一些建议,以避免将来出现问题。

  • 不要定义你不打算使用的变量,或者你不打算改变的变量。变量在 make 中作为常量工作。您可以在一个地方定义它们,但在 Makefile 上到处重复它们。这些是要使用的候选对象。

  • make 有一堆已经定义好的规则(实际上,从 .o 文件构建对象 .c 文件的规则已经包含在几乎所有 { {1}} 实际使用中的实现。因此,您最好尊重已安装的规则,而不是提供您自己的规则,因为此规则通常适用于您的系统,并且 make 内容更易于移植。

  • 这同样适用于代表系统程序的变量,如MakefileCCRMLEX等。通常,当程序有特殊的编译需求(这不是你的情况)

  • 当您为链接器指定选项 YACC 时,您在 makefile 的最后链接阶段出错,而它应该是 -o $(LDFLAGS) $(EXEC)(如果您将 $(LDFLAGS) -o $(EXEC)首先,因为一旦处理完所有目标文件,就会应用链接选项)

有了这个前提,这是为您的项目建议的 $(LDFLAGS)

Makefile

PACKAGE = Crypto_ivsk VERSION = 0.3 DISTNAME = $(PACKAGE)-$(VERSION) # don_t include system headers,because 1) you are never to # modify them and 2) because they are in a different # directory and make will not find them,and then it will # try to create them in the local dir,if you put any in a # dependency rule. headers = alea.h cripto.h main.h # This variable is understood by the C source compilation rule. CFLAGS = -Wall # targets holds the list of programs we are to build. targets = Crypt # toclean is a variable we initialize to the programs we are # to build and for each program we add all the objects we # compile of it. toclean = $(targets) # put here programs that must be built before linking Crypt,# e.g. program resource files,that are not used in the linking. In this case we have none. Crypt_deps = # Put here things that must be built before linking Crypt,# e.g. object files,that ***are*** used to link it. Crypt_objs = alea.o cripto.o main.o # Place for the libraries to build Crypt. Crypt_libs = -lgmp # For each program we add to toclean the object files that # compose it,so we can erase just doing $(RM) $(toclean) # Pay special attention to the += operator. toclean += $(Crypt_objs) # If we have more programs to build,add (prefixed) groups # of variables like the above. DISTFILES = $(Cryp_objs:.o=.c) Makefile $(headers) # all should be a .PHONY target. .PHONY: all clean dist all: $(targets) @echo Build finished at: `date` # repeat this for each file in $(targets) # $@ is the target of the rule Crypt: $(Crypt_deps) $(Crypt_objs) $(CC) $(LDFLAGS) $(Crypt_ldfl) -o $@ $(Crypt_objs) $(Crypt_libs) dist: $(DISTNAME).tar.gz # we link the files in $(DISTFILES) so we don_t consume # disk space with the copies. $(DISTNAME).tar.gz: $(DISTFILES) mkdir $(DISTNAME) ln $(DISTFILES) $(DISTNAME)/. tar cvfz $@ $(DISTNAME) $(RM) $(DISTNAME) # this cleans everything built. clean: $(RM) $(toclean) # this can be written as # alea.o cripto.o main.o: $(headers) # but in case they include different lists of header is # better to put it this way. alea.o: $(headers) cripto.o: $(headers) main.o: $(headers) 架构将为您提供更好的结果,并且可以轻松扩展以构建多个程序或库。

如您所见,目标文件的源代码没有编译规则。这是因为 Makefile 中有一个内置规则。 make(在 GNU RM 中)和 make 还有一个默认定义。

不要将 CC 重新定义为 CC,这一点很重要,因为如果您不强迫每个人都使用 gcc 构建您的程序,您的代码将更具可移植性。>

无论如何,如果您使用可选赋值,

gcc

相反,您将允许构建器在命令行中(或通过环境)为 CFLAGS ?= -O -Wall -std=c98 -pedantic 指定不同的值,并且您的脚本将更加灵活。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。