我是初学者。我想为 Linux 中的 C 程序创建一个 makefile。
我的程序流程是,
cmd.c
电话 cdirec(), dspecd(), sfile(), hfile()
在 mainl.h
中声明(但未在其中定义)
cdirec(), dspecd(), sfile() and hfile()
在 cdirec.c, dspecd.c, sfile.c
中定义和 hfile.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 的 undefined reference . 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
(“对象”的缩写):
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 , 所以我不会在这里讨论。
关于Linux 中的 C 程序生成文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13947175/