c - 如何为 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”时,会出现以下错误:“no rule to make target gmp.h required by alea.o STOP”
我的水平很低,对此我无能为力,有人可以帮助我吗?
谢谢 :)
解决方案
您已经说过您的所有%.o
文件都依赖于具有扩展名的同名文件.c
以及它们包含的头文件。
您已将gmp.h
其作为包含放入此目录中,make
但找不到(我想您指的是 GNU Multiprecision 库包含文件),这是您不应该放入$(HEADER)
变量中的文件。为什么?
非常简单,因为您永远不会更改该文件,因此必须重新编译依赖于它的文件,因为它是系统文件。
我给你一些建议,以避免将来出现问题。
不要定义你不会使用的变量,或者你不打算改变的变量。变量
make
作为常量起作用。你在一个地方定义它们,但是你在你的Makefile
. 这些是要使用的候选人。make
有一堆已经定义的规则(事实上,.o
从文件构建目标文件的规则.c
已经包含在几乎所有make
实际使用的实现中。所以你最好尊重已经安装的规则,而不是提供你的规则,因为此规则通常适用于您的系统,并且Makefile
内容更便携。这同样适用于表示系统程序的变量,如
CC
,RM
,LEX
,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
. RM
(在 GNU 中)make
和CC
.
重要的是不要重新定义CC
为gcc
,因为如果您不强迫每个人都使用gcc
.
无论如何,如果您使用可选分配,
CFLAGS ?= -O -Wall -std=c98 -pedantic
相反,您将允许构建器在命令行中(或通过环境)指定不同的值CFLAGS
,您的脚本将更加灵活。
推荐阅读
- html - 如何从谷歌图表编辑器打印 png 图表?
- python-3.x - Python从同一行的列表中返回特定项目
- ios - 为 UIButton 设置用户定义的属性时崩溃
- python - 如何使用数组查找向量化函数
- hybris - 查询hyris中所有已发布的促销活动
- homebrew - 尝试使用 brew 安装 java11 时出错
- sql - SQL 子查询根据另一列的最大平均值显示一列的分组值
- kubernetes - Helm:values.yaml 中的变量
- react-native - Android 依赖 'com.google.android.gms:play-services-base' 的编译(16.0.1)和运行时(17.0.0)类路径有不同的版本
- android - 在高阶函数中使用 lambda 时不能删除重复项