有没有办法为C文件生成包含映射?

时间:2017-03-08 01:53:38

标签: c header-files

假设:

  • 包含多个包含头文件的C文件
  • 一堆包含文件搜索文件夹

有没有办法为C文件生成某种 include map

虽然IDE可以有时帮助找到头文件中符号的定义/声明。但我认为 include map 可以让我更好地了解当项目变得复杂时这些文件是如何相关的。并确定诸如循环包含等问题。

ADD 1

类似的线程,但没有多大帮助。

  • 构建时,它仅在“输出”窗口中的文本中生成包含层次结构。
  • 它仅适用于本机VC ++项目。不适用于NMAKE C项目。

Displaying the #include hierarchy for a C++ file in Visual Studio

ADD 2

我刚试过上面提到的Include Manager帖子。虽然不是免费的,但它并不昂贵且非常适合我的情景。

2 个答案:

答案 0 :(得分:2)

不确定这是否是您所追求的,但我很好奇这是什么样的图表,所以我把它扔在了一起。这有点乱,但对于丢弃的脚本是可行的:

#!/bin/bash

INCLUDE_DIRS=()

# Add any include dirs here
# INCLUDE_DIRS+=("/usr/include")

# If you want to add flags for some pkg-config modules (space
# separated)
PKG_CONFIG_PKGS=""

FOLLOW_SYS_INCLUDES=y



while read dir; do
    dir="$(readlink -f "${dir}")"
    for d in "${INCLUDE_DIRS[@]}"; do
    if [ "${dir}" = "${d}" ]; then
        continue
    fi
    done

    INCLUDE_DIRS+=("${dir}")
done < <(echo | cc -Wp,-v -x c - -fsyntax-only 2>&1 | grep '^ ' | cut -b2-)

PROCESSED=()

while read flag; do
    if [ -n "${flag}" ]; then
    INCLUDE_DIRS+=("${flag}")
    fi
done < <(pkg-config --cflags-only-I "${PKG_CONFIG_PKGS}" | sed -E 's/-I([^ ]*)/\1\n/g')

function not_found {
    echo "  \"$1\" [style=filled,color=lightgrey];"
    echo "  \"$2\" -> \"$1\""
}

function handle_file {
    filename="${1}"
    for f in "${PROCESSED[@]}"; do
    if [ "${f}" = "${1}" ]; then
        echo "  \"$2\" -> \"$1\""
        return
    fi
    done

    PROCESSED+=("$1")
    if [ -n "${2}" ]; then
    echo "  \"${2}\" -> \"${1}\";"
    fi

    if [ ! "${FOLLOW_SYS_INCLUDES}" = "y" ]; then
    for d in "${INCLUDE_DIRS[@]}"; do
        case "${1}" in
        "${d}"/*)
            return
            ;;
        esac
    done
    fi

    parse_file "$1"
}

function handle_include {
    case "${1}" in
    /*)
        handle_file "${name}" "$2"
        return
        ;;
    esac

    for dir in "${INCLUDE_DIRS[@]}"; do
    if [ -f "${dir}/${1}" ]; then
        handle_file "${dir}/${1}" "$2"
        return
    fi
    done

    not_found "${1}" "${2}"
}

function handle_include_2 {
    case "${1}" in
    /*)
        handle_file "${1}" "$2"
        return
        ;;
    esac

    FILE="$(readlink -f "$(dirname "${2}")/${1}")"
    if [ -f "${FILE}" ]; then
    handle_file "${FILE}" "$2"
    fi
}

function parse_file {
    while read name; do
        handle_include "$name" "$1";
    done < <(grep '^[ \t]*#[ \t]*include <' "$1" | sed -E 's/[ \t]*#[ \t]*include ?<([^>]+)>.*/\1/')

    while read name; do
        handle_include_2 "$name" "$1" "$PWD";
    done < <(grep '^[ \t]*#[ \t]*include "' "$1" | sed -E 's/[ \t]*#[ \t]*include \"([^"]+)\"/\1/')
}

echo "digraph G {"
echo "graph [rankdir = \"LR\"];"
parse_file "$(readlink -f "${1}")" "" "$PWD"
echo "}"

传递一个文件,它将生成一个graphviz文件。把它管到点:

$ ./include-map.sh /usr/include/stdint.h | dot -Tx11

你有一些好看的东西。

答案 1 :(得分:0)

最近几乎所有特色IDE都可以帮助你内置.Visual Studio或Jetbrain的Clion适合你。你没有写过任何平台或环境,但也许值得尝试,即使努力正确设置编译的项目。 回到过去,我发现使用doxygen生成文档也很有用,我记得也会创建这样的maps / links /。