[英]How can i make a Makefile for a GMP project
I have a problem while attempting to generate a Makefile for my C project.我在尝试为我的 C 项目生成 Makefile 时遇到问题。 It contains 3 files alea.c crypto.c and main.c.
它包含 3 个文件 alea.c crypto.c 和 main.c。 Here is my Makefile:
这是我的 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
but when i type "make" in my shell the following error appears: "no rule to make target gmp.h needed by alea.o STOP"但是当我在我的 shell 中键入“make”时,会出现以下错误:“no rule to make target gmp.h required by alea.o STOP”
I can't do anything about this with my low level, can someone please help me?我的水平很低,对此我无能为力,有人可以帮助我吗?
Thank you:)谢谢:)
You have said that all your %.o
files depend of the file of same name with extension .c
and from the header files they include.您已经说过,您所有的
%.o
文件都依赖于扩展名为.c
的同名文件以及它们包含的 header 文件。
You have put gmp.h
as an include in this directory that make
does not find (I imagine you refer to the GNU Multiprecision library include file) which is a file you should not put in your $(HEADER)
variable.您已将
gmp.h
作为包含在此目录中的make
找不到(我想您指的是 GNU Multiprecision 库包含文件),这是一个您不应该放入$(HEADER)
变量的文件。 Why?为什么?
Very simple, because you are never going to change that file, so the files dependent of it have to be recompiled, as it is a system file.非常简单,因为您永远不会更改该文件,因此必须重新编译依赖于它的文件,因为它是系统文件。
There are some recommendations I'm givin to you to avoid problems in the future.我给你一些建议,以避免将来出现问题。
Don't define variables you are not going to use, or variables you don't plan to change.不要定义你不会使用的变量,或者你不打算改变的变量。 Variables work in
make
as constants.变量在
make
中作为常量工作。 You define them in a single place, but you repeat them here and there on your Makefile
.您在一个地方定义它们,但您在
Makefile
上到处重复它们。 These are the candidates to use.这些是要使用的候选人。
make
has a bunch of already defined rules (indeed, the rule to build an object .o
file from a .c
file is already included in almost any of the make
implementations actually in use. So you have better to respect the already installed rule, than provide you yours, because this rule is normally adapted to your system, and the Makefile
contents is more portable. make
有一堆已经定义的规则(实际上,从.c
文件构建 object .o
文件的规则已经包含在几乎所有实际使用的make
实现中。所以你最好尊重已经安装的规则,而不是为您提供您的,因为此规则通常适用于您的系统,并且Makefile
的内容更便携。
The same applies to variables that represent system programs, like CC
, RM
, LEX
, YACC
, etc. Normally, one redefines it when the program has special compilation needs (which is not your case)这同样适用于表示系统程序的变量,如
CC
、 RM
、 LEX
、 YACC
等。通常,当程序有特殊编译需求时会重新定义它(这不是你的情况)
You have an error in the final link phase of your makefile as you specify options -o $(LDFLAGS) $(EXEC)
to the linker, while it should be $(LDFLAGS) -o $(EXEC)
(better if you put $(LDFLAGS)
first, as the linking options will be applied once all object files have been processed)您在 makefile 的最终链接阶段出现错误,因为您将选项
-o $(LDFLAGS) $(EXEC)
指定给 linker,而它应该是$(LDFLAGS) -o $(EXEC)
(如果你放$(LDFLAGS)
首先,因为一旦处理了所有 object 文件,将应用链接选项)
With this premises, this is the suggested Makefile
for your project.有了这个前提,这是为您的项目建议的
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)
This Makefile
schema will give you better results, and it is easily extensible to build several programs or libraries.此
Makefile
架构将为您提供更好的结果,并且可以轻松扩展构建多个程序或库。
As you see, there's no compilation rule for the sources to object files.如您所见,object 文件的源代码没有编译规则。 This is because there's a builtin rule in
make
.这是因为
make
中有一个内置规则。 There's also a default definition for RM
(in GNU make
) and for CC
. RM
(在 GNU make
中)和CC
也有一个默认定义。
It's important that you don't redefine CC
to gcc
, as your code will be more portable if you don't force everybody to build your program with gcc
.重要的是不要将
CC
重新定义为gcc
,因为如果您不强迫每个人都使用gcc
构建程序,您的代码将更具可移植性。
In any case, if you use optional assignments,无论如何,如果您使用可选分配,
CFLAGS ?= -O -Wall -std=c98 -pedantic
instead, then you'll allow the builder to specify a different value for CFLAGS
in the command line (or through the environment) and your script will be more flexible.相反,您将允许构建器在命令行中(或通过环境)为
CFLAGS
指定不同的值,并且您的脚本将更加灵活。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.