如何记录 makefile?

问题描述 投票:0回答:9

有没有办法在 Makefile 中编写“标准”注释,以便稍后将它们提供给类似 Doxygen 的程序,从而输出漂亮的(例如 HTML 或 man)文档?我想在某个地方清楚地了解我的主要目标,但不要太花哨。

makefile documentation-generation
9个回答
61
投票

以下是一个更简单的解决方案,不需要定义用户函数或将帮助文本从其记录的规则中聚合出来。

# This is a regular comment, that will not be displayed

## ----------------------------------------------------------------------
## This is a help comment. The purpose of this Makefile is to demonstrate
## a simple help mechanism that uses comments defined alongside the rules
## they describe without the need of additional help files or echoing of
## descriptions. Help comments are displayed in the order defined within
## the Makefile.
## ----------------------------------------------------------------------

help:     ## Show this help.
    @sed -ne '/@sed/!s/## //p' $(MAKEFILE_LIST)

build:    ## Build something.

install:  ## Install something.

deploy:   ## Deploy something.

format:   ## Help comments are display with their leading whitespace. For
          ## example, all comments in this snippet are aligned with spaces.

运行

make
make help
会产生以下结果:

----------------------------------------------------------------------
This is a help comment. The purpose of this Makefile is to demonstrate
a simple help mechanism that uses comments defined alongside the rules
they describe without the need of additional help files or echoing of
descriptions. Help comments are displayed in the order defined within
the Makefile.
----------------------------------------------------------------------
help:     Show this help.
build:    Build something.
install:  Install something.
deploy:   Deploy something.
format:   Help comments are display with their leading whitespace. For
          example, all comments in this snippet are aligned with spaces.

11
投票

在 makefile 中,例如:

install: ## Do a
  @echo "foo"

start: ## Do b
  @echo "bar"

test: ## Do c
  @echo "baz"

help:
  @egrep -h '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m  %-30s\033[0m %s\n", $$1, $$2}'

将输出:


9
投票

一个不错的做法是提供一个虚假的

help
目标,打印目标和选项的摘要。来自 Linux 内核
Makefile
:

help:
        @echo  'Cleaning targets:'
        @echo  '  clean           - Remove most generated files but keep the config and'
        @echo  '                    enough build support to build external modules'
        @echo  '  mrproper        - Remove all generated files + config + various backup files'
        @echo  '  distclean       - mrproper + remove editor backup and patch files'
        @echo  ''
        @echo  'Configuration targets:'
        @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
        @echo  ''

以这种方式维护文档可能需要一些工作,但我发现它很好地将面向“用户”的内容与面向维护

Makefile
本身的人(内联注释)的内容区分开来。


8
投票

我使用一个简短的 Perl 脚本制作了自己的解决方案,该脚本将帮助格式化为其他 GNU 工具:

SCRIPT_VERSION=v1.0
SCRIPT_AUTHOR=John Doe

all:                ##@Build Build all the project 

clean:              ##@Cleaning Remove all intermediate objects

mrproper: clean     ##@Cleaning Remove all output and interemediate objects

HELP_FUN = \
    %help; while(<>){push@{$$help{$$2//'options'}},[$$1,$$3] \
    if/^([\w-_]+)\s*:.*\#\#(?:@(\w+))?\s(.*)$$/}; \
    print"$$_:\n", map"  $$_->[0]".(" "x(20-length($$_->[0])))."$$_->[1]\n",\
    @{$$help{$$_}},"\n" for keys %help; \

help: ##@Miscellaneous Show this help
    @echo -e "Usage: make [target] ...\n"
    @perl -e '$(HELP_FUN)' $(MAKEFILE_LIST)
    @echo -e "Written by $(SCRIPT_AUTHOR), version $(SCRIPT_VERSION)"
    @echo -e "Please report any bug or error to the author." 

这给出了:

$ make help
Usage: make [target] ...

Miscellaneous:
  help                Show this help

Build:
  all                 Build all the project

Cleaning:
  clean               Remove all intermediate objects
  mrproper            Remove all output and interemediate objects

Written by John Doe, version v1.0
Please report any bug or error to the author.

1
投票

自记录 Makefiles(John Graham-Cumming,2005)让您可以在每个规则旁边编写帮助。这是一个轻量级且非常漂亮的解决方案,至少可以与 GNU Make 一起使用。

这是我的稍微修改过的版本(def-help-section有助于组织长长的规则列表)。


1
投票

这是我的版本,它还消除了目标的依赖关系,并将帮助字符串对齐到偶数列。

help:   ## Show this help.
    @sed -ne 's/^\([^[:space:]]*\):.*##/\1:\t/p' $(MAKEFILE_LIST) | column -t -s $$'\t'

image: src/*.s src/*.c src/**/*.c   ## Build the image
    riscv32-unknown-elf-gcc $^ -march=rv32i_zicsr -Wall -ggdb -O0 -o image -ffreestanding -nostdlib -lgcc

launch: ## Image Launch the image in renode
    renode --net vexriscv.resc --console

输出

help:    Show this help.
image    Build the image
launch:  Image Launch the image in renode

0
投票

我正是为此目的编写了 MakeHelp 库。它允许您在每个规则上方编写规则文档。非常容易使用。

我发现它与这里的其他自记录 Makefile 不同,因为它没有重复性并且允许多行文档和私有规则。


0
投票

再举一个例子: 允许在命令行之前写入帮助消息。

您可以在帮助消息中使用“:”将其打印在单独的列中。

## Another help message with data: in a separate column
test::
    echo ""

## Print this help
help::
    @awk '/^## /{c=substr($$0,3);next}c&&/^[[:alpha:]][[:alnum:]_/-]+:/{print substr($$1,1,index($$1,":")),c}1{c=0}' $(MAKEFILE_LIST) | column -s: -t -W 2,3 -o " "

输出:

test       Another help message with data                           in a separate column
help       Print this help                                         

0
投票

允许在命令行之前编写帮助消息并将其分为几个部分

根据 https://stackoverflow.com/a/77566974/23306035 在命令行之前编写帮助消息 根据 https://stackoverflow.com/a/30796664/23306035

将其分为几部分
build_test_1:
    echo ""

###@clean Help: message for clean_test_1
clean_test_1:
    echo ""

###@build Help: message for build_test_2
build_test_2:
    echo ""

###@clean Help: message for clean_test_2
clean_test_2:
    echo ""

### help: Print this help
help: #check build clean upload
    @awk ' \
        match($$0,/^###(@(\w+))? [Hh]elp: /,m) \
        {c=m[2];h=substr($$0,RLENGTH);next} \
        h&&/^[[:alpha:]][[:alnum:]_/-]+:/ \
        {help[c][idx[c]++]=sprintf("\033[36m%s\033[0m\t%s", substr($$1,1,index($$1,":")-1),h)} \
        1{c=0;h=0} \
        END{ \
            n=asorti(help, help_); \
            for (c = 1; c <= n; c++) { \
                if(help_[c]){indent="  ";printf "\n%s:\n", help_[c]}\
                asort(help[help_[c]]); \
                for(x in help[help_[c]]){print indent help[help_[c]][x]} \
            } \
        }' $(MAKEFILE_LIST) | column -s$$'\t' -tL

输出:


build:
  build_test_1   message for build_test_1
  build_test_2   message for build_test_2

clean:
  clean_test_1   message for clean_test_1
  clean_test_2   message for clean_test_2```
© www.soinside.com 2019 - 2024. All rights reserved.