使用 Makefile 重新定义问题

Posted

技术标签:

【中文标题】使用 Makefile 重新定义问题【英文标题】:Redefinition Issue using Makefile 【发布时间】:2013-03-01 23:37:55 【问题描述】:

ma​​in.c:

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

int main(void)


    return(0);
 // end main

support.c:

#include "proto.h"

\\ only function defintions

proto.h:

#ifndef proto
#define proto
double PI = 3.14159;
int LOOP_LIMIT = 90;

#endif

制作文件:

main: main.o  support.o 
    gcc -lm -o main main.o support.o
main.o: main.c proto.h
    gcc -c main.c
support.o: support.c proto.h
    gcc -c support.c

每当我使用上述定义的文件运行 makefile 时,我总是会遇到多重定义错误,尽管有条件编译。

我不确定这里发生了什么以及如何解决问题。

错误信息是:

multiple definition of `PI'
multiple definition of `LOOP_LIMIT'

【问题讨论】:

包含实际的错误信息。 【参考方案1】:

您不能在从多个编译单元包含的标头中定义变量。 PILOOP_LIMIT 最终都出现在 main.osupport.o 中,因此会出现链接器错误。正确的做法是在标题中声明它们extern

proto.h

#ifndef proto
#define proto
extern double PI;
extern int LOOP_LIMIT;

#endif

然后在一个且只有一个 .c 文件中定义它们:

support.c

#include "proto.h"

double PI = 3.14159;
int LOOP_LIMIT = 90;

\\ only function defintions

顺便说一句,看起来这些家伙可能是常量而不是变量,所以要么将它们声明并定义为const,要么将它们写为预处理器定义:

#define PI 3.14159
#define LOOP_LIMIT 90

有了这些,您还可以避免链接问题。

【讨论】:

宾果游戏,这似乎可以解决问题 :) 只需一个注释,为什么 #define 会起作用?是否会尝试重新定义相同的东西,就像变量的多个定义一样。 没有。 #define 几乎像复制/粘贴操作一样工作,由预处理器处理,甚至在编译器看到代码之前。所以如果你写double circumference = PI * diameter;,编译器会看到double circumference = 3.14159 * diameter;。实际符号 PI 根本不会出现在编译的目标文件中。

以上是关于使用 Makefile 重新定义问题的主要内容,如果未能解决你的问题,请参考以下文章

makefile

MakeFile 文件的使用

避免使用 makefile 进行不必要的重新编译

重建后的Makefile重新编译代码需要很多时间

如何使用带有 gprof 的 makefile 重新编译依赖项?

如何根据vs工程构建makefile文件