C语言 如何为GMP项目制作Makefile ?



我有一个问题,而试图生成一个Makefile为我的C项目。它包含三个文件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

但是当我输入"make"在我的shell中出现以下错误:没有制定目标gmp的规则。o STOP"

我的水平很低,对此我无能为力,有人能帮帮我吗?

谢谢你:)

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

你已经把gmp.h作为一个包含在这个目录中,make没有找到(我想你指的是GNU多精度库包含文件),这是一个文件,你不应该把你的$(HEADER)变量。为什么?

非常简单,因为您永远不会更改该文件,因此依赖于它的文件必须重新编译,因为它是一个系统文件。

我给你一些建议,以避免将来出现问题。

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

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

  • 同样适用于表示系统程序的变量,如CCRMLEXYACC等。通常,当程序有特殊的编译需要时(这不是您的情况),人们会重新定义它

  • 当你指定选项-o $(LDFLAGS) $(EXEC)到链接器时,你在makefile的最后链接阶段有一个错误,而它应该是$(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中有一个内置规则。RM(在GNUmake中)和CC也有默认定义。

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

在任何情况下,如果使用可选赋值,

CFLAGS       ?= -O -Wall -std=c98 -pedantic

,然后您将允许构建器在命令行(或通过环境)中为CFLAGS指定不同的值,您的脚本将更加灵活。

最新更新