简体   繁体   English

C程序makefile在linux中

[英]C Program makefile in linux

I'm a beginner. 我是初学者。 I'd like to create a makefile for C programs in Linux. 我想在Linux中为C程序创建一个makefile。

My program flow is, cmd.c calls cdirec(), dspecd(), sfile(), hfile() which are declared in mainl.h (but not defined in it) 我的程序流是, cmd.c调用cdirec(), dspecd(), sfile(), hfile()mainl.h中声明(但未在其中定义)

cdirec(), dspecd(), sfile() and hfile() are defined in cdirec.c, dspecd.c, sfile.c and hfile.c respectively. cdirec(), dspecd(), sfile() and hfile()分别在cdirec.c, dspecd.c, sfile.chfile.c中定义。

cdirec() in turn calls mimx(), skloc(), fnc() and fcmp() which are declared in subl.h (but not defined in it) cdirec()又调用mimx(), skloc(), fnc() and fcmp()这是在宣告subl.h (但它没有定义)

mimx(), skloc(), fnc() and fcmp() are defined in mimx.c, skloc.c, fnc.c and fcmp.c respectively. mimx(), skloc(), fnc() and fcmp()分别在mimx.c, skloc.c, fnc.c and fcmp.c中定义。

I tried to create a makefile as follows, 我试着创建一个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

I don't understand what the problem is. 我不明白问题是什么。 But I get an undefined reference to main in cdir.o . 但是我在cdir.o得到了一个未定义的main cdir.o cdirec.c looks like this, cdirec.c看起来像这样,

#include<stdio.h>
#include "subl.h"

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

I don't and can't have a main in it, as it is just a function declaration file. 我没有也不能有一个main,因为它只是一个函数声明文件。 Kindly guide me. 请指导我。

ANSWER: 回答:

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

The problem occurs here: 问题出现在这里:

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

This is telling cc to link these given .o files into an executable named cdir.o . 这告诉cc将这些给定的.o文件链接到名为cdir.o的可执行文件中。 An executable needs a main function. 可执行文件需要main函数。 But it looks like you're not trying to link an executable; 但看起来你并没有试图链接可执行文件; instead, you're trying to collect multiple object files into a single object file. 相反,您正在尝试将多个目标文件收集到单个目标文件中。

You don't need to do this; 你不需要这样做; you can just link all of your object files together in the final executable. 您可以在最终的可执行文件中将所有目标文件链接在一起。 If you just find it cumbersome to deal with that many files on one line, you can define a Make variable; 如果你发现在一行上处理那么多文件很麻烦,你可以定义一个Make变量; a common name is OBJS (short for "objects"): 一个通用名称是OBJS (“对象”的缩写):

OBJS  = cdirec.o 
OBJS += mimx.o 
OBJS += skloc.o 
OBJS += fnc.o 
OBJS += fcmp.o 
# ... etc

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

If you want to collect them into a single file, you can build a library, and then link that into the final executable. 如果要将它们收集到一个文件中,可以构建一个库,然后将其链接到最终的可执行文件中。 A library is built with the ar command; 使用ar命令构建库; it should have the extension .a : 它应该有扩展名.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

You then link that when building your final executable: 然后在构建最终可执行文件时链接它:

cc cmd.o dspecd.o sfile.o hfile.o cdir.a -o sourceinfo

As an aside on your organization, it looks like you might be defining one function per source file. 作为您组织的一部分,看起来您可能正在为每个源文件定义一个函数。 That gets pretty cumbersome pretty quick. 这非常麻烦很快。 You usually group related functions together in the same source file. 您通常将相关功能组合在同一源文件中。 It's possible that all of cdirec() , mimx() skloc() , fnc() and fcmp() should be defined in the same file, so that they produce a single object file, though I can't say for sure without seeing your actual code. 有可能所有的cdirec()mimx() skloc()fnc()fcmp()应该在同一个文件中定义,这样它们就可以产生一个单独的目标文件,但我不能肯定地说你的实际代码。

There are also further features in Make that would make your Makefile much simpler. Make中还有其他功能可以使Makefile更简单。 In particular, there are already implicit rules for compiling .c files into .o , so you don't need all those rules, just the dependencies on the headers (because those aren't generated implicitly): 特别是,已经存在将.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

You can actually generate these dependencies automatically as well, but that's a bit more complicated , so I won't go into it here. 你实际上也可以自动生成这些依赖项,但这有点复杂 ,所以我不会在这里讨论它。

If you are not trying to create a static/dynamic library, you need to have main somewhere. 如果您不想创建静态/动态库,则需要将main设置为某个位置。 Add some test file with main, and compile with that file. 使用main添加一些测试文件,然后使用该文件进行编译。
Also I don't think any need for all those *.o to be mentioned explicitly. 此外,我认为没有必要明确提及所有* .o。 The Make is smart enough to figure that out. Make非常聪明,可以解决这个问题。

Do not bother with hand writing of dependencies. 不要打扰依赖的手写。 Use autotools or light version -- gcc -MM ./* . 使用autotools或light version - gcc -MM ./*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM