我是个初学者。我想为Linux中的C程序创建一个makefile。
我的程序流程是,cmd.c调用在mainl.h中声明(但没有在其中定义)的cdirec(), dspecd(), sfile(), hfile()。
cdirec(), dspecd(), sfile() and hfile()分别在cdirec.c, dspecd.c, sfile.c和hfile.c中定义。
cdirec()反过来调用在subl.h中声明(但没有在其中定义)的mimx(), skloc(), fnc() and fcmp()
在mimx.c, skloc.c, fnc.c and fcmp.c中分别定义了mimx(), skloc(), fnc() and fcmp()。
我尝试创建了一个makefile,如下所示:
all: cmd.o cdir.o dspecd.o sfile.o hfile.o
cc cmd.o cdir.o dspecd.o sfile.o hfile.o -o sourceinfo
cmd.o: cmd.c mainl.h
cc -c cmd.c
cdir.o: cdirec.o mimx.o skloc.o fnc.o fcmp.o
cc cdirec.o mimx.o skloc.o fnc.o fcmp.o -o cdir.o
cdirec.o: cdirec.c mainl.h subl.h
cc -c cdirec.c
dspecd.o: dspecd.c mainl.h
cc -c dspecd.c
sfile.o: sfile.c mainl.h
cc -c sfile.c
hfile.o: hfile.c mainl.h
cc -c hfile.c
mimx.o: mimx.c subl.h
cc -c mimx.c
skloc.o: skloc.c subl.h
cc -c skloc.c
fnc.o: fnc.c subl.h
cc -c fnc.c
fcmp.o: fcmp.c subl.h
cc -c fcmp.c我不明白问题出在哪里。但是我在cdir.o中得到了一个未定义的对main的引用。cdirec.c如下所示:
#include<stdio.h>
#include "subl.h"
void cdirec()
{
printf("\nAll details of current directory is printed.\n");
mimx();
skloc();
fnc();
fcmp();
}我没有也不能在其中包含main,因为它只是一个函数声明文件。请指点一下。
答案:
all: cmd.o cdirec.o dspecd.o sfile.o hfile.o mimx.o skloc.o fnc.o fcmp.o
cc cmd.o cdirec.o dspecd.o sfile.o hfile.o mimx.o skloc.o fnc.o fcmp.o -o sourceinfo
cmd.o: cmd.c mainl.h
cc -c cmd.c
cdirec.o: cdirec.c mainl.h subl.h
cc -c cdirec.c
dspecd.o: dspecd.c mainl.h
cc -c dspecd.c
sfile.o: sfile.c mainl.h
cc -c sfile.c
hfile.o: hfile.c mainl.h
cc -c hfile.c
mimx.o: mimx.c subl.h
cc -c mimx.c
skloc.o: skloc.c subl.h
cc -c skloc.c
fnc.o: fnc.c subl.h
cc -c fnc.c
fcmp.o: fcmp.c subl.h
cc -c fcmp.c
clean:
rm -rf *.o sourceinfo发布于 2012-12-19 15:29:14
问题出现在这里:
cdir.o: cdirec.o mimx.o skloc.o fnc.o fcmp.o
cc cdirec.o mimx.o skloc.o fnc.o fcmp.o -o cdir.o这将告诉cc将这些给定的.o文件链接到一个名为cdir.o的可执行文件中。可执行文件需要main函数。但是看起来您并没有试图链接一个可执行文件;相反,您正在尝试将多个目标文件收集到单个目标文件中。
您不需要这样做;您只需在最终可执行文件中将所有目标文件链接在一起即可。如果你觉得在一行上处理这么多文件很麻烦,你可以定义一个Make变量;一个常用的名字是OBJS (“objects”的缩写):
OBJS = cdirec.o
OBJS += mimx.o
OBJS += skloc.o
OBJS += fnc.o
OBJS += fcmp.o
# ... etc
sourceinfo: ${OBJS}
cc ${OBJS} -o sourceinfo如果要将它们收集到单个文件中,可以构建一个库,然后将其链接到最终的可执行文件中。库是使用ar命令构建的;它的扩展名应该是.a
cdir.a: cdirec.o mimx.o skloc.o fnc.o fcmp.o
ar rcs cdir.a cdirec.o mimx.o skloc.o fnc.o fcmp.o然后在构建最终的可执行文件时将其链接起来:
cc cmd.o dspecd.o sfile.o hfile.o cdir.a -o sourceinfo顺便说一句,您可能会为每个源文件定义一个函数。这很快就会变得相当麻烦。通常将相关函数组合在同一个源文件中。有可能所有的cdirec(),mimx() skloc(),fnc()和fcmp()都应该定义在同一个文件中,这样它们就会产生一个单一的目标文件,尽管我不能肯定地说,如果没有看到你的实际代码。
Make中还有更多的特性可以让你的Makefile变得更简单。特别是,已经存在用于将.c文件编译为.o的隐式规则,因此您不需要所有这些规则,只需要对头文件的依赖项(因为这些规则不是隐式生成的):
cmd.o: mainl.h
cdirec.o: mainl.h subl.h
dspecd.o: mainl.h
sfile.o: mainl.h
hfile.o: mainl.h
mimx.o: subl.h
skloc.o: subl.h
fnc.o: subl.h
fcmp.o: subl.h实际上,您也可以自动生成这些依赖项,但这是一个bit more complicated,所以我在这里不再赘述。
发布于 2012-12-19 15:26:46
如果你不想创建一个静态/动态库,你需要在某个地方拥有main。使用main添加一些测试文件,并使用该文件进行编译。
此外,我认为没有必要明确提到所有这些*.o。制造商是足够聪明的,可以弄清楚这一点。
发布于 2012-12-19 15:11:45
不要费心手写依赖项。使用autotools或轻量级版本-- gcc -MM ./*。
https://stackoverflow.com/questions/13947175
复制相似问题