简体   繁体   English

如何在C中处理包含带有makefile的头文件的头文件?

[英]How do you handle headers that include headers with a makefile in C?

Suppose you have a file called file.c. 假设您有一个名为file.c的文件。

  • file.c includes header1.h file.c包括header1.h
  • header1.h includes header2.h header1.h包括header2.h

Here's what I have for the makefile: 这是我对makefile的看法:

file.x: file.o
        -gcc file.o -o file.x

file.o: file.c header1.h header2.h
        -gcc file.c header1.h header2.h

I am confused about how to handle when header2.h includes header1.h. 当header2.h包含header1.h时,我对如何处理感到困惑。

Is this line redundant? 这条线是多余的吗? Or is it good style to show dependencies? 或者是显示依赖关系的好方式?

file.c header1.h header2.h

Update: I apologize for the confusion. 更新:我为这种困惑道歉。 I have reverted the edits I made to the question. 我已经恢复了我对这个问题所做的编辑。 The current makefile is the one I posted in the original question that Jonathan's answer refers to. 当前的makefile是我在Jonathan的回答所引用的原始问题中发布的。

The original version of the question contained the following lines in the makefile : 问题的原始版本包含makefile中的以下行:

file.o: file.c header1.h header2.h
        -gcc file.c header1.h header2.h

My answer addresses the original version of the question, before it got fixed up. 我的答案在修复之前解决了问题的原始版本。

Note that the compilation line generates the executable a.out unless the compiler objects to compiling the header files. 请注意,编译行生成可执行文件a.out除非编译器对象编译头文件。 You should have -c in the command line. 你应该在命令行中有-c


A couple of issues: 几个问题:

  1. In a makefile , when does the object file need rebuilding? makefile ,目标文件何时需要重建?

    Answer: when the source file or one of the headers it includes changes. 答案:当源文件或其中包含的一个标题发生变化时。

    Subsidiary Q: what does this dependency line mean: 子公司Q:这个依赖关系是什么意思:

     file.o: file.c header1.h header2.h 

    Subsidiary A: file.o needs rebuilding if the source file or one of the headers it includes changes. 子公司A: file.o需要重建,如果源文件或其中包含的一个标题更改。

  2. If you stipulate: header1.h depends on header2.h , what's going to happen to header1.h when you change header2.h ? 如果你规定: header1.h依赖于header2.h ,当你改变header2.hheader1.h会发生什么?

    Answer: nothing. 答:没事。 You don't compile header1.h per se. 你不编译header1.h本身。 It is the object files that change. 它是目标文件的变化。

  3. If you stipulate the file.c depends on header1.h or header2.h or both, what's going to happen to file.c when you change one of the headers? 如果规定了file.c取决于header1.hheader2.h或两个,有什么事情发生到file.c当您更改其中一个标题?

    Answer: nothing again. 答:没有了。 You don't change file.c ; 你不要改变file.c ; you recompile the object file again. 您再次重新编译目标文件。

So, the dependency portion of your object file rule is fine (within limitations related to automatic dependency generation). 因此,对象文件规则的依赖部分很好(在与自动依赖关系生成相关的限制内)。 There is no point in a rule that says the source file depends on the headers; 规则中没有必要说源文件依赖于头文件; in fact, the source file does not directly depend on the headers. 实际上,源文件并不直接依赖于头文件。 (It indirectly depends on them in that if the header contents change so that what was valid code is no longer valid code, nothing will compile until the source is fixed. But that is slightly off the subject.) (它间接依赖于它们,如果标题内容发生变化,那么有效代码不再是有效代码,在修复源代码之前不会编译任何东西。但这稍微偏离了主题。)

Hard-coding the dependencies is problematic; 对依赖项进行硬编码是有问题的; they change. 他们改变了。 On the other hand, generating the dependencies automatically is fiddly. 另一方面,自动生成依赖关系是繁琐的。 There are GCC options (like -M , -MM , -MF , -MG , -MP , -MQ , -MD , -MMD , -MT , -H — such an abundance of options tells you there are issues here!) to assist, and GNU make has 'conditional inclusion' to include dependency files if they exist and not witter if they don't. 有GCC选项(如-M-MM-MF-MG-MP-MQ-MD-MMD-MT-H -的选项,例如丰富的告诉你,有问题在这里!)到协助,GNU make有'条件包含',如果它们存在则包含依赖文件,如果不存在则不包括witter。 These can help. 这些可以帮助你。 Look up makedepend , mkdep and related commands for other ways of automating that. 查找makedependmkdep和相关命令以获得其他自动化方法。


Ignoring automatic dependency generation, your makefile might read: 忽略自动依赖关系生成,您的makefile可能会读取:

FILES.o = file.o

file.x: ${FILES.o}
        ${CC} -o $@ ${CFLAGS} ${FILES.o} 

file.o: file.c header1.h header2.h

make will provide a command to compile file.c into file.o . make将提供将file.c编译到file.o的命令。

When your program grows to use other.o too, you simply add other.o to the macro FILES.o (that's why it is a plural name). 当你的程序增长到使用other.o ,你只需将other.o添加到宏FILES.o (这就是为什么它是复数名称)。 You might add dependency information too. 您也可以添加依赖项信息。 If you need libraries too, then you can add options to the link line: 如果您也需要库,则可以向链接行添加选项:

LDFLAGS = -L/usr/local/lib
LDLIBS  = -llocal

FILES.o = file.o other1.o other2.o

file.x: ${FILES.o}
        ${CC} -o $@ ${CFLAGS} ${FILES.o} ${LDFLAGS} ${LDLIBS}

file.o: file.c header1.h header2.h

Note that the libraries should go after the object files. 请注意,库应该在目标文件之后。 Listing libraries before object files is apt to lead to link-time failures on other platforms, to the irritation of those trying to build your software. 在目标文件之前列出库容易导致其他平台上的链接时失败,以及那些试图构建软件的人的烦恼。

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

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