【问题标题】:Find all header files in all sub-directories查找所有子目录下的所有头文件
【发布时间】:2024-04-18 21:00:04
【问题描述】:

我正在尝试在我的src 文件夹中的任何源文件中使用我的include 文件夹中的任何标题。现在,我正在使用"#include ../../include/subfolder/file.h"#include "../include/otherfile.h" 来访问我的头文件,但这非常冗长,而且每当我进行目录重组时,我都必须返回并更改对受影响头文件的每个引用。我希望能够从任何源文件中执行#include "file.h",但我似乎做不到。由于某种原因,执行-Iinclude-Iinclude/subfolder 中找不到标题。将我的 include 语句更改为 #include <file.h> 也不起作用。我该怎么做才能解决这个问题?

我的项目布局如下所示:

Makefile

include
    subfolder
        file.h
    otherfile.h

src
    subfolder
        file.c
    otherfile.c

我的 Makefile 如下所示:

TARGET = program
LIBS = -llibs
CC = gcc
CFLAGS = -Wall -g -Iinclude/

.PHONY: default all clean

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.c, %.o, $(shell find . -name '*.c'))
HEADERS = $(shell find . -name '*.h')

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

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    find . -type f -name '*.o' -exec rm {} +
    find . -type f -name $(TARGET) -exec rm {} +

【问题讨论】:

    标签: c++ c makefile


    【解决方案1】:

    简单,只需使用

    #include <myheader.h>
    

    并通过-I开关将相关目录传递给编译器。

    例如,如果 myheader.hinclude/subfolder 中,那么,

    $(CC) -Iinclude/subfolder
    

    会起作用的。

    请注意,您还必须在-I 参数中包含子文件夹,因为只扫描*目录的标题。

    【讨论】:

    • 没有找到所有子目录下的所有头文件。我必须为每个子文件夹做-Iinclude/subfolder
    • @MuhammadYojer 好吧,这就是你必须做的。另一种方法是将文件夹放在#include 语句本身中。和#include "subfolder/file.h" 一样,并且只使用-Iinclude 作为编译器开关。
    • @NikosC。没有其他选择吗?
    • 是的,使用完整的全功能构建系统,例如autotoolscmake。这样您就不必担心自己将值传递给编译器。而且更改和修复它们要容易得多(更易于维护)。
    • @MuhammadYojer 好吧,如果您手动编写 makefile,您也必须手动处理这些内容。另一种方法是使用像 Meson 或 CMake 这样的构建系统,它们会自动完成大部分工作。您仍然需要告诉他们标头所在的目录,但他们会处理编译器标志。
    【解决方案2】:

    您可以简单地自动生成包含目录标志:

     INC_DIRS := $(shell find include -type d)
     C_INC_FLAGS := $(addprefix -I,$(INC_DIRS))
    
     %.o: %.c $(HEADERS)
        $(CC) $(CFLAGS) $(C_INC_FLAGS) -c $< -o $@
    

    请注意,大多数系统都有最大行长度(通常约为 64k),因此如果您有很多目录,您可能不得不担心超出最大行长度(此时您将目录通过管道传输到文件并包含@file...)

    此外,如果您通过 make 规则在包含目录中自动生成新目录,这将不起作用,因为当您第一次填充 INC_DIRS 时,这些目录将不存在。

    【讨论】:

      最近更新 更多