请教一个makefile头文件包含的问题

时间:2022-09-17 16:48:35
假设我当前的工程结构是这样的:
project folder----------------------------------------
makefile
main.c
public.h
--------sub folder------------------------------------
        sub.c
        sub.h

其中main.c需要包含sub目录下的sub.h,而sub.h又需要包含上一层目录(main.c所在目录)中的public.h,如果要保证sub.h中包含public.h不使用“../”这样的路径信息(也就是说包含的语句为#include "public.h"),这种情况下makefile要怎么写呢?

自己写了一下,总是会出现在编译main.c的时候找到了sub.h,然后再依据sub.h中的包含找public.h的时候找不到文件的情况。

9 个解决方案

#1



SRC_DIR = .
SRC_DIR_SUB = ./sub

OBJ_DIR = .

OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) \
$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c))

INCLUDE_DIR = -I. -I./sub

vpath %.h .
vpath %.h ./sub

vpath %.c .
vpath %.c ./sub

All: $(OBJS)
gcc -o main.out $(OBJS)

$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR_SUB)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

#2


引用 1 楼 zilaishuichina 的回复:

SRC_DIR = .
SRC_DIR_SUB = ./sub

OBJ_DIR = .

OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) \
$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c))

INCLUDE_DIR = -I. -I./sub

vpath %.h .
vpath %.h ./sub

vpath %.c .
vpath %.c ./sub

All: $(OBJS)
gcc -o main.out $(OBJS)

$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR_SUB)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@


如果我在包含里面加上了"-I.",会导致编译的时候出现这样的错误:
/usr/include/sys/cdefs.h:46:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:50:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:138:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:196:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:205:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:214:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:223:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:235:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:245:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:254:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:262:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:276:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:286:20: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:291:20: error: missing binary operator before token "("
。。。

#3


引用 2 楼 ziibin 的回复:
Quote: 引用 1 楼 zilaishuichina 的回复:


SRC_DIR = .
SRC_DIR_SUB = ./sub

OBJ_DIR = .

OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) \
$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c))

INCLUDE_DIR = -I. -I./sub

vpath %.h .
vpath %.h ./sub

vpath %.c .
vpath %.c ./sub

All: $(OBJS)
gcc -o main.out $(OBJS)

$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR_SUB)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@


如果我在包含里面加上了"-I.",会导致编译的时候出现这样的错误:
/usr/include/sys/cdefs.h:46:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:50:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:138:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:196:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:205:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:214:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:223:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:235:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:245:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:254:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:262:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:276:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:286:20: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:291:20: error: missing binary operator before token "("
。。。


这种错误通常是文件包含顺序的问题

可以每次尝试注释掉一部分代码,看看是哪个头文件, 或者是哪段代码导致的错误

你还可以把你的 public.h 放到sub 下面, 然后不加 -I., 看能不能编译

因为没有具体代码, 我只能尝试怎么去试,来找到问题

#4


可能是你使用的编辑器将makefile里面的tab字符替换成了若干个空格。

#5


我按你的目录结构给一个例子:
public.h:很简单的一个宏,求一个数的一半

#ifndef __PUBLIC_H__
#define __PUBLIC_H__

#define HALF(a) (a / 2)

#endif


sub.h:两数相减

#ifndef __SUB_H__
#define __SUB_H__

int sub(int a, int b);

#endif 


sub.c:实现对两数分别除以2之后再相减,用到public.h中的HALF宏

#include "sub.h"
#include "public.h"

int sub(int a, int b)
{
return HALF(a) - HALF(b);
}


main.c:调用sub,两数相减

#include <stdio.h>

#include "sub.h"

void main()
{
int a = 10;
int b = 20;
printf("%d\n", sub(a, b));
}


运行结果:
请教一个makefile头文件包含的问题

#6


引用 5 楼 zilaishuichina 的回复:
我按你的目录结构给一个例子:
public.h:很简单的一个宏,求一个数的一半

#ifndef __PUBLIC_H__
#define __PUBLIC_H__

#define HALF(a) (a / 2)

#endif


sub.h:两数相减

#ifndef __SUB_H__
#define __SUB_H__

int sub(int a, int b);

#endif 


sub.c:实现对两数分别除以2之后再相减,用到public.h中的HALF宏

#include "sub.h"
#include "public.h"

int sub(int a, int b)
{
return HALF(a) - HALF(b);
}


main.c:调用sub,两数相减

#include <stdio.h>

#include "sub.h"

void main()
{
int a = 10;
int b = 20;
printf("%d\n", sub(a, b));
}


运行结果:
请教一个makefile头文件包含的问题


是的,我自己写的简单的测试也是可以的,但是在工程里就是不行,工程里第一个文件就会编译出错,但我把这个文件和它的头文件拿到测试工程里面来又都是可以编译过去的,很奇怪。出错的文件并没有多少头文件依赖,因此可以比较确定是不会发生依赖顺序问题的。

#7


引用 4 楼 zhao4zhong1 的回复:
可能是你使用的编辑器将makefile里面的tab字符替换成了若干个空格。


仔细查看了,没有这种情况。而且我的问题出在不加"-I."的包含会有些头文件找不到包含,加了“-I.”之后又会出现上面说的编译错误,很头痛

#8


搞了大半天了,测了很多个文件慢慢摸清楚应该是最上面那一层里定义的一些头文件里定义的东西跟系统的头文件库里的东西有什么冲突导致的,再花些时间应该能摸清楚,谢谢两位了

#9


搜“跟我一起写makefile”?

#1



SRC_DIR = .
SRC_DIR_SUB = ./sub

OBJ_DIR = .

OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) \
$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c))

INCLUDE_DIR = -I. -I./sub

vpath %.h .
vpath %.h ./sub

vpath %.c .
vpath %.c ./sub

All: $(OBJS)
gcc -o main.out $(OBJS)

$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR_SUB)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

#2


引用 1 楼 zilaishuichina 的回复:

SRC_DIR = .
SRC_DIR_SUB = ./sub

OBJ_DIR = .

OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) \
$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c))

INCLUDE_DIR = -I. -I./sub

vpath %.h .
vpath %.h ./sub

vpath %.c .
vpath %.c ./sub

All: $(OBJS)
gcc -o main.out $(OBJS)

$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR_SUB)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@


如果我在包含里面加上了"-I.",会导致编译的时候出现这样的错误:
/usr/include/sys/cdefs.h:46:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:50:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:138:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:196:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:205:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:214:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:223:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:235:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:245:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:254:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:262:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:276:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:286:20: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:291:20: error: missing binary operator before token "("
。。。

#3


引用 2 楼 ziibin 的回复:
Quote: 引用 1 楼 zilaishuichina 的回复:


SRC_DIR = .
SRC_DIR_SUB = ./sub

OBJ_DIR = .

OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)) \
$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c))

INCLUDE_DIR = -I. -I./sub

vpath %.h .
vpath %.h ./sub

vpath %.c .
vpath %.c ./sub

All: $(OBJS)
gcc -o main.out $(OBJS)

$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@

$(patsubst $(SRC_DIR_SUB)/%.c, $(OBJ_DIR)/%.o, $(wildcard $(SRC_DIR_SUB)/*.c)): $(OBJ_DIR)/%.o: $(SRC_DIR_SUB)/%.c
gcc -c $< $(INCLUDE_DIR) -o $@


如果我在包含里面加上了"-I.",会导致编译的时候出现这样的错误:
/usr/include/sys/cdefs.h:46:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:50:44: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:138:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:196:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:205:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:214:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:223:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:235:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:245:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:254:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:262:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:276:19: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:286:20: error: missing binary operator before token "("
/usr/include/sys/cdefs.h:291:20: error: missing binary operator before token "("
。。。


这种错误通常是文件包含顺序的问题

可以每次尝试注释掉一部分代码,看看是哪个头文件, 或者是哪段代码导致的错误

你还可以把你的 public.h 放到sub 下面, 然后不加 -I., 看能不能编译

因为没有具体代码, 我只能尝试怎么去试,来找到问题

#4


可能是你使用的编辑器将makefile里面的tab字符替换成了若干个空格。

#5


我按你的目录结构给一个例子:
public.h:很简单的一个宏,求一个数的一半

#ifndef __PUBLIC_H__
#define __PUBLIC_H__

#define HALF(a) (a / 2)

#endif


sub.h:两数相减

#ifndef __SUB_H__
#define __SUB_H__

int sub(int a, int b);

#endif 


sub.c:实现对两数分别除以2之后再相减,用到public.h中的HALF宏

#include "sub.h"
#include "public.h"

int sub(int a, int b)
{
return HALF(a) - HALF(b);
}


main.c:调用sub,两数相减

#include <stdio.h>

#include "sub.h"

void main()
{
int a = 10;
int b = 20;
printf("%d\n", sub(a, b));
}


运行结果:
请教一个makefile头文件包含的问题

#6


引用 5 楼 zilaishuichina 的回复:
我按你的目录结构给一个例子:
public.h:很简单的一个宏,求一个数的一半

#ifndef __PUBLIC_H__
#define __PUBLIC_H__

#define HALF(a) (a / 2)

#endif


sub.h:两数相减

#ifndef __SUB_H__
#define __SUB_H__

int sub(int a, int b);

#endif 


sub.c:实现对两数分别除以2之后再相减,用到public.h中的HALF宏

#include "sub.h"
#include "public.h"

int sub(int a, int b)
{
return HALF(a) - HALF(b);
}


main.c:调用sub,两数相减

#include <stdio.h>

#include "sub.h"

void main()
{
int a = 10;
int b = 20;
printf("%d\n", sub(a, b));
}


运行结果:
请教一个makefile头文件包含的问题


是的,我自己写的简单的测试也是可以的,但是在工程里就是不行,工程里第一个文件就会编译出错,但我把这个文件和它的头文件拿到测试工程里面来又都是可以编译过去的,很奇怪。出错的文件并没有多少头文件依赖,因此可以比较确定是不会发生依赖顺序问题的。

#7


引用 4 楼 zhao4zhong1 的回复:
可能是你使用的编辑器将makefile里面的tab字符替换成了若干个空格。


仔细查看了,没有这种情况。而且我的问题出在不加"-I."的包含会有些头文件找不到包含,加了“-I.”之后又会出现上面说的编译错误,很头痛

#8


搞了大半天了,测了很多个文件慢慢摸清楚应该是最上面那一层里定义的一些头文件里定义的东西跟系统的头文件库里的东西有什么冲突导致的,再花些时间应该能摸清楚,谢谢两位了

#9


搜“跟我一起写makefile”?