mbox series

[RFC,v4,00/19] Modernize the build system

Message ID cover.1729771605.git.ps@pks.im (mailing list archive)
Headers show
Series Modernize the build system | expand

Message

Patrick Steinhardt Oct. 24, 2024, 12:39 p.m. UTC
Hi,

this is the fourth version of my patch series that modernizes our build
system. It refactors various parts of it to make it possible to perform
out-of-tree builds in theory and then wires up Meson.

Changes compared to v3:

  - Various typo fixes.

  - Our Makefile now detects unsubstituted build options in the newly-
    introduced "GIT-BUILD-OPTIONS.in" template.

  - I've wired up support for building and installing manpages. This was
    the last important bit missing to get a fully functioning Git
    installation. We generate the same set of manpages that our Makefile
    would and also render a subset of the HTML pages we generate. Not
    wired up are our technical docs, but doing those shouldn't be all
    that involved.

    Documentation is not built by default, but can be enabled by passing
    any combination of `-Ddocs=html,man`.

  - I've dropped the target names for `custom_target()` invocations.
    Those are auto-derived from the first output anyway, so they only
    add unnecessary noise.

  - The last patch is a compatibility patch for "seen". There are a
    couple of topics that interact with this series, and I didn't want
    to make all of them a strict dependency. So I've decided to just
    create a fixup-style commit that does the necessary changes in order
    to work with "seen". Like this, you can test without "seen" by
    simply dropping that last commit, and you can test with "seen" by
    merging it into this topic.

    @Taylor: I didn't really have a better idea than this. There are
    six additional topics that this branch interacts with, and building
    the branch with eight dependencies in total didn't feel sensible.
    Ideally, the topic branch itself shouldn't have the last commit, but
    once it gets merged into 'seen' we should have it. Let me know in
    case you have a better idea though.

This topic is built on top of fd3785337b (The third batch, 2024-10-22)
with the following two branches merged into it:

  - ps/upgrade-clar at 30bf9f0aaa (cmake: set up proper dependencies for
    generated clar headers, 2024-10-21). This is currently in 'seen'.

  - ps/platform-compat-fixes at 80ebd91b83 (http: fix build error on
    FreeBSD, 2024-10-16). This has been merged to 'next'.

I was pondering a bit whether I should split this topic up even further.
I've already evicted other parts out of it such that they can land
separately, and landing the Makefile refactorings independently would
reduce the overall review load. These steps also make sense even if we
don't have Meson, as those are all either simplifications, improvements
for CMake or a necessary step towards out-of-tree builds. Let me know
your thoughts!

Thanks!

Patrick

Patrick Steinhardt (19):
  Makefile: use common template for GIT-BUILD-OPTIONS
  Makefile: consistently use @PLACEHOLDER@ to substitute
  Makefile: consistently use PERL_PATH
  Makefile: extract script to massage Perl scripts
  Makefile: use "generate-perl.sh" to massage Perl library
  Makefile: extract script to massage Shell scripts
  Makefile: extract script to generate gitweb.cgi
  Makefile: refactor GIT-VERSION-GEN to be reusable
  Makefile: refactor generators to be PWD-independent
  Makefile: allow "bin-wrappers/" directory to exist
  Makefile: simplify building of templates
  Documentation: allow sourcing generated includes from separate dir
  Documentation: teach "cmd-list.perl" about out-of-tree builds
  Documentation: extract script to generate a list of mergetools
  t: better support for out-of-tree builds
  t: allow overriding build dir
  Documentation: add comparison of build systems
  Introduce support for the Meson build system
  meson: fix conflicts with in-flight topics

 .gitignore                                    |    1 -
 Documentation/CodingGuidelines                |    2 +-
 Documentation/Makefile                        |   28 +-
 Documentation/build-docdep.perl               |    2 +
 Documentation/cmd-list.perl                   |   23 +-
 Documentation/config/diff.txt                 |    2 +-
 Documentation/config/merge.txt                |    2 +-
 Documentation/generate-mergetool-list.sh      |   17 +
 Documentation/git.txt                         |   24 +-
 Documentation/meson.build                     |  317 ++++
 Documentation/technical/build-systems.txt     |  224 +++
 GIT-BUILD-OPTIONS.in                          |   47 +
 GIT-VERSION-GEN                               |   12 +-
 Makefile                                      |  209 +--
 bin-wrappers/.gitignore                       |    9 +
 bin-wrappers/meson.build                      |   28 +
 bin-wrappers/wrap-for-bin.sh                  |   37 +
 configure.ac                                  |    2 +-
 contrib/buildsystems/CMakeLists.txt           |  218 ++-
 contrib/completion/meson.build                |    8 +
 contrib/meson.build                           |    1 +
 generate-cmdlist.sh                           |   42 +-
 generate-configlist.sh                        |   20 +-
 generate-hooklist.sh                          |   15 +-
 generate-perl.sh                              |   36 +
 generate-script.sh                            |   34 +
 git-cvsserver.perl                            |    2 +-
 git-instaweb.sh                               |    8 +-
 git-request-pull.sh                           |    2 +-
 git-send-email.perl                           |    2 +-
 git-sh-i18n.sh                                |    6 +-
 git-sh-setup.sh                               |    6 +-
 git-svn.perl                                  |    2 +-
 gitk-git/po/vi.po                             |    2 +-
 gitweb/GITWEB-BUILD-OPTIONS.in                |   25 +
 gitweb/Makefile                               |   58 +-
 gitweb/generate-gitweb.sh                     |   45 +
 gitweb/gitweb.perl                            |   44 +-
 gitweb/meson.build                            |   63 +
 meson.build                                   | 1618 +++++++++++++++++
 meson_options.txt                             |   73 +
 perl/FromCPAN/Mail/meson.build                |    7 +
 perl/FromCPAN/meson.build                     |    9 +
 perl/Git/I18N.pm                              |    6 +-
 perl/Git/LoadCPAN.pm                          |    6 +-
 perl/Git/LoadCPAN/Mail/meson.build            |    7 +
 perl/Git/LoadCPAN/meson.build                 |    9 +
 perl/Git/SVN/Memoize/meson.build              |    7 +
 perl/Git/SVN/meson.build                      |   20 +
 perl/Git/meson.build                          |   18 +
 .../header_templates/fixed_prefix.template.pl |    2 +-
 .../runtime_prefix.template.pl                |    8 +-
 perl/meson.build                              |   12 +
 po/meson.build                                |   27 +
 subprojects/.gitignore                        |    1 +
 subprojects/curl.wrap                         |   13 +
 subprojects/expat.wrap                        |   13 +
 subprojects/openssl.wrap                      |   15 +
 subprojects/pcre2.wrap                        |   16 +
 subprojects/zlib.wrap                         |   13 +
 t/helper/meson.build                          |   92 +
 t/lib-gettext.sh                              |    4 +-
 t/meson.build                                 | 1110 +++++++++++
 t/t7609-mergetool--lib.sh                     |    2 +-
 t/test-lib.sh                                 |   22 +-
 templates/Makefile                            |   39 +-
 templates/branches--                          |    1 -
 templates/{this--description => description}  |    0
 .../applypatch-msg.sample}                    |    0
 .../commit-msg.sample}                        |    0
 .../fsmonitor-watchman.sample}                |    0
 templates/hooks/meson.build                   |   24 +
 .../post-update.sample}                       |    0
 .../pre-applypatch.sample}                    |    0
 .../pre-commit.sample}                        |    0
 .../pre-merge-commit.sample}                  |    0
 .../pre-push.sample}                          |    0
 .../pre-rebase.sample}                        |    0
 .../pre-receive.sample}                       |    0
 .../prepare-commit-msg.sample}                |    0
 .../push-to-checkout.sample}                  |    0
 .../sendemail-validate.sample}                |    0
 .../update.sample}                            |    0
 templates/{info--exclude => info/exclude}     |    0
 templates/info/meson.build                    |    5 +
 templates/meson.build                         |   13 +
 unimplemented.sh                              |    2 +-
 wrap-for-bin.sh                               |   36 -
 88 files changed, 4428 insertions(+), 447 deletions(-)
 create mode 100755 Documentation/generate-mergetool-list.sh
 create mode 100644 Documentation/meson.build
 create mode 100644 Documentation/technical/build-systems.txt
 create mode 100644 GIT-BUILD-OPTIONS.in
 create mode 100644 bin-wrappers/.gitignore
 create mode 100644 bin-wrappers/meson.build
 create mode 100755 bin-wrappers/wrap-for-bin.sh
 create mode 100644 contrib/completion/meson.build
 create mode 100644 contrib/meson.build
 create mode 100755 generate-perl.sh
 create mode 100755 generate-script.sh
 create mode 100644 gitweb/GITWEB-BUILD-OPTIONS.in
 create mode 100755 gitweb/generate-gitweb.sh
 create mode 100644 gitweb/meson.build
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100644 perl/FromCPAN/Mail/meson.build
 create mode 100644 perl/FromCPAN/meson.build
 create mode 100644 perl/Git/LoadCPAN/Mail/meson.build
 create mode 100644 perl/Git/LoadCPAN/meson.build
 create mode 100644 perl/Git/SVN/Memoize/meson.build
 create mode 100644 perl/Git/SVN/meson.build
 create mode 100644 perl/Git/meson.build
 create mode 100644 perl/meson.build
 create mode 100644 po/meson.build
 create mode 100644 subprojects/.gitignore
 create mode 100644 subprojects/curl.wrap
 create mode 100644 subprojects/expat.wrap
 create mode 100644 subprojects/openssl.wrap
 create mode 100644 subprojects/pcre2.wrap
 create mode 100644 subprojects/zlib.wrap
 create mode 100644 t/helper/meson.build
 create mode 100644 t/meson.build
 delete mode 100644 templates/branches--
 rename templates/{this--description => description} (100%)
 rename templates/{hooks--applypatch-msg.sample => hooks/applypatch-msg.sample} (100%)
 rename templates/{hooks--commit-msg.sample => hooks/commit-msg.sample} (100%)
 rename templates/{hooks--fsmonitor-watchman.sample => hooks/fsmonitor-watchman.sample} (100%)
 create mode 100644 templates/hooks/meson.build
 rename templates/{hooks--post-update.sample => hooks/post-update.sample} (100%)
 rename templates/{hooks--pre-applypatch.sample => hooks/pre-applypatch.sample} (100%)
 rename templates/{hooks--pre-commit.sample => hooks/pre-commit.sample} (100%)
 rename templates/{hooks--pre-merge-commit.sample => hooks/pre-merge-commit.sample} (100%)
 rename templates/{hooks--pre-push.sample => hooks/pre-push.sample} (100%)
 rename templates/{hooks--pre-rebase.sample => hooks/pre-rebase.sample} (100%)
 rename templates/{hooks--pre-receive.sample => hooks/pre-receive.sample} (100%)
 rename templates/{hooks--prepare-commit-msg.sample => hooks/prepare-commit-msg.sample} (100%)
 rename templates/{hooks--push-to-checkout.sample => hooks/push-to-checkout.sample} (100%)
 rename templates/{hooks--sendemail-validate.sample => hooks/sendemail-validate.sample} (100%)
 rename templates/{hooks--update.sample => hooks/update.sample} (100%)
 rename templates/{info--exclude => info/exclude} (100%)
 create mode 100644 templates/info/meson.build
 create mode 100644 templates/meson.build
 delete mode 100644 wrap-for-bin.sh

Range-diff against v3:
 1:  800fb080f45 !  1:  8c481cb9e01 Makefile: use common template for GIT-BUILD-OPTIONS
    @@ Makefile: GIT-LDFLAGS: FORCE
     +		-e "s|@GIT_TEST_PERL_FATAL_WARNINGS@|\'$(GIT_TEST_PERL_FATAL_WARNINGS)\'|" \
     +		-e "s|@RUNTIME_PREFIX@|\'$(RUNTIME_PREFIX)\'|" \
     +		GIT-BUILD-OPTIONS.in >$@+
    ++	@if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi
      	@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi
      	@if test -f GIT-BUILD-DIR; then rm GIT-BUILD-DIR; fi
      
 2:  1a4a23c66ca =  2:  308dcbe0bd4 Makefile: consistently use @PLACEHOLDER@ to substitute
 3:  8261f108968 =  3:  20e77ffc5f5 Makefile: consistently use PERL_PATH
 4:  4894179b948 =  4:  50b607a412a Makefile: extract script to massage Perl scripts
 5:  b40bc302291 =  5:  eddafe1cf89 Makefile: use "generate-perl.sh" to massage Perl library
 6:  c13ce99be3a !  6:  2cf8cf86218 Makefile: extract script to massage Shell scripts
    @@ Makefile: GIT-BUILD-OPTIONS: FORCE
     +		-e "s|@LOCALEDIR@|\'$(localedir_SQ)\'|" \
     +		-e "s|@BROKEN_PATH_FIX@|\'$(BROKEN_PATH_FIX)\'|" \
      		GIT-BUILD-OPTIONS.in >$@+
    + 	@if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi
      	@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi
    - 	@if test -f GIT-BUILD-DIR; then rm GIT-BUILD-DIR; fi
     
      ## contrib/buildsystems/CMakeLists.txt ##
     @@ contrib/buildsystems/CMakeLists.txt: set(git_shell_scripts
 7:  ebffd855836 =  7:  e8abda661cf Makefile: extract script to generate gitweb.cgi
 8:  d2cdfad10f5 =  8:  0e682b68e25 Makefile: refactor GIT-VERSION-GEN to be reusable
 9:  9be0719ce1b !  9:  46b7760fbcd Makefile: refactor generators to be PWD-independent
    @@ Commit message
         We have multiple scripts that generate headers from other data. All of
         these scripts have the assumption built-in that they are executed in the
         current source directory, which makes them a bit unwieldy to use during
    -    out-of-tree builds. This makes them a bit unwieldy to use. Refactor them
    -    to instead take the source directory as well as the output file as
    -    arguments.
    +    out-of-tree builds.
    +
    +    Refactor them to instead take the source directory as well as the output
    +    file as arguments.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
10:  93869e53178 = 10:  ec4a9e65ec3 Makefile: allow "bin-wrappers/" directory to exist
11:  1c37d6d1f19 ! 11:  b330fd783d4 Makefile: simplify building of templates
    @@ Commit message
     
         When we install Git we also install a set of default templates that both
         git-init(1) and git-clone(1) populate into our build directories. The
    -    way the pristine templates are layed out in our source directory is
    +    way the pristine templates are laid out in our source directory is
         somewhat weird though: instead of reconstructing the actual directory
         hierarchy in "templates/", we represent directory separators with "--".
     
 -:  ----------- > 12:  fb7231ae4c7 Documentation: allow sourcing generated includes from separate dir
 -:  ----------- > 13:  cf1743667e9 Documentation: teach "cmd-list.perl" about out-of-tree builds
 -:  ----------- > 14:  6926a282a80 Documentation: extract script to generate a list of mergetools
12:  c45d2df6b8d = 15:  ed3affb794c t: better support for out-of-tree builds
13:  542b01515e1 ! 16:  205b038f961 t: allow overriding build dir
    @@ Commit message
         using build systems that support out-of-tree builds.
     
         In commit ee9e66e4e7 (cmake: avoid editing t/test-lib.sh, 2022-10-18),
    -    we have introduce support for overriding the GIT_BIULD_DIR by creating
    +    we have introduce support for overriding the GIT_BUILD_DIR by creating
         the file "$GIT_BUILD_DIR/GIT-BUILD-DIR" with its contents pointing to
         the location of the build directory. The intent was to stop modifying
         "t/test-lib.sh" with the CMake build systems while allowing out-of-tree
14:  bd59e31bb55 = 17:  bef26dd67c5 Documentation: add comparison of build systems
15:  ac327d98e9c ! 18:  780180568d9 Introduce support for the Meson build system
    @@ Commit message
         Introduce support for the Meson build system
     
         Introduce support for the Meson build system, a "modern" meta build
    -    system that supports many different plaforms, including Linux, macOS,
    +    system that supports many different platforms, including Linux, macOS,
         Windows and BSDs. Meson supports different backends, including Ninja,
         Xcode and Microsoft Visual Studio. Several common IDEs provide an
         integration with it.
    @@ Commit message
         strongly favor Meson over CMake. In my opinion, it feels significantly
         easier to use with a syntax that feels more like a "real" programming
         language. The second big reason is that Meson supports Rust natively,
    -    which may prove to be important given that the project is likely to pick
    -    up Rust as another language eventually.
    +    which may prove to be important given that the project may pick up Rust
    +    as another language eventually.
     
         Using Meson is rather straight-forward. An example:
     
    @@ Commit message
             # Running `meson test` without any arguments will execute all tests,
             # but the syntax supports globbing to select only some tests.
             $ meson test 't-*'
    -        # Execute single test interactively to allow fordebugging.
    +        # Execute single test interactively to allow for debugging.
             $ meson test 't0000-*' --interactive --test-args=-ix
             ```
     
    @@ Commit message
     
           - We do not install dashed binaries into `$libexec/git-core` anymore.
             So there won't e.g. be a symlink for git-add(1). These are not
    -        required by modern Git and there isn't really much of a usecase for
    +        required by modern Git and there isn't really much of a use case for
             those anymore. By not installing those symlinks we thus start the
             deprecation of this layout.
     
    -      - Support for installing documentation has not been wired up yet. This
    -        will follow if the project can agree on Meson as build system.
    -
           - Documentation does not yet exist. Same here, it will follow if the
             project can agree on Meson.
     
    -      - We're targeting a Meson 1.3.0, which has been released relatively
    +      - We're targeting Meson 1.3.0, which has been released relatively
             recently November 2023. The only feature we use from that version is
             `fs.relative_to()`, which we could replace if necessary. If so, we
             could start to target Meson 1.0.0 and newer, released in December
             2022.
     
    -      - The whole build instructions count around 3000 lines, half of which
    +      - The whole build instructions count around 3300 lines, half of which
             is listing all of our code and test files. Our Makefiles are around
             5000 lines, autoconf adds another 1300 lines. CMake in comparison
             has only 1200 linescode, but it avoids listing individual files and
    @@ Commit message
         Helped-by: Eli Schwartz <eschwartz@gentoo.org>
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
    + ## Documentation/meson.build (new) ##
    +@@
    ++manpages = {
    ++  # Category 1.
    ++  'git-add.txt' : 1,
    ++  'git-am.txt' : 1,
    ++  'git-annotate.txt' : 1,
    ++  'git-apply.txt' : 1,
    ++  'git-archimport.txt' : 1,
    ++  'git-archive.txt' : 1,
    ++  'git-bisect.txt' : 1,
    ++  'git-blame.txt' : 1,
    ++  'git-branch.txt' : 1,
    ++  'git-bugreport.txt' : 1,
    ++  'git-bundle.txt' : 1,
    ++  'git-cat-file.txt' : 1,
    ++  'git-check-attr.txt' : 1,
    ++  'git-check-ignore.txt' : 1,
    ++  'git-check-mailmap.txt' : 1,
    ++  'git-checkout-index.txt' : 1,
    ++  'git-checkout.txt' : 1,
    ++  'git-check-ref-format.txt' : 1,
    ++  'git-cherry-pick.txt' : 1,
    ++  'git-cherry.txt' : 1,
    ++  'git-citool.txt' : 1,
    ++  'git-clean.txt' : 1,
    ++  'git-clone.txt' : 1,
    ++  'git-column.txt' : 1,
    ++  'git-commit-graph.txt' : 1,
    ++  'git-commit-tree.txt' : 1,
    ++  'git-commit.txt' : 1,
    ++  'git-config.txt' : 1,
    ++  'git-count-objects.txt' : 1,
    ++  'git-credential-cache--daemon.txt' : 1,
    ++  'git-credential-cache.txt' : 1,
    ++  'git-credential-store.txt' : 1,
    ++  'git-credential.txt' : 1,
    ++  'git-cvsexportcommit.txt' : 1,
    ++  'git-cvsimport.txt' : 1,
    ++  'git-cvsserver.txt' : 1,
    ++  'git-daemon.txt' : 1,
    ++  'git-describe.txt' : 1,
    ++  'git-diagnose.txt' : 1,
    ++  'git-diff-files.txt' : 1,
    ++  'git-diff-index.txt' : 1,
    ++  'git-difftool.txt' : 1,
    ++  'git-diff-tree.txt' : 1,
    ++  'git-diff.txt' : 1,
    ++  'git-fast-export.txt' : 1,
    ++  'git-fast-import.txt' : 1,
    ++  'git-fetch-pack.txt' : 1,
    ++  'git-fetch.txt' : 1,
    ++  'git-filter-branch.txt' : 1,
    ++  'git-fmt-merge-msg.txt' : 1,
    ++  'git-for-each-ref.txt' : 1,
    ++  'git-for-each-repo.txt' : 1,
    ++  'git-format-patch.txt' : 1,
    ++  'git-fsck-objects.txt' : 1,
    ++  'git-fsck.txt' : 1,
    ++  'git-fsmonitor--daemon.txt' : 1,
    ++  'git-gc.txt' : 1,
    ++  'git-get-tar-commit-id.txt' : 1,
    ++  'git-grep.txt' : 1,
    ++  'git-gui.txt' : 1,
    ++  'git-hash-object.txt' : 1,
    ++  'git-help.txt' : 1,
    ++  'git-hook.txt' : 1,
    ++  'git-http-backend.txt' : 1,
    ++  'git-http-fetch.txt' : 1,
    ++  'git-http-push.txt' : 1,
    ++  'git-imap-send.txt' : 1,
    ++  'git-index-pack.txt' : 1,
    ++  'git-init-db.txt' : 1,
    ++  'git-init.txt' : 1,
    ++  'git-instaweb.txt' : 1,
    ++  'git-interpret-trailers.txt' : 1,
    ++  'git-log.txt' : 1,
    ++  'git-ls-files.txt' : 1,
    ++  'git-ls-remote.txt' : 1,
    ++  'git-ls-tree.txt' : 1,
    ++  'git-mailinfo.txt' : 1,
    ++  'git-mailsplit.txt' : 1,
    ++  'git-maintenance.txt' : 1,
    ++  'git-merge-base.txt' : 1,
    ++  'git-merge-file.txt' : 1,
    ++  'git-merge-index.txt' : 1,
    ++  'git-merge-one-file.txt' : 1,
    ++  'git-mergetool--lib.txt' : 1,
    ++  'git-mergetool.txt' : 1,
    ++  'git-merge-tree.txt' : 1,
    ++  'git-merge.txt' : 1,
    ++  'git-mktag.txt' : 1,
    ++  'git-mktree.txt' : 1,
    ++  'git-multi-pack-index.txt' : 1,
    ++  'git-mv.txt' : 1,
    ++  'git-name-rev.txt' : 1,
    ++  'git-notes.txt' : 1,
    ++  'git-p4.txt' : 1,
    ++  'git-pack-objects.txt' : 1,
    ++  'git-pack-redundant.txt' : 1,
    ++  'git-pack-refs.txt' : 1,
    ++  'git-patch-id.txt' : 1,
    ++  'git-prune-packed.txt' : 1,
    ++  'git-prune.txt' : 1,
    ++  'git-pull.txt' : 1,
    ++  'git-push.txt' : 1,
    ++  'git-quiltimport.txt' : 1,
    ++  'git-range-diff.txt' : 1,
    ++  'git-read-tree.txt' : 1,
    ++  'git-rebase.txt' : 1,
    ++  'git-receive-pack.txt' : 1,
    ++  'git-reflog.txt' : 1,
    ++  'git-refs.txt' : 1,
    ++  'git-remote-ext.txt' : 1,
    ++  'git-remote-fd.txt' : 1,
    ++  'git-remote.txt' : 1,
    ++  'git-repack.txt' : 1,
    ++  'git-replace.txt' : 1,
    ++  'git-replay.txt' : 1,
    ++  'git-request-pull.txt' : 1,
    ++  'git-rerere.txt' : 1,
    ++  'git-reset.txt' : 1,
    ++  'git-restore.txt' : 1,
    ++  'git-revert.txt' : 1,
    ++  'git-rev-list.txt' : 1,
    ++  'git-rev-parse.txt' : 1,
    ++  'git-rm.txt' : 1,
    ++  'git-send-email.txt' : 1,
    ++  'git-send-pack.txt' : 1,
    ++  'git-shell.txt' : 1,
    ++  'git-sh-i18n--envsubst.txt' : 1,
    ++  'git-sh-i18n.txt' : 1,
    ++  'git-shortlog.txt' : 1,
    ++  'git-show-branch.txt' : 1,
    ++  'git-show-index.txt' : 1,
    ++  'git-show-ref.txt' : 1,
    ++  'git-show.txt' : 1,
    ++  'git-sh-setup.txt' : 1,
    ++  'git-sparse-checkout.txt' : 1,
    ++  'git-stage.txt' : 1,
    ++  'git-stash.txt' : 1,
    ++  'git-status.txt' : 1,
    ++  'git-stripspace.txt' : 1,
    ++  'git-submodule.txt' : 1,
    ++  'git-svn.txt' : 1,
    ++  'git-switch.txt' : 1,
    ++  'git-symbolic-ref.txt' : 1,
    ++  'git-tag.txt' : 1,
    ++  'git-unpack-file.txt' : 1,
    ++  'git-unpack-objects.txt' : 1,
    ++  'git-update-index.txt' : 1,
    ++  'git-update-ref.txt' : 1,
    ++  'git-update-server-info.txt' : 1,
    ++  'git-upload-archive.txt' : 1,
    ++  'git-upload-pack.txt' : 1,
    ++  'git-var.txt' : 1,
    ++  'git-verify-commit.txt' : 1,
    ++  'git-verify-pack.txt' : 1,
    ++  'git-verify-tag.txt' : 1,
    ++  'git-version.txt' : 1,
    ++  'git-web--browse.txt' : 1,
    ++  'git-whatchanged.txt' : 1,
    ++  'git-worktree.txt' : 1,
    ++  'git-write-tree.txt' : 1,
    ++  'git.txt' : 1,
    ++  'gitk.txt' : 1,
    ++  'gitweb.txt' : 1,
    ++  'scalar.txt' : 1,
    ++
    ++  # Category 5.
    ++  'gitattributes.txt' : 5,
    ++  'gitformat-bundle.txt' : 5,
    ++  'gitformat-chunk.txt' : 5,
    ++  'gitformat-commit-graph.txt' : 5,
    ++  'gitformat-index.txt' : 5,
    ++  'gitformat-pack.txt' : 5,
    ++  'gitformat-signature.txt' : 5,
    ++  'githooks.txt' : 5,
    ++  'gitignore.txt' : 5,
    ++  'gitmailmap.txt' : 5,
    ++  'gitmodules.txt' : 5,
    ++  'gitprotocol-capabilities.txt' : 5,
    ++  'gitprotocol-common.txt' : 5,
    ++  'gitprotocol-http.txt' : 5,
    ++  'gitprotocol-pack.txt' : 5,
    ++  'gitprotocol-v2.txt' : 5,
    ++  'gitrepository-layout.txt' : 5,
    ++  'gitweb.conf.txt' : 5,
    ++
    ++  # Category 7.
    ++  'gitcli.txt' : 7,
    ++  'gitcore-tutorial.txt' : 7,
    ++  'gitcredentials.txt' : 7,
    ++  'gitcvs-migration.txt' : 7,
    ++  'gitdiffcore.txt' : 7,
    ++  'giteveryday.txt' : 7,
    ++  'gitfaq.txt' : 7,
    ++  'gitglossary.txt' : 7,
    ++  'gitpacking.txt' : 7,
    ++  'gitnamespaces.txt' : 7,
    ++  'gitremote-helpers.txt' : 7,
    ++  'gitrevisions.txt' : 7,
    ++  'gitsubmodules.txt' : 7,
    ++  'gittutorial-2.txt' : 7,
    ++  'gittutorial.txt' : 7,
    ++  'gitworkflows.txt' : 7,
    ++}
    ++
    ++asciidoc = find_program('asciidoc')
    ++git = find_program('git', required: false)
    ++xmlto = find_program('xmlto')
    ++
    ++git_revdate = ''
    ++if git.found()
    ++  git_revdate = run_command(git, 'show', '--quiet', '--pretty=%as', check: false).stdout().strip()
    ++endif
    ++
    ++asciidoc_common_options = [
    ++  asciidoc,
    ++  '--conf-file=' + meson.current_source_dir() / 'asciidoc.conf',
    ++  '--attribute=manual=Git Manual',
    ++  '--attribute=mansource=Git ' + git_version,
    ++  '--attribute=revdate=' + git_revdate,
    ++  '--attribute=build_dir=' + meson.current_build_dir(),
    ++]
    ++
    ++cmd_lists = [
    ++    'cmds-ancillaryinterrogators.txt',
    ++	'cmds-ancillarymanipulators.txt',
    ++	'cmds-mainporcelain.txt',
    ++	'cmds-plumbinginterrogators.txt',
    ++	'cmds-plumbingmanipulators.txt',
    ++	'cmds-synchingrepositories.txt',
    ++	'cmds-synchelpers.txt',
    ++	'cmds-guide.txt',
    ++	'cmds-developerinterfaces.txt',
    ++	'cmds-userinterfaces.txt',
    ++	'cmds-purehelpers.txt',
    ++	'cmds-foreignscminterface.txt',
    ++]
    ++
    ++documentation_deps = [ ]
    ++
    ++documentation_deps += custom_target(
    ++  command: [
    ++    perl,
    ++    meson.current_source_dir() / 'cmd-list.perl',
    ++    meson.project_source_root(),
    ++    meson.current_build_dir(),
    ++  ] + cmd_lists,
    ++  output: cmd_lists
    ++)
    ++
    ++foreach mode : [ 'diff', 'merge' ]
    ++  documentation_deps += custom_target(
    ++    command: [
    ++      shell,
    ++      meson.current_source_dir() / 'generate-mergetool-list.sh',
    ++      '..',
    ++      'diff',
    ++      '@OUTPUT@'
    ++    ],
    ++    env: [
    ++      'MERGE_TOOLS_DIR=' + meson.project_source_root() / 'mergetools',
    ++      'TOOL_MODE=' + mode,
    ++    ],
    ++    output: 'mergetools-' + mode + '.txt',
    ++  )
    ++endforeach
    ++
    ++foreach manpage, category : manpages
    ++  if get_option('docs').contains('man')
    ++    manpage_xml_target = custom_target(
    ++      command: asciidoc_common_options + [
    ++        '--backend=docbook',
    ++        '--doctype=manpage',
    ++        '--out-file=@OUTPUT@',
    ++        meson.current_source_dir() / manpage,
    ++      ],
    ++      depends: documentation_deps,
    ++      output: fs.stem(manpage) + '.xml',
    ++    )
    ++
    ++    manpage_path = fs.stem(manpage) + '.' + category.to_string()
    ++    manpage_target = custom_target(
    ++      command: [
    ++        xmlto,
    ++        '-m',
    ++        meson.current_source_dir() / 'manpage-normal.xsl',
    ++        '-m',
    ++        meson.current_source_dir() / 'manpage-bold-literal.xsl',
    ++        '--stringparam',
    ++        'man.base.url.for.relative.links=' + get_option('prefix') / get_option('mandir'),
    ++        'man',
    ++        manpage_xml_target,
    ++        '-o',
    ++        meson.current_build_dir(),
    ++      ],
    ++      output: manpage_path,
    ++      install: true,
    ++      install_dir: get_option('mandir') / 'man' + category.to_string(),
    ++    )
    ++  endif
    ++
    ++  if get_option('docs').contains('html') and category == 1
    ++    custom_target(
    ++      command: asciidoc_common_options + [
    ++        '--backend=xhtml11',
    ++        '--doctype=manpage',
    ++        '--out-file=@OUTPUT@',
    ++        meson.current_source_dir() / manpage,
    ++      ],
    ++      depends: documentation_deps,
    ++      output: fs.stem(manpage) + '.html',
    ++      install: true,
    ++      install_dir: get_option('datadir') / 'doc/git-doc',
    ++    )
    ++  endif
    ++endforeach
    +
      ## bin-wrappers/meson.build (new) ##
     @@
     +bin_wrappers_config = configuration_data()
    @@ gitweb/meson.build (new)
     +  configuration: gitweb_config,
     +)
     +
    -+test_dependencies += custom_target(script,
    ++test_dependencies += custom_target(
     +  input: 'gitweb.perl',
     +  output: 'gitweb.cgi',
     +  command: [
    @@ meson.build (new)
     +]
     +
     +libgit_sources += custom_target(
    -+  'command-list.h',
     +  input: 'command-list.txt',
     +  output: 'command-list.h',
     +  command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'],
    @@ meson.build (new)
     +)
     +
     +libgit_sources += custom_target(
    -+  'config-list.h',
     +  output: 'config-list.h',
     +  command: [
     +    shell,
    @@ meson.build (new)
     +)
     +
     +libgit_sources += custom_target(
    -+  'hook-list.h',
     +  input: 'Documentation/githooks.txt',
     +  output: 'hook-list.h',
     +  command: [
    @@ meson.build (new)
     +endif
     +
     +foreach script : scripts_sh
    -+  test_dependencies += custom_target(script,
    ++  test_dependencies += custom_target(
     +    input: script,
     +    output: fs.stem(script),
     +    command: [
    @@ meson.build (new)
     +  ]
     +
     +  foreach script : scripts_perl
    -+    generated_script = custom_target(script,
    ++    generated_script = custom_target(
     +      input: script,
     +      output: fs.stem(script),
     +      command: generate_perl_command,
    @@ meson.build (new)
     +endif
     +
     +subdir('bin-wrappers')
    ++if get_option('docs') != []
    ++  subdir('Documentation')
    ++endif
     
      ## meson_options.txt (new) ##
     @@
    -+option('default_help_format', type: 'combo', choices: ['man', 'html', 'info'], value: 'man',
    -+  description: 'Format of installed documentation.')
     +option('default_pager', type: 'string', value: 'less',
     +  description: 'Fall-back pager.')
     +option('default_editor', type: 'string', value: 'vi',
    @@ meson_options.txt (new)
     +option('gitweb_site_footer', type: 'string', value: '')
     +option('highlight_bin', type: 'string', value: 'highlight')
     +
    ++option('docs', type: 'array', choices: ['man', 'html'], value: [],
    ++  description: 'Which documenattion formats to build and install.')
    ++option('default_help_format', type: 'combo', choices: ['man', 'html'], value: 'man',
    ++  description: 'Default format used when executing git-help(1).')
    ++
     +option('tests', type: 'boolean', value: true,
     +  description: 'Enable building tests. This requires Perl, but is separate from the "perl" option such that you can build tests without Perl features enabled.')
     +option('test_output_directory', type: 'string',
    @@ meson_options.txt (new)
     
      ## perl/FromCPAN/Mail/meson.build (new) ##
     @@
    -+test_dependencies += custom_target('Address.pm',
    ++test_dependencies += custom_target(
     +  input: 'Address.pm',
     +  output: 'Address.pm',
     +  command: generate_perl_command,
    @@ perl/FromCPAN/Mail/meson.build (new)
     
      ## perl/FromCPAN/meson.build (new) ##
     @@
    -+test_dependencies += custom_target('Error.pm',
    ++test_dependencies += custom_target(
     +  input: 'Error.pm',
     +  output: 'Error.pm',
     +  command: generate_perl_command,
    @@ perl/FromCPAN/meson.build (new)
     
      ## perl/Git/LoadCPAN/Mail/meson.build (new) ##
     @@
    -+test_dependencies += custom_target('Address.pm',
    ++test_dependencies += custom_target(
     +  input: 'Address.pm',
     +  output: 'Address.pm',
     +  command: generate_perl_command,
    @@ perl/Git/LoadCPAN/Mail/meson.build (new)
     
      ## perl/Git/LoadCPAN/meson.build (new) ##
     @@
    -+test_dependencies += custom_target('Error.pm',
    ++test_dependencies += custom_target(
     +  input: 'Error.pm',
     +  output: 'Error.pm',
     +  command: generate_perl_command,
    @@ perl/Git/LoadCPAN/meson.build (new)
     
      ## perl/Git/SVN/Memoize/meson.build (new) ##
     @@
    -+test_dependencies += custom_target('YAML.pm',
    ++test_dependencies += custom_target(
     +  input: 'YAML.pm',
     +  output: 'YAML.pm',
     +  command: generate_perl_command,
    @@ perl/Git/SVN/meson.build (new)
     +  'Ra.pm',
     +  'Utils.pm',
     +]
    -+  test_dependencies += custom_target(source,
    ++  test_dependencies += custom_target(
     +    input: source,
     +    output: source,
     +    command: generate_perl_command,
    @@ perl/Git/meson.build (new)
     +  'Packet.pm',
     +  'SVN.pm',
     +]
    -+  test_dependencies += custom_target(source,
    ++  test_dependencies += custom_target(
     +    input: source,
     +    output: source,
     +    command: generate_perl_command,
    @@ perl/Git/meson.build (new)
     
      ## perl/meson.build (new) ##
     @@
    -+test_dependencies += custom_target('Git.pm',
    ++test_dependencies += custom_target(
     +  input: 'Git.pm',
     +  output: 'Git.pm',
     +  command: generate_perl_command,
    @@ po/meson.build (new)
     +    'zh_TW',
     +  ],
     +  install: true,
    -+  install_dir: get_option('datadir'),
     +)
     +test_dependencies += translations[0]
     
    @@ t/meson.build (new)
     +  'unit-tests/unit-test.c',
     +]
     +
    -+clar_decls_h = custom_target('clar_decls_h',
    ++clar_decls_h = custom_target(
     +  input: clar_test_suites,
     +  output: 'clar-decls.h',
     +  command : [shell, meson.current_source_dir() + '/unit-tests/generate-clar-decls.sh', '@OUTPUT@', '@INPUT@'],
    @@ t/meson.build (new)
     +)
     +clar_sources += clar_decls_h
     +
    -+clar_sources += custom_target('clar_suite',
    ++clar_sources += custom_target(
     +  input: clar_decls_h,
     +  output: 'clar.suite',
     +  feed: true,
    @@ t/meson.build (new)
     +  'unit-tests/t-reftable-block.c',
     +  'unit-tests/t-reftable-merged.c',
     +  'unit-tests/t-reftable-pq.c',
    ++  'unit-tests/t-reftable-reader.c',
     +  'unit-tests/t-reftable-readwrite.c',
     +  'unit-tests/t-reftable-record.c',
     +  'unit-tests/t-reftable-stack.c',
    @@ t/meson.build (new)
     +  't2405-worktree-submodule.sh',
     +  't2406-worktree-repair.sh',
     +  't2407-worktree-heads.sh',
    ++  't2408-worktree-relative.sh',
     +  't2500-untracked-overwriting.sh',
     +  't2501-cwd-empty.sh',
     +  't3000-ls-files-others.sh',
 -:  ----------- > 19:  45e2ab4044a meson: fix conflicts with in-flight topics

Comments

Taylor Blau Oct. 24, 2024, 4:02 p.m. UTC | #1
On Thu, Oct 24, 2024 at 02:39:43PM +0200, Patrick Steinhardt wrote:
>   - The last patch is a compatibility patch for "seen". There are a
>     couple of topics that interact with this series, and I didn't want
>     to make all of them a strict dependency. So I've decided to just
>     create a fixup-style commit that does the necessary changes in order
>     to work with "seen". Like this, you can test without "seen" by
>     simply dropping that last commit, and you can test with "seen" by
>     merging it into this topic.
>
>     @Taylor: I didn't really have a better idea than this. There are
>     six additional topics that this branch interacts with, and building
>     the branch with eight dependencies in total didn't feel sensible.
>     Ideally, the topic branch itself shouldn't have the last commit, but
>     once it gets merged into 'seen' we should have it. Let me know in
>     case you have a better idea though.
>
> This topic is built on top of fd3785337b (The third batch, 2024-10-22)
> with the following two branches merged into it:
>
>   - ps/upgrade-clar at 30bf9f0aaa (cmake: set up proper dependencies for
>     generated clar headers, 2024-10-21). This is currently in 'seen'.
>
>   - ps/platform-compat-fixes at 80ebd91b83 (http: fix build error on
>     FreeBSD, 2024-10-16). This has been merged to 'next'.

Thanks for all of the helpful information. I changed the base up to
"The third batch" and merged in the two branches you mentioned.
Everything builds fine at the tip and passes 'make test'.

> I was pondering a bit whether I should split this topic up even further.
> I've already evicted other parts out of it such that they can land
> separately, and landing the Makefile refactorings independently would
> reduce the overall review load. These steps also make sense even if we
> don't have Meson, as those are all either simplifications, improvements
> for CMake or a necessary step towards out-of-tree builds. Let me know
> your thoughts!

I think erring on the side of smaller series makes them easier to
review, as Stolee and I were talking about in another thread. But if you
feel like this topic is receiving sufficient review as-is, then I
wouldn't bother changing it.

Thanks,
Taylor
Taylor Blau Oct. 25, 2024, 7:59 p.m. UTC | #2
On Thu, Oct 24, 2024 at 02:39:43PM +0200, Patrick Steinhardt wrote:
> Hi,
>
> this is the fourth version of my patch series that modernizes our build
> system. It refactors various parts of it to make it possible to perform
> out-of-tree builds in theory and then wires up Meson.

I was thinking a little bit about this topic last night and wanted to
collect my thoughts somewhere.

I think that there are a couple of things that I'm not 100% clear or
sold on, which are:

  - What is the eventual goal of this series? Do we plan to transition
    the existing make-driven builds to instead be built with Meson? Will
    we have both? Something else?

  - What is the eventual plan for CMake, which is maintained currently
    in the contrib directory? Will it be deprecated in favor of Meson?
    Will we continue to support it?

Let me expand a little on each of those in turn:

== What is the eventual goal?

From reading [PATCH 17/19], it seems the main arguments in favor of
using Meson are:

  - Ease of use: easy to use, discovering available options is easy. The
    scripting language is straight-forward to use.
  - IDE support: Supports generating build instructions for Xcode and Microsoft
    Visual Studio, a plugin exists for Visual Studio Code.
  - Out-of-tree builds: supported.
  - Cross-platform builds: supported.
  - Language support:
    - C: Supported for GCC, Clang, MSVC and other toolchains.
    - Rust: Supported for rustc.
  - Test integration: supported. Interactive tests are supported starting with
    Meson 1.5.0 via the `--interactive` flag.

I don't think that when reading these any of them stick out to me and
compel me to learn a new build system. I understand and am sympathetic
to the fact that GNU Make has odd syntax and can be cumbersome. But I
don't think that incrementally modifying our Makefile over time is
difficult, and it has certainly worked well over the years.

Certainly there is ample support for IDE integration with Make.
Out-of-tree builds and cross-platform builds could be supported in
theory as you note within the existing build system. Another suggestion
you make is that Meson has better native support for Rust, which I agree
may be important to consider in the future.

But I don't think that any of those three (out-of-tree builds,
cross-compilation, or Rust support) are insurmountable challenges in
Make. Certainly there is a lot of inertia there, but I don't think
that's a bad thing. Contributors are used to the existing build system,
it has worked well for us, works across many platforms and has (IMO)
stood the test of time.

I admittedly have a hard time squaring the benefits and goals we have
with Meson with the cost of learning a new build system, and/or moving
away from Make entirely.

I am entirely open to the possibility that there is something that I am
missing here, and that Meson really is a better choice for Git given our
current direction. But I think if that's true, then the series needs to
explain that more prominently.

== What is the eventual plan for CMake?

From [PATCH 18/19], you write:

> If this patch lands the expectation is that it will coexist
> with our other build systems for a while. Like this, distributions can
> slowly migrate over to Meson and report any findings they have to us
> such that we can continue to iterate. A potential cutoff date for other
> build systems may be Git 3.0.

I don't view this is a good intermediate state, and is in my view making
an existing problem that we have worse. On the "existing problem": I
think that landing CMake support in contrib was a mistake. In my view,
CMake support should have either been a first-class citizen in Git (such
that we don't consider a change "done" until it can be built by CMake),
or should have been maintained out-of-tree.

But I think we struck a worst-of-both-worlds balance by landing it in
contrib. It's maintained in the tree, so people expect to be able to
build the project with it because it comes with a bog-standard clone of
git.git.

But despite living in the project's tree, it is not a first-class
citizen, and subjectively it seems that we get an awful lot of mail
asking why something doesn't build in CMake, etc. (To your credit, I
think you have been one of the main people to help with that, often
fixing those bugs yourself, which is greatly appreciated).

I don't want to see the project have to pseudo-maintain three build
systems. It seems like doing so would be cumbersome, and error-prone. I
am already probably guilty of breaking CMake builds when I add a new
compilation unit to the project, because of a combination of my lack of
familiarity with CMake, and the fact that we don't have a project-wide
convention of treating it with the same care as we do the Makefile. I
think that having three build systems (even if they only co-existed
until Git 3.0) would make that problem worse.

I feel that if we are going to pursue Meson over CMake and/or Make, we
should have a clear plan to either get rid of CMake, keep it up-to-date,
or something else.

== Conclusion

To step back, I want to say that I appreciate your work on this series
and am certainly not opposed[^1] to the idea that we may need to make
significant changes to our build infrastructure to support the project's
goals.

But I think that what I'm missing currently is a clear picture of what
goals we *can't* achieve with the existing build system (or could, but
only at significant cost/awkwardness), and why Meson is the right choice
to address those gaps.

If the project can agree that pursuing Meson as a replacement for Make,
CMake, or both, then I think we would need further clarification on what
we want to do with CMake (and more generally how we want to support new
efforts to add additional build systems to Git in the future).

Anyway. If I have significantly missed the point here, please feel free
to correct me. In the meantime, I think discussing these points would be
useful to clarifying the direction of the series.

Thanks,
Taylor

[^1]: Both in my current capacity as interim-maintainer, but also as a
  regular contributor to the project, who would (in both cases) be
  interested in evolving the build system we use in furtherance of
  project goals.
Ramsay Jones Oct. 28, 2024, 9:34 p.m. UTC | #3
On 24/10/2024 13:39, Patrick Steinhardt wrote:
> Hi,
> 
> this is the fourth version of my patch series that modernizes our build
> system. It refactors various parts of it to make it possible to perform
> out-of-tree builds in theory and then wires up Meson.

As Promised, I have tested this version on Linux and Cygwin (not full test
on patches 1-18). When built on top of fd3785337b (The third batch) with
the two branches merged (as indicated below) Linux (build+test) and cygwin
(just build) work as expected.

> Changes compared to v3:
> 
>   - Various typo fixes.
> 
>   - Our Makefile now detects unsubstituted build options in the newly-
>     introduced "GIT-BUILD-OPTIONS.in" template.
> 
>   - I've wired up support for building and installing manpages. This was
>     the last important bit missing to get a fully functioning Git
>     installation. We generate the same set of manpages that our Makefile
>     would and also render a subset of the HTML pages we generate. Not
>     wired up are our technical docs, but doing those shouldn't be all
>     that involved.
> 
>     Documentation is not built by default, but can be enabled by passing
>     any combination of `-Ddocs=html,man`.

I haven't tried this (yet).

>   - I've dropped the target names for `custom_target()` invocations.
>     Those are auto-derived from the first output anyway, so they only
>     add unnecessary noise.
> 
>   - The last patch is a compatibility patch for "seen". There are a
>     couple of topics that interact with this series, and I didn't want
>     to make all of them a strict dependency. So I've decided to just
>     create a fixup-style commit that does the necessary changes in order
>     to work with "seen". Like this, you can test without "seen" by
>     simply dropping that last commit, and you can test with "seen" by
>     merging it into this topic.

I couldn't try this patch because (at the time) the 'seen' branch
didn't build. :(

>     @Taylor: I didn't really have a better idea than this. There are
>     six additional topics that this branch interacts with, and building
>     the branch with eight dependencies in total didn't feel sensible.
>     Ideally, the topic branch itself shouldn't have the last commit, but
>     once it gets merged into 'seen' we should have it. Let me know in
>     case you have a better idea though.
> 
> This topic is built on top of fd3785337b (The third batch, 2024-10-22)
> with the following two branches merged into it:
> 
>   - ps/upgrade-clar at 30bf9f0aaa (cmake: set up proper dependencies for
>     generated clar headers, 2024-10-21). This is currently in 'seen'.
> 
>   - ps/platform-compat-fixes at 80ebd91b83 (http: fix build error on
>     FreeBSD, 2024-10-16). This has been merged to 'next'.

As indicated above, this worked just fine.

Now that 'seen' builds again [92855bf61d ("Merge branch 'ps/build' into seen",
2024-10-27)], I tested meson on Linux and Cygwin (build and *full* test this
time).

On Linux, the result looks like:

  $ tail meson-logs/testlog.txt
  Summary of Failures:
  
   117/1035 t1017-cat-file-remote-object-info              FAIL            0.01s   exit status 2
  
  Ok:                 1034
  Expected Fail:      0   
  Fail:               1   
  Unexpected Pass:    0   
  Skipped:            0   
  Timeout:            0   
  $ 
  
It looks like a branch has been removed from 'seen'. :) (ie the t1017* test
file does not exist).

On cygwin, the result looks like:

  $ tail -11 meson-logs/testlog.txt
  Summary of Failures:
  
    23/1035 t-reftable-stack                               TIMEOUT        30.26s   killed by signal 15 SIGTERM
   114/1035 t1017-cat-file-remote-object-info              FAIL            0.13s   exit status 127
  
  Ok:                 1033
  Expected Fail:      0   
  Fail:               1   
  Unexpected Pass:    0   
  Skipped:            0   
  Timeout:            1   
  $ 

The t-reftable-stack unit test took just over 75s on the v2.27.0 test run.
I haven't looked into it yet, but plenty of other tests run for longer than
the 30s, so I don't know why that test seems to be different.

Also, it is worth noting that the test ran for 2hr50min. Usually I have to
wait 6hr approx. for 'make test' to finish because I don't like to use any
'-j' parameters (You can't do anything else on the machine while it is
cooking the cpu!). :)

Thanks!

ATB,
Ramsay Jones
Patrick Steinhardt Nov. 4, 2024, 12:16 p.m. UTC | #4
On Mon, Oct 28, 2024 at 09:34:25PM +0000, Ramsay Jones wrote:
> 
> 
> On 24/10/2024 13:39, Patrick Steinhardt wrote:
> > Hi,
> > 
> > this is the fourth version of my patch series that modernizes our build
> > system. It refactors various parts of it to make it possible to perform
> > out-of-tree builds in theory and then wires up Meson.
> 
> As Promised, I have tested this version on Linux and Cygwin (not full test
> on patches 1-18). When built on top of fd3785337b (The third batch) with
> the two branches merged (as indicated below) Linux (build+test) and cygwin
> (just build) work as expected.

Thanks!

> >   - I've dropped the target names for `custom_target()` invocations.
> >     Those are auto-derived from the first output anyway, so they only
> >     add unnecessary noise.
> > 
> >   - The last patch is a compatibility patch for "seen". There are a
> >     couple of topics that interact with this series, and I didn't want
> >     to make all of them a strict dependency. So I've decided to just
> >     create a fixup-style commit that does the necessary changes in order
> >     to work with "seen". Like this, you can test without "seen" by
> >     simply dropping that last commit, and you can test with "seen" by
> >     merging it into this topic.
> 
> I couldn't try this patch because (at the time) the 'seen' branch
> didn't build. :(

Okay. I'll adapt the next version accordingly.

> On cygwin, the result looks like:
> 
>   $ tail -11 meson-logs/testlog.txt
>   Summary of Failures:
>   
>     23/1035 t-reftable-stack                               TIMEOUT        30.26s   killed by signal 15 SIGTERM
>    114/1035 t1017-cat-file-remote-object-info              FAIL            0.13s   exit status 127
>   
>   Ok:                 1033
>   Expected Fail:      0   
>   Fail:               1   
>   Unexpected Pass:    0   
>   Skipped:            0   
>   Timeout:            1   
>   $ 
> 
> The t-reftable-stack unit test took just over 75s on the v2.27.0 test run.
> I haven't looked into it yet, but plenty of other tests run for longer than
> the 30s, so I don't know why that test seems to be different.

Meson has a default timeout of 30 seconds for tests. I only removed that
timeout for our shell scripts, but didn't for the unit tests. I'll fix
that in the next version.

> Also, it is worth noting that the test ran for 2hr50min. Usually I have to
> wait 6hr approx. for 'make test' to finish because I don't like to use any
> '-j' parameters (You can't do anything else on the machine while it is
> cooking the cpu!). :)

You probably know, but you can of course also pick the number of CPU
cores to run tests on with Meson: `meson test -j1`.

Patrick
Patrick Steinhardt Nov. 4, 2024, 12:17 p.m. UTC | #5
On Fri, Oct 25, 2024 at 03:59:30PM -0400, Taylor Blau wrote:
> On Thu, Oct 24, 2024 at 02:39:43PM +0200, Patrick Steinhardt wrote:
> > Hi,
> >
> > this is the fourth version of my patch series that modernizes our build
> > system. It refactors various parts of it to make it possible to perform
> > out-of-tree builds in theory and then wires up Meson.
> 
> I was thinking a little bit about this topic last night and wanted to
> collect my thoughts somewhere.
> 
> I think that there are a couple of things that I'm not 100% clear or
> sold on, which are:
> 
>   - What is the eventual goal of this series? Do we plan to transition
>     the existing make-driven builds to instead be built with Meson? Will
>     we have both? Something else?
> 
>   - What is the eventual plan for CMake, which is maintained currently
>     in the contrib directory? Will it be deprecated in favor of Meson?
>     Will we continue to support it?

My goal is to end up with a single build system eventually, so yes, we'd
at one point in time drop both the Makefile and our CMake build
instructions. That would of course not happen over night, but across
multiple releases such that devs and packagers can start exercising the
new build infra before we remove it.

> Let me expand a little on each of those in turn:
> 
> == What is the eventual goal?
> 
> From reading [PATCH 17/19], it seems the main arguments in favor of
> using Meson are:
> 
>   - Ease of use: easy to use, discovering available options is easy. The
>     scripting language is straight-forward to use.
>   - IDE support: Supports generating build instructions for Xcode and Microsoft
>     Visual Studio, a plugin exists for Visual Studio Code.
>   - Out-of-tree builds: supported.
>   - Cross-platform builds: supported.
>   - Language support:
>     - C: Supported for GCC, Clang, MSVC and other toolchains.
>     - Rust: Supported for rustc.
>   - Test integration: supported. Interactive tests are supported starting with
>     Meson 1.5.0 via the `--interactive` flag.
> 
> I don't think that when reading these any of them stick out to me and
> compel me to learn a new build system. I understand and am sympathetic
> to the fact that GNU Make has odd syntax and can be cumbersome. But I
> don't think that incrementally modifying our Makefile over time is
> difficult, and it has certainly worked well over the years.

My main goal isn't necessarily to make things work better for old
timers, but _especially_ to make it easier for newcomers. You of course
can wire up many missing features with Makefiles, but that only goes so
far. What you won't get with them is good cross-platform support, deep
integration with IDEs and good discoverability.

> Certainly there is ample support for IDE integration with Make.

Not quite. While there is ample support for executing Makefile targets,
there isn't really a lot of integration for "advanced" features:

  - Auto-configuration.
  - Multiple build types.
  - Code completion.
  - Discovery of the working set of source files.

So the integration that exists for Makefiles is for most of the part
extremely shallow.

Also, I'd claim that Makefiles are really only well-integrated on Linux
or BSDs. For other systems like Windows it is extremely awkward and you
don't really have a nice developer experience there.

There are other factors as well, like auto-detection of the system. Our
Makefile only works well for specific platforms that somebody uses on a
regular basis, and wiring up a new platform requires manual code in our
"config.mak.uname" file. That's somewhat awkward and hard to maintain
going forward as every single platform requires its own bits and pieces.

The solution to that problem is autoconfiguration by detecting platform
specific bits and pieces. And we _also_ have such a build system in the
form of autoconf, but now we're entering territory that is awfully hard
to maintain. Most people don't use it at all, the only user seems to
really be distros. And they tend to hit many issues with autoconf
because we devs don't use that infra in the first place, creating a bit
of an awkward situation. Unifying this infrastructure such that devs and
packagers use the same build infra is thus another goal of my series.

> Out-of-tree builds and cross-platform builds could be supported in
> theory as you note within the existing build system. Another suggestion
> you make is that Meson has better native support for Rust, which I agree
> may be important to consider in the future.
> 
> But I don't think that any of those three (out-of-tree builds,
> cross-compilation, or Rust support) are insurmountable challenges in
> Make. Certainly there is a lot of inertia there, but I don't think
> that's a bad thing. Contributors are used to the existing build system,
> it has worked well for us, works across many platforms and has (IMO)
> stood the test of time.

We indeed can wire up all of these features. But the way things are
wired up right now is extremely fragile and very manual. I don't
disagree with your statement that we old-timers know our way around the
build system. But I certainly don't think it is easy to hack on, and
that is a problem especially if we want to set up Git for success for
the next decade. I want to ensure that the Git project is easily
accessible to people.

> I admittedly have a hard time squaring the benefits and goals we have
> with Meson with the cost of learning a new build system, and/or moving
> away from Make entirely.

I guess this depends on the exact persona you're optimizing for. There
are three main personas involved here:

  - Long-time Git contributors. I don't worry about that persona too
    much. Folks in this category tend to be highly skilled, and they
    should not have much of an issue with adapting to Meson.

  - New contributors. This is a group of people that I think would
    benefit from Meson. They get integration with their favorite IDE,
    have easy ways to discover how to tweak build instructions and can
    use standard invocations for Meson that they might already know from
    other projects.

  - Packagers. This is another group of people that would benefit from
    my point of view. This is mostly because Meson has certain standards
    for how to approach problems, and thus the packager would know for
    how to handle things. They don't have to manually track build
    options and changes thereof, as these can be easily discovered and
    because Meson will error out in case invalid options are passed.

> I am entirely open to the possibility that there is something that I am
> missing here, and that Meson really is a better choice for Git given our
> current direction. But I think if that's true, then the series needs to
> explain that more prominently.

Sure, I am happy to update the commit message.

> == What is the eventual plan for CMake?
> 
> From [PATCH 18/19], you write:
> 
> > If this patch lands the expectation is that it will coexist
> > with our other build systems for a while. Like this, distributions can
> > slowly migrate over to Meson and report any findings they have to us
> > such that we can continue to iterate. A potential cutoff date for other
> > build systems may be Git 3.0.
> 
> I don't view this is a good intermediate state, and is in my view making
> an existing problem that we have worse. On the "existing problem": I
> think that landing CMake support in contrib was a mistake. In my view,
> CMake support should have either been a first-class citizen in Git (such
> that we don't consider a change "done" until it can be built by CMake),
> or should have been maintained out-of-tree.
> 
> But I think we struck a worst-of-both-worlds balance by landing it in
> contrib. It's maintained in the tree, so people expect to be able to
> build the project with it because it comes with a bog-standard clone of
> git.git.
> 
> But despite living in the project's tree, it is not a first-class
> citizen, and subjectively it seems that we get an awful lot of mail
> asking why something doesn't build in CMake, etc. (To your credit, I
> think you have been one of the main people to help with that, often
> fixing those bugs yourself, which is greatly appreciated).
> 
> I don't want to see the project have to pseudo-maintain three build
> systems. It seems like doing so would be cumbersome, and error-prone. I
> am already probably guilty of breaking CMake builds when I add a new
> compilation unit to the project, because of a combination of my lack of
> familiarity with CMake, and the fact that we don't have a project-wide
> convention of treating it with the same care as we do the Makefile. I
> think that having three build systems (even if they only co-existed
> until Git 3.0) would make that problem worse.
> 
> I feel that if we are going to pursue Meson over CMake and/or Make, we
> should have a clear plan to either get rid of CMake, keep it up-to-date,
> or something else.

I fully agree with all you're saying here. Whatever the solution, the
new build system should be a proper first-class citizen and should be
exercised by our CI systems such that they don't silently break.

I also agree that it's going to be a hassle to maintain three (or three
and a half if you count autoconf) build systems. But I don't want to
break any users out there by dropping everything but Meson immediately,
so I think we just have to accept multiple build systems as an
intermediate step. How exactly that would look like is certainly up for
debate. My take would be:

  1. Adopt the new build system and start exercising it via CI.

  2. Drop CMake.

  3. Drop autoconf.

  4. Drop Makefiles.

This should happen over multiple releases such that every step will pull
in additional user groups, which will make the new build system more
solid overall. I could see that one step corresponds to one release
cycle, but I'm also happy to adapt the pacing as necessary.

Patrick
Eli Schwartz Nov. 4, 2024, 3:03 p.m. UTC | #6
On 11/4/24 7:17 AM, Patrick Steinhardt wrote:
> The solution to that problem is autoconfiguration by detecting platform
> specific bits and pieces. And we _also_ have such a build system in the
> form of autoconf, but now we're entering territory that is awfully hard
> to maintain. Most people don't use it at all, the only user seems to
> really be distros. And they tend to hit many issues with autoconf
> because we devs don't use that infra in the first place, creating a bit
> of an awkward situation. Unifying this infrastructure such that devs and
> packagers use the same build infra is thus another goal of my series.


As a distro packager (not of git specifically), my understanding was
that *no* distros use the autoconf, and that at least some distros say
the reason for this is that the autoconf is so unused that it doesn't
actually work.

We tried to use the autoconf but failed.
Eli Schwartz Nov. 4, 2024, 3:11 p.m. UTC | #7
On 10/25/24 3:59 PM, Taylor Blau wrote:

> == Conclusion
> 
> To step back, I want to say that I appreciate your work on this series
> and am certainly not opposed[^1] to the idea that we may need to make
> significant changes to our build infrastructure to support the project's
> goals.
> 
> But I think that what I'm missing currently is a clear picture of what
> goals we *can't* achieve with the existing build system (or could, but
> only at significant cost/awkwardness), and why Meson is the right choice
> to address those gaps.
> 
> If the project can agree that pursuing Meson as a replacement for Make,
> CMake, or both, then I think we would need further clarification on what
> we want to do with CMake (and more generally how we want to support new
> efforts to add additional build systems to Git in the future).


One extremely big distinction is that Make is not a configuration
system, and cannot be, and git has many configuration options that are
currently underserved to the point of nonexistence. This causes a *lot*
of trouble to people attempting to build git as it's not often clear how
to do so other than by building a stock no-options build.

When you do try it, you frequently end up with broken option passing
resulting in an inconsistent git installation where some parts of the
code are built with one option, and other parts of the code are built
with its inverse, and neither of them are the third set of options that
you had finally settled on. This also affects distro maintainers.

The configure.ac tries to solve this problem and fails because it
appears no one bothers to maintain it. The CMake files try to solve this
problem but only for Windows (?). Possibly the reason people struggle
with both is because both feel quite painful to use -- the initial
premise of this patch series is, after all, "I the submitter believe
this build system is nicer than the other option".
Taylor Blau Nov. 4, 2024, 3:18 p.m. UTC | #8
On Mon, Nov 04, 2024 at 01:17:00PM +0100, Patrick Steinhardt wrote:
> > I admittedly have a hard time squaring the benefits and goals we have
> > with Meson with the cost of learning a new build system, and/or moving
> > away from Make entirely.
>
> I guess this depends on the exact persona you're optimizing for. There
> are three main personas involved here:
>
>   - Long-time Git contributors. I don't worry about that persona too
>     much. Folks in this category tend to be highly skilled, and they
>     should not have much of an issue with adapting to Meson.
>
>   - New contributors. This is a group of people that I think would
>     benefit from Meson. They get integration with their favorite IDE,
>     have easy ways to discover how to tweak build instructions and can
>     use standard invocations for Meson that they might already know from
>     other projects.
>
>   - Packagers. This is another group of people that would benefit from
>     my point of view. This is mostly because Meson has certain standards
>     for how to approach problems, and thus the packager would know for
>     how to handle things. They don't have to manually track build
>     options and changes thereof, as these can be easily discovered and
>     because Meson will error out in case invalid options are passed.

I appreciate your thoughtful response to my concerns here. Please feel
free to correct me if I am wrong, but I think the bulk of your argument
is captured fairly well by these three points, so I want to focus my
response here.

Responding in turn, I think my feeling is something like:

  - Long-time Git contributors are going to be the ones who will most
    frequently use the new build system. I am definitely sympathetic to
    getting too comfortable with our existing tools, but so far in your
    response I have not seen a compelling reason to switch the project
    to use Meson.

    What I really want to say here is that I don't think we should be
    over-correcting on things that we are all comfortable with when they
    are indeed not the optimal solution.

    We can and should challenge those assumptions. But I think what I
    see here is us challenging the assumption that 'make' is not the
    right tool for the project, and (at least personally) not seeing
    that it isn't.

  - New contributors are a group that we should be optimizing for, I
    certainly agree with you there. But I think there are a couple of
    points that your response glosses over:

      * New contributors should be telling us what build system they
        prefer, not the other way around. If we are going to switch to
        using a new build system to better accommodate new contributors,
        it should be because either (a) they have told us what doesn't
        work with 'make', or (b) we have a bulk of evidence that new
        contributors cannot easily build the project.

      * New contributors do not interact with build system internals
        nearly as much as more experienced contributors. I would imagine
        that the vast majority of those interactions are simply running
        "make" or "make test".

        You mention a handful of other niceties that Meson provides,
        like language server support, but I am not sure that I agree
        those are (a) the responsibility of the build system to provide,
        or (b) that those needs aren't already well met by the vast
        number of existing tools and IDE integrations that can work with
        ctags.

  - Packagers are something that I admittedly have less exposure to than
    the other groups listed here, but I think my feeling there is
    similar. While they are more likely to exercise far more parts of
    the build system, I think we should also only be switching to a new
    build system if there is evidence of significant, unmet needs by
    packagers, which I have not seen.

> > I feel that if we are going to pursue Meson over CMake and/or Make, we
> > should have a clear plan to either get rid of CMake, keep it up-to-date,
> > or something else.
>
> I fully agree with all you're saying here. Whatever the solution, the
> new build system should be a proper first-class citizen and should be
> exercised by our CI systems such that they don't silently break.
>
> I also agree that it's going to be a hassle to maintain three (or three
> and a half if you count autoconf) build systems. But I don't want to
> break any users out there by dropping everything but Meson immediately,
> so I think we just have to accept multiple build systems as an
> intermediate step. How exactly that would look like is certainly up for
> debate. My take would be:
>
>   1. Adopt the new build system and start exercising it via CI.
>
>   2. Drop CMake.
>
>   3. Drop autoconf.
>
>   4. Drop Makefiles.
>
> This should happen over multiple releases such that every step will pull
> in additional user groups, which will make the new build system more
> solid overall. I could see that one step corresponds to one release
> cycle, but I'm also happy to adapt the pacing as necessary.

I have a hard time imagining the project ever dropping its Makefile
entirely, if for no other reason that make is available nearly
everywhere that we want to build Git, and the Makefile is the product of
nearly two decades of work to make it compile anywhere.

If our tree really is going to have a Makefile in it forever, then I
think adding Meson (even if we remove CMake support) has many of the
same challenges as the state we're in today "supporting" Make and CMake
in parallel.

Thanks,
Taylor
David Aguilar Nov. 9, 2024, 12:58 p.m. UTC | #9
On Mon, Nov 04, 2024 at 10:18:20AM -0500, Taylor Blau wrote:
> On Mon, Nov 04, 2024 at 01:17:00PM +0100, Patrick Steinhardt wrote:
> > > I admittedly have a hard time squaring the benefits and goals we have
> > > with Meson with the cost of learning a new build system, and/or moving
> > > away from Make entirely.
> >
> > I guess this depends on the exact persona you're optimizing for. There
> > are three main personas involved here:
> >
> >   - New contributors. This is a group of people that I think would
> >     benefit from Meson. They get integration with their favorite IDE,
> >     have easy ways to discover how to tweak build instructions and can
> >     use standard invocations for Meson that they might already know from
> >     other projects.

As someone that was once a New Contributor, my perception is that new
contributors are more likely to be familiar with CMake due to its longer
history and wider general popularity.

CMake has standard invocations and IDE integration so this isn't really
a Meson-specific feature.

That said, if we mean, "Linux/Unix-savvy New Contributors," then
I can understand why Meson might be a favorite, and perhaps this
might be the crowd we are looking to target (in the same vein of
the original argument for why Git uses C instead of C++).

The remainder of my reply assumes that we are targetting a general
audience (in other words, including Windows users).

Disclaimer ~ I don't use Windows so I'm making some broad assumptions and
generalizations about that userbase.

> Patrick Steinhardt wrote:
> >   - Packagers. This is another group of people that would benefit from
> >     my point of view. This is mostly because Meson has certain standards
> >     for how to approach problems, and thus the packager would know for
> >     how to handle things. They don't have to manually track build
> >     options and changes thereof, as these can be easily discovered and
> >     because Meson will error out in case invalid options are passed.

CMake's option() variables and its GNUInstallDirs module pretty much
handles all of the standardization that packagers are looking for on
this front, so this argument doesn't push the needle towards Meson over
CMake from my perspective.


> Taylor Blau wrote:
> I appreciate your thoughtful response to my concerns here. Please feel
> free to correct me if I am wrong, but I think the bulk of your argument
> is captured fairly well by these three points, so I want to focus my
> response here.
> 
> Responding in turn, I think my feeling is something like:
> 
>   - Long-time Git contributors are going to be the ones who will most
>     frequently use the new build system. I am definitely sympathetic to
>     getting too comfortable with our existing tools, but so far in your
>     response I have not seen a compelling reason to switch the project
>     to use Meson.

Likewise, I have not seen a compelling reason to not focus the
effort on CMake instead. In other words, why not enhance the current
status quo (Make + CMake) instead of trying to replace it?


>   - New contributors are a group that we should be optimizing for, I
>     certainly agree with you there. But I think there are a couple of
>     points that your response glosses over:
> 
>       * New contributors should be telling us what build system they
>         prefer, not the other way around. If we are going to switch to
>         using a new build system to better accommodate new contributors,
>         it should be because either (a) they have told us what doesn't
>         work with 'make', or (b) we have a bulk of evidence that new
>         contributors cannot easily build the project.

As someone that was once a New Contributor, I would be more comfortable
with CMake (over Meson) because it's widespread and because it has
less dependencies.


>       * New contributors do not interact with build system internals
>         nearly as much as more experienced contributors. I would imagine
>         that the vast majority of those interactions are simply running
>         "make" or "make test".
> 
>         You mention a handful of other niceties that Meson provides,
>         like language server support, but I am not sure that I agree
>         those are (a) the responsibility of the build system to provide,
>         or (b) that those needs aren't already well met by the vast
>         number of existing tools and IDE integrations that can work with
>         ctags.

CMake has all of these same bells and whistles, and it's already present
in git.git. LSP support just means being able to generate a
compile_commands.json file, and the current CMake setup already does
that.

The one thing that no one has mentioned is dependencies.

CMake has less dependencies. Python is arguably a liability in the build
system arena, and Meson requires it.

Furthermore, if you must have your fast Ninja builds then CMake supports
that too, but, critically, it's optional. If you don't have Ninja then
you can use CMake's Makefile generator. Meson, OTOH, requires
Ninja. CMake seems like a more pragmatic option in that regard.

Sorry for derailing this thread to share my Meson vs. CMake opinion, but
if the main con that the Meson website has to say about CMake is, "The
scripting language is cumbersome to work with. Some simple things are
more complicated than necessary." [1] then my general feeling is that
it's not a very strong reason for Git's needs.

[1] https://mesonbuild.com/Comparisons.html#cmake


>   - Packagers are something that I admittedly have less exposure to than
>     the other groups listed here, but I think my feeling there is
>     similar. While they are more likely to exercise far more parts of
>     the build system, I think we should also only be switching to a new
>     build system if there is evidence of significant, unmet needs by
>     packagers, which I have not seen.

I concur with that. As someone that deals with packaging I strongly
prefer tools that have minimal dependencies, just like Git. Meson
brings along extra requirements (namely Python, as I mentioned before)
whereas CMake requires just a C++ compiler and Make.

On that front, Git's Make-only setup is pretty wonderful from a
packager's perspective because all you need is Make, so I don't
think we would ever want to ditch the Makefiles, and that's okay.


> > > I feel that if we are going to pursue Meson over CMake and/or Make, we
> > > should have a clear plan to either get rid of CMake, keep it up-to-date,
> > > or something else.

We should also have a strong reason to transition to Meson over the
"something else" option of improving the CMake integration instead of
trying to replace it.


> > I fully agree with all you're saying here. Whatever the solution, the
> > new build system should be a proper first-class citizen and should be
> > exercised by our CI systems such that they don't silently break.
> >
> > I also agree that it's going to be a hassle to maintain three (or three
> > and a half if you count autoconf) build systems. But I don't want to
> > break any users out there by dropping everything but Meson immediately,
> > so I think we just have to accept multiple build systems as an
> > intermediate step. How exactly that would look like is certainly up for
> > debate. My take would be:
> >
> >   1. Adopt the new build system and start exercising it via CI.
> >
> >   2. Drop CMake.
> >
> >   3. Drop autoconf.
> >
> >   4. Drop Makefiles.
> >
> > This should happen over multiple releases such that every step will pull
> > in additional user groups, which will make the new build system more
> > solid overall. I could see that one step corresponds to one release
> > cycle, but I'm also happy to adapt the pacing as necessary.

My take would be:

1. Enhance CMake
2. Drop Autoconf
3. Profit?

This would not need to happen over multiple releases. There'd just be
one minor or major release where (2) would happen once (1) has reached
some substantial level of maturity, and that'd be it.

Arguably, we could even do (2) before (1) and it'd be fine.


> I have a hard time imagining the project ever dropping its Makefile
> entirely, if for no other reason that make is available nearly
> everywhere that we want to build Git, and the Makefile is the product of
> nearly two decades of work to make it compile anywhere.
> 
> If our tree really is going to have a Makefile in it forever, then I
> think adding Meson (even if we remove CMake support) has many of the
> same challenges as the state we're in today "supporting" Make and CMake
> in parallel.

I agree, and from my outsider perspective it seems like a simpler answer
would be to double-down on CMake rather than having to adopt another
system and do the whole deprecation dance.

My perception is that any benefits we would get from supporting Meson
would also be present with CMake, but with less effort.

That's just my opinion, though. Perhaps there are strong reasons for why
Meson is a better tool for the purposes of attracting New Contributors
and improving our day-to-day usage, but the benefits are not immediately
obvious to me at least.
Eli Schwartz Nov. 10, 2024, 1:07 a.m. UTC | #10
On 11/9/24 7:58 AM, David Aguilar wrote:
>> Patrick Steinhardt wrote:
>>>   - Packagers. This is another group of people that would benefit from
>>>     my point of view. This is mostly because Meson has certain standards
>>>     for how to approach problems, and thus the packager would know for
>>>     how to handle things. They don't have to manually track build
>>>     options and changes thereof, as these can be easily discovered and
>>>     because Meson will error out in case invalid options are passed.
> 
> CMake's option() variables and its GNUInstallDirs module pretty much
> handles all of the standardization that packagers are looking for on
> this front, so this argument doesn't push the needle towards Meson over
> CMake from my perspective.


The specific points brought by Patrick, which I guess you are disputing,
are that meson options are "easily discovered" and "will error out in
case invalid options are passed".


Obviously biased as a Meson maintainer, but

No. Absolutely not. CMake's option() variables are deeply, frustratingly
bad as a user experience, for one simple reason. They are
turing-complete and you cannot know they exist until you have
successfully configured cmake at least once. Even then, the only way to
find out about them is to execute a cmake subcommand that prints "cache
variables" rather than "options", since options are just cache variables
marked with an explanation.

In comparison, GNU autotools rigorously defined the standard GNU
interface to configuring a build. In a freshly extracted copy of the
source code, run

./configure --help

It lists various options, split up by section e.g.


Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]


It has additional sections for "optional features" / "optional
packages", and lists "Some influential environment variables" as well.
You do *not* need to successfully configure before seeing this help
text, and the same options always exist every time you run it.

Meson does something similar: in a freshly extracted source tree, run
"meson configure". It has some cool tricks, such as opening into a pager
if possible, and having table-formatted, colored output to make it easy
to distinguish between the option name, its default and allowed values,
and the description.

Meson splits the options table between core, base, compiler-specific,
directory standards, and project-specific options. All the options that
come from the project itself are further available in a single
meson_options.txt" / "meson.options" file at the root of the project,
you don't have to inspect thousands of lines of code to see where
option() might have been invoked, or figure out whether it was
transitively defined by including a module installed by a different
project to /usr/share/ECM/modules/ (???) that includes a third module
from /usr/share/cmake/Modules/ without which the option simply does not
exist at all.


CMake thus fails on both points raised by Patrick:

- cmake options *cannot* be easily discovered, and many people (myself
  included) would argue that they cannot be discovered at all, whether
  easily or otherwise

- since cmake options are, in fact, just cache variables, it logically
  cannot be an error to define options that don't exist. You are quite
  free to define any cache variables you want, whether they exist or
  not, and cmake is entirely unconcerned with your doing so. Define a
  "NOT_AN_OPTION" variable that doesn't exist? ok, no effect -- no part
  of the build attempts to dereference ${NOT_AN_OPTION} so it is simply
  ignored.

...

GNUInstallDirs is... workable, sort of, but is also a tremendous footgun
as you have to manually set it up and most people do not. Being able to
work around the bad defaults is better than nothing, sure. No one is
forcing any given project to use the bad defaults. But I'd hardly call
that a ringing endorsement.


> As someone that was once a New Contributor, I would be more comfortable
> with CMake (over Meson) because it's widespread and because it has
> less dependencies.


I just took a look at cmake's dependencies on my Gentoo system. It
appears to have a whole lot of them.


RDEPEND="
        >=app-arch/libarchive-3.3.3:=
        app-crypt/rhash:0=
        >=dev-libs/expat-2.0.1
        >=dev-libs/jsoncpp-1.9.2-r2:0=
        >=dev-libs/libuv-1.10.0:=
        >=net-misc/curl-7.21.5[ssl]
        sys-libs/zlib
        virtual/pkgconfig
        dap? ( dev-cpp/cppdap )
        gui? (
                !qt6? (
                        dev-qt/qtcore:5
                        dev-qt/qtgui:5
                        dev-qt/qtwidgets:5
                )
                qt6? ( dev-qt/qtbase:6[gui,widgets] )
        )
        ncurses? ( sys-libs/ncurses:= )
"

It also is written in C++.

meson is written in python, so it depends on that. And of course on
ninja (for unix systems). It has no other dependencies, period, end of
story.

Although like cmake, it depends on my system on virtual/pkgconfig -- for
both packages, that pkgconfig dependency is a convenience since software
has a habit of using build system functions such as "pkg_check_modules"
(cmake) or "dependency" (meson) with almost universal regularity, so
it's easier than having tens of thousands of packages all depend on
virtual/pkgconfig.

cmake is easily installed from their website as a prebuilt binary with
all dependencies bundled inside, I suppose. So that is "less
dependencies"? But meson releases a prebuilt binary redistributable as a
Windows MSI as well -- and on Linux, python is usually preinstalled.
There's no *demand* for a prebuilt binary redistributable for Linux. If
there was, we already have the packaging scripts to make one, and it's
how I test the operation of the Windows MSI.

By the way, Python 3.6 to 3.10 use C89 "with several select C99
features". There are people who consider CMake's C++ requirement an
insurmountably steep obstacle, e.g. that is why OpenSSL refuses to use
any build system other than their own custom one written in Perl.


> The one thing that no one has mentioned is dependencies.
> 
> CMake has less dependencies. Python is arguably a liability in the build
> system arena, and Meson requires it.


Please explain more about this. I don't really understand what you mean
by "a liability", nor how it is "more dependencies" than cmake.


> Furthermore, if you must have your fast Ninja builds then CMake supports
> that too, but, critically, it's optional. If you don't have Ninja then
> you can use CMake's Makefile generator. Meson, OTOH, requires
> Ninja. CMake seems like a more pragmatic option in that regard.
> 
> Sorry for derailing this thread to share my Meson vs. CMake opinion, but
> if the main con that the Meson website has to say about CMake is, "The
> scripting language is cumbersome to work with. Some simple things are
> more complicated than necessary." [1] then my general feeling is that
> it's not a very strong reason for Git's needs.
> 
> [1] https://mesonbuild.com/Comparisons.html#cmake


Those are "some pros and cons", not all pros and cons, and it may
surprise you to hear that that page is not well maintained because a) no
one is strongly motivated to do so, b) no one feels passionately about
making an anti-cmake rant part of the core documentation.

That page was written once in 2014 and essentially never touched since,
though tree-wide formatting tweaks were made and the documentation
switched hosting and git imported into the main git repository in 2017.


> I concur with that. As someone that deals with packaging I strongly
> prefer tools that have minimal dependencies, just like Git. Meson
> brings along extra requirements (namely Python, as I mentioned before)
> whereas CMake requires just a C++ compiler and Make.


... wait, so is this or isn't this about the dependencies for building
and installing cmake, rather than merely running it?

CMake depends on projects that build with cmake, by the way. This is the
hell dimension of distro packaging.

(It also depends on jsoncpp which builds with meson, incidentally.)
Patrick Steinhardt Nov. 11, 2024, 10:36 a.m. UTC | #11
On Mon, Nov 04, 2024 at 10:03:17AM -0500, Eli Schwartz wrote:
> On 11/4/24 7:17 AM, Patrick Steinhardt wrote:
> > The solution to that problem is autoconfiguration by detecting platform
> > specific bits and pieces. And we _also_ have such a build system in the
> > form of autoconf, but now we're entering territory that is awfully hard
> > to maintain. Most people don't use it at all, the only user seems to
> > really be distros. And they tend to hit many issues with autoconf
> > because we devs don't use that infra in the first place, creating a bit
> > of an awkward situation. Unifying this infrastructure such that devs and
> > packagers use the same build infra is thus another goal of my series.
> 
> 
> As a distro packager (not of git specifically), my understanding was
> that *no* distros use the autoconf, and that at least some distros say
> the reason for this is that the autoconf is so unused that it doesn't
> actually work.
> 
> We tried to use the autoconf but failed.

I thought I saw some distros using autoconf, so it at least isn't
_completely_ broken. Let me double check... FreeBSD uses it, but other
than that all the others that I've checked use the Makefile directly.

Patrick
Patrick Steinhardt Nov. 11, 2024, 10:36 a.m. UTC | #12
On Mon, Nov 04, 2024 at 10:18:20AM -0500, Taylor Blau wrote:
> On Mon, Nov 04, 2024 at 01:17:00PM +0100, Patrick Steinhardt wrote:
> > > I admittedly have a hard time squaring the benefits and goals we have
> > > with Meson with the cost of learning a new build system, and/or moving
> > > away from Make entirely.
> >
> > I guess this depends on the exact persona you're optimizing for. There
> > are three main personas involved here:
> >
> >   - Long-time Git contributors. I don't worry about that persona too
> >     much. Folks in this category tend to be highly skilled, and they
> >     should not have much of an issue with adapting to Meson.
> >
> >   - New contributors. This is a group of people that I think would
> >     benefit from Meson. They get integration with their favorite IDE,
> >     have easy ways to discover how to tweak build instructions and can
> >     use standard invocations for Meson that they might already know from
> >     other projects.
> >
> >   - Packagers. This is another group of people that would benefit from
> >     my point of view. This is mostly because Meson has certain standards
> >     for how to approach problems, and thus the packager would know for
> >     how to handle things. They don't have to manually track build
> >     options and changes thereof, as these can be easily discovered and
> >     because Meson will error out in case invalid options are passed.
> 
> I appreciate your thoughtful response to my concerns here. Please feel
> free to correct me if I am wrong, but I think the bulk of your argument
> is captured fairly well by these three points, so I want to focus my
> response here.
> 
> Responding in turn, I think my feeling is something like:
> 
>   - Long-time Git contributors are going to be the ones who will most
>     frequently use the new build system. I am definitely sympathetic to
>     getting too comfortable with our existing tools, but so far in your
>     response I have not seen a compelling reason to switch the project
>     to use Meson.

Yes, that's certainly true. And while I think we should optimize more
for newcomers as stated, I still think that Meson is very much
preferable over Makefiles for long-time contributors, as well. The
transition period may take some time, but in the end it just feels
superior to Make from my poin of view.

Out of curiosity: did you try the Meson build? I personally have to say
that I already prefer working with it because the workflow with it is so
much nicer. It has nicer output, is faster, has out-of-tree builds,
makes it easier to configure and test execution feels way nicer compared
to my previous workflow with make.

This is all subjective of course.

>     What I really want to say here is that I don't think we should be
>     over-correcting on things that we are all comfortable with when they
>     are indeed not the optimal solution.
> 
>     We can and should challenge those assumptions. But I think what I
>     see here is us challenging the assumption that 'make' is not the
>     right tool for the project, and (at least personally) not seeing
>     that it isn't.

As said, Makefiles have some problems that aren't really solveable from
my perspective. And I think part of the problem in this context is that
the typical developer working on Git is very much centered around Unix.
The experience on non-Unix systems is kind of a pain though as there is
no proper integration with anything.

And that's not only true for non-Unix-like platforms, but basically for
anyone who isn't comfortable working from the command line. Integration
of the project into an IDE with our Makefile is hard to pull off. While
many editors can of course trivially execute the Makefile for you,
setting things up such that it is _properly_ integrated into the IDE is
hard.

Overall, I don't think we old time contributors lose anything by using
Meson instead of Makefiles, quite on the contrary we get speedier builds
and nicer integration. We'd have to adapt eventually, but I don't see
that as a huge barrier.

>   - New contributors are a group that we should be optimizing for, I
>     certainly agree with you there. But I think there are a couple of
>     points that your response glosses over:
> 
>       * New contributors should be telling us what build system they
>         prefer, not the other way around. If we are going to switch to
>         using a new build system to better accommodate new contributors,
>         it should be because either (a) they have told us what doesn't
>         work with 'make', or (b) we have a bulk of evidence that new
>         contributors cannot easily build the project.

That's basically why the whole patch series is marked as an RFC: to get
feedback from people and ask them for their opinion.

>       * New contributors do not interact with build system internals
>         nearly as much as more experienced contributors. I would imagine
>         that the vast majority of those interactions are simply running
>         "make" or "make test".

Agreed.

I assume that what they are after is a streamlined process for how to
compile and test the project. The build system should be providing good
feedback for missing dependencies, for existing build options and how to
use them. These are all things that Meson provides by default, and our
Makefile doesn't.

>         You mention a handful of other niceties that Meson provides,
>         like language server support, but I am not sure that I agree
>         those are (a) the responsibility of the build system to provide,
>         or (b) that those needs aren't already well met by the vast
>         number of existing tools and IDE integrations that can work with
>         ctags.

From my own experience the integration with other IDEs isn't great at
all in Makefile-based projects. I don't use IDEs though, so I am
probably not the best resource to judge.

>   - Packagers are something that I admittedly have less exposure to than
>     the other groups listed here, but I think my feeling there is
>     similar. While they are more likely to exercise far more parts of
>     the build system, I think we should also only be switching to a new
>     build system if there is evidence of significant, unmet needs by
>     packagers, which I have not seen.

We have repeatedly gotten feedback that our autoconf-based build is
basically broken and does not work well. After all, that's what spawned
the whole discussion around a more modern build system that is able to
properly auto-detect what the host system provides.

> > > I feel that if we are going to pursue Meson over CMake and/or Make, we
> > > should have a clear plan to either get rid of CMake, keep it up-to-date,
> > > or something else.
> >
> > I fully agree with all you're saying here. Whatever the solution, the
> > new build system should be a proper first-class citizen and should be
> > exercised by our CI systems such that they don't silently break.
> >
> > I also agree that it's going to be a hassle to maintain three (or three
> > and a half if you count autoconf) build systems. But I don't want to
> > break any users out there by dropping everything but Meson immediately,
> > so I think we just have to accept multiple build systems as an
> > intermediate step. How exactly that would look like is certainly up for
> > debate. My take would be:
> >
> >   1. Adopt the new build system and start exercising it via CI.
> >
> >   2. Drop CMake.
> >
> >   3. Drop autoconf.
> >
> >   4. Drop Makefiles.
> >
> > This should happen over multiple releases such that every step will pull
> > in additional user groups, which will make the new build system more
> > solid overall. I could see that one step corresponds to one release
> > cycle, but I'm also happy to adapt the pacing as necessary.
> 
> I have a hard time imagining the project ever dropping its Makefile
> entirely, if for no other reason that make is available nearly
> everywhere that we want to build Git, and the Makefile is the product of
> nearly two decades of work to make it compile anywhere.
> 
> If our tree really is going to have a Makefile in it forever, then I
> think adding Meson (even if we remove CMake support) has many of the
> same challenges as the state we're in today "supporting" Make and CMake
> in parallel.

If our stance is that we cannot ever drop our Makefile because it has
grown for such a long time, but maintaing two official build systems at
the same time is not an option either, then our hands are tied. So I
don't think is a reasonable approach overall.

Yes, transitions like this will cause some pain, but I think that it is
relatively easy to avoid most of the pain by having a proper plan for
how to do the transition. The biggest pain will be that we have to
maintain multiple build systems and keep them in sync for some time, but
that also has a couple of advantages:

  - We can iteratively evolve the replacement build system over time
    until it is ready to fully replace the old one.

  - We don't have to screw anyone over by having a hard cutoff date.

  - We can decide that the replacement build system is insufficient and
    discard it.

  - Users of the build system can experiment with both build systems.

Patrick
Patrick Steinhardt Nov. 11, 2024, 10:36 a.m. UTC | #13
On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
> On Mon, Nov 04, 2024 at 10:18:20AM -0500, Taylor Blau wrote:
> > On Mon, Nov 04, 2024 at 01:17:00PM +0100, Patrick Steinhardt wrote:
> > > > I admittedly have a hard time squaring the benefits and goals we have
> > > > with Meson with the cost of learning a new build system, and/or moving
> > > > away from Make entirely.
> > >
> > > I guess this depends on the exact persona you're optimizing for. There
> > > are three main personas involved here:
> > >
> > >   - New contributors. This is a group of people that I think would
> > >     benefit from Meson. They get integration with their favorite IDE,
> > >     have easy ways to discover how to tweak build instructions and can
> > >     use standard invocations for Meson that they might already know from
> > >     other projects.
> 
> As someone that was once a New Contributor, my perception is that new
> contributors are more likely to be familiar with CMake due to its longer
> history and wider general popularity.
> 
> CMake has standard invocations and IDE integration so this isn't really
> a Meson-specific feature.
> 
> That said, if we mean, "Linux/Unix-savvy New Contributors," then
> I can understand why Meson might be a favorite, and perhaps this
> might be the crowd we are looking to target (in the same vein of
> the original argument for why Git uses C instead of C++).
> 
> The remainder of my reply assumes that we are targetting a general
> audience (in other words, including Windows users).
> 
> Disclaimer ~ I don't use Windows so I'm making some broad assumptions and
> generalizations about that userbase.

My goal is to not only make things easier to use for Linux users, but
also for users on other platforms like Windows while also catering to
the typical developer of Git and making the solution for them as tasty
as possible.

I agree that CMake is a tad easier to use and set up on Windows, mostly
because it is directly integrated into MSVC. But I also think that CMake
is a harder sell towards the power users because it is comparatively
hard to maintain due to its somewhat arcane syntax, implicit variables
and things like this.

So I'm basically trying to find a good middle ground where all of the
respective target audiences get benefit:

  - For Unix devs I think that Meson is easier to maintain and use
    compared to CMake. We also get nice features like out-of-source
    builds, good integration with the test suite and easy integration
    with IDEs.

  - For Windows devs we have an officially supported way to build Meson
    from MSVC and co. Also, subprojects allow us to have as easy story
    for how to build Git without preinstalled dependencies, which is not
    currently possible with CMake to the best of my knowledge.

  - For packagers I think that Meson provides better discoverability of
    options than CMake.

So Meson may not be the perfect solution for everyone of these target
audiences, and better solutions may exist to cater specific needs. But
it provides a net benefit for every single one of these audiences from
my point of view. And when taking the benefits for all target audiences
combined I think that Meson provides the bigger win compared to CMake.

> > Patrick Steinhardt wrote:
> > >   - Packagers. This is another group of people that would benefit from
> > >     my point of view. This is mostly because Meson has certain standards
> > >     for how to approach problems, and thus the packager would know for
> > >     how to handle things. They don't have to manually track build
> > >     options and changes thereof, as these can be easily discovered and
> > >     because Meson will error out in case invalid options are passed.
> 
> CMake's option() variables and its GNUInstallDirs module pretty much
> handles all of the standardization that packagers are looking for on
> this front, so this argument doesn't push the needle towards Meson over
> CMake from my perspective.

I think that discoverability of Meson is way better. Here you can simply
say `meson configure` and it provides you a nice list of all options
that are available. For CMake it always used to be a big pain.

> > Taylor Blau wrote:
> > I appreciate your thoughtful response to my concerns here. Please feel
> > free to correct me if I am wrong, but I think the bulk of your argument
> > is captured fairly well by these three points, so I want to focus my
> > response here.
> > 
> > Responding in turn, I think my feeling is something like:
> > 
> >   - Long-time Git contributors are going to be the ones who will most
> >     frequently use the new build system. I am definitely sympathetic to
> >     getting too comfortable with our existing tools, but so far in your
> >     response I have not seen a compelling reason to switch the project
> >     to use Meson.
> 
> Likewise, I have not seen a compelling reason to not focus the
> effort on CMake instead. In other words, why not enhance the current
> status quo (Make + CMake) instead of trying to replace it?

As mentioned above, I mostly think that Meson makes for a more
compelling overall package. That being said, if we eventually come to
the conclusion that we as a community want CMake instead of Meson, then
I am willing to go there.

> >       * New contributors do not interact with build system internals
> >         nearly as much as more experienced contributors. I would imagine
> >         that the vast majority of those interactions are simply running
> >         "make" or "make test".
> > 
> >         You mention a handful of other niceties that Meson provides,
> >         like language server support, but I am not sure that I agree
> >         those are (a) the responsibility of the build system to provide,
> >         or (b) that those needs aren't already well met by the vast
> >         number of existing tools and IDE integrations that can work with
> >         ctags.
> 
> CMake has all of these same bells and whistles, and it's already present
> in git.git. LSP support just means being able to generate a
> compile_commands.json file, and the current CMake setup already does
> that.
> 
> The one thing that no one has mentioned is dependencies.
> 
> CMake has less dependencies. Python is arguably a liability in the build
> system arena, and Meson requires it.

Eli has menitoned [muon](https://muon.build/), which is a drop-in
replacement for Meson written in plain C99. I don't know whether it is
currently able to compile the Git project, but if this is going to be a
concern for people I can try to make sure that it does.

> Furthermore, if you must have your fast Ninja builds then CMake supports
> that too, but, critically, it's optional. If you don't have Ninja then
> you can use CMake's Makefile generator. Meson, OTOH, requires
> Ninja. CMake seems like a more pragmatic option in that regard.
> 
> Sorry for derailing this thread to share my Meson vs. CMake opinion, but
> if the main con that the Meson website has to say about CMake is, "The
> scripting language is cumbersome to work with. Some simple things are
> more complicated than necessary." [1] then my general feeling is that
> it's not a very strong reason for Git's needs.

No need to be sorry at all, the whole thread is marked as an RFC exactly
so that people can provide their opinions.

> > > I fully agree with all you're saying here. Whatever the solution, the
> > > new build system should be a proper first-class citizen and should be
> > > exercised by our CI systems such that they don't silently break.
> > >
> > > I also agree that it's going to be a hassle to maintain three (or three
> > > and a half if you count autoconf) build systems. But I don't want to
> > > break any users out there by dropping everything but Meson immediately,
> > > so I think we just have to accept multiple build systems as an
> > > intermediate step. How exactly that would look like is certainly up for
> > > debate. My take would be:
> > >
> > >   1. Adopt the new build system and start exercising it via CI.
> > >
> > >   2. Drop CMake.
> > >
> > >   3. Drop autoconf.
> > >
> > >   4. Drop Makefiles.
> > >
> > > This should happen over multiple releases such that every step will pull
> > > in additional user groups, which will make the new build system more
> > > solid overall. I could see that one step corresponds to one release
> > > cycle, but I'm also happy to adapt the pacing as necessary.
> 
> My take would be:
> 
> 1. Enhance CMake
> 2. Drop Autoconf
> 3. Profit?
> 
> This would not need to happen over multiple releases. There'd just be
> one minor or major release where (2) would happen once (1) has reached
> some substantial level of maturity, and that'd be it.
> 
> Arguably, we could even do (2) before (1) and it'd be fine.

I'd honestly be sad if we go down the CMake route, mostly because I
think that it is an inferior build system compared to Meson. I have
worked with it extensively in the context of libgit2 and always found it
to be a pain due to its esoteric syntax, the use of so many implicit
variables, platform CMake policies, and there being so many ways to do
the same thing and, where the easiest solution is typically the wrong
one to pick.

That being said, I'm trying to be as pragmatic is possible: my main goal
is to have a modern build system that is easier to use. So while I think
that Meson fits better into that role, the next-best thing would be
CMake from my point of view.

So I'll continue to champion Meson, but if the project as a whole agrees
to take up CMake as another official build system then I'll adapt and
make that happen.

> > I have a hard time imagining the project ever dropping its Makefile
> > entirely, if for no other reason that make is available nearly
> > everywhere that we want to build Git, and the Makefile is the product of
> > nearly two decades of work to make it compile anywhere.
> > 
> > If our tree really is going to have a Makefile in it forever, then I
> > think adding Meson (even if we remove CMake support) has many of the
> > same challenges as the state we're in today "supporting" Make and CMake
> > in parallel.
> 
> I agree, and from my outsider perspective it seems like a simpler answer
> would be to double-down on CMake rather than having to adopt another
> system and do the whole deprecation dance.
> 
> My perception is that any benefits we would get from supporting Meson
> would also be present with CMake, but with less effort.

I doubt the "less effort" part. The Meson build instructions are way
more complete compared to the CMake build instructions by now -- many
things that work with Meson don't work with CMake. So we would have to
invest significant resources to polish CMake.

> That's just my opinion, though. Perhaps there are strong reasons for why
> Meson is a better tool for the purposes of attracting New Contributors
> and improving our day-to-day usage, but the benefits are not immediately
> obvious to me at least.

Thanks for your input, highly appreciated!

Patrick
Jeff King Nov. 11, 2024, 9:06 p.m. UTC | #14
On Mon, Nov 11, 2024 at 11:36:30AM +0100, Patrick Steinhardt wrote:

> >   - Long-time Git contributors are going to be the ones who will most
> >     frequently use the new build system. I am definitely sympathetic to
> >     getting too comfortable with our existing tools, but so far in your
> >     response I have not seen a compelling reason to switch the project
> >     to use Meson.
> 
> Yes, that's certainly true. And while I think we should optimize more
> for newcomers as stated, I still think that Meson is very much
> preferable over Makefiles for long-time contributors, as well. The
> transition period may take some time, but in the end it just feels
> superior to Make from my poin of view.

The number one thing I care about as a developer is that the build is
_reliable_. Right now, if I move forwards and backwards in history and
type "make" I will almost[1] always get a correct result based on the
current tree, with the minimal required amount of building. This is
important for bisecting.

When I have worked on other projects, especially those that use
autotools, I quite frequently run into cases where building from a dirty
state cause bizarre problems that go away with a "git clean &&
./configure && make". But then bisection is _much_ slower because we're
building from scratch (not to mention that autoconf itself is
horrifically slow).

How does the meson build do here? I don't have any reason to think it
would be bad, but I am nervous of any change.

[1] I say "almost" because there are one or two spots in our history
    where you can run into link errors jumping over them. But for a
    20-year project that's not too bad, and they happen infrequently
    enough that I don't worry about it.

> Out of curiosity: did you try the Meson build? I personally have to say
> that I already prefer working with it because the workflow with it is so
> much nicer. It has nicer output, is faster, has out-of-tree builds,
> makes it easier to configure and test execution feels way nicer compared
> to my previous workflow with make.

I hadn't tried it. I did now, checking out origin/ps/build^ (to drop the
"seen" resolution topic), but it didn't work:

  $ meson setup build
  [...]
  Program msgfmt found: NO
  po/meson.build:3: WARNING: Gettext not found, all translation (po) targets will be ignored.

  po/meson.build:3:20: ERROR: Can not assign void to variable.

I guess the assignment of "translations" there needs to be made
conditional?

-Peff
Eli Schwartz Nov. 11, 2024, 9:39 p.m. UTC | #15
On 11/11/24 4:06 PM, Jeff King wrote:
> The number one thing I care about as a developer is that the build is
> _reliable_. Right now, if I move forwards and backwards in history and
> type "make" I will almost[1] always get a correct result based on the
> current tree, with the minimal required amount of building. This is
> important for bisecting.
> 
> When I have worked on other projects, especially those that use
> autotools, I quite frequently run into cases where building from a dirty
> state cause bizarre problems that go away with a "git clean &&
> ./configure && make". But then bisection is _much_ slower because we're
> building from scratch (not to mention that autoconf itself is
> horrifically slow).
> 
> How does the meson build do here? I don't have any reason to think it
> would be bad, but I am nervous of any change.


This is something that has bothered me about autoconf as well. Meson is
much more reliable about:

- forcing a buildsystem reconfigure on any changes to the buildsystem
  files

- due to using ninja, forcing any object files to be rebuilt on e.g. any
  changes to compiler flags, since the *entire* compiler command line is
  part of the key that determines staleness

- keeping your existing objects between buildsystem reconfigures, if the
  resulting reconfigure didn't change the compiler command line for that
  specific object file


>> Out of curiosity: did you try the Meson build? I personally have to say
>> that I already prefer working with it because the workflow with it is so
>> much nicer. It has nicer output, is faster, has out-of-tree builds,
>> makes it easier to configure and test execution feels way nicer compared
>> to my previous workflow with make.
> 
> I hadn't tried it. I did now, checking out origin/ps/build^ (to drop the
> "seen" resolution topic), but it didn't work:
> 
>   $ meson setup build
>   [...]
>   Program msgfmt found: NO
>   po/meson.build:3: WARNING: Gettext not found, all translation (po) targets will be ignored.
> 
>   po/meson.build:3:20: ERROR: Can not assign void to variable.
> 
> I guess the assignment of "translations" there needs to be made
> conditional?


Yeah, this is an interesting quirk. Many projects would tend to figure
that translation (po) targets are "optional" because if you don't have
msgfmt installed then you can just install the project without any
translations and then non-English speakers will be inconvenienced but at
least the entire project isn't completely un-buildable. So meson
automatically disables the target and logs a warning, but then this
project *also* wants to depend on the translations for the testsuite.

So this should be taken into account. Do the tests actually need
translations, though?
Eli Schwartz Nov. 11, 2024, 9:48 p.m. UTC | #16
On 11/11/24 5:36 AM, Patrick Steinhardt wrote:
> On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
>> The one thing that no one has mentioned is dependencies.
>>
>> CMake has less dependencies. Python is arguably a liability in the build
>> system arena, and Meson requires it.
> 
> Eli has menitoned [muon](https://muon.build/), which is a drop-in
> replacement for Meson written in plain C99. I don't know whether it is
> currently able to compile the Git project, but if this is going to be a
> concern for people I can try to make sure that it does.

I was wondering whether I should say something, because I don't really
feel the criticism was on-target to begin with. But...

I am delighted to be able to confirm, that muon works quite well here.

It did require two small tweaks for not yet implemented features in
muon, that meson had and which this patch series depends on:

the iconv special dependency, which I provided a patch for:

https://git.sr.ht/~lattis/muon/commit/75d33f6b6d482344d969e4ad6ce1527353f91cce

using fallback from gnu99 to c11 for the sake of MSVC, which I reported
and got the muon developer to implement:

https://git.sr.ht/~lattis/muon/commit/a70e9687f3bfb8b9c21baf9acdfe84f97a42b11f


(Note the commit author dates by the way. I had the same general thought
about whether muon could satisfy git users such as, frankly, ones more
interesting to me than "python has too many dependencies". Such as
perhaps HPE NonStop users, and I tried muon out a month ago. Yes -- even
though I am a *meson* maintainer, I consider this a useful alternative
to have. Meson's FAQ includes discussion about whether it makes sense to
require Python, and notes that we specifically avoided providing any
"provide your own python extensions" functionality because it would
prevent being able to ever rewrite in another not-python language. We
also document muon as an alternative in our FAQ.)


With these two small changes, muon compiles git successfully, and passes
all tests but one:



running tests for project 'git'
1030/1030 f:1 s:0 j:1
[===========================================================================================================================================================================================]
finished 1030 tests, 0 expected fail, 1 fail, 0 skipped
fail    9.32s t5324-split-commit-graph
stdout: 'ok 1 - setup repo
ok 2 - tweak umask for modebit tests
ok 3 - create commits and write commit-graph
ok 4 - check normal git operations: graph exists
ok 5 - add more commits, and write a new base graph
ok 6 - fork and fail to base a chain on a commit-graph file
ok 7 - add three more commits, write a tip graph
ok 8 - check normal git operations: split commit-graph: merge 3 vs 2
ok 9 - add one commit, write a tip graph
ok 10 - check normal git operations: three-layer commit-graph: commit 11
vs 6
ok 11 - add one commit, write a merged graph
ok 12 - check normal git operations: merged commit-graph: commit 12 vs 6
ok 13 - create fork and chain across alternate
ok 14 - check normal git operations: alternate: commit 13 vs 6
ok 15 - test merge stragety constants
ok 16 - remove commit-graph-chain file after flattening
ok 17 - verify hashes along chain, even in shallow
ok 18 - verify notices chain slice which is bogus (base)
ok 19 - verify notices chain slice which is bogus (tip)
ok 20 - verify --shallow does not check base contents
ok 21 - warn on base graph chunk incorrect
ok 22 - verify after commit-graph-chain corruption (base)
ok 23 - verify after commit-graph-chain corruption (tip)
ok 24 - verify notices too-short chain file
ok 25 - verify across alternates
ok 26 - reader bounds-checks base-graph chunk
ok 27 - add octopus merge
ok 28 - check normal git operations: graph exists
ok 29 - split across alternate where alternate is not split
ok 30 - --split=no-merge always writes an incremental
ok 31 - --split=replace replaces the chain
not ok 32 - handles file descriptor exhaustion
#	
#		git init ulimit &&
#		(
#			cd ulimit &&
#			for i in $(test_seq 64)
#			do
#				test_commit $i &&
#				run_with_limited_open_files test_might_fail git commit-graph write \
#					--split=no-merge --reachable || return 1
#			done
#		)
#	
ok 33 - split commit-graph respects core.sharedrepository 0666
ok 34 - split commit-graph respects core.sharedrepository 0600
ok 35 - --split=replace with partial Bloom data
ok 36 - prevent regression for duplicate commits across layers
ok 37 - setup repo for mixed generation commit-graph-chain
ok 38 - do not write generation data chunk if not present on existing tip
ok 39 - do not write generation data chunk if the topmost remaining
layer does not have generation data chunk
ok 40 - write generation data chunk if topmost remaining layer has
generation data chunk
ok 41 - write generation data chunk when commit-graph chain is replaced
ok 42 - temporary graph layer is discarded upon failure
# failed 1 among 42 test(s)
1..42
'
Jeff King Nov. 11, 2024, 10:13 p.m. UTC | #17
On Mon, Nov 11, 2024 at 04:39:08PM -0500, Eli Schwartz wrote:

> > I hadn't tried it. I did now, checking out origin/ps/build^ (to drop the
> > "seen" resolution topic), but it didn't work:
> > 
> >   $ meson setup build
> >   [...]
> >   Program msgfmt found: NO
> >   po/meson.build:3: WARNING: Gettext not found, all translation (po) targets will be ignored.
> > 
> >   po/meson.build:3:20: ERROR: Can not assign void to variable.
> > 
> > I guess the assignment of "translations" there needs to be made
> > conditional?
> 
> 
> Yeah, this is an interesting quirk. Many projects would tend to figure
> that translation (po) targets are "optional" because if you don't have
> msgfmt installed then you can just install the project without any
> translations and then non-English speakers will be inconvenienced but at
> least the entire project isn't completely un-buildable. So meson
> automatically disables the target and logs a warning, but then this
> project *also* wants to depend on the translations for the testsuite.
> 
> So this should be taken into account. Do the tests actually need
> translations, though?

No, they don't. I don't have msgfmt on my system at all, and always
build with NO_GETTEXT.

-Peff
Eli Schwartz Nov. 11, 2024, 11:55 p.m. UTC | #18
On 11/11/24 5:13 PM, Jeff King wrote:
> No, they don't. I don't have msgfmt on my system at all, and always
> build with NO_GETTEXT.


Well, even systems without msgfmt installed may have the gettext()
family of symbols available. On various systems, it may even be built
into their libc.

So, detecting and handling this case sensibly out of the box would be
good, which I guess means checking for find_program('msgfmt') inside of
po/meson.build

That being said, the meson way to handle NO_GETTEXT is to use the build
option

meson setup builddir -Dgettext=disabled


That option is a "feature option", which means by default its value is
auto, not disabled, and it will check for an available libintl / libc
gettext().

The po/ directory is only processed if libintl / libc gettext() is
found. Passing -Dgettext=disabled means that it will be forcibly
overridden to "not found". Meson will log this configuration message:


Dependency intl skipped: feature gettext disabled
Jeff King Nov. 12, 2024, 2:21 a.m. UTC | #19
On Mon, Nov 11, 2024 at 06:55:38PM -0500, Eli Schwartz wrote:

> On 11/11/24 5:13 PM, Jeff King wrote:
> > No, they don't. I don't have msgfmt on my system at all, and always
> > build with NO_GETTEXT.
> 
> Well, even systems without msgfmt installed may have the gettext()
> family of symbols available. On various systems, it may even be built
> into their libc.
> 
> So, detecting and handling this case sensibly out of the box would be
> good, which I guess means checking for find_program('msgfmt') inside of
> po/meson.build

Yes, this is a glibc system where gettext() is in the libc. I agree the
fault is in po/meson.build which is not ready to handle the null return
from import('i18n'). So it is not handling the case where gettext() is
available but msgfmt is not.

Mostly I was responding to your original question, though, which is: do
the tests need translations. They definitely do not, as I do not
generally build Git with gettext support at all. So if there is a
dependency there, it seems wrong.

> That being said, the meson way to handle NO_GETTEXT is to use the build
> option
> 
> meson setup builddir -Dgettext=disabled

Yes, that does get "meson setup" to complete for me. That gives me two
other questions:

 - how would I know this option exists? I think you mentioned elsewhere
   in the thread the ability to ask about which options exist, but I
   couldn't find anything via "meson -h", etc.

 - is there a way to put configuration like this in a file, similar to
   our current config.mak?

-Peff
Eli Schwartz Nov. 12, 2024, 2:36 a.m. UTC | #20
On 11/11/24 9:21 PM, Jeff King wrote:
> Yes, that does get "meson setup" to complete for me. That gives me two
> other questions:
> 
>  - how would I know this option exists? I think you mentioned elsewhere
>    in the thread the ability to ask about which options exist, but I
>    couldn't find anything via "meson -h", etc.


meson -h lists:


    configure               Change project options


Which could perhaps be reworded as it allows you to both view and change
them.

If you install meson via a linux distribution package, it probably has
nice integration with our manpage. If you install it with `pip install
meson` then not so much...

$ man meson

The configure command
       meson configure provides a way to configure a Meson project from
       the command line.  Its usage is simple:

       meson configure [ build directory ] [ options to set ]

       If build directory is omitted, the current directory is used
       instead.

       If no parameters are set, meson configure will print the value of
       all build options to the console.

       To set values, use the -D command line argument like this.

       meson configure -Dopt1=value1 -Dopt2=value2


>  - is there a way to put configuration like this in a file, similar to
>    our current config.mak?


https://mesonbuild.com/Machine-files.html

machine files (passed via --cross-file or --native-file) allow you to
define your toolchain, e.g. set up persistent CFLAGS and CC that you can
store as a configuration file, check into git, share with people, etc.

You can also store configuration options in them:

[project options]
gettext = 'disabled'
default_editor = 'vim'


[built-in options]
c_std = 'gnu17'
b_lto = true
b_sanitize = 'address,undefined'
Jeff King Nov. 12, 2024, 4:52 a.m. UTC | #21
On Mon, Nov 11, 2024 at 09:36:25PM -0500, Eli Schwartz wrote:

> >  - how would I know this option exists? I think you mentioned elsewhere
> >    in the thread the ability to ask about which options exist, but I
> >    couldn't find anything via "meson -h", etc.
> 
> 
> meson -h lists:
> 
> 
>     configure               Change project options
> 
> 
> Which could perhaps be reworded as it allows you to both view and change
> them.

Ah. I saw that, but I tried:

  $ meson configure build
  Meson configurator encountered an error:

  ERROR: Directory /home/peff/compile/git/build is neither a Meson build directory nor a project source directory.

which seemed like a chicken-and-egg (I cannot configure a build
directory until I "setup", but I cannot "setup" until I figure out the
configuration options that work).

But it seems:

  $ meson configure .

gives me a list, albeit with a warning about using the source directory.
It looks like just "meson configure" does the same, but somehow I didn't
try that. ;)

> >  - is there a way to put configuration like this in a file, similar to
> >    our current config.mak?
> 
> https://mesonbuild.com/Machine-files.html
> 
> machine files (passed via --cross-file or --native-file) allow you to
> define your toolchain, e.g. set up persistent CFLAGS and CC that you can
> store as a configuration file, check into git, share with people, etc.

Thanks. And sorry, I am being a bit more lazy than usual about going out
and reading documentation on my own[1].

My usual workflow is to symlink config.mak to my custom file (which of
course I maintain in another Git repo). And then "make" just does the
right thing, even if I'm moving around through history, bisecting, etc.

I think the meson equivalent is that I would "meson setup build
--native-file /path/to/my/config.mak" once, which would copy all of the
values in to that environment. And then starting ninja from that "build"
directory would presumably work throughout history. My config.mak does
have some runtime logic, though (e.g., when bisecting old commits it
relaxes the compiler options). It sounds like that would need to re-run
meson, and not work at the ninja level.

I'm also not clear on how to alternatively build with different
optimization levels, or with different sanitizers. Right now that is:

  # normal build and test some script
  make && cd t && ./t0000-basic.sh -v -i

  # now with sanitizer
  make SANITIZE=address && cd t && ./t0000-basic.sh -v -i

If I understand correctly, the workflow here is either to have two
separate build directories, or to "meson configure" between the two.
And AFAICT the tests _have_ to be run via "meson test" now, if we want
them to find the Git built in the separate directories.

-Peff

[1] I think my gut feeling is that these are questions that Patrick
    should be answering if he wants to sell the project on moving away
    from make. I know we can't expect to be spoon-fed all parts of a
    transition, but I am starting from the point of view of: I am
    perfectly happy with make, why do you want me to switch?

    Another thing I am observing about this is that "meson" is not
    really just replacing "make". It is also replacing autoconf to some
    degree in probing various things (like gettext). But that is not
    something I (or most developers) were using at all. So it is not
    just transitioning to a different piece of software, but also
    changing the fundamental approach. Though I imagine with the right
    --native-file options, I could disable all of the probing entirely.
Junio C Hamano Nov. 12, 2024, 5:07 a.m. UTC | #22
Jeff King <peff@peff.net> writes:

> [1] I think my gut feeling is that these are questions that Patrick
>     should be answering if he wants to sell the project on moving away
>     from make. I know we can't expect to be spoon-fed all parts of a
>     transition, but I am starting from the point of view of: I am
>     perfectly happy with make, why do you want me to switch?

Yeah, that is a very fair thing to say.

Even if you personally (or I for that matter) were not 100% happy
with make, it is important for somebody who has sufficiently gained
respect in the project to play devil's advocate to say it, and I am
glad you did.
Eli Schwartz Nov. 12, 2024, 5:29 a.m. UTC | #23
On 11/11/24 11:52 PM, Jeff King wrote:
> I think the meson equivalent is that I would "meson setup build
> --native-file /path/to/my/config.mak" once, which would copy all of the
> values in to that environment. And then starting ninja from that "build"
> directory would presumably work throughout history. My config.mak does
> have some runtime logic, though (e.g., when bisecting old commits it
> relaxes the compiler options). It sounds like that would need to re-run
> meson, and not work at the ninja level.


Well, at least to change compiler options and relax them it would need
to re-run meson once.


> I'm also not clear on how to alternatively build with different
> optimization levels, or with different sanitizers. Right now that is:
> 
>   # normal build and test some script
>   make && cd t && ./t0000-basic.sh -v -i
> 
>   # now with sanitizer
>   make SANITIZE=address && cd t && ./t0000-basic.sh -v -i
> 
> If I understand correctly, the workflow here is either to have two
> separate build directories, or to "meson configure" between the two.
> And AFAICT the tests _have_ to be run via "meson test" now, if we want
> them to find the Git built in the separate directories.


Yes, and yes. Well, kind of.



meson test t0000-basic

# supports globbing and passing args
meson test t0000* --test-args="-v -i"

GIT_BUILD_DIR=$PWD/../build ./t0000-basic.sh -v -i



are all functional. The introduction of meson doesn't change how the
tests actually work, but it does introduce an environment variable
pointing to the built git program(s) in some location other than "the
parent directory of t/ itself", and `meson test` sets that variable then
runs ./tXXXX-testname.sh itself. So you could continue to run it directly.


> [1] I think my gut feeling is that these are questions that Patrick
>     should be answering if he wants to sell the project on moving away
>     from make. I know we can't expect to be spoon-fed all parts of a
>     transition, but I am starting from the point of view of: I am
>     perfectly happy with make, why do you want me to switch?
> 
>     Another thing I am observing about this is that "meson" is not
>     really just replacing "make". It is also replacing autoconf to some
>     degree in probing various things (like gettext). But that is not
>     something I (or most developers) were using at all. So it is not
>     just transitioning to a different piece of software, but also
>     changing the fundamental approach. Though I imagine with the right
>     --native-file options, I could disable all of the probing entirely.


I would say that technically you were already probing various things. It
is simply that the Makefile performed all those probes each time you ran
`make`, e.g.

ifndef CURL_LDFLAGS
    CURL_LDFLAGS = $(eval CURL_LDFLAGS := $$(shell $$(CURL_CONFIG)
--libs))$(CURL_LDFLAGS)
endif


ran curl-config --libs every time, which is very much a probe.

Other things like NEEDS_LIBICONV were not a probe, but did require the
user to know it was necessary... possibly since conditionally checking
for -liconv -lintl in a Makefile is difficult to do automatically. :)

Really, the main difference in my view is that probing is moved to an
explicit step rather than happening "under the hood" as part of
executing `make`. And that's a definite difference, since `make` is a
single step and `meson setup build && ninja -C build/` is two steps.
Patrick Steinhardt Nov. 12, 2024, 10:48 a.m. UTC | #24
On Tue, Nov 12, 2024 at 02:07:25PM +0900, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
> 
> > [1] I think my gut feeling is that these are questions that Patrick
> >     should be answering if he wants to sell the project on moving away
> >     from make. I know we can't expect to be spoon-fed all parts of a
> >     transition, but I am starting from the point of view of: I am
> >     perfectly happy with make, why do you want me to switch?
> 
> Yeah, that is a very fair thing to say.
> 
> Even if you personally (or I for that matter) were not 100% happy
> with make, it is important for somebody who has sufficiently gained
> respect in the project to play devil's advocate to say it, and I am
> glad you did. 

Yup, I agree with you a 100%.

I was first focussing on getting everything set up and then get some
early signals as to whether this is a direction that we can go into in
the first place, and because of that I didn't yet provide any docs. But
based on your feedback I guess I should focus on exactly that as my next
step. So I'll include docs in the next reroll that demonstrate everyday
workflows in Git and how to do these with Meson.

Thanks!

Patrick
Patrick Steinhardt Nov. 12, 2024, 10:48 a.m. UTC | #25
On Mon, Nov 11, 2024 at 04:48:14PM -0500, Eli Schwartz wrote:
> On 11/11/24 5:36 AM, Patrick Steinhardt wrote:
> > On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
> >> The one thing that no one has mentioned is dependencies.
> >>
> >> CMake has less dependencies. Python is arguably a liability in the build
> >> system arena, and Meson requires it.
> > 
> > Eli has menitoned [muon](https://muon.build/), which is a drop-in
> > replacement for Meson written in plain C99. I don't know whether it is
> > currently able to compile the Git project, but if this is going to be a
> > concern for people I can try to make sure that it does.
> 
> I was wondering whether I should say something, because I don't really
> feel the criticism was on-target to begin with. But...
> 
> I am delighted to be able to confirm, that muon works quite well here.
> 
> It did require two small tweaks for not yet implemented features in
> muon, that meson had and which this patch series depends on:
> 
> the iconv special dependency, which I provided a patch for:
> 
> https://git.sr.ht/~lattis/muon/commit/75d33f6b6d482344d969e4ad6ce1527353f91cce
> 
> using fallback from gnu99 to c11 for the sake of MSVC, which I reported
> and got the muon developer to implement:
> 
> https://git.sr.ht/~lattis/muon/commit/a70e9687f3bfb8b9c21baf9acdfe84f97a42b11f
> 
> 
> (Note the commit author dates by the way. I had the same general thought
> about whether muon could satisfy git users such as, frankly, ones more
> interesting to me than "python has too many dependencies". Such as
> perhaps HPE NonStop users, and I tried muon out a month ago. Yes -- even
> though I am a *meson* maintainer, I consider this a useful alternative
> to have. Meson's FAQ includes discussion about whether it makes sense to
> require Python, and notes that we specifically avoided providing any
> "provide your own python extensions" functionality because it would
> prevent being able to ever rewrite in another not-python language. We
> also document muon as an alternative in our FAQ.)
> 
> 
> With these two small changes, muon compiles git successfully, and passes
> all tests but one:

Thanks, I'll have a look at the test failure.

Patrick
Patrick Steinhardt Nov. 12, 2024, 3:56 p.m. UTC | #26
On Tue, Nov 12, 2024 at 11:48:31AM +0100, Patrick Steinhardt wrote:
> On Mon, Nov 11, 2024 at 04:48:14PM -0500, Eli Schwartz wrote:
> > On 11/11/24 5:36 AM, Patrick Steinhardt wrote:
> > > On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
> > >> The one thing that no one has mentioned is dependencies.
> > >>
> > >> CMake has less dependencies. Python is arguably a liability in the build
> > >> system arena, and Meson requires it.
> > > 
> > > Eli has menitoned [muon](https://muon.build/), which is a drop-in
> > > replacement for Meson written in plain C99. I don't know whether it is
> > > currently able to compile the Git project, but if this is going to be a
> > > concern for people I can try to make sure that it does.
> > 
> > I was wondering whether I should say something, because I don't really
> > feel the criticism was on-target to begin with. But...
> > 
> > I am delighted to be able to confirm, that muon works quite well here.
> > 
> > It did require two small tweaks for not yet implemented features in
> > muon, that meson had and which this patch series depends on:
> > 
> > the iconv special dependency, which I provided a patch for:
> > 
> > https://git.sr.ht/~lattis/muon/commit/75d33f6b6d482344d969e4ad6ce1527353f91cce
> > 
> > using fallback from gnu99 to c11 for the sake of MSVC, which I reported
> > and got the muon developer to implement:
> > 
> > https://git.sr.ht/~lattis/muon/commit/a70e9687f3bfb8b9c21baf9acdfe84f97a42b11f
> > 
> > 
> > (Note the commit author dates by the way. I had the same general thought
> > about whether muon could satisfy git users such as, frankly, ones more
> > interesting to me than "python has too many dependencies". Such as
> > perhaps HPE NonStop users, and I tried muon out a month ago. Yes -- even
> > though I am a *meson* maintainer, I consider this a useful alternative
> > to have. Meson's FAQ includes discussion about whether it makes sense to
> > require Python, and notes that we specifically avoided providing any
> > "provide your own python extensions" functionality because it would
> > prevent being able to ever rewrite in another not-python language. We
> > also document muon as an alternative in our FAQ.)
> > 
> > 
> > With these two small changes, muon compiles git successfully, and passes
> > all tests but one:
> 
> Thanks, I'll have a look at the test failure.

I couldn't reproduce the test failures on my system reliably. I did
notice that some of the tests are quite flaky, and that seems mostly to
be attributed to file descriptor exhaustion. These problems go away when
running `muon test -j1`.

So maybe there is an issue to how file descriptor are allocated? That's
just a guess though.

Patrick
David Aguilar Nov. 13, 2024, 9:21 a.m. UTC | #27
On Mon, Nov 11, 2024 at 11:36:34AM +0100, Patrick Steinhardt wrote:
> On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
> > That said, if we mean, "Linux/Unix-savvy New Contributors," then
> > I can understand why Meson might be a favorite, and perhaps this
> > might be the crowd we are looking to target [...]
> 
> My goal is to not only make things easier to use for Linux users, but
> also for users on other platforms like Windows while also catering to
> the typical developer of Git and making the solution for them as tasty
> as possible.
> 
> I agree that CMake is a tad easier to use and set up on Windows, mostly
> because it is directly integrated into MSVC. But I also think that CMake
> is a harder sell towards the power users because it is comparatively
> hard to maintain due to its somewhat arcane syntax, implicit variables
> and things like this.
> 
> So I'm basically trying to find a good middle ground where all of the
> respective target audiences get benefit:
> 
>   - For Unix devs I think that Meson is easier to maintain and use
>     compared to CMake. We also get nice features like out-of-source
>     builds, good integration with the test suite and easy integration
>     with IDEs.
> 
>   - For Windows devs we have an officially supported way to build Meson
>     from MSVC and co. Also, subprojects allow us to have as easy story
>     for how to build Git without preinstalled dependencies, which is not
>     currently possible with CMake to the best of my knowledge.
> 
>   - For packagers I think that Meson provides better discoverability of
>     options than CMake.
> 
> So Meson may not be the perfect solution for everyone of these target
> audiences, and better solutions may exist to cater specific needs. But
> it provides a net benefit for every single one of these audiences from
> my point of view. And when taking the benefits for all target audiences
> combined I think that Meson provides the bigger win compared to CMake.

Thanks for clarifying. Not that it matters, but you've convinced me.
Constructive criticism follows below in the hope that it can help you
further harden the arguments for Meson.


> > > Patrick Steinhardt wrote:
> > > >   - Packagers. This is another group of people that would benefit from
> > > >     my point of view. This is mostly because Meson has certain standards
> > > >     for how to approach problems, and thus the packager would know for
> > > >     how to handle things. They don't have to manually track build
> > > >     options and changes thereof, as these can be easily discovered and
> > > >     because Meson will error out in case invalid options are passed.
> > 
> > CMake's option() variables and its GNUInstallDirs module pretty much
> > handles all of the standardization that packagers are looking for on
> > this front, so this argument doesn't push the needle towards Meson over
> > CMake from my perspective.
> 
> I think that discoverability of Meson is way better. Here you can simply
> say `meson configure` and it provides you a nice list of all options
> that are available. For CMake it always used to be a big pain.

The pain of discovering options with CMake is true in the general case.

A specific project can enforce conventions so that all option()s are
specified at the top of the main build script or a designated file
specifically for options. That would trivially make the options easily
discoverable in that there's only a single place to look, but that's
nowhere near the rigor that Meson enforces.

Following a sensible convention is why I didn't originally vibe with the
argument that option()s are insufficient, but that would merely be one
project's conventions and is by no means a universal practice.

Elsewhere in this thread it was also mentioned that unknown options are
blindly accepted by CMake. That's actually not true.

While it's not as rigorous as Meson because it doesn't error out by
default, CMake does issue a warning when you specify variables/options
that are not used by the project. IIRC this warning can be made into an
error by using the "cmake -Werror=dev" option, but I appreciate Meson
taking the stricter route as it results in better overall usability.


> > > Taylor Blau wrote:
> > > I appreciate your thoughtful response to my concerns here. Please feel
> > > free to correct me if I am wrong, but I think the bulk of your argument
> > > is captured fairly well by these three points, so I want to focus my
> > > response here.
> > > 
> > > Responding in turn, I think my feeling is something like:
> > > 
> > >   - Long-time Git contributors are going to be the ones who will most
> > >     frequently use the new build system. I am definitely sympathetic to
> > >     getting too comfortable with our existing tools, but so far in your
> > >     response I have not seen a compelling reason to switch the project
> > >     to use Meson.
> > 
> > Likewise, I have not seen a compelling reason to not focus the
> > effort on CMake instead. In other words, why not enhance the current
> > status quo (Make + CMake) instead of trying to replace it?
> 
> As mentioned above, I mostly think that Meson makes for a more
> compelling overall package. That being said, if we eventually come to
> the conclusion that we as a community want CMake instead of Meson, then
> I am willing to go there.

I hope that's not where things land because the separation of
configuration vs. build steps does provide a benefit in day-to-day use
(specifically, faster incremental builds) due to the clean separation
of the configuration and build steps.

It seems like it would be nice if the Meson build were eventually
hooked up so that we can continue typing "make prefix=... install"
(perhaps through an opt-in "enable meson" variable) and the Makefile
would handle driving Meson + Ninja, but that's probably an untenable
feature given the complexity of the current Makefile.

If the Makefile were completely replaced one day then that would be
a nice to have, but it would probably be a bad crutch because the
natural tendency would be to shadow all of Meson's options behind
Makefile knobs. Encouraging users to just run meson directly
seems like a better overall situation. Bisecting is the only
reason why something like that might seem appealing, but
I probably wouldn't push for it myself and maybe there's a better
way to handle that when we cross that bridge.


> > >       * New contributors do not interact with build system internals
> > >         nearly as much as more experienced contributors. I would imagine
> > >         that the vast majority of those interactions are simply running
> > >         "make" or "make test".
> > > 
> > >         You mention a handful of other niceties that Meson provides,
> > >         like language server support, but I am not sure that I agree
> > >         those are (a) the responsibility of the build system to provide,
> > >         or (b) that those needs aren't already well met by the vast
> > >         number of existing tools and IDE integrations that can work with
> > >         ctags.
> > 
> > CMake has all of these same bells and whistles, and it's already present
> > in git.git. LSP support just means being able to generate a
> > compile_commands.json file, and the current CMake setup already does
> > that.
> > 
> > The one thing that no one has mentioned is dependencies.
> > 
> > CMake has less dependencies. Python is arguably a liability in the build
> > system arena, and Meson requires it.
> 
> Eli has menitoned [muon](https://muon.build/), which is a drop-in
> replacement for Meson written in plain C99. I don't know whether it is
> currently able to compile the Git project, but if this is going to be a
> concern for people I can try to make sure that it does.

Thanks both for confirming that muon is a viable alternative.

Elsewhere in this thread packaging metadata for CMake was shared
arguing that CMake also has many dependencies. A subtle nuance there
is that those are all either optional dependencies (e.g. Qt for the GUI
parts) or they are dependencies that can be optionally supplied.

You can build CMake without those dependencies installed and CMake's
vendored versions will be statically linked instead. So, from the
perspective of wanting to go from 0 to 100 with just gcc/g++ installed,
CMake has less dependencies. This might be slightly disingenuous because
CMake vendors its dependencies and distros have to opt-in so that they
can supply their own versions, but the main takeaway is that GCC is all
you need and that's what I meant by, "less dependencies."

This is a moot point for most users, though, and it's even moreso moot
if muon compatibility can be maintained.

As to why I consider Python a liability ~ this is more of a concern for
Meson and it doesn't really matter for end users, but Python has a
proven track record of making breaking changes.

If you're building everything from scratch with new versions of
compilers and tools then the C++ project is the one that's going to
build just fine a decade from now with little to minimal effort.
Python doesn't have that track record.

Even though CMake is written in C++ (which is unacceptable for some
projects), this is subjectively one advantage that CMake seems to have.
This is a moot point, though, and perhaps Python will eventually reach
this same level of respect for not introducing breaking changes.

Furthermore, I suspect that most contributors are simply going to
"apt install meson" or "brew install meson" so it's not really that much
of an issue in practice for the majority of users/contributors.


> I'd honestly be sad if we go down the CMake route, mostly because I
> think that it is an inferior build system compared to Meson. I have
> worked with it extensively in the context of libgit2 and always found it
> to be a pain due to its esoteric syntax, the use of so many implicit
> variables, platform CMake policies, and there being so many ways to do
> the same thing and, where the easiest solution is typically the wrong
> one to pick.
> 
> That being said, I'm trying to be as pragmatic is possible: my main goal
> is to have a modern build system that is easier to use. So while I think
> that Meson fits better into that role, the next-best thing would be
> CMake from my point of view.
> 
> So I'll continue to champion Meson, but if the project as a whole agrees
> to take up CMake as another official build system then I'll adapt and
> make that happen.

I agree with you. Meson looks to be a technically better option.
I kinda wonder how many folks are actually using the contrib/ CMakeLists.txt,
and whether this effort would be helped by retiring it sooner rather
than later?

Would it be worth adding a canary to the CMake build that forces it to
fail to build unless "cmake -D ENABLE_DEPRECATED_BUILD=ON" option is
specified?

It could error out with a message telling users to reach out to the
list alongside the hint to specify the option if they just want
to get a working build.


On a rather low-powered machine here are some timings:

    $ make clean
    $ time make -j
    181.36s user 15.35s system 99% cpu 3:17.33 total

    $ ninja -C build clean
    $ time ninja -C build
    11.23s user 4.67s system 47% cpu 33.605 total

34s vs 3m17s ~ nice! That's also surprising.

That large of a difference is not explained by the extra
probes done by the Makefile; a no-op incremental build is 0.5s for
Make and 0.02s for Meson so the Makefile probes seem to only account
for at most 0.5s.

Is the Meson build simply building much less, and that's why
it's currently so much faster?

Or.. is it because I have "sccache" installed and Meson automatically
uses it? "ninja -C build -v" confirms that it's using sccache and
"make V=1" does not, so maybe that's why.

How do we disable the sccache usage?
"meson configure build" doesn't seem to list anything related to
caching, but it is really nice seeing all of the other options in one
place.

Improvement in build time seems like it could be something that sways
long-time contributors towards Meson. It is pretty nice that it
automatically picked up sccache in my $PATH and automatically gave me
those speedups.


> Thanks for your input, highly appreciated!

Thanks. I don't want to be the CMake champion, so here are a few
helpful/surprising details about the Meson build to help make it better.


(1) I first built w/out having "curl-config" installed. I was surprised
to find that "ninja -C build install" ended up installing "bin/curl" and
"bin/curl-config" into the prefix.

Is there a way to have the install step only install Git without
bringing along these other non-Git bits?


(2) There seems to be a difference in how symlinks and hardlinks are
handled in the install step.

Running "make prefix=$PWD/dist install" ends up with real files in
dist/bin/ (hardlinks) whereas with Meson all of the files in the bin/
directory are symlinks into ../libexec/.


(3) Not all of the same files seems to be getting installed.

I don't see bin/gitk or bin/git-cvsserver when building with Meson.

The share/git-core/templates/ directory is missing completely.

git-gui and its related files are missing. Perhaps this is
intentional/todo at this stage and hasn't been added yet.

Meson installs bin/git-http-backend (symlinked to libexec)
but in the original Makefile this file only exists in libexec/.

The contents of libexec/git-core/ seems to be missing dozens of
files compared to the Makefile build.

share/perl5/ has a bunch of extra git-{cvsserver,send-email,svn,...}
scripts so perhaps this is where some of those files went?
The Makefile places these files in the libexec/ area instead
of in the share/perl5/ area.

The Makefile does not install share/gitweb/static/js/.
Instead, it seems to mash everything together into a single
share/gitweb/static/gitweb.js file which Meson does not install.
Meson installs separate files in the share/gitweb/static/js/ area.
Was that intentional, or is that just another todo?

cheers,
Patrick Steinhardt Nov. 13, 2024, 1:29 p.m. UTC | #28
On Wed, Nov 13, 2024 at 01:21:52AM -0800, David Aguilar wrote:
> On Mon, Nov 11, 2024 at 11:36:34AM +0100, Patrick Steinhardt wrote:
> > On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
> > > That said, if we mean, "Linux/Unix-savvy New Contributors," then
> > > I can understand why Meson might be a favorite, and perhaps this
> > > might be the crowd we are looking to target [...]
> > 
> > My goal is to not only make things easier to use for Linux users, but
> > also for users on other platforms like Windows while also catering to
> > the typical developer of Git and making the solution for them as tasty
> > as possible.
> > 
> > I agree that CMake is a tad easier to use and set up on Windows, mostly
> > because it is directly integrated into MSVC. But I also think that CMake
> > is a harder sell towards the power users because it is comparatively
> > hard to maintain due to its somewhat arcane syntax, implicit variables
> > and things like this.
> > 
> > So I'm basically trying to find a good middle ground where all of the
> > respective target audiences get benefit:
> > 
> >   - For Unix devs I think that Meson is easier to maintain and use
> >     compared to CMake. We also get nice features like out-of-source
> >     builds, good integration with the test suite and easy integration
> >     with IDEs.
> > 
> >   - For Windows devs we have an officially supported way to build Meson
> >     from MSVC and co. Also, subprojects allow us to have as easy story
> >     for how to build Git without preinstalled dependencies, which is not
> >     currently possible with CMake to the best of my knowledge.
> > 
> >   - For packagers I think that Meson provides better discoverability of
> >     options than CMake.
> > 
> > So Meson may not be the perfect solution for everyone of these target
> > audiences, and better solutions may exist to cater specific needs. But
> > it provides a net benefit for every single one of these audiences from
> > my point of view. And when taking the benefits for all target audiences
> > combined I think that Meson provides the bigger win compared to CMake.
> 
> Thanks for clarifying. Not that it matters, but you've convinced me.
> Constructive criticism follows below in the hope that it can help you
> further harden the arguments for Meson.

Very happy to hear!

> > > > Patrick Steinhardt wrote:
> > > > >   - Packagers. This is another group of people that would benefit from
> > > > >     my point of view. This is mostly because Meson has certain standards
> > > > >     for how to approach problems, and thus the packager would know for
> > > > >     how to handle things. They don't have to manually track build
> > > > >     options and changes thereof, as these can be easily discovered and
> > > > >     because Meson will error out in case invalid options are passed.
> > > 
> > > CMake's option() variables and its GNUInstallDirs module pretty much
> > > handles all of the standardization that packagers are looking for on
> > > this front, so this argument doesn't push the needle towards Meson over
> > > CMake from my perspective.
> > 
> > I think that discoverability of Meson is way better. Here you can simply
> > say `meson configure` and it provides you a nice list of all options
> > that are available. For CMake it always used to be a big pain.
> 
> The pain of discovering options with CMake is true in the general case.
> 
> A specific project can enforce conventions so that all option()s are
> specified at the top of the main build script or a designated file
> specifically for options. That would trivially make the options easily
> discoverable in that there's only a single place to look, but that's
> nowhere near the rigor that Meson enforces.
> 
> Following a sensible convention is why I didn't originally vibe with the
> argument that option()s are insufficient, but that would merely be one
> project's conventions and is by no means a universal practice.
> 
> Elsewhere in this thread it was also mentioned that unknown options are
> blindly accepted by CMake. That's actually not true.
> 
> While it's not as rigorous as Meson because it doesn't error out by
> default, CMake does issue a warning when you specify variables/options
> that are not used by the project. IIRC this warning can be made into an
> error by using the "cmake -Werror=dev" option, but I appreciate Meson
> taking the stricter route as it results in better overall usability.

Ah, fair enough, I remember seeing these warnings myself. As you say, I
also prefer being as strict as possible, as otherwise it is so easy to
miss the fact that a build option has been mistyped, removed or renamed.
The warning helps the dev if they pay attention, but especially in
automated systems I'd expect it to go unnoticed quite often.

> > > > Taylor Blau wrote:
> > > > I appreciate your thoughtful response to my concerns here. Please feel
> > > > free to correct me if I am wrong, but I think the bulk of your argument
> > > > is captured fairly well by these three points, so I want to focus my
> > > > response here.
> > > > 
> > > > Responding in turn, I think my feeling is something like:
> > > > 
> > > >   - Long-time Git contributors are going to be the ones who will most
> > > >     frequently use the new build system. I am definitely sympathetic to
> > > >     getting too comfortable with our existing tools, but so far in your
> > > >     response I have not seen a compelling reason to switch the project
> > > >     to use Meson.
> > > 
> > > Likewise, I have not seen a compelling reason to not focus the
> > > effort on CMake instead. In other words, why not enhance the current
> > > status quo (Make + CMake) instead of trying to replace it?
> > 
> > As mentioned above, I mostly think that Meson makes for a more
> > compelling overall package. That being said, if we eventually come to
> > the conclusion that we as a community want CMake instead of Meson, then
> > I am willing to go there.
> 
> I hope that's not where things land because the separation of
> configuration vs. build steps does provide a benefit in day-to-day use
> (specifically, faster incremental builds) due to the clean separation
> of the configuration and build steps.
> 
> It seems like it would be nice if the Meson build were eventually
> hooked up so that we can continue typing "make prefix=... install"
> (perhaps through an opt-in "enable meson" variable) and the Makefile
> would handle driving Meson + Ninja, but that's probably an untenable
> feature given the complexity of the current Makefile.
> 
> If the Makefile were completely replaced one day then that would be
> a nice to have, but it would probably be a bad crutch because the
> natural tendency would be to shadow all of Meson's options behind
> Makefile knobs. Encouraging users to just run meson directly
> seems like a better overall situation. Bisecting is the only
> reason why something like that might seem appealing, but
> I probably wouldn't push for it myself and maybe there's a better
> way to handle that when we cross that bridge.

In theory it is of course possible to have a thin wrapper around Meson,
but as you say it'd likely be a bit more on the painful side to write.
One could be pragmatic and only map the most commonly used options and
otherwise let the autodetection of features do its thing, which could be
good enough for bisectability.

On the other hand I don't see that our Makefile would go away anytime
soon. I would eventually want to remove it so that we have a single
build system, only, but I'd think that the timeline here would rather be
a year or two before we do so. So maybe that reduces the need for such a
mechanism.

> > > >       * New contributors do not interact with build system internals
> > > >         nearly as much as more experienced contributors. I would imagine
> > > >         that the vast majority of those interactions are simply running
> > > >         "make" or "make test".
> > > > 
> > > >         You mention a handful of other niceties that Meson provides,
> > > >         like language server support, but I am not sure that I agree
> > > >         those are (a) the responsibility of the build system to provide,
> > > >         or (b) that those needs aren't already well met by the vast
> > > >         number of existing tools and IDE integrations that can work with
> > > >         ctags.
> > > 
> > > CMake has all of these same bells and whistles, and it's already present
> > > in git.git. LSP support just means being able to generate a
> > > compile_commands.json file, and the current CMake setup already does
> > > that.
> > > 
> > > The one thing that no one has mentioned is dependencies.
> > > 
> > > CMake has less dependencies. Python is arguably a liability in the build
> > > system arena, and Meson requires it.
> > 
> > Eli has menitoned [muon](https://muon.build/), which is a drop-in
> > replacement for Meson written in plain C99. I don't know whether it is
> > currently able to compile the Git project, but if this is going to be a
> > concern for people I can try to make sure that it does.
> 
> Thanks both for confirming that muon is a viable alternative.
> 
> Elsewhere in this thread packaging metadata for CMake was shared
> arguing that CMake also has many dependencies. A subtle nuance there
> is that those are all either optional dependencies (e.g. Qt for the GUI
> parts) or they are dependencies that can be optionally supplied.
> 
> You can build CMake without those dependencies installed and CMake's
> vendored versions will be statically linked instead. So, from the
> perspective of wanting to go from 0 to 100 with just gcc/g++ installed,
> CMake has less dependencies. This might be slightly disingenuous because
> CMake vendors its dependencies and distros have to opt-in so that they
> can supply their own versions, but the main takeaway is that GCC is all
> you need and that's what I meant by, "less dependencies."
> 
> This is a moot point for most users, though, and it's even moreso moot
> if muon compatibility can be maintained.

Fair. I don't really expect anybody to use the combination of muon/sumo
for everyday work, mostly because the usability is not quite up to par
with Meson/Ninja. But there are two use cases that I deem important:

  - Esoteric platforms that may not have Python available. I don't know
    whether there actually are any relevant ones, but with muon/sumo it
    is possible to support these.

  - Bootstrappability, which I think is rather critical for a project
    like Git that is at the core of the whole software ecosystem.
    Depending only on a C99 compiler and a shell is a huge win here.

A bit of an anecdota, but CMake itself for example struggles with this
quite heavily because it has dependencies that use CMake themselves. So
it is nice that there is a clear path for bootstrapping with Meson and
thus Git.

> As to why I consider Python a liability ~ this is more of a concern for
> Meson and it doesn't really matter for end users, but Python has a
> proven track record of making breaking changes.
> 
> If you're building everything from scratch with new versions of
> compilers and tools then the C++ project is the one that's going to
> build just fine a decade from now with little to minimal effort.
> Python doesn't have that track record.
> 
> Even though CMake is written in C++ (which is unacceptable for some
> projects), this is subjectively one advantage that CMake seems to have.
> This is a moot point, though, and perhaps Python will eventually reach
> this same level of respect for not introducing breaking changes.
> 
> Furthermore, I suspect that most contributors are simply going to
> "apt install meson" or "brew install meson" so it's not really that much
> of an issue in practice for the majority of users/contributors.

Agreed.

> > I'd honestly be sad if we go down the CMake route, mostly because I
> > think that it is an inferior build system compared to Meson. I have
> > worked with it extensively in the context of libgit2 and always found it
> > to be a pain due to its esoteric syntax, the use of so many implicit
> > variables, platform CMake policies, and there being so many ways to do
> > the same thing and, where the easiest solution is typically the wrong
> > one to pick.
> > 
> > That being said, I'm trying to be as pragmatic is possible: my main goal
> > is to have a modern build system that is easier to use. So while I think
> > that Meson fits better into that role, the next-best thing would be
> > CMake from my point of view.
> > 
> > So I'll continue to champion Meson, but if the project as a whole agrees
> > to take up CMake as another official build system then I'll adapt and
> > make that happen.
> 
> I agree with you. Meson looks to be a technically better option.
> I kinda wonder how many folks are actually using the contrib/ CMakeLists.txt,
> and whether this effort would be helped by retiring it sooner rather
> than later?
> 
> Would it be worth adding a canary to the CMake build that forces it to
> fail to build unless "cmake -D ENABLE_DEPRECATED_BUILD=ON" option is
> specified?
> 
> It could error out with a message telling users to reach out to the
> list alongside the hint to specify the option if they just want
> to get a working build.

I think it's still a bit too early to think about the actual deprecation
road -- before removing things I want to connect with any stakeholders
that use the old system and figure out whether I've got everything
covered that they need. I know that Johannes for example uses CMake
extensively, so I will make sure to connect with him before proposing
its removal.

I've also shifted my thinking a bit: instead of removing CMake as a
first step I'd like to remove the autoconf code. It is known to be
broken in many situations and there is only a very small set of users
out there. So replacing that with Meson would be a good first target
from my point of view.

In any case I don't want to negatively surprise anybody, so I am of
course very happy to discuss the roadmap here and will work with anybody
who has needs that I haven't addressed yet.

> On a rather low-powered machine here are some timings:
> 
>     $ make clean
>     $ time make -j
>     181.36s user 15.35s system 99% cpu 3:17.33 total
> 
>     $ ninja -C build clean
>     $ time ninja -C build
>     11.23s user 4.67s system 47% cpu 33.605 total
> 
> 34s vs 3m17s ~ nice! That's also surprising.

Awesome!

> That large of a difference is not explained by the extra
> probes done by the Makefile; a no-op incremental build is 0.5s for
> Make and 0.02s for Meson so the Makefile probes seem to only account
> for at most 0.5s.
> 
> Is the Meson build simply building much less, and that's why
> it's currently so much faster?

We don't build documentation by default and don't have gitk wired up,
but other than that the builds should be mostly equivalent.

> Or.. is it because I have "sccache" installed and Meson automatically
> uses it? "ninja -C build -v" confirms that it's using sccache and
> "make V=1" does not, so maybe that's why.
> 
> How do we disable the sccache usage?
> "meson configure build" doesn't seem to list anything related to
> caching, but it is really nice seeing all of the other options in one
> place.

Yes, Meson knows to pick up sccache and ccache automatically. [1]
mentions that you can disable this by setting the compiler explicitly
via the CC environment variable.

[1]: https://mesonbuild.com/Feature-autodetection.html#ccache

> Improvement in build time seems like it could be something that sways
> long-time contributors towards Meson. It is pretty nice that it
> automatically picked up sccache in my $PATH and automatically gave me
> those speedups.

True.

> > Thanks for your input, highly appreciated!
> 
> Thanks. I don't want to be the CMake champion, so here are a few
> helpful/surprising details about the Meson build to help make it better.
> 
> 
> (1) I first built w/out having "curl-config" installed. I was surprised
> to find that "ninja -C build install" ended up installing "bin/curl" and
> "bin/curl-config" into the prefix.
> 
> Is there a way to have the install step only install Git without
> bringing along these other non-Git bits?

It definitely shouldn't install curl and curl-config, I'll have a look
at that. But other than that Meson is currently set up such that it will
automatically fall back to the subprojects in case certain dependencies
cannot be found. This can be disabled via `meson setup --wrap-mode
nofallback`.

> (2) There seems to be a difference in how symlinks and hardlinks are
> handled in the install step.
> 
> Running "make prefix=$PWD/dist install" ends up with real files in
> dist/bin/ (hardlinks) whereas with Meson all of the files in the bin/
> directory are symlinks into ../libexec/.

Yup, that's documented as part of the commit message that introduces
Meson as one of the main differences.

> (3) Not all of the same files seems to be getting installed.
> 
> I don't see bin/gitk or bin/git-cvsserver when building with Meson.
> 
> The share/git-core/templates/ directory is missing completely.
> 
> git-gui and its related files are missing. Perhaps this is
> intentional/todo at this stage and hasn't been added yet.
> 
> Meson installs bin/git-http-backend (symlinked to libexec)
> but in the original Makefile this file only exists in libexec/.
> 
> The contents of libexec/git-core/ seems to be missing dozens of
> files compared to the Makefile build.
> 
> share/perl5/ has a bunch of extra git-{cvsserver,send-email,svn,...}
> scripts so perhaps this is where some of those files went?
> The Makefile places these files in the libexec/ area instead
> of in the share/perl5/ area.
> 
> The Makefile does not install share/gitweb/static/js/.
> Instead, it seems to mash everything together into a single
> share/gitweb/static/gitweb.js file which Meson does not install.
> Meson installs separate files in the share/gitweb/static/js/ area.
> Was that intentional, or is that just another todo?

gitk and git-gui aren't currently wired up. All the other ones I'll have
a look at.

Thanks a lot for your feedback!

Patrick
Eli Schwartz Nov. 13, 2024, 2:57 p.m. UTC | #29
On 11/13/24 4:21 AM, David Aguilar wrote:
> As to why I consider Python a liability ~ this is more of a concern for
> Meson and it doesn't really matter for end users, but Python has a
> proven track record of making breaking changes.
> 
> If you're building everything from scratch with new versions of
> compilers and tools then the C++ project is the one that's going to
> build just fine a decade from now with little to minimal effort.
> Python doesn't have that track record.
> 
> Even though CMake is written in C++ (which is unacceptable for some
> projects), this is subjectively one advantage that CMake seems to have.
> This is a moot point, though, and perhaps Python will eventually reach
> this same level of respect for not introducing breaking changes.
> 
> Furthermore, I suspect that most contributors are simply going to
> "apt install meson" or "brew install meson" so it's not really that much
> of an issue in practice for the majority of users/contributors.


For what it's worth, meson is aware that python breaking changes are a
potential issue. Although the general python ecosystem is fairly lax
about this -- on *all* points across:

- cpython itself being backwards incompatible

- projects making breaking changes in a micro release

- projects deciding to only support the latest, or 2 most recent,
  versions of cpython

meson pedantically avoids non-standard-library dependencies both for
bootstrappability and for points 2 & 3.

Regarding point 1, meson can't do a lot other than adapt. But the latest
version of meson will always support *all* non-EOL versions of python,
we do prerelease testing of cpython betas, and we do not drop support
even for EOL versions of cpython unless, having carefully evaluated the
benefits and negatives, we decide that the advantages of relying on a
new version outweigh the downside of preventing people on older systems
with older cpython from upgrading meson.

Currently that means we still support 7 different versions of cpython,
including 2 versions that are EOL (and 4 versions that built with c89,
before the migration to c11).

Of course, as you say it's a bit of a moot point given that muon exists.
But I just wanted to clarify that meson does take this concern seriously
and we try to do everything we can to make that work -- even when some
meson maintainers are unhappy and feel that being unable to depend on
unpredictable third-party modules cramps their style.

We know that we are core FOSS infrastructure, and are used by other core
FOSS infrastructure projects such as init systems (both systemd and
openrc), graphics stacks (mesa, libdrm, both xorg and wayland), desktops
(gnome has an official directive to use meson), and a variety of
freedesktop projects, many of which need to keep building on LTS
versions of Debian oldoldstable (not a typo) and oftentimes on even more
surprising platforms.

And in some cases we've been a bit influential in getting cpython to
revert breaking changes :) e.g. python 3.13 reverted the removal of the
importlib.resources "Functional API".
Eli Schwartz Nov. 13, 2024, 2:57 p.m. UTC | #30
On 11/13/24 8:29 AM, Patrick Steinhardt wrote:
> Fair. I don't really expect anybody to use the combination of muon/sumo
> for everyday work, mostly because the usability is not quite up to par
> with Meson/Ninja. But there are two use cases that I deem important:


(samu :P)


>   - Esoteric platforms that may not have Python available. I don't know
>     whether there actually are any relevant ones, but with muon/sumo it
>     is possible to support these.
> 
>   - Bootstrappability, which I think is rather critical for a project
>     like Git that is at the core of the whole software ecosystem.
>     Depending only on a C99 compiler and a shell is a huge win here.
> 
> A bit of an anecdota, but CMake itself for example struggles with this
> quite heavily because it has dependencies that use CMake themselves. So
> it is nice that there is a clear path for bootstrapping with Meson and
> thus Git.


Yeah, the cmake bootstrap route tends to be an issue for Linux distros
because we want to use system packages for those dependencies, and while
it's possible to build a bootstrap seed `cmake` binary using their
shellscript and use it to build a "real" cmake, that doesn't really help
you install cmake's dependencies. There are some tricks you can do like
for example on Gentoo, bootstrap the OS with http2 support in curl
toggled off, so you can build without nghttp2 / no cmake, then use that
to build cmake, then rebuild curl. It requires manual intervention but
then you can reuse the existing cmake binary.

There's generally no path for building cmake with bundled dependencies,
as that would conflict with the desired end state of distributing cmake
linked to system packages.



>> Thanks. I don't want to be the CMake champion, so here are a few
>> helpful/surprising details about the Meson build to help make it better.
>>
>>
>> (1) I first built w/out having "curl-config" installed. I was surprised
>> to find that "ninja -C build install" ended up installing "bin/curl" and
>> "bin/curl-config" into the prefix.
>>
>> Is there a way to have the install step only install Git without
>> bringing along these other non-Git bits?
> 
> It definitely shouldn't install curl and curl-config, I'll have a look
> at that. But other than that Meson is currently set up such that it will
> automatically fall back to the subprojects in case certain dependencies
> cannot be found. This can be disabled via `meson setup --wrap-mode
> nofallback`.



https://github.com/mesonbuild/wrapdb/tree/master/subprojects/packagefiles/curl

could be updated to handle the case where meson.is_subproject() returns
"true", by not installing tooling.

Alternatively, meson install --skip-subprojects can avoid installing
*any* files from subprojects, on the theory that subprojects exist
solely to provide static libraries linked into the real project.

(In theory, one could have a subproject where arbitrary data files from
a subproject dependency are crucial at runtime. I think the gnome
ecosystem does this, hence using GLib / Gtk as a subproject "needs" to
install the subproject too -- but curl definitely doesn't have this
issue...)
Junio C Hamano Nov. 14, 2024, 4:24 a.m. UTC | #31
Patrick Steinhardt <ps@pks.im> writes:

>> (2) There seems to be a difference in how symlinks and hardlinks are
>> handled in the install step.
>> 
>> Running "make prefix=$PWD/dist install" ends up with real files in
>> dist/bin/ (hardlinks) whereas with Meson all of the files in the bin/
>> directory are symlinks into ../libexec/.
>
> Yup, that's documented as part of the commit message that introduces
> Meson as one of the main differences.

Is there a way to disable that?  These symbolic-links pretending to
be installed files are quite annoying---when the target file is lost,
the links become useless.
Eli Schwartz Nov. 14, 2024, 4:46 a.m. UTC | #32
On 11/13/24 11:24 PM, Junio C Hamano wrote:
> Is there a way to disable that?  These symbolic-links pretending to
> be installed files are quite annoying---when the target file is lost,
> the links become useless.


INSTALL_SYMLINKS=1 in the existing Makefile is of course the one true
way... (and really, why would you expect the target file to be lost for
any reason).

That being said, it doesn't appear the patch series implements any of
the other multiplicity of choice in what kind of filesystem object gets
used for multiple copies of the same file. No hardlink or copy support
has been rigged up.

(Meson doesn't have a builtin function for performing hardlinks, by the
way. I don't really think I've seen people desire to do this outside of
one project being discussed right here right now. hardlinks are mainly
good at fooling people who look at them into not understanding the
association between the two, and at breaking across multiple
filesystems. It's definitely impossible to get it right automatically,
and asking users to make an informed choice here is just not something
that projects other than git seem to find valuable, for whatever reason.
So basically, it's fairly understandable that meson hasn't previously
added hardlink support.)
Patrick Steinhardt Nov. 14, 2024, 8:15 a.m. UTC | #33
On Wed, Nov 13, 2024 at 01:21:52AM -0800, David Aguilar wrote:
> On Mon, Nov 11, 2024 at 11:36:34AM +0100, Patrick Steinhardt wrote:
> > On Sat, Nov 09, 2024 at 04:58:56AM -0800, David Aguilar wrote:
> (3) Not all of the same files seems to be getting installed.
> 
> I don't see bin/gitk or bin/git-cvsserver when building with Meson.

gitk is intentionally committed. git-cvsserver is fixed now.

> The share/git-core/templates/ directory is missing completely.

Fixed.

> git-gui and its related files are missing. Perhaps this is
> intentional/todo at this stage and hasn't been added yet.

Yup, this is intentionally omitted for now.

> Meson installs bin/git-http-backend (symlinked to libexec)
> but in the original Makefile this file only exists in libexec/.

Huh, true. On my system (NixOS) it's also installed in 'bin/', but when
using the Makefile it indeed only ends up in 'libexec/'. Fixed now.

> The contents of libexec/git-core/ seems to be missing dozens of
> files compared to the Makefile build.

This is intentional, as I'm dropping the dashed builitins. Git does not
need these nowadays and resolves them internally anyway.

> share/perl5/ has a bunch of extra git-{cvsserver,send-email,svn,...}
> scripts so perhaps this is where some of those files went?
> The Makefile places these files in the libexec/ area instead
> of in the share/perl5/ area.

Fixed.

> The Makefile does not install share/gitweb/static/js/.
> Instead, it seems to mash everything together into a single
> share/gitweb/static/gitweb.js file which Meson does not install.
> Meson installs separate files in the share/gitweb/static/js/ area.
> Was that intentional, or is that just another todo?

No, this was unintentional, fixed now. What is missing in this context
is wiring up jsmin and cssmin, but I'll leave that as a todo for now.

Will send a new version later today with these fixes.

Patrick
Patrick Steinhardt Nov. 14, 2024, 8:15 a.m. UTC | #34
On Wed, Nov 13, 2024 at 09:57:55AM -0500, Eli Schwartz wrote:
> On 11/13/24 8:29 AM, Patrick Steinhardt wrote:
> > Fair. I don't really expect anybody to use the combination of muon/sumo
> > for everyday work, mostly because the usability is not quite up to par
> > with Meson/Ninja. But there are two use cases that I deem important:
> 
> (samu :P)

Heh. Just double checked that I got it correct in the docs, but seems
like I did.

> >> Thanks. I don't want to be the CMake champion, so here are a few
> >> helpful/surprising details about the Meson build to help make it better.
> >>
> >>
> >> (1) I first built w/out having "curl-config" installed. I was surprised
> >> to find that "ninja -C build install" ended up installing "bin/curl" and
> >> "bin/curl-config" into the prefix.
> >>
> >> Is there a way to have the install step only install Git without
> >> bringing along these other non-Git bits?
> > 
> > It definitely shouldn't install curl and curl-config, I'll have a look
> > at that. But other than that Meson is currently set up such that it will
> > automatically fall back to the subprojects in case certain dependencies
> > cannot be found. This can be disabled via `meson setup --wrap-mode
> > nofallback`.
> 
> https://github.com/mesonbuild/wrapdb/tree/master/subprojects/packagefiles/curl
> 
> could be updated to handle the case where meson.is_subproject() returns
> "true", by not installing tooling.
> 
> Alternatively, meson install --skip-subprojects can avoid installing
> *any* files from subprojects, on the theory that subprojects exist
> solely to provide static libraries linked into the real project.
> 
> (In theory, one could have a subproject where arbitrary data files from
> a subproject dependency are crucial at runtime. I think the gnome
> ecosystem does this, hence using GLib / Gtk as a subproject "needs" to
> install the subproject too -- but curl definitely doesn't have this
> issue...)

Yeah. `--skip-subprojects` is one way to do this, but that of course
requires the user to know about it. It would be nice if one could wire
this up in "meson.build" directly, e.g. by passing a `install: false`
flag to `dependency()`. We don't want to install any of the subprojects
as we build all of them statically and link them into the final
binaries.

Patrick
Patrick Steinhardt Nov. 14, 2024, 8:15 a.m. UTC | #35
On Wed, Nov 13, 2024 at 11:46:32PM -0500, Eli Schwartz wrote:
> On 11/13/24 11:24 PM, Junio C Hamano wrote:
> > Is there a way to disable that?  These symbolic-links pretending to
> > be installed files are quite annoying---when the target file is lost,
> > the links become useless.
> 
> INSTALL_SYMLINKS=1 in the existing Makefile is of course the one true
> way... (and really, why would you expect the target file to be lost for
> any reason).
> 
> That being said, it doesn't appear the patch series implements any of
> the other multiplicity of choice in what kind of filesystem object gets
> used for multiple copies of the same file. No hardlink or copy support
> has been rigged up.
> 
> (Meson doesn't have a builtin function for performing hardlinks, by the
> way. I don't really think I've seen people desire to do this outside of
> one project being discussed right here right now. hardlinks are mainly
> good at fooling people who look at them into not understanding the
> association between the two, and at breaking across multiple
> filesystems. It's definitely impossible to get it right automatically,
> and asking users to make an informed choice here is just not something
> that projects other than git seem to find valuable, for whatever reason.
> So basically, it's fairly understandable that meson hasn't previously
> added hardlink support.)

Yeah, for now we exclusively use symlinks for this and I didn't wire up
an alternative. This was mostly to keep things simple while still ending
up with a fully functional Git distribution. I also couldn't think of a
scenario where symlinks would be an issue -- Meson also supports them on
Windows, so that would not be an issue.

If this is a requirement I can adapt though. While Meson does not
support hardlinks natively, we can of of course manually wire up them
if required.

Patrick
Junio C Hamano Nov. 14, 2024, 11:06 p.m. UTC | #36
Patrick Steinhardt <ps@pks.im> writes:

> If this is a requirement I can adapt though. While Meson does not
> support hardlinks natively, we can of of course manually wire up them
> if required.

Nah, there must be bigger fish to fry in the new build system
integration, and I have a feeling that by the time we are done, we
may have lost the largest need for hardlinks.

I have a feeling that in _some_ future, we may not be installing
"git-add" and friends for the built-in commands anywhere on disk,
which is historically the primary thing we use hardlinks for to
conserve both disk space and inodes.

Thanks.