mbox series

[nft,0/6] no recursive make

Message ID 20230825113042.2607496-1-thaller@redhat.com
Headers show
Series no recursive make | expand

Message

Thomas Haller Aug. 25, 2023, 11:27 a.m. UTC
Switch from recursive make to a single toplevel Makefile.

[Quote commit message from first commit]

Unlike meson's subdir() or C's #include, automake's SUBDIRS= does not
include a Makefile. Instead, it calls `make -C $dir`.

  https://www.gnu.org/software/make/manual/html_node/Recursion.html
  https://www.gnu.org/software/automake/manual/html_node/Subdirectories.html

This has several problems, which we an avoid with a single Makefile:

- recursive make is harder to maintain and understand as a whole.
  Recursive make makes sense, when there are truly independent
  sub-projects. Which is not the case here. The project needs to be
  considered as a whole and not one directory at a time. When
  we add unit tests (which we should), those would reside in separate
  directories but have dependencies between directories. With a single
  Makefile, we see all at once. There is a certain complexity to the build
  setup, that complexity is not automatically reduced by splitting it into
  more files. On the contrary it helps to have it all at once place,
  provided that it's still sensibly structured, named and organized.

- typing `make` prints irrelevant "Entering directory" messages. So much
  so, that at the end of the build, the terminal is filled with such
  messages and we have to scroll to see what happened.

- with recursive make, during build we see:

    make[3]: Entering directory '.../nftables/src'
      CC       meta.lo
    meta.c:13:2: error: #warning hello test [-Werror=cpp]
       13 | #warning hello test
          |  ^~~~~~~

  With a single Makefile we get

      CC       src/meta.lo
    src/meta.c:13:2: error: #warning hello test [-Werror=cpp]
       13 | #warning hello test
          |  ^~~~~~~

  This shows the full filename, assuming that the developer works from
  the top level directory. The full name is useful, for example to
  copy+paste into the terminal.

- single Makefile is also faster:

    $ make && perf stat -r 200 -B make -j

  I measure 35msec vs. 80msec.

- recursive make limits parallel make. You have to craft the SUBDIRS= in
  the correct order. The dependencies between directories are limited,
  as make only sees "LDADD = $(top_builddir)/src/libnftables.la" and
  not the deeper dependencies for the library.

- I presume, some people like recursive make because of `make -C $subdir`
  to only rebuild one directory. Rebuilding the entire tree is very
  fast, so this feature seems not relevant. Also, as dependency handling
  is limited, we might wrongly not rebuild a target. For example,

        make check
        touch src/meta.c
        make -C examples check

  does not rebuild "examples/nft-json-file".
  What we now can do with single Makefile (and better than before), is
  `make examples/nft-json-file`, which works as desired.

Thomas Haller (6):
  build: drop recursive make for "include/**/Makefile.am"
  build: drop recursive make for "py/Makefile.am"
  build: drop recursive make for "files/**/Makefile.am"
  build: drop recursive make for "src/Makefile.am"
  build: drop recursive make for "examples/Makefile.am"
  build: drop recursive make for "doc/Makefile.am"

 Make_global.am                             |  21 --
 Makefile.am                                | 408 ++++++++++++++++++++-
 configure.ac                               |  16 -
 doc/Makefile.am                            |  30 --
 examples/Makefile.am                       |   6 -
 files/Makefile.am                          |   3 -
 files/examples/Makefile.am                 |   5 -
 files/nftables/Makefile.am                 |  14 -
 files/osf/Makefile.am                      |   2 -
 include/Makefile.am                        |  42 ---
 include/linux/Makefile.am                  |  12 -
 include/linux/netfilter/Makefile.am        |  10 -
 include/linux/netfilter_arp/Makefile.am    |   1 -
 include/linux/netfilter_bridge/Makefile.am |   1 -
 include/linux/netfilter_ipv4/Makefile.am   |   1 -
 include/linux/netfilter_ipv6/Makefile.am   |   1 -
 include/nftables/Makefile.am               |   1 -
 py/Makefile.am                             |   1 -
 src/Makefile.am                            | 122 ------
 19 files changed, 399 insertions(+), 298 deletions(-)
 delete mode 100644 Make_global.am
 delete mode 100644 doc/Makefile.am
 delete mode 100644 examples/Makefile.am
 delete mode 100644 files/Makefile.am
 delete mode 100644 files/examples/Makefile.am
 delete mode 100644 files/nftables/Makefile.am
 delete mode 100644 files/osf/Makefile.am
 delete mode 100644 include/Makefile.am
 delete mode 100644 include/linux/Makefile.am
 delete mode 100644 include/linux/netfilter/Makefile.am
 delete mode 100644 include/linux/netfilter_arp/Makefile.am
 delete mode 100644 include/linux/netfilter_bridge/Makefile.am
 delete mode 100644 include/linux/netfilter_ipv4/Makefile.am
 delete mode 100644 include/linux/netfilter_ipv6/Makefile.am
 delete mode 100644 include/nftables/Makefile.am
 delete mode 100644 py/Makefile.am
 delete mode 100644 src/Makefile.am