使用另一个文件中的方法而不包括它

时间:2014-11-19 15:19:36

标签: c makefile

我有两个.c文件,我在makefile上编译。

foo.c的:

void foo()
{
    printf("this is foo");
}

main.c中:

#include  <stdio.h>

int main()
{
    printf("this is main\n");
    foo();
}

makefile看起来像这样:

all: main.o foo.o
    gcc -o prog foo.o main.o

main.o: main.c
    gcc -c main.c

foo.o: foo.c
    gcc -c foo.c

所以问题是: 如何在没有我的情况下使用printf()包括stdio.h以及main.c如何在没有我的情况下使用方法foo()包括foo.c。

我的猜测/研究是makefile作为链接器工作。但我没有证明这一点,并希望了解这是如何工作的。

如果我误解了某些事情,请纠正我。

3 个答案:

答案 0 :(得分:0)

makefile不是链接器。它是输入。 makefile只是告诉make在什么条件下执行什么命令。

您的all目标在链接/链接器模式gcc中正在运行gcc -o prog foo.o main.o

foo.omain.o目标在编译模式gcc中运行gcc -c foo.c的方式相同。

对于记录,您可以将两个.o目标合并到

%.o: %.c
        gcc -c $^

实际上,它已经是make中的默认规则,因此您根本不需要包含该规则。

此外,您的all目标不遵循投注习惯,因为它会生成与目标名称不匹配的文件。所以你应该使用

all: prog

prog: main.o foo.o
        gcc -o prog foo.o main.o

代替。

虽然默认情况下会再次出现,因此您的整个makefile可以替换为

all: prog

prog: main.o foo.o

你应该得到相同的结果。

答案 1 :(得分:0)

在makefile中,您可以强制编译器包含<stdio>或任何其他标题:

来自文档:

  

-include file

     
    

处理文件,好像#include&#34; file&#34;出现了作为第一行     主要源文件。但是,搜索文件的第一个目录是     预处理器的工作目录而不是目录     包含主要源文件。如果在那里找不到,则搜索它     因为#include&#34; ...&#34;的其余部分搜索链正常。如果     给出了多个包含选项,文件包含在     命令它们出现在命令行中。

  

只需在makefile中的GCC /编译器命令行中添加-include filename.h

答案 2 :(得分:0)

在编译阶段,编译器会根据原型检查函数调用。任何缺少原型的函数都假定返回int并接受任意数量的参数。

如果您调高警告级别,gcc会在原型丢失时发出警告。您应该添加-Wall,还可以添加-pedantic以获取编译器认为可疑的其他内容的诊断信息。

如果编译步骤成功,编译器将创建一个包含已编译代码和2个引用表的目标文件。第一个表是导出表。它包含从目标文件导出的所有函数和变量的名称。 第二个表是导入表。它包含所引用的所有函数和变量的列表,但缺少声明的位置。

在你的情况下,我们有:

<强> foo.o的:

导出:

foo

导入:

printf

<强> main.o

导出:

main

导入:

printf
foo

在链接器阶段,链接器将获取导入和导出列表并匹配它们。除了在命令行中指定的目标文件和库之外,链接器还将自动与libc链接,libc包含c语言定义的所有函数。