我是个初学者。我想为Linux中的C程序创建一个makefile。
我的程序流程是,
cmd.c调用cdirec(), dspecd(), sfile(), hfile()mainl.h中声明(但未在其中定义)
cdirec(), dspecd(), sfile() and hfile()分别在cdirec.c, dspecd.c, sfile.chfile.c中定义。
cdirec()依次调用在mimx(), skloc(), fnc() and fcmp()中声明的subl.h(但未在其中定义)
mimx(), skloc(), fnc() and fcmp()分别在mimx.c, skloc.c, fnc.c and fcmp.c中定义。
我试图创建一个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

最佳答案

问题出现在:

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,所以我不在这里讨论它。

关于c - Linux中的C程序makefile,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13947175/

10-11 16:18