首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux下的C程序makefile

问linux下的C程序makefile
EN

Stack Overflow用户
提问于 2012-12-19 15:06:21
回答 3查看 400关注 0票数 1

我是个初学者。我想为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,如下所示:

代码语言:javascript
复制
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如下所示:

代码语言:javascript
复制
#include<stdio.h>
#include "subl.h"

void cdirec()
{
printf("\nAll details of current directory is printed.\n");
mimx();
skloc();
fnc();
fcmp();
}

我没有也不能在其中包含main,因为它只是一个函数声明文件。请指点一下。

答案:

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-19 15:29:14

问题出现在这里:

代码语言:javascript
复制
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”的缩写):

代码语言:javascript
复制
OBJS  = cdirec.o 
OBJS += mimx.o 
OBJS += skloc.o 
OBJS += fnc.o 
OBJS += fcmp.o 
# ... etc

sourceinfo: ${OBJS}
    cc ${OBJS} -o sourceinfo

如果要将它们收集到单个文件中,可以构建一个库,然后将其链接到最终的可执行文件中。库是使用ar命令构建的;它的扩展名应该是.a

代码语言:javascript
复制
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

然后在构建最终的可执行文件时将其链接起来:

代码语言:javascript
复制
cc cmd.o dspecd.o sfile.o hfile.o cdir.a -o sourceinfo

顺便说一句,您可能会为每个源文件定义一个函数。这很快就会变得相当麻烦。通常将相关函数组合在同一个源文件中。有可能所有的cdirec(),mimx() skloc(),fnc()和fcmp()都应该定义在同一个文件中,这样它们就会产生一个单一的目标文件,尽管我不能肯定地说,如果没有看到你的实际代码。

Make中还有更多的特性可以让你的Makefile变得更简单。特别是,已经存在用于将.c文件编译为.o的隐式规则,因此您不需要所有这些规则,只需要对头文件的依赖项(因为这些规则不是隐式生成的):

代码语言:javascript
复制
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,所以我在这里不再赘述。

票数 3
EN

Stack Overflow用户

发布于 2012-12-19 15:26:46

如果你不想创建一个静态/动态库,你需要在某个地方拥有main。使用main添加一些测试文件,并使用该文件进行编译。

此外,我认为没有必要明确提到所有这些*.o。制造商是足够聪明的,可以弄清楚这一点。

票数 1
EN

Stack Overflow用户

发布于 2012-12-19 15:11:45

不要费心手写依赖项。使用autotools或轻量级版本-- gcc -MM ./*。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13947175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档