0

我需要帮助编写一个生成文件,该文件创建两个独立的可执行文件,这些可执行文件依赖于一个公共文件。所以,我有三个源文件:Master.c Common.c Worker.c,以及三个对应的头文件。现在,Master.c 包括 Master.h 和 Common.h。同样,Worker.c 包括 Worker.h 和 Common.h。我想使用相同的 makefile 创建两个可执行文件,即 Master 和 Worker。我有以下 makefile,但它无法正常运行,因为对于 Common.h 中声明的每个全局变量,当我键入make时,我会收到错误“Multiple declarations”。请注意,我在所有头文件中都使用了#indef、#define 和#endif。

CC = gcc
CFLAGS= -g -I -pthread -lpthread -std=c99
DEPS = Common.h
OBJ1 = Master.o Common.o 
OBJ2 = Worker.o Common.o 

%.o: %.c $(DEPS)
     $(CC) -c -o $@ $< $(CFLAGS)

all: Master Worker

Master: $(OBJ1)
     gcc -o $@ $^ $(CFLAGS)

Worker: $(OBJ2)
     gcc -o $@ $^ $(CFLAGS)

clean:
        rm -f *.o

你能帮忙吗

4

2 回答 2

0

不要把全局变量的定义放到头文件中;相反,将它们放在源文件之一中,并且只在标头中声明变量:

常见的.h:

extern int foo;    /* declaration only */

Common.c:

#include "Common.h"

int foo;           /* definition */

否则在多个翻译单元中包含标题违反了单一定义规则。

于 2013-10-22T20:28:58.120 回答
0

上面的makefile完美吗?

不,我可以看到几个问题,如果您解决它们,那么它将是“最先进的”:

  1. (一个错误)所有目标至少应该依赖于$(MAKEFILE)

    MAKEFILE := $(lastword $(MAKEFILE_LIST))

    然后,您还需要过滤$^配方中的:$(filter %.o, $^),无论如何这是一个好习惯

  2. 使用:=代替,它更有效,并且通常使代码中的逻辑更易于理解,除非有必要=,否则应始终默认使用=

  3. 您正在定义然后CCgcc使用它而是使用gcc

  4. 考虑自动生成依赖项(grep 手册),在这种小情况下可能不需要,但对于更大的情况,您将需要它 - 现在有很好的gcc支持

  5. 使用“罐装食谱”(grep the manual)作为重复食谱

  6. .PHONY: all clean

  7. clean不会删除所有内容

于 2013-10-22T23:49:26.573 回答