git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC PATCH 0/1] Implement CMake build
@ 2018-01-23  0:16 Isaac Hier
  2018-01-23  0:16 ` [RFC PATCH 1/1] " Isaac Hier
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Isaac Hier @ 2018-01-23  0:16 UTC (permalink / raw)
  To: gitster; +Cc: Isaac Hier, git

This patch adds a mostly complete (aside from building tests, documentation,
installation, etc.) CMake build to the git project. I am not sure how much
interest there is in a CMake build, so please send me feedback one way or
another. Personally, I believe CMake will help with Windows builds and is
somewhat easier to read than a Makefile. I considered, adding this to the
contrib directory, but CMakeLists.txt almost always reside in the original
directories, and I'm not sure how wise it would be to do otherwise. If you are
interested in a CMake build, I would be more than happy to finish up the work
here. Decided to wait until I discussed the issue here to finish the final parts
of the build.

Isaac Hier (1):
  Implement CMake build

 CMakeLists.txt              | 1849 +++++++++++++++++++++++++++++++++++++++++++
 cmake/GenerateCmdlist.cmake |   83 ++
 cmake/fopen_dir_test.c      |   11 +
 cmake/fstat_test.c          |   37 +
 cmake/gmtime_test.c         |    7 +
 cmake/iconv_test.c          |   13 +
 cmake/inline_test.c         |    9 +
 cmake/mkdir_test.c          |    7 +
 cmake/mmap_test.c           |   35 +
 cmake/parens_test.c         |    6 +
 cmake/snprintf_test.c       |    7 +
 cmake/sysctl_test.c         |   11 +
 12 files changed, 2075 insertions(+)
 create mode 100644 CMakeLists.txt
 create mode 100644 cmake/GenerateCmdlist.cmake
 create mode 100644 cmake/fopen_dir_test.c
 create mode 100644 cmake/fstat_test.c
 create mode 100644 cmake/gmtime_test.c
 create mode 100644 cmake/iconv_test.c
 create mode 100644 cmake/inline_test.c
 create mode 100644 cmake/mkdir_test.c
 create mode 100644 cmake/mmap_test.c
 create mode 100644 cmake/parens_test.c
 create mode 100644 cmake/snprintf_test.c
 create mode 100644 cmake/sysctl_test.c

-- 
2.14.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [RFC PATCH 1/1] Implement CMake build
  2018-01-23  0:16 [RFC PATCH 0/1] Implement CMake build Isaac Hier
@ 2018-01-23  0:16 ` Isaac Hier
  2018-01-24 13:45 ` [RFC PATCH 0/1] " Isaac Hier
  2018-01-24 19:36 ` Jeff Hostetler
  2 siblings, 0 replies; 18+ messages in thread
From: Isaac Hier @ 2018-01-23  0:16 UTC (permalink / raw)
  To: gitster; +Cc: Isaac Hier, git

Signed-off-by: Isaac Hier <isaachier@gmail.com>
---
 CMakeLists.txt              | 1849 +++++++++++++++++++++++++++++++++++++++++++
 cmake/GenerateCmdlist.cmake |   83 ++
 cmake/fopen_dir_test.c      |   11 +
 cmake/fstat_test.c          |   37 +
 cmake/gmtime_test.c         |    7 +
 cmake/iconv_test.c          |   13 +
 cmake/inline_test.c         |    9 +
 cmake/mkdir_test.c          |    7 +
 cmake/mmap_test.c           |   35 +
 cmake/parens_test.c         |    6 +
 cmake/snprintf_test.c       |    7 +
 cmake/sysctl_test.c         |   11 +
 12 files changed, 2075 insertions(+)
 create mode 100644 CMakeLists.txt
 create mode 100644 cmake/GenerateCmdlist.cmake
 create mode 100644 cmake/fopen_dir_test.c
 create mode 100644 cmake/fstat_test.c
 create mode 100644 cmake/gmtime_test.c
 create mode 100644 cmake/iconv_test.c
 create mode 100644 cmake/inline_test.c
 create mode 100644 cmake/mkdir_test.c
 create mode 100644 cmake/mmap_test.c
 create mode 100644 cmake/parens_test.c
 create mode 100644 cmake/snprintf_test.c
 create mode 100644 cmake/sysctl_test.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000..dff3a44c8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,1849 @@
+cmake_minimum_required(VERSION 3.3)
+
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+set(bin_dir "bin")
+set(lib_dir "lib")
+set(git_exec_dir "libexec/git-core")
+set(mergetools_dir "${git_exec_dir}/mergetools")
+set(share_dir "share")
+set(man_dir "${share_dir}/man")
+set(info_dir "${share_dir}/info")
+set(gitweb_dir "${share_dir}/gitweb")
+set(locale_dir "${share_dir}/locale")
+set(template_dir "${share_dir}/git-core/templates")
+set(html_dir "${share_dir}/doc/git-doc")
+set(etc_gitconfig "etc/gitconfig")
+set(etc_gitattributes "etc/gitattributes")
+
+find_package(Git)
+if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND GIT_FOUND)
+  execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse -q --verify HEAD
+                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                  OUTPUT_VARIABLE GIT_BUILT_FROM_COMMIT
+                  OUTPUT_STRIP_TRAILING_WHITESPACE)
+  message(STATUS "GIT_BUILT_FROM_COMMIT: ${GIT_BUILT_FROM_COMMIT}")
+endif()
+
+if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/version" AND
+   NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/version")
+  file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version" GIT_VERSION)
+elseif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND GIT_FOUND)
+  execute_process(COMMAND ${GIT_EXECUTABLE} describe --match "v[0-9]*" HEAD
+                  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                  OUTPUT_VARIABLE GIT_VERSION
+                  OUTPUT_STRIP_TRAILING_WHITESPACE)
+  if(GIT_VERSION MATCHES "v[0-9]*")
+    string(REPLACE "-" "." GIT_VERSION "${GIT_VERSION}")
+    execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
+                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+                    OUTPUT_VARIABLE git_diff_index_output
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if(git_diff_index_output)
+      set(GIT_VERSION "${GIT_VERSION}.dirty")
+    endif()
+    message(STATUS "GIT_VERSION: ${GIT_VERSION}")
+  else()
+    message(FATAL_ERROR "Cannot determine project version")
+  endif()
+else()
+  set(GIT_VERSION "${DEFAULT_VERSION}")
+endif()
+
+string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+).*$" "\\1"
+       simplified_version "${GIT_VERSION}")
+project(git VERSION "${simplified_version}" LANGUAGES C)
+message(STATUS "PROJECT_VERSION: ${PROJECT_VERSION}")
+
+set(GIT_USER_AGENT "git/${PROJECT_VERSION}" CACHE STRING
+    "User-agent used for network interactions")
+message(STATUS "GIT_USER_AGENT: ${GIT_USER_AGENT}")
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+include(CheckCCompilerFlag)
+include(CheckIncludeFile)
+include(CheckFunctionExists)
+include(CheckLibraryExists)
+include(CheckPrototypeDefinition)
+include(CheckStructHasMember)
+include(CheckSymbolExists)
+include(CheckTypeSize)
+include(CMakeDependentOption)
+include(CTest)
+
+include(GenerateCmdlist)
+
+generate_cmdlist()
+
+macro(print_bool arg_name)
+  if(${arg_name})
+    message(STATUS "${arg_name}: true")
+  else()
+    message(STATUS "${arg_name}: false")
+  endif()
+endmacro()
+
+macro(add_c_flag c_flags flag)
+  string(MAKE_C_IDENTIFIER "${flag}" flag_var)
+  check_c_compiler_flag("${flag}" have_${flag_var})
+  if(have_${flag_var})
+    set(${c_flags} "${${c_flags}} ${flag}")
+  endif()
+endmacro()
+
+# Sources defined here to append to during configuration stage.
+
+set(program_src
+    "credential-store.c"
+    "daemon.c"
+    "fast-import.c"
+    "http-backend.c"
+    "sh-i18n--envsubst.c"
+    "shell.c"
+    "show-index.c"
+    "upload-pack.c")
+
+if(ENABLE_TESTING)
+  set(test_program_src
+    "t/helper/test-chmtime.c"
+    "t/helper/test-ctype.c"
+    "t/helper/test-config.c"
+    "t/helper/test-date.c"
+    "t/helper/test-delta.c"
+    "t/helper/test-drop-caches.c"
+    "t/helper/test-dump-cache-tree.c"
+    "t/helper/test-dump-fsmonitor.c"
+    "t/helper/test-dump-split-index.c"
+    "t/helper/test-dump-untracked-cache.c"
+    "t/helper/test-example-decorate.c"
+    "t/helper/test-fake-ssh.c"
+    "t/helper/test-genrandom.c"
+    "t/helper/test-hashmap.c"
+    "t/helper/test-index-version.c"
+    "t/helper/test-lazy-init-name-hash.c"
+    "t/helper/test-line-buffer.c"
+    "t/helper/test-match-trees.c"
+    "t/helper/test-mergesort.c"
+    "t/helper/test-mktemp.c"
+    "t/helper/test-online-cpus.c"
+    "t/helper/test-parse-options.c"
+    "t/helper/test-path-utils.c"
+    "t/helper/test-prio-queue.c"
+    "t/helper/test-read-cache.c"
+    "t/helper/test-write-cache.c"
+    "t/helper/test-ref-store.c"
+    "t/helper/test-regex.c"
+    "t/helper/test-revision-walking.c"
+    "t/helper/test-run-command.c"
+    "t/helper/test-scrap-cache-tree.c"
+    "t/helper/test-sha1.c"
+    "t/helper/test-sha1-array.c"
+    "t/helper/test-sigchain.c"
+    "t/helper/test-strcmp-offset.c"
+    "t/helper/test-string-list.c"
+    "t/helper/test-submodule-config.c"
+    "t/helper/test-subprocess.c"
+    "t/helper/test-svn-fe.c"
+    "t/helper/test-urlmatch-normalization.c"
+    "t/helper/test-wildmatch.c")
+endif()
+
+set(lib_src
+    "abspath.c"
+    "advice.c"
+    "alias.c"
+    "alloc.c"
+    "apply.c"
+    "archive.c"
+    "archive-tar.c"
+    "archive-zip.c"
+    "argv-array.c"
+    "attr.c"
+    "base85.c"
+    "bisect.c"
+    "blame.c"
+    "blob.c"
+    "branch.c"
+    "bulk-checkin.c"
+    "bundle.c"
+    "cache-tree.c"
+    "checkout.c"
+    "color.c"
+    "column.c"
+    "combine-diff.c"
+    "commit.c"
+    "compat/obstack.c"
+    "compat/terminal.c"
+    "config.c"
+    "connect.c"
+    "connected.c"
+    "convert.c"
+    "copy.c"
+    "credential.c"
+    "csum-file.c"
+    "ctype.c"
+    "date.c"
+    "decorate.c"
+    "diffcore-break.c"
+    "diffcore-delta.c"
+    "diffcore-order.c"
+    "diffcore-pickaxe.c"
+    "diffcore-rename.c"
+    "diff-delta.c"
+    "diff-lib.c"
+    "diff-no-index.c"
+    "diff.c"
+    "dir.c"
+    "dir-iterator.c"
+    "editor.c"
+    "entry.c"
+    "environment.c"
+    "ewah/bitmap.c"
+    "ewah/ewah_bitmap.c"
+    "ewah/ewah_io.c"
+    "ewah/ewah_rlw.c"
+    "exec_cmd.c"
+    "fetch-pack.c"
+    "fsck.c"
+    "fsmonitor.c"
+    "gettext.c"
+    "gpg-interface.c"
+    "graph.c"
+    "grep.c"
+    "hashmap.c"
+    "help.c"
+    "hex.c"
+    "ident.c"
+    "kwset.c"
+    "levenshtein.c"
+    "line-log.c"
+    "line-range.c"
+    "list-objects.c"
+    "list-objects-filter.c"
+    "list-objects-filter-options.c"
+    "ll-merge.c"
+    "lockfile.c"
+    "log-tree.c"
+    "mailinfo.c"
+    "mailmap.c"
+    "match-trees.c"
+    "merge.c"
+    "merge-blobs.c"
+    "merge-recursive.c"
+    "mergesort.c"
+    "mru.c"
+    "name-hash.c"
+    "notes.c"
+    "notes-cache.c"
+    "notes-merge.c"
+    "notes-utils.c"
+    "object.c"
+    "oidmap.c"
+    "oidset.c"
+    "packfile.c"
+    "pack-bitmap.c"
+    "pack-bitmap-write.c"
+    "pack-check.c"
+    "pack-objects.c"
+    "pack-revindex.c"
+    "pack-write.c"
+    "pager.c"
+    "parse-options.c"
+    "parse-options-cb.c"
+    "patch-delta.c"
+    "patch-ids.c"
+    "path.c"
+    "pathspec.c"
+    "pkt-line.c"
+    "preload-index.c"
+    "pretty.c"
+    "prio-queue.c"
+    "progress.c"
+    "prompt.c"
+    "protocol.c"
+    "quote.c"
+    "reachable.c"
+    "read-cache.c"
+    "reflog-walk.c"
+    "refs.c"
+    "refs/files-backend.c"
+    "refs/iterator.c"
+    "refs/packed-backend.c"
+    "refs/ref-cache.c"
+    "ref-filter.c"
+    "remote.c"
+    "replace_object.c"
+    "repository.c"
+    "rerere.c"
+    "resolve-undo.c"
+    "revision.c"
+    "run-command.c"
+    "send-pack.c"
+    "sequencer.c"
+    "server-info.c"
+    "setup.c"
+    "sha1-array.c"
+    "sha1-lookup.c"
+    "sha1_file.c"
+    "sha1_name.c"
+    "shallow.c"
+    "sideband.c"
+    "sigchain.c"
+    "split-index.c"
+    "strbuf.c"
+    "streaming.c"
+    "string-list.c"
+    "submodule.c"
+    "submodule-config.c"
+    "sub-process.c"
+    "symlinks.c"
+    "tag.c"
+    "tempfile.c"
+    "tmp-objdir.c"
+    "trace.c"
+    "trailer.c"
+    "transport.c"
+    "transport-helper.c"
+    "tree-diff.c"
+    "tree.c"
+    "tree-walk.c"
+    "unpack-trees.c"
+    "url.c"
+    "urlmatch.c"
+    "usage.c"
+    "userdiff.c"
+    "utf8.c"
+    "varint.c"
+    "version.c"
+    "versioncmp.c"
+    "walker.c"
+    "wildmatch.c"
+    "worktree.c"
+    "wrapper.c"
+    "write_or_die.c"
+    "ws.c"
+    "wt-status.c"
+    "xdiff-interface.c"
+    "zlib")
+
+set(builtin_src
+    "builtin/add.c"
+    "builtin/am.c"
+    "builtin/annotate.c"
+    "builtin/apply.c"
+    "builtin/archive.c"
+    "builtin/bisect--helper.c"
+    "builtin/blame.c"
+    "builtin/branch.c"
+    "builtin/bundle.c"
+    "builtin/cat-file.c"
+    "builtin/check-attr.c"
+    "builtin/check-ignore.c"
+    "builtin/check-mailmap.c"
+    "builtin/check-ref-format.c"
+    "builtin/checkout-index.c"
+    "builtin/checkout.c"
+    "builtin/clean.c"
+    "builtin/clone.c"
+    "builtin/column.c"
+    "builtin/commit-tree.c"
+    "builtin/commit.c"
+    "builtin/config.c"
+    "builtin/count-objects.c"
+    "builtin/credential.c"
+    "builtin/describe.c"
+    "builtin/diff-files.c"
+    "builtin/diff-index.c"
+    "builtin/diff-tree.c"
+    "builtin/diff.c"
+    "builtin/difftool.c"
+    "builtin/fast-export.c"
+    "builtin/fetch-pack.c"
+    "builtin/fetch.c"
+    "builtin/fmt-merge-msg.c"
+    "builtin/for-each-ref.c"
+    "builtin/fsck.c"
+    "builtin/gc.c"
+    "builtin/get-tar-commit-id.c"
+    "builtin/grep.c"
+    "builtin/hash-object.c"
+    "builtin/help.c"
+    "builtin/index-pack.c"
+    "builtin/init-db.c"
+    "builtin/interpret-trailers.c"
+    "builtin/log.c"
+    "builtin/ls-files.c"
+    "builtin/ls-remote.c"
+    "builtin/ls-tree.c"
+    "builtin/mailinfo.c"
+    "builtin/mailsplit.c"
+    "builtin/merge.c"
+    "builtin/merge-base.c"
+    "builtin/merge-file.c"
+    "builtin/merge-index.c"
+    "builtin/merge-ours.c"
+    "builtin/merge-recursive.c"
+    "builtin/merge-tree.c"
+    "builtin/mktag.c"
+    "builtin/mktree.c"
+    "builtin/mv.c"
+    "builtin/name-rev.c"
+    "builtin/notes.c"
+    "builtin/pack-objects.c"
+    "builtin/pack-redundant.c"
+    "builtin/pack-refs.c"
+    "builtin/patch-id.c"
+    "builtin/prune-packed.c"
+    "builtin/prune.c"
+    "builtin/pull.c"
+    "builtin/push.c"
+    "builtin/read-tree.c"
+    "builtin/rebase--helper.c"
+    "builtin/receive-pack.c"
+    "builtin/reflog.c"
+    "builtin/remote.c"
+    "builtin/remote-ext.c"
+    "builtin/remote-fd.c"
+    "builtin/repack.c"
+    "builtin/replace.c"
+    "builtin/rerere.c"
+    "builtin/reset.c"
+    "builtin/rev-list.c"
+    "builtin/rev-parse.c"
+    "builtin/revert.c"
+    "builtin/rm.c"
+    "builtin/send-pack.c"
+    "builtin/shortlog.c"
+    "builtin/show-branch.c"
+    "builtin/show-ref.c"
+    "builtin/stripspace.c"
+    "builtin/submodule--helper.c"
+    "builtin/symbolic-ref.c"
+    "builtin/tag.c"
+    "builtin/unpack-file.c"
+    "builtin/unpack-objects.c"
+    "builtin/update-index.c"
+    "builtin/update-ref.c"
+    "builtin/update-server-info.c"
+    "builtin/upload-archive.c"
+    "builtin/var.c"
+    "builtin/verify-commit.c"
+    "builtin/verify-pack.c"
+    "builtin/verify-tag.c"
+    "builtin/worktree.c"
+    "builtin/write-tree.c")
+
+add_c_flag(CMAKE_C_FLAGS "-Wall")
+
+option(DEVELOPER "Enable developer warnings" OFF)
+if(DEVELOPER)
+  set(dev_c_flags
+      "-Werror"
+      "-Wdeclaration-after-statement"
+      "-Wno-format-zero-length"
+      "-Wold-style-definition"
+      "-Woverflow"
+      "-Wpointer-arith"
+      "-Wstrict-prototypes"
+      "-Wunused"
+      "-Wvla")
+  foreach(flag ${dev_c_flags})
+    add_c_flag(CMAKE_C_FLAGS "${flag}")
+  endforeach()
+endif()
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SANITIZE "" CACHE STRING "Comma-delimited list of sanitizer flags")
+if(SANITIZE)
+  add_c_flag(CMAKE_C_FLAGS "-fsanitize=${SANITIZE}")
+  add_c_flag(CMAKE_C_FLAGS "-fno-sanitize-recover=${SANITIZE}")
+  add_c_flag(CMAKE_C_FLAGS "-fno-omit-frame-pointer")
+  string(REPLACE "," ";" SANITIZERS "${SANITIZE}")
+  if("undefined" IN_LIST SANITIZERS)
+    list(APPEND basic_defs "-DNO_UNALIGNED_LOADS")
+  endif()
+  if("leak" IN_LIST SANITIZERS)
+    list(APPEND basic_defs "-DSUPPRESS_ANNOTATED_LEAKS")
+  endif()
+endif()
+
+message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
+
+list(APPEND basic_defs "-DGIT_HOST_CPU=\"${CMAKE_SYSTEM_PROCESSOR}\"")
+message(STATUS "GIT_HOST_CPU: ${CMAKE_SYSTEM_PROCESSOR}")
+
+if(WIN32)
+  set(socket_headers "winsock2.h;ws2tcpip.h")
+else()
+  set(socket_headers "sys/types.h;sys/socket.h")
+endif()
+
+set(CMAKE_EXTRA_INCLUDE_FILES ${socket_headers})
+check_type_size(socklen_t sizeof_socklen_t)
+if(sizeof_socklen_t)
+  set(SOCKLEN_T "socklen_t")
+else()
+  set(SOCKLEN_T "size_t")
+endif()
+set(CMAKE_EXTRA_INCLUDE_FILES)
+message(STATUS "socklen_t type: ${SOCKLEN_T}")
+if(SOCKLEN_T)
+  list(APPEND basic_defs "-Dsocklen_t=${SOCKLEN_T}")
+endif()
+
+set(INLINE "")
+foreach(inline_keyword "inline" "__inline" "__inline__")
+  try_compile(inline_compile_result
+    "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+    SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/inline_test.c"
+    COMPILE_DEFINITIONS "-DINLINE=${inline_keyword}")
+  if(inline_compile_result)
+    set(INLINE "${inline_keyword}")
+    break()
+  endif()
+endforeach()
+message(STATUS "INLINE: ${INLINE}")
+if(INLINE)
+  list(APPEND basic_defs "-DINLINE=${INLINE}")
+endif()
+
+if(NOT CMAKE_CROSSCOMPILING)
+  string(REPLACE "-Wall" "" flags_warning_disabled "${CMAKE_C_FLAGS}")
+  string(REPLACE "-Werror" "" flags_warning_disabled
+         "${flags_warning_disabled}")
+  try_run(snprintf_run_result
+          snprintf_compile_result
+          "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+          "${CMAKE_CURRENT_SOURCE_DIR}/cmake/snprintf_test.c"
+          CMAKE_FLAGS "-DCMAKE_C_FLAGS=${flags_warnings_disabled}"
+          COMPILE_OUTPUT_VARIABLE snprintf_compile_output)
+  if(snprintf_compile_result)
+    if(snprintf_run_result EQUAL -1)
+      set(SNPRINTF_RETURNS_BOGUS ON)
+    elseif(NOT snprintf_run_result EQUAL 2)
+      message(WARNING
+        "Invalid return value for snprintf_test: ${snprintf_run_result}")
+      set(SNPRINTF_RETURNS_BOGUS ON)
+    endif()
+  else()
+    message(WARNING "Cannot compile snprintf_test: ${snprintf_compile_output}")
+    set(SNPRINTF_RETURNS_BOGUS ON)
+  endif()
+endif()
+print_bool(SNPRINTF_RETURNS_BOGUS)
+if(SNPRINTF_RETURNS_BOGUS)
+  list(APPEND compat_defs "-DSNPRINTF_RETURNS_BOGUS")
+  list(APPEND compat_src "compat/snprintf.c")
+endif()
+
+if(NOT CMAKE_CROSSCOMPILING)
+  try_run(fopen_dir_run_result
+          fopen_dir_compile_result
+          "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+          "${CMAKE_CURRENT_SOURCE_DIR}/cmake/fopen_dir_test.c"
+          COMPILE_OUTPUT_VARIABLE fopen_dir_compile_output
+          ARGS "${CMAKE_CURRENT_SOURCE_DIR}")
+  if(fopen_dir_compile_result)
+    if(fopen_dir_run_result EQUAL 0)
+      set(FREAD_READS_DIRECTORIES ON)
+    endif()
+  else()
+    message(WARNING "Cannot compile fopen_dir_test: "
+            "${fopen_dir_compile_output}")
+  endif()
+endif()
+print_bool(FREAD_READS_DIRECTORIES)
+if(FREAD_READS_DIRECTORIES)
+  list(APPEND compat_defs "-DFREAD_READS_DIRECTORIES")
+  list(APPEND compat_src "compat/fopen.c")
+endif()
+
+find_package(OpenSSL)
+cmake_dependent_option(
+  OPENSSL "Use OpenSSL" ON "OPENSSL_FOUND;not_apple_common_crypto" OFF)
+if(NOT OPENSSL)
+  list(APPEND basic_defs "-DNO_OPENSSL")
+endif()
+
+set(PCRE_VERSION "" CACHE STRING "pcre version (1 or 2), leave blank to omit")
+set_property(CACHE PCRE_VERSION PROPERTY STRINGS "1;2")
+if(PCRE_VERSION AND NOT PCRE_VERSION MATCHES "^(1|2)$")
+  message(FATAL_ERROR "Invalid pcre version, must be blank, 1, or 2")
+endif()
+
+if(PCRE_VERSION)
+  if(NOT DEFINED PCRE_LIBRARY OR NOT DEFINED PCRE_INCLUDE_DIR)
+    if(PCRE_VERSION STREQUAL "2")
+      find_path(PCRE_INCLUDE_DIR "pcre2.h")
+      find_library(PCRE_LIBRARY NAMES pcre2)
+    else()
+      set(PCRE_VERSION "1")
+      find_path(PCRE_INCLUDE_DIR "pcre.h")
+      find_library(PCRE_LIBRARY NAMES pcre)
+    endif()
+    mark_as_advanced(PCRE_LIBRARY PCRE_INCLUDE_DIR)
+
+    message(STATUS "PCRE_VERSION: ${PCRE_VERSION}")
+    message(STATUS "PCRE_INCLUDE_DIR: ${PCRE_INCLUDE_DIR}")
+    message(STATUS "PCRE_LIBRARY: ${PCRE_LIBRARY}")
+  endif()
+
+  if(PCRE_INCLUDE_DIR AND PCRE_LIBRARY)
+    list(APPEND basic_defs "-DUSE_LIBPCRE${PCRE_VERSION}")
+    list(APPEND include_dirs ${PCRE_INCLUDE_DIR})
+    list(APPEND libs ${PCRE_LIBRARY})
+
+    if(PCRE_VERSION STREQUAL "1" AND PCRE_LIBRARY)
+      check_symbol_exists(PCRE_JIT_CONFIG "pcre.h" has_jit)
+      set(CMAKE_REQUIRED_INCLUDES)
+      if(has_jit)
+        set(LIBPCRE1_JIT ON)
+      endif()
+      print_bool(LIBPCRE1_JIT)
+      if(NOT LIBPCRE1_JIT)
+        list(APPEND basic_defs "-DNO_LIBPCRE1_JIT")
+      endif()
+    endif()
+  endif()
+endif()
+
+check_include_file("alloca.h" HAVE_ALLOCA_H)
+print_bool(HAVE_ALLOCA_H)
+if(HAVE_ALLOCA_H)
+  list(APPEND basic_defs "-DHAVE_ALLOCA_H")
+endif()
+
+find_package(CURL)
+cmake_dependent_option(CURL "Use libcurl, needed for HTTP transport" ON
+                       "CURL_FOUND" OFF)
+if(CURL)
+  set(NO_CURL "0")
+else()
+  set(NO_CURL "1")
+  list(APPEND basic_defs "-DNO_CURL")
+endif()
+
+find_package(EXPAT)
+cmake_dependent_option(EXPAT "Enable expat for HTTP parsing" ON
+                      "EXPAT_FOUND" OFF)
+# EXPAT_NEEDS_XMLPARSE_H not handled in CMake build, seeing as CMake FindEXPAT
+# explicitly relies on the existence of "expat.h" to find includes directory.
+
+if(CURL AND CURL_VERSION_STRING VERSION_GREATER_EQUAL "7.22.0")
+  list(APPEND basic_defs "-DUSE_CURL_FOR_IMAP_SEND")
+  set(imap_send_builddeps "http.c")
+  set(imap_send_libs ${CURL_LIBRARIES})
+endif()
+
+find_package(Gettext)
+find_package(Intl)
+cmake_dependent_option(GETTEXT "Translate git output" ON
+                       "GETTEXT_FOUND;Intl_FOUND" OFF)
+
+find_library(iconv_lib_path NAMES iconv libiconv libiconv-2)
+if(iconv_lib_path)
+  set(iconv_lib ${iconv_lib_path})
+endif()
+
+if(NOT GETTEXT)
+  list(APPEND basic_defs "-DNO_GETTEXT")
+  set(no_gettext ON)
+endif()
+cmake_dependent_option(USE_GETTEXT_SCHEME_FALLTHROUGH "${doc_string}" OFF
+                       "no_gettext" ON)
+if(GETTEXT)
+  set(doc_string "Enable if you do not trust installed gettext translation")
+  set(doc_string "${doc_string} of the shell scripts output")
+
+  check_include_file("libcharset.h" HAVE_LIBCHARSET_H)
+  if(HAVE_LIBCHARSET_H)
+    list(APPEND basic_defs "-DHAVE_LIBCHARSET_H")
+    check_library_exists(charset locale_charset "" have_libcharset)
+    if(have_libcharset)
+      set(CHARSET_LIB charset)
+    elseif(iconv_lib)
+      check_library_exists(${iconv_lib} locale_charset "" have_locale_charset_libiconv)
+      if(have_locale_charset_libiconv)
+        set(CHARSET_LIB ${iconv_lib})
+      else()
+        message(FATAL_ERROR "Cannot find library that defines locale_charset")
+      endif()
+    endif()
+    list(APPEND libs ${CHARSET_LIB})
+  endif()
+
+  check_function_exists(nl_langinfo LIBC_CONTAINS_LIBINTL)
+  print_bool(LIBC_CONTAINS_LIBINTL)
+  if(NOT LIBC_CONTAINS_LIBINTL)
+    list(APPEND libs ${Intl_LIBRARY})
+    set(CMAKE_REQUIRED_LIBRARIES "${Intl_LIBRARY}")
+    check_function_exists(nl_langinfo nl_langinfo_found)
+    if(NOT nl_langinfo_found)
+      message(FATAL_ERROR "nl_langinfo cannot be found in ${Intl_LIBRARY}")
+    endif()
+    set(CMAKE_REQUIRED_LIBRARIES)
+  endif()
+
+  # TODO: MSGFMT_EXTENDED_OPTIONS?
+endif()
+
+check_include_file("paths.h" HAVE_PATHS_H)
+print_bool(HAVE_PATHS_H)
+if(HAVE_PATHS_H)
+  list(APPEND basic_defs "-DHAVE_PATHS_H")
+endif()
+
+check_include_file("inttypes.h" HAVE_INTTYPES_H)
+print_bool(HAVE_INTTYPES_H)
+if(NOT HAVE_INTTYPES_H)
+  list(APPEND basic_defs "-DNO_INTTYPES_H")
+endif()
+
+check_symbol_exists(DT_UNKNOWN "dirent.h" have_dt_unknown)
+if(have_dt_unknown)
+  check_struct_has_member("struct dirent" d_type "dirent.h" have_d_type)
+  if(have_d_type)
+    set(D_TYPE_IN_DIRENT ON)
+  endif()
+  print_bool(D_TYPE_IN_DIRENT)
+else()
+  set(D_TYPE_IN_DIRENT ON)
+endif()
+
+if(NOT D_TYPE_IN_DIRENT)
+  list(APPEND basic_defs "-DNO_D_TYPE_IN_DIRENT")
+endif()
+
+check_include_file("strings.h" HAVE_STRINGS_H)
+print_bool(HAVE_STRINGS_H)
+if(HAVE_STRINGS_H)
+  list(APPEND basic_defs "-DHAVE_STRINGS_H")
+endif()
+
+check_function_exists(strcasestr STRCASESTR)
+print_bool(STRCASESTR)
+if(NOT STRCASESTR)
+  list(APPEND compat_defs "-DNO_STRCASESTR")
+  list(APPEND compat_src "compat/strcasestr.c")
+endif()
+
+check_function_exists(hstrerror HSTRERROR)
+print_bool(HSTRERROR)
+if(NOT HSTRERROR)
+  list(APPEND compat_defs "-DNO_HSTRERROR")
+  list(APPEND compat_src "compat/hstrerror.c")
+endif()
+
+check_function_exists(memmem MEMMEM)
+print_bool(MEMMEM)
+if(NOT MEMMEM)
+  list(APPEND compat_defs "-DNO_MEMMEM")
+  list(APPEND compat_src "compat/memmem.c")
+endif()
+
+check_function_exists(getpagesize GETPAGESIZE)
+print_bool(GETPAGESIZE)
+if(NOT GETPAGESIZE)
+  list(APPEND compat_defs "-DNO_GETPAGESIZE")
+endif()
+
+check_function_exists(strlcpy STRLCPY)
+print_bool(STRLCPY)
+if(NOT STRLCPY)
+  list(APPEND compat_defs "-DNO_STRLCPY")
+  list(APPEND compat_src "compat/strlcpy.c")
+endif()
+
+check_function_exists(strtoimax have_strtoimax)
+if(NOT have_strtoimax)
+  check_function_exists(strtoumax have_strtoumax)
+endif()
+if(have_strtoimax OR have_strtoumax)
+  set(STRTOUMAX ON)
+endif()
+print_bool(STRTOUMAX)
+if(NOT STRTOUMAX)
+  list(APPEND compat_defs "-DNO_STRTOUMAX")
+  list(APPEND compat_src
+       "compat/strtoumax.c"
+       "compat/strtoimax.c")
+endif()
+
+check_function_exists(strtoull STRTOULL)
+print_bool(STRTOULL)
+if(NOT STRTOULL)
+  list(APPEND compat_defs "-DNO_STRTOULL")
+endif()
+
+check_function_exists(setenv SETENV)
+print_bool(SETENV)
+if(NOT SETENV)
+  list(APPEND compat_defs "-DNO_SETENV")
+  list(APPEND compat_src "compat/setenv.c")
+endif()
+
+check_function_exists(unsetenv UNSETENV)
+print_bool(UNSETENV)
+if(NOT UNSETENV)
+  list(APPEND compat_defs "-DNO_UNSETENV")
+  list(APPEND compat_src "compat/unsetenv.c")
+endif()
+
+check_function_exists(mkdtemp MKDTEMP)
+print_bool(MKDTEMP)
+if(NOT MKDTEMP)
+  list(APPEND compat_defs "-DNO_MKDTEMP")
+  list(APPEND compat_src "compat/mkdtemp.c")
+endif()
+
+check_function_exists(initgroups INITGROUPS)
+print_bool(INITGROUPS)
+if(NOT INITGROUPS)
+  list(APPEND compat_defs "-DNO_INITGROUPS")
+endif()
+
+if(NOT CMAKE_CROSSCOMPILING)
+  set(test_dir_path "${CMAKE_CURRENT_BINARY_DIR}/mkdir_test_dir")
+  try_run(mkdir_run_result
+          mkdir_compile_result
+          "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+          "${CMAKE_CURRENT_SOURCE_DIR}/cmake/mkdir_test.c"
+          COMPILE_OUTPUT_VARIABLE mkdir_compile_output
+          ARGS "${test_dir_path}/")
+  if(mkdir_compile_result)
+    if(mkdir_run_result EQUAL 0 AND IS_DIRECTORY "${test_dir_path}")
+      file(REMOVE_RECURSE "${test_dir_path}")
+      set(MKDIR_W_TRAILING_SLASH ON)
+    endif()
+  else()
+    message(WARNING "Failed to compile mkdir_test: ${mkdir_compile_output}")
+  endif()
+endif()
+print_bool(MKDIR_W_TRAILING_SLASH)
+if(NOT MKDIR_W_TRAILING_SLASH)
+  list(APPEND compat_defs "-DMKDIR_WO_TRAILING_SLASH")
+  list(APPEND compat_src "compat/mkdir.c")
+endif()
+
+check_struct_has_member("struct passwd" pw_gecos "pwd.h" GECOS_IN_PWENT)
+print_bool(GECOS_IN_PWENT)
+if(NOT GECOS_IN_PWENT)
+  list(APPEND basic_defs "-DNO_GECOS_IN_PWENT")
+endif()
+
+check_include_file("libgen.h" LIBGEN_H)
+print_bool(LIBGEN_H)
+if(NOT LIBGEN_H)
+  list(APPEND compat_defs "-DNO_LIBGEN_H")
+  list(APPEND compat_src "compat/basename.c")
+endif()
+
+check_function_exists(dirname libc_has_dirname)
+if(NOT libc_has_dirname)
+  set(NEEDS_LIBGEN ON)
+endif()
+print_bool(NEEDS_LIBGEN)
+if(NEEDS_LIBGEN)
+  list(APPEND libs gen)
+endif()
+
+check_include_file("sys/select.h" SYS_SELECT_H)
+print_bool(SYS_SELECT_H)
+if(NOT SYS_SELECT_H)
+  list(APPEND basic_defs "-DNO_SYS_SELECT_H")
+endif()
+
+if(NOT WIN32)
+  set(not_windows ON)
+endif()
+cmake_dependent_option(
+  SYMLINK_HEAD "Occasionally use symbolic link for .git/HEAD" ON
+  "not_windows" OFF)
+print_bool(SYMLINK_HEAD)
+if(NOT SYMLINK_HEAD)
+  list(APPEND basic_defs "-DNO_SYMLINK_HEAD")
+endif()
+
+option(SVN_TESTS "Build time-consuming SVN tests" ON)
+print_bool(SVN_TESTS)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+  set(doc_template "Use @tool@ installations when present in @location@ for")
+  set(doc_template "${doc_template} includes/libraries")
+
+  set(tool "Fink")
+  set(location "/sw")
+  string(CONFIGURE doc_string "${doc_template}")
+  option(FINK "${doc_string}" ON)
+  print_bool(FINK)
+  if(FINK AND IS_DIRECTORY "/sw")
+    if(IS_DIRECTORY "/sw/include")
+      list(APPEND include_dirs "/sw/include")
+    endif()
+    if(IS_DIRECTORY "/sw/lib")
+      list(APPEND link_dirs "/sw/lib")
+    endif()
+  endif()
+
+  set(tool "DarwinPorts")
+  set(location "/opt/local")
+  string(CONFIGURE doc_string "${doc_template}")
+  option(DARWIN_PORTS "${doc_string}" ON)
+  print_bool(DARWIN_PORTS)
+  if(DARWIN_PORTS AND IS_DIRECTORY "/opt/local")
+    if(IS_DIRECTORY "/opt/local/include")
+      list(APPEND include_dirs "/opt/local/include")
+    endif()
+    if(IS_DIRECTORY "/opt/local/lib")
+      list(APPEND link_dirs "/opt/local/lib")
+    endif()
+  endif()
+
+  option(APPLE_COMMON_CRYPTO "Use Apple's CommonCrypto library" ON)
+  print_bool(APPLE_COMMON_CRYPTO)
+  if(APPLE_COMMON_CRYPTO)
+    list(APPEND compat_defs "-DAPPLE_COMMON_CRYPTO")
+  else()
+    set(not_apple_common_crypto ON)
+  endif()
+endif()
+
+set(doc_string
+    "Limit the amount of data that will be hashed in one call to the "
+    "platform's SHA1_Update()")
+if(APPLE_COMMON_CRYPTO)
+  set(SHA1_MAX_BLOCK_SIZE "1024L*1024L*1024L" CACHE STRING "${doc_string}")
+else()
+  set(SHA1_MAX_BLOCK_SIZE "" CACHE STRING "${doc_string}")
+endif()
+
+if(SHA1_MAX_BLOCK_SIZE)
+  list(APPEND basic_defs "-DSHA1_MAX_BLOCK_SIZE=\"${SHA1_MAX_BLOCK_SIZE}\"")
+  list(APPEND lib_src "compat/sha1-chunked.c")
+endif()
+
+if(OPENSSL)
+  set(sha1_default_implementation "OPENSSL_SHA1")
+else()
+  set(sha1_default_implementation "BLK_SHA1")
+endif()
+set(SHA1_IMPLEMENTATION "${sha1_default_implementation}" CACHE STRING
+    "Source to use for SHA1 implementation")
+set_property(CACHE SHA1_IMPLEMENTATION PROPERTY STRINGS
+             "OPENSSL_SHA1;BLK_SHA1;PPC_SHA1;DC_SHA1")
+message(STATUS "SHA1_IMPLEMENTATION: ${SHA1_IMPLEMENTATION}")
+if(SHA1_IMPLEMENTATION STREQUAL "DC_SHA1")
+  set(DC_SHA1_EXTERNAL "" CACHE STRING "external SHA1 collision-detect library")
+  set(doc_string
+      "use the sha1collisiondetection shipped as a submodule instead of the")
+  set(doc_string "${doc_string} non-submodule copy in sha1dc")
+  message(STATUS "DC_SHA1_EXTERNAL: ${DC_SHA1_EXTERNAL}")
+
+  option(DC_SHA1_SUBMODULE "${doc_string}" OFF)
+  print_bool(DC_SHA1_SUBMODULE)
+endif()
+
+if(SHA1_IMPLEMENTATION STREQUAL "OPENSSL_SHA1")
+  list(APPEND include_dirs ${OPENSSL_INCLUDE_DIRS})
+  list(APPEND libs ${OPENSSL_LIBRARIES})
+  list(APPEND basic_defs "-DSHA1_OPENSSL")
+elseif(SHA1_IMPLEMENTATION STREQUAL "BLK_SHA1")
+  list(APPEND lib_src "block-sha1/sha1.c")
+  list(APPEND basic_defs "-DSHA1_BLK")
+elseif(SHA1_IMPLEMENTATION STREQUAL "PPC_SHA1")
+  list(APPEND lib_src
+       "ppc/sha1.c"
+       "ppc/sha1ppc.c")
+  list(APPEND basic_defs "-DSHA1_PPC")
+elseif(SHA1_IMPLEMENTATION STREQUAL "APPLE_COMMON_CRYPTO")
+  list(APPEND compat_defs "-DCOMMON_DIGEST_FOR_OPENSSL")
+  list(APPEND basic_defs "-DSHA1_APPLE")
+else()
+  if(NOT SHA1_IMPLEMENTATION STREQUAL "DC_SHA1")
+    message(FATAL_ERROR "Invalid SHA1_IMPLEMENTATION: ${SHA1_IMPLEMENTATION}")
+  endif()
+  list(APPEND basic_defs "-DSHA1_DC")
+  list(APPEND lib_src "sha1dc_git.c")
+
+  if(DC_SHA1_EXTERNAL)
+    if(DC_SHA1_SUBMODULE)
+      message(FATAL_ERROR
+        "Only set DC_SHA1_EXTERNAL or DC_SHA1_SUBMODULE, not both")
+    endif()
+    list(APPEND basic_defs "-DDC_SHA1_EXTERNAL")
+    list(APPEND libs sha1detectcoll)
+  elseif(DC_SHA1_SUBMODULE)
+    list(APPEND lib_src
+         "sha1collisiondetection/lib/sha1.c"
+         "sha1collisiondetection/lib/ubc_check.c")
+    list(APPEND basic_defs "-DDC_SHA1_SUBMODULE")
+  else()
+    list(APPEND lib_src
+         "sha1collisiondetection/sha1.c"
+         "sha1collisiondetection/ubc_check.c")
+  endif()
+  list(APPEND basic_defs
+       "-DSHA1DC_NO_STANDARD_INCLUDES"
+       "-DSHA1DC_INIT_SAFE_HASH_DEFAULT=0"
+       "-DSHA1DC_CUSTOM_INCLUDE_SHA1_C=\"cache.h\""
+       "-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C=\"git-compat-util.h\"")
+endif()
+
+set(CMAKE_EXTRA_INCLUDE_FILES "stdint.h")
+
+check_type_size(intptr_t INTPTR_T)
+print_bool(INTPTR_T)
+if(NOT INTPTR_T)
+  list(APPEND compat_defs "-DNO_INTPTR_T")
+endif()
+
+check_type_size(uintmax_t UINTMAX_T)
+print_bool(UINTMAX_T)
+if(NOT UINTMAX_T)
+  list(APPEND compat_defs "-Duintmax_t=uint32_t")
+endif()
+
+set(CMAKE_EXTRA_INCLUDE_FILES)
+
+check_function_exists(mmap have_mmap)
+cmake_dependent_option(MMAP "Use mmap" ON "have_mmap" OFF)
+print_bool(MMAP)
+
+cmake_dependent_option(
+  USE_WIN32_MMAP "Use Windows mmap" OFF "WIN32;MMAP" OFF)
+if(MMAP)
+  if(USE_WIN32_MMAP)
+    list(APPEND compat_defs "-DUSE_WIN32_MMAP")
+    list(APPEND compat_src "compat/win32mmap.c")
+  endif()
+else()
+  list(APPEND compat_defs "-DNO_MMAP")
+  list(APPEND compat_src "compat/mmap.c")
+endif()
+
+if(MMAP)
+  if(CMAKE_CROSSCOMPILING)
+    set(MMAP_PREVENTS_DELETE ON)
+  else()
+    file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/mmap_test.c"
+         DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp")
+    try_run(mmap_run_result
+            mmap_compile_result
+            "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+            "${CMAKE_CURRENT_SOURCE_DIR}/cmake/mmap_test.c"
+            COMPILE_OUTPUT_VARIABLE mmap_compile_output
+            ARGS "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/mmap_test.c")
+    if(mmap_compile_result)
+      if(NOT mmap_run_result EQUAL 0)
+        set(MMAP_PREVENTS_DELETE ON)
+      endif()
+    else()
+      message(WARNING "Failed to compile mmap_test: ${mmap_compile_output}")
+      set(MMAP_PREVENTS_DELETE ON)
+    endif()
+  endif()
+  print_bool(MMAP_PREVENTS_DELETE)
+endif()
+
+if(MMAP_PREVENTS_DELETE)
+  list(APPEND basic_defs "-DMMAP_PREVENTS_DELETE")
+endif()
+
+option(POLL "Use poll()" ON)
+if(POLL)
+  check_include_file("sys/poll.h" SYS_POLL_H)
+  print_bool(SYS_POLL_H)
+  if(NOT SYS_POLL_H)
+    list(APPEND basic_defs "-DNO_SYS_POLL_H")
+  endif()
+else()
+  list(APPEND compat_defs "-DNO_POLL")
+  list(APPEND compat_include_dirs "compat/poll")
+  list(APPEND compat_src "compat/poll/poll.c")
+endif()
+
+if(NOT SYS_POLL_H)
+  list(APPEND basic_defs "-DNO_SYS_POLL_H")
+endif()
+
+find_package(Threads)
+cmake_dependent_option(PTHREADS "Use pthreads" ON "CMAKE_USE_PTHREADS_INIT" OFF)
+print_bool(PTHREADS)
+
+if(PTHREADS)
+  list(APPEND libs Threads::Threads)
+  list(APPEND lib_src "thread-utils.c")
+else()
+  list(APPEND basic_defs "-DNO_PTHREADS")
+endif()
+
+check_function_exists(pread have_pread)
+cmake_dependent_option(PREAD "Use pread system call" ON "have_pread" OFF)
+print_bool(PREAD)
+if(NOT PREAD)
+  list(APPEND compat_defs "-DNO_PREAD")
+  list(APPEND compat_src "compat/pread.c")
+endif()
+
+set(CMAKE_EXTRA_INCLUDE_FILES "sys/time.h")
+check_type_size("struct itimerval" STRUCT_ITIMERVAL)
+print_bool(STRUCT_ITIMERVAL)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+if(STRUCT_ITIMERVAL)
+  check_function_exists(setitimer SETITIMER)
+  print_bool(SETITIMER)
+else()
+  list(APPEND "-DNO_STRUCT_ITIMERVAL")
+endif()
+
+if(NOT SETITIMER)
+  list(APPEND compat_defs "-DNO_SETITIMER")
+endif()
+
+option(FAST_WORKING_DIRECTORY
+  "Accessing working directory is faster than accessing objects in pack files"
+  ON)
+print_bool(FAST_WORKING_DIRECTORY)
+if(NOT FAST_WORKING_DIRECTORY)
+  list(APPEND basic_defs "-DNO_FAST_WORKING_DIRECTORY")
+endif()
+
+option(TRUSTABLE_FILEMODE "Filesystem supports executable file mode" ON)
+print_bool(TRUSTABLE_FILEMODE)
+if(NOT TRUSTABLE_FILEMODE)
+  list(APPEND basic_defs "-DNO_TRUSTABLE_FILEMODE")
+endif()
+
+option(NEEDS_MODE_TRANSLATION
+       "OS strays from the typical file type bits in mode values"
+       OFF)
+print_bool(NEEDS_MODE_TRANSLATION)
+if(NEEDS_MODE_TRANSLATION)
+  list(APPEND compat_defs "-DNEEDS_MODE_TRANSLATION")
+  list(APPEND compat_src "compat/stat.c")
+endif()
+
+option(IPV6 "System supports IPv6" ON)
+print_bool(IPV6)
+if(NOT IPV6)
+  list(APPEND basic_defs "-DNO_IPV6")
+endif()
+
+check_function_exists(inet_ntop HAVE_INET_NTOP)
+if(NOT HAVE_INET_NTOP)
+  list(APPEND lib_src "compat/inet_ntop.c")
+  list(APPEND basic_defs "-DNO_INET_NTOP")
+endif()
+
+check_function_exists(inet_pton HAVE_INET_PTON)
+if(NOT HAVE_INET_PTON)
+  list(APPEND lib_src "compat/inet_pton.c")
+  list(APPEND basic_defs "-DNO_INET_PTON")
+endif()
+
+check_symbol_exists(AF_UNIX "${socket_headers}" UNIX_SOCKETS)
+print_bool(UNIX_SOCKETS)
+if(UNIX_SOCKETS)
+  list(APPEND lib_src "unix-socket.c")
+  list(APPEND program_src
+       "credential-cache.c"
+       "credential-cache--daemon.c")
+endif()
+
+set(CMAKE_EXTRA_INCLUDE_FILES "${socket_headers}")
+check_type_size("struct sockaddr" SOCKADDR_STORAGE)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+print_bool(SOCKADDR_STORAGE)
+if(NOT SOCKADDR_STORAGE)
+  if(IPV6)
+    list(APPEND basic_defs "-Dsockaddr_storage=sockaddr_in6")
+  else()
+    list(APPEND basic_defs "-Dsockaddr_storage=sockaddr_in")
+  endif()
+endif()
+
+check_include_file("iconv.h" have_iconv_h)
+if(have_iconv_h)
+  try_compile(new_iconv
+    "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+    SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/iconv_test.c"
+    COMPILE_DEFINITIONS "-DCONST="
+    LINK_LIBRARIES $<$<BOOL:${iconv_lib}>:${iconv_lib}>
+    OUTPUT_VARIABLE new_iconv_output)
+  if(NOT new_iconv)
+    try_compile(OLD_ICONV
+      "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+      SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/iconv_test.c"
+      COMPILE_DEFINITIONS "-DCONST=const"
+      LINK_LIBRARIES $<$<BOOL:${iconv_lib}>:${iconv_lib}>
+      OUTPUT_VARIABLE old_iconv_output)
+    if(NOT OLD_ICONV)
+      message(WARNING "Cannot compile call to iconv"
+              "New iconv test output: ${new_iconv_output}"
+              "Old iconv test output: ${old_iconv_output}")
+      set(NO_ICONV ON)
+    endif()
+  endif()
+else()
+  set(NO_ICONV ON)
+endif()
+print_bool(OLD_ICONV)
+print_bool(NO_ICONV)
+
+if(NO_ICONV)
+  list(APPEND basic_defs "-DNO_ICONV")
+endif()
+
+if(OLD_ICONV)
+  list(APPEND basic_defs "-DOLD_ICONV")
+endif()
+
+if(NOT NO_ICONV AND iconv_lib)
+  list(APPEND libs "${iconv_lib}")
+endif()
+
+if(UNIX)
+  set(POSIX_GOODIES ON)
+endif()
+print_bool(POSIX_GOODIES)
+
+if(NOT POSIX_GOODIES)
+  list(APPEND basic_defs "-DNO_POSIX_GOODIES")
+endif()
+
+find_package(ZLIB)
+if(ZLIB_FOUND)
+  list(APPEND include_dirs ${ZLIB_INCLUDE_DIRS})
+  list(APPEND libs ${ZLIB_LIBRARIES})
+
+  set(CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}")
+  check_function_exists(deflateBound DEFLATE_BOUND)
+  set(CMAKE_REQUIRED_LIBRARIES)
+  if(NOT DEFLATE_BOUND)
+    list(APPEND basic_defs "-DNO_DEFLATE_BOUND")
+  endif()
+endif()
+print_bool(DEFLATE_BOUND)
+
+option(NORETURN "Use of attribute((__noreturn__))" ON)
+print_bool(NORETURN)
+if(NOT NORETURN)
+  list(APPEND basic_defs "-DNO_NORETURN")
+endif()
+
+check_struct_has_member("struct stat" st_ctimespec "sys/stat.h" USE_ST_TIMESPEC)
+print_bool(USE_ST_TIMESPEC)
+if(USE_ST_TIMESPEC)
+  list(APPEND basic_defs "-DUSE_ST_TIMESPEC")
+endif()
+
+check_struct_has_member("struct stat" "st_ctim.tv_nsec" "sys/stat.h" HAVE_NSEC)
+print_bool(HAVE_NSEC)
+if(NOT HAVE_NSEC)
+  list(APPEND basic_defs "-DNO_NSEC")
+endif()
+
+cmake_dependent_option(
+  USE_NSEC "Use subsecond file mtimes and ctimes" OFF "HAVE_NSEC" OFF)
+print_bool(USE_NSEC)
+if(USE_NSEC)
+  list(APPEND basic_defs "-DUSE_NSEC")
+endif()
+
+check_struct_has_member(
+  "struct stat" st_blocks "sys/stat.h" ST_BLOCKS_IN_STRUCT_STAT)
+print_bool(ST_BLOCKS_IN_STRUCT_STAT)
+if(NOT ST_BLOCKS_IN_STRUCT_STAT)
+  list(APPEND basic_defs "-DNO_ST_BLOCKS_IN_STRUCT_STAT")
+endif()
+
+find_program(PERL_PATH perl)
+message(STATUS "PERL_PATH: ${PERL_PATH}")
+
+cmake_dependent_option(PERL "Enable Perl scripts and libraries" ON
+                       "PERL_PATH" OFF)
+print_bool(PERL)
+
+find_program(PYTHON_PATH python)
+message(STATUS "PYTHON_PATH: ${PYTHON_PATH}")
+
+cmake_dependent_option(PYTHON "Enable Python scripts and libraries" ON
+                       "PYTHON_PATH" OFF)
+print_bool(PYTHON)
+
+find_package(TCL)
+set(TCLTK_PATH "${TK_WISH}")
+message(STATUS "TCLTK_PATH: ${TCLTK_PATH}")
+
+cmake_dependent_option(TCLTK "Enable Tcl/Tk GUI" ON "TCLTK_PATH" OFF)
+print_bool(TCLTK)
+if(TCLTK)
+  set(TCL_PATH "${TCL_TCLSH}")
+  message(STATUS "TCL_PATH: ${TCL_PATH}")
+endif()
+
+set(doc_string "Set to -a if using recent versions of GNU grep that are picky")
+set(doc_string "${doc_string} with non-ASCII data")
+set(SANE_TEXT_GREP "" CACHE STRING "${doc_string}")
+message(STATUS "SANE_TEXT_GREP: ${SANE_TEXT_GREP}")
+
+option(INTERNAL_QSORT "Use git's internal qsort" OFF)
+print_bool(INTERNAL_QSORT)
+if(INTERNAL_QSORT)
+  list(APPEND compat_defs "-DINTERNAL_QSORT")
+  list(APPEND compat_src "compat/qsort.c")
+endif()
+
+check_function_exists(qsort_s HAVE_ISO_QSORT_S)
+print_bool(HAVE_ISO_QSORT_S)
+if(HAVE_ISO_QSORT_S)
+  list(APPEND compat_defs "-DHAVE_ISO_QSORT_S")
+else()
+  list(APPEND compat_src "compat/qsort_s.c")
+endif()
+
+if(NOT CMAKE_CROSSCOMPILING)
+  try_run(fstat_run_result
+          fstat_compile_result
+          "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+          "${CMAKE_CURRENT_SOURCE_DIR}/cmake/fstat_test.c"
+          COMPILE_OUTPUT_VARIABLE fstat_compile_output
+          ARGS "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/fstat_tmp.txt")
+  if(fstat_compile_result)
+    if(fstat_run_result EQUAL 0)
+      set(UNRELIABLE_FSTAT ON)
+    endif()
+  else()
+    message(WARNING "Cannot compile fstat_test: ${fstat_compile_output}")
+  endif()
+endif()
+print_bool(UNRELIABLE_FSTAT)
+if(UNRELIABLE_FSTAT)
+  list(APPEND basic_defs "-DUNRELIABLE_FSTAT")
+endif()
+
+cmake_dependent_option(
+  OBJECT_CREATION_USES_RENAMES
+  "Use file rename instead of hardlink with immediate unlink"
+  OFF
+  "not_windows"
+  ON)
+print_bool(OBJECT_CREATION_USES_RENAMES)
+if(OBJECT_CREATION_USES_RENAMES)
+  list(APPEND compat_defs "-DOBJECT_CREATION_MODE=1")
+endif()
+
+option(USE_NED_ALLOCATOR
+       "Use nedmalloc allocator instead of platform allocator"
+       OFF)
+print_bool(USE_NED_ALLOCATOR)
+
+if(USE_NED_ALLOCATOR)
+  list(APPEND compat_include_dirs
+       "compat/nedmalloc")
+  list(APPEND compat_src
+       "compat/nedmalloc/nedmalloc.c")
+endif()
+
+if(NOT USE_NED_ALLOCATOR)
+  set(not_use_ned_allocator ON)
+endif()
+cmake_dependent_option(
+  OVERRIDE_STRDUP "Override libc strdup" OFF "not_use_ned_allocator" ON)
+print_bool(OVERRIDE_STRDUP)
+
+if(OVERRIDE_STRDUP)
+  list(APPEND compat_defs "-DOVERRIDE_STRDUP")
+  list(APPEND compat_src "compat/strdup.c")
+endif()
+
+check_symbol_exists(REG_STARTEND "regex.h" REGEX)
+print_bool(REGEX)
+
+if(NOT REGEX)
+  list(APPEND compat_include_dirs "compat/regex")
+  list(APPEND compat_src "compat/regex/regex.c")
+endif()
+
+if(CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin|SunOS")
+  set(default_have_dev_tty ON)
+else()
+  set(default_have_dev_tty OFF)
+endif()
+option(
+  HAVE_DEV_TTY
+  "System can open /dev/tty to interact with user"
+  ${default_have_dev_tty})
+print_bool(HAVE_DEV_TTY)
+if(HAVE_DEV_TTY)
+  list(APPEND basic_defs "-DHAVE_DEV_TTY")
+endif()
+
+option(GETTEXT_POISON "Debug choice of strings marked for translation" OFF)
+print_bool(GETTEXT_POISON)
+if(GETTEXT_POISON)
+  list(APPEND basic_defs "-DGETTEXT_POISON")
+endif()
+
+find_program(LESS_PATH less)
+set(DEFAULT_PAGER "${LESS_PATH}" CACHE FILEPATH "Sensible pager command")
+list(APPEND basic_defs "-DDEFAULT_PAGER=\"${DEFAULT_PAGER}\"")
+message(STATUS "DEFAULT_PAGER: ${DEFAULT_PAGER}")
+
+find_program(VI_PATH vi)
+set(DEFAULT_EDITOR "${VI_PATH}" CACHE FILEPATH "Sensible editor command")
+list(APPEND basic_defs "-DDEFAULT_EDITOR=\"${DEFAULT_EDITOR}\"")
+message(STATUS "DEFAULT_EDITOR: ${DEFAULT_EDITOR}")
+
+if(WIN32 OR MINGW)
+  set(NATIVE_CRLF ON)
+endif()
+print_bool(NATIVE_CRLF)
+
+if(NATIVE_CRLF)
+  list(APPEND basic_defs "-DNATIVE_CRLF")
+endif()
+
+set(help_formats man info html)
+set(DEFAULT_HELP_FORMAT "man" CACHE FILEPATH "\"git help\" format")
+set_property(CACHE DEFAULT_HELP_FORMAT PROPERTY STRINGS "${help_formats}")
+message(STATUS "DEFAULT_HELP_FORMAT: ${DEFAULT_HELP_FORMAT}")
+list(APPEND basic_defs "-DDEFAULT_HELP_FORMAT=\"${DEFAULT_HELP_FORMAT}\"")
+
+set(TEST_GIT_INDEX_VERSION "" CACHE STRING "Version of indexfile to test")
+set_property(CACHE TEST_GIT_INDEX_VERSION PROPERTY STRINGS "2;3;4")
+
+if(NOT CMAKE_CROSSCOMPILING)
+  try_run(gmtime_run_result
+          gmtime_compile_result
+          "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+          "${CMAKE_CURRENT_SOURCE_DIR}/cmake/gmtime_test.c"
+          COMPILE_OUTPUT_VARIABLE gmtime_compile_output)
+  if(gmtime_compile_result)
+    if(gmtime_run_result EQUAL 0)
+      set(GMTIME_UNRELIABLE_ERRORS ON)
+    endif()
+  else()
+    message(WARNING "Cannot compile gmtime_test: ${gmtime_compile_output}")
+  endif()
+endif()
+print_bool(GMTIME_UNRELIABLE_ERRORS)
+
+if(GMTIME_UNRELIABLE_ERRORS)
+  list(APPEND compat_defs "-DGMTIME_UNRELIABLE_ERRORS")
+  list(APPEND compat_src "compat/gmtime.c")
+endif()
+
+check_function_exists(clock_gettime libc_has_clock_gettime)
+if(libc_has_clock_gettime)
+  set(HAVE_CLOCK_GETTIME ON)
+else()
+  set(CMAKE_REQUIRED_LIBRARIES rt)
+  check_function_exists(clock_gettime librt_has_clock_gettime)
+  if(librt_has_clock_gettime)
+    set(HAVE_CLOCK_GETTIME ON)
+    set(NEEDS_LIBRT ON)
+  endif()
+endif()
+print_bool(HAVE_CLOCK_GETTIME)
+print_bool(NEEDS_LIBRT)
+
+if(HAVE_CLOCK_GETTIME)
+  list(APPEND basic_defs "-DHAVE_CLOCK_GETTIME")
+endif()
+
+if(NEEDS_LIBRT)
+  list(APPEND libs rt)
+endif()
+
+check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_CLOCK_MONOTONIC)
+print_bool(HAVE_CLOCK_MONOTONIC)
+
+if(HAVE_CLOCK_MONOTONIC)
+  list(APPEND basic_defs "-DHAVE_CLOCK_MONOTONIC")
+endif()
+
+try_compile(USE_PARENS_AROUND_GETTEXT_N
+  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+  SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/parens_test.c")
+print_bool(USE_PARENS_AROUND_GETTEXT_N)
+if(USE_PARENS_AROUND_GETTEXT_N)
+  list(APPEND basic_defs "-DUSE_PARENS_AROUND_GETTEXT_N=1")
+else()
+  list(APPEND basic_defs "-DUSE_PARENS_AROUND_GETTEXT_N=0")
+endif()
+
+try_compile(HAVE_BSD_SYSCTL
+  "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp"
+  SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/sysctl_test.c")
+print_bool(HAVE_BSD_SYSCTL)
+
+if(HAVE_BSD_SYSCTL)
+  list(APPEND basic_defs "-DHAVE_BSD_SYSCTL")
+endif()
+
+check_function_exists(getdelim HAVE_GETDELIM)
+print_bool(HAVE_GETDELIM)
+
+if(HAVE_GETDELIM)
+  list(APPEND basic_defs "-DHAVE_GETDELIM")
+endif()
+
+set(doc_string "SP separated VAR=VAL pairs to define default environment")
+set(doc_string "${doc_string} variables to be passed when a pager is spawned")
+set(PAGER_ENV "LESS=FRX LV=-c" CACHE STRING "${doc_string}")
+message(STATUS "PAGER_ENV: ${PAGER_ENV}")
+list(APPEND basic_defs "-DPAGER_ENV=\"${PAGER_ENV}\"")
+
+find_program(SHELL_PATH sh)
+message(STATUS "SHELL_PATH: ${SHELL_PATH}")
+list(APPEND basic_defs "-DSHELL_PATH=\"${SHELL_PATH}\"")
+
+# Build rules
+
+list(APPEND lib_src ${compat_src})
+list(APPEND basic_defs ${compat_defs})
+
+add_library(libgit STATIC ${lib_src})
+
+set(xdiff_src
+  "xdiff/xdiffi.c"
+  "xdiff/xprepare.c"
+  "xdiff/xutils.c"
+  "xdiff/xemit.c"
+  "xdiff/xmerge.c"
+  "xdiff/xpatience.c"
+  "xdiff/xhistogram.c")
+add_library(xdiff STATIC ${xdiff_src})
+target_compile_definitions(xdiff PUBLIC ${basic_defs})
+target_include_directories(xdiff PUBLIC ${compat_include_dirs})
+target_link_libraries(xdiff PUBLIC ${libs})
+
+set(vcssvn_src
+  "vcs-svn/line_buffer.c"
+  "vcs-svn/sliding_window.c"
+  "vcs-svn/fast_export.c"
+  "vcs-svn/svndiff.c"
+  "vcs-svn/svndump.c")
+add_library(vcssvn STATIC ${vcssvn_src})
+target_compile_definitions(vcssvn PUBLIC ${basic_defs})
+target_include_directories(vcssvn PUBLIC ${compat_include_dirs})
+target_link_libraries(vcssvn PUBLIC ${libs})
+
+target_compile_definitions(libgit PUBLIC ${basic_defs})
+target_include_directories(libgit PUBLIC ${compat_include_dirs})
+target_link_libraries(libgit PUBLIC ${libs})
+
+set(src_defs
+    "GIT_HTML_PATH=\"${html_dir}\""
+    "GIT_MAN_PATH=\"${man_dir}\""
+    "GIT_INFO_PATH=\"${info_dir}\"")
+set_source_files_properties(
+  "git.c" "builtin/help.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "${src_defs}")
+
+set(src_defs
+    "GIT_VERSION=\"${GIT_VERSION}\""
+    "GIT_USER_AGENT=\"${GIT_USER_AGENT}\""
+    "GIT_BUILT_FROM_COMMIT=\"${GIT_BUILT_FROM_COMMIT}\"")
+set_source_files_properties(
+  "version.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "${src_defs}")
+
+set(src_defs
+    "GIT_EXEC_PATH=\"${git_exec_dir}\""
+    "BINDIR=\"${bin_dir}\""
+    "PREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+set_source_files_properties(
+  "exec_cmd.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "${src_defs}")
+
+set_source_files_properties(
+  "builtin/init-db.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "DEFAULT_GIT_TEMPLATE_DIR=\"${template_dir}\"")
+
+set_source_files_properties(
+  "config.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "ETC_GITCONFIG=\"${etc_gitconfig}\"")
+
+set_source_files_properties(
+  "attr.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "ETC_GITATTRIBUTES=\"${etc_gitattributes}\"")
+
+set_source_files_properties(
+  "gettext.c"
+  PROPERTIES
+  COMPILE_DEFINITIONS "GIT_LOCALE_PATH=\"${locale_dir}\"")
+
+# TODO: Sparse
+if(SPARSE)
+  set_source_files_properties(
+    "http-push.c" "http.c" "http-walker.c" "remote-curl.c" "imap-send.c"
+    PROPERTIES
+    COMPILE_DEFINITIONS "CURL_DISABLE_TYPECHECK")
+endif()
+
+if(NOT EXPAT)
+  set_source_files_properties(
+    "http-walker.c"
+    PROPERTIES
+    COMPILE_DEFINITIONS "NO_EXPAT")
+endif()
+
+if(NOT REGEX)
+  set_source_files_properties(
+    "compat/regex/regex.c"
+    PROPERTIES
+    COMPILE_DEFINITIONS "GAWK;NO_MBSUPPORT")
+endif()
+
+if(USE_NED_ALLOCATOR)
+  if(SPARSE)
+    add_c_flag(SPARSE_FLAGS "-Wno-non-pointer-null")
+  endif()
+  set_source_files_properties(
+    "compat/nedmalloc/nedmalloc.c"
+    PROPERTIES
+    COMPILE_DEFINITIONS "NDEBUG;REPLACE_SYSTEM_ALLOCATOR"
+    COMPILE_FLAGS "${SPARSE_FLAGS}")
+  # TODO: Decide how this relates to Debug/Release modes
+endif()
+
+add_library(common-main "common-main.c" ${builtin_src})
+target_link_libraries(common-main PUBLIC libgit xdiff)
+
+add_executable(git "git.c")
+target_link_libraries(git PUBLIC common-main)
+
+add_executable(git-imap-send "imap-send.c" ${imap_send_builddeps})
+target_link_libraries(git-imap-send PUBLIC ${imap_send_libs} common-main)
+
+if(CURL)
+  add_executable(git-http-fetch "http.c" "http-walker.c" "http-fetch.c")
+  target_include_directories(git-http-fetch PUBLIC ${CURL_INCLUDE_DIRS})
+  target_link_libraries(git-http-fetch PUBLIC ${CURL_LIBRARIES} common-main)
+
+  if(EXPAT)
+    if(CURL_VERSION_STRING VERSION_GREATER_EQUAL "7.9.8")
+      add_executable(git-http-push "http.c" "http-push.c")
+      target_include_directories(git-http-push PUBLIC
+        ${CURL_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS})
+      target_link_libraries(git-http-push PUBLIC
+        ${CURL_LIBRARIES} ${EXPAT_LIBRARIES} common-main)
+    endif()
+
+    add_executable(git-remote-http "remote-curl.c" "http.c" "http-walker.c")
+    target_link_libraries(git-remote-http PUBLIC
+      ${CURL_LIBRARIES} ${EXPAT_LIBRARIES} common-main)
+    foreach(remote_curl_alias "git-remote-https" "git-remote-ftp"
+            "git-remote-ftps")
+      if(UNIX)
+        set(cmake_subcommand "create_symlink")
+      else()
+        set(cmake_subcommand "copy")
+      endif()
+      add_custom_command(
+        TARGET git-remote-http
+        POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E ${cmake_subcommand}
+                git-remote-http "${remote_curl_alias}"
+        VERBATIM
+        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+    endforeach()
+  endif()
+endif()
+
+add_executable(git-remote-testsvn "remote-testsvn.c")
+target_link_libraries(git-remote-testsvn PUBLIC common-main vcssvn)
+
+foreach(src ${program_src})
+  get_filename_component(base "${src}" NAME_WE)
+  add_executable("git-${base}" "${src}")
+  target_link_libraries("git-${base}" PUBLIC common-main)
+endforeach()
+
+foreach(src ${builtin_src})
+  get_filename_component(base "${src}" NAME_WE)
+  if(UNIX)
+    set(cmake_subcommand "create_symlink")
+  else()
+    set(cmake_subcommand "copy")
+  endif()
+
+  set(src "git")
+  set(dst "git-${base}")
+  add_custom_command(
+    TARGET git POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E ${cmake_subcommand} "${src}" "${dst}"
+    VERBATIM
+    WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+  install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${dst}"
+          DESTINATION "${bin_dir}")
+endforeach()
+
+# Scripts
+
+find_program(DIFF diff)
+message(STATUS "DIFF: ${DIFF}")
+
+set(doc_string "Set to colon-separated list of paths to prepend to PATH if")
+set(doc_string "${doc_string} your tools in /usr/bin are broken")
+set(SANE_TOOL_PATH "" CACHE STRING "${doc_string}")
+
+function(fix_shebang script_path program_path output_content)
+  file(STRINGS "${script_path}" line LIMIT_COUNT 1)
+  string(LENGTH "${line}" offset)
+  file(READ "${script_path}" content OFFSET ${offset})
+  if(line MATCHES "#!")
+    set(${output_content} "#!${program_path}${content}" PARENT_SCOPE)
+  else()
+    set(${output_content} "${line}${content}" PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(munge_script script_path output_name)
+  fix_shebang("${script_path}" "${SHELL_PATH}" script_content)
+  string(REPLACE "@SHELL_PATH@" "${SHELL_PATH}"
+         script_content "${script_content}")
+  string(REPLACE "@@DIFF@@" "${DIFF}" script_content "${script_content}")
+  string(REPLACE "@@LOCALEDIR@@" "${locale_dir}"
+         script_content "${script_content}")
+  string(REPLACE "@@NO_CURL@@" "${NO_CURL}"
+         script_content "${script_content}")
+  if(USE_GETTEXT_SCHEME_FALLTHROUGH)
+    string(REPLACE "@@USE_GETTEXT_SCHEME@@" "fallthrough"
+           script_content "${script_content}")
+  endif()
+
+  if(SANE_TOOL_PATH)
+    set(broken_path_fix "git_broken_path_fix ${SANE_TOOL_PATH}")
+  endif()
+  string(REGEX REPLACE "^# @@BROKEN_PATH_FIX@@$" "${broken_path_fix}"
+         script_content "${script_content}")
+
+  string(REPLACE "@@GITWEBDIR@@" "${gitweb_dir}"
+         script_content "${script_content}")
+  string(REPLACE "@@PERL@@" "${PERL}" script_content "${script_content}")
+  string(REPLACE "@@SANE_TEXT_GREP@@" "${SANE_TEXT_GREP}"
+         script_content "${script_content}")
+  string(REPLACE "@@PAGER_ENV@@" "${PAGER_ENV}"
+         script_content "${script_content}")
+
+  file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+       CONTENT "${script_content}")
+endfunction()
+
+list(APPEND script_sh "git-bisect.sh")
+list(APPEND script_sh "git-difftool--helper.sh")
+list(APPEND script_sh "git-filter-branch.sh")
+list(APPEND script_sh "git-merge-octopus.sh")
+list(APPEND script_sh "git-merge-one-file.sh")
+list(APPEND script_sh "git-merge-resolve.sh")
+list(APPEND script_sh "git-mergetool.sh")
+list(APPEND script_sh "git-quiltimport.sh")
+list(APPEND script_sh "git-rebase.sh")
+list(APPEND script_sh "git-remote-testgit.sh")
+list(APPEND script_sh "git-request-pull.sh")
+list(APPEND script_sh "git-stash.sh")
+list(APPEND script_sh "git-submodule.sh")
+list(APPEND script_sh "git-web--browse.sh")
+
+list(APPEND script_lib "git-mergetool--lib.sh")
+list(APPEND script_lib "git-parse-remote.sh")
+list(APPEND script_lib "git-rebase--am.sh")
+list(APPEND script_lib "git-rebase--interactive.sh")
+list(APPEND script_lib "git-rebase--merge.sh")
+list(APPEND script_lib "git-sh-setup.sh")
+list(APPEND script_lib "git-sh-i18n.sh")
+
+foreach(script_path ${script_sh})
+  get_filename_component(output_name "${script_path}" NAME_WE)
+  munge_script("${script_path}" "${output_name}")
+  if(NOT script_path STREQUAL
+     "git-remote-testgit.sh")
+    install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+            DESTINATION "${git_exec_dir}")
+  endif()
+endforeach()
+foreach(script_path ${script_lib})
+  get_filename_component(output_name "${script_path}" NAME_WE)
+  munge_script("${script_path}" "${output_name}")
+  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+          DESTINATION "${git_exec_dir}")
+endforeach()
+install(FILES ${script_lib_gen} DESTINATION "${git_exec_dir}")
+
+list(APPEND script_perl "git-add--interactive.perl")
+list(APPEND script_perl "git-archimport.perl")
+list(APPEND script_perl "git-cvsexportcommit.perl")
+list(APPEND script_perl "git-cvsimport.perl")
+list(APPEND script_perl "git-cvsserver.perl")
+list(APPEND script_perl "git-send-email.perl")
+list(APPEND script_perl "git-svn.perl")
+if(PERL)
+  foreach(script_path ${script_perl})
+    fix_shebang("${script_path}" "${PERL_PATH}" script_content)
+    string(FIND "${script_content}" "\n" first_line_ending)
+    string(SUBSTRING "${script_content}" 0 ${first_line_ending} first_line)
+    string(SUBSTRING "${script_content}" ${first_line_ending} -1 rest_of_script)
+    # ${lib_dir} relative to ${git_exec_dir} is "../../${lib_dir}"
+    string(CONCAT script_content
+      "${first_line}\n"
+      "use FindBin;\n"
+      "use lib (split(/$(pathsep)/, \$ENV{GITPERLLIB} || "
+      "\"$FindBin::Bin/../../${lib_dir}\"));"
+      "${rest_of_script}")
+    string(REPLACE "@@GIT_VERSION@@" "${GIT_VERSION}"
+           script_content "${script_content}")
+    string(REPLACE "$<" "$UID" script_content "${script_content}")
+
+    get_filename_component(output_name "${script_path}" NAME_WE)
+    file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+         CONTENT "${script_content}")
+    install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+            DESTINATION "${git_exec_dir}")
+  endforeach()
+else()
+  foreach(script_path ${script_perl})
+    fix_shebang("unimplemented.sh"
+                "${SHELL_PATH}" script_content)
+    string(REPLACE "@@REASON@@" "PERL=OFF" script_content "${script_content}")
+    get_filename_component(output_name "${script_path}" NAME_WE)
+    file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+         CONTENT "${script_content}")
+    install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+            DESTINATION "${git_exec_dir}")
+  endforeach()
+endif()
+
+list(APPEND script_python "git-p4.py")
+if(PYTHON)
+  foreach(script_path ${script_python})
+    fix_shebang("${script_path}" "${PYTHON_PATH}" script_content)
+    get_filename_component(output_name "${script_path}" NAME_WE)
+    file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+         CONTENT "${script_content}")
+    install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+            DESTINATION "${git_exec_dir}")
+  endforeach()
+else()
+  foreach(script_path ${script_python})
+    fix_shebang("unimplemented.sh"
+                "${SHELL_PATH}" script_content)
+    string(REPLACE "@@REASON@@" "PYTHON=OFF" script_content "${script_content}")
+    get_filename_component(output_name "${script_path}" NAME_WE)
+    file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+         CONTENT "${script_content}")
+    install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${output_name}"
+            DESTINATION "${git_exec_dir}")
+  endforeach()
+endif()
diff --git a/cmake/GenerateCmdlist.cmake b/cmake/GenerateCmdlist.cmake
new file mode 100644
index 000000000..1063627b1
--- /dev/null
+++ b/cmake/GenerateCmdlist.cmake
@@ -0,0 +1,83 @@
+if(__generate_cmdlist)
+  return()
+endif()
+set(__generate_cmdlist 1)
+
+function(generate_cmdlist)
+  string(CONCAT cmdlist_content
+"/* Automatically generated by cmake/generate-cmdlist.cmake */
+struct cmdname_help {
+	char name[16];
+	char help[80];
+	unsigned char group;
+};
+
+static const char *common_cmd_groups[] = {")
+
+  set(group_pattern "^([^ ]+)[ ]+(.+)[ ]*$")
+  set(command_pattern "^([^ ]+)[ ]+[^ ]+[ ]+([^ ]+)[ ]*$")
+
+  file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/command-list.txt" lines)
+  foreach(line ${lines})
+    if(line MATCHES "^### common groups")
+      set(context "groups")
+    elseif(line MATCHES "^### command list")
+      set(context "commands")
+    endif()
+
+    if(line AND NOT line MATCHES "^#")
+      if(context STREQUAL "groups")
+        string(REGEX REPLACE "${group_pattern}" "\\1" group "${line}")
+        string(REGEX REPLACE "${group_pattern}" "\\2" doc_string "${line}")
+        if(group)
+          list(APPEND groups "${group}")
+          list(APPEND group_docs "${doc_string}")
+        endif()
+      elseif(context STREQUAL "commands")
+        if(line MATCHES "${command_pattern}")
+          string(REGEX REPLACE "${command_pattern}" "\\1" command "${line}")
+          string(REGEX REPLACE "${command_pattern}" "\\2" group_name "${line}")
+          list(APPEND commands "${command}")
+          list(APPEND command_group_names "${group_name}")
+        endif()
+      endif()
+    endif()
+  endforeach()
+
+  list(LENGTH groups num_groups)
+  math(EXPR num_groups "${num_groups} - 1")
+  foreach(group_index RANGE ${num_groups})
+    list(GET group_docs ${group_index} doc_string)
+    set(cmdlist_content "${cmdlist_content}
+	N_(\"${doc_string}\"),")
+  endforeach()
+
+  set(cmdlist_content "${cmdlist_content}
+};
+
+static struct cmdname_help common_cmds[] = {")
+
+  list(LENGTH commands num_commands)
+  math(EXPR num_commands "${num_commands} - 1")
+  foreach(command_index RANGE ${num_commands})
+    list(GET commands ${command_index} command)
+    list(GET command_group_names ${command_index} group_name)
+    list(FIND groups ${group_name} group_index)
+    if(NOT group_index EQUAL -1)
+      string(REPLACE "git-" "" command_no_git "${command}")
+      file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/Documentation/${command}.txt"
+           doc_string
+           LIMIT_COUNT 1
+           REGEX "^${command} -")
+      string(REGEX REPLACE "^${command} - " "" doc_string "${doc_string}")
+      set(cmdlist_content "${cmdlist_content}
+	{\"${command_no_git}\", N_(\"${doc_string}\"), ${group_index}},")
+    endif()
+  endforeach()
+
+  set(cmdlist_content "${cmdlist_content}
+};
+")
+  file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/common-cmds.h"
+       CONTENT "${cmdlist_content}")
+endfunction()
diff --git a/cmake/fopen_dir_test.c b/cmake/fopen_dir_test.c
new file mode 100644
index 000000000..7c8de4eb7
--- /dev/null
+++ b/cmake/fopen_dir_test.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+	FILE* f = fopen(argv[1], "r");
+	if (f != NULL) {
+		fclose(f);
+		return 0;
+	}
+	return 1;
+}
diff --git a/cmake/fstat_test.c b/cmake/fstat_test.c
new file mode 100644
index 000000000..629e18f34
--- /dev/null
+++ b/cmake/fstat_test.c
@@ -0,0 +1,37 @@
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int main(int argc, const char **argv)
+{
+	int fd = open(argv[1], O_WRONLY);
+	if (fd == -1) {
+		return EXIT_FAILURE;
+	}
+
+	const char *data = "hello world\n";
+	int data_length = strlen(data);
+	ssize_t written = write(fd, data, data_length);
+	if (written != data_length) {
+		close(fd);
+		return EXIT_FAILURE;
+	}
+
+	struct stat fstat_result;
+	if (fstat(fd, &fstat_result) != 0) {
+		close(fd);
+		return EXIT_FAILURE;
+	}
+
+	close(fd);
+	struct stat lstat_result;
+	if (lstat(argv[1], &lstat_result) != 0) {
+		return EXIT_FAILURE;
+	}
+
+	/* Only returns 0 if fstat_result != lstat_result */
+	return (fstat_result.st_mtime != lstat_result.st_mtime) ||
+		   (fstat_result.st_ctime != lstat_result.st_ctime);
+}
diff --git a/cmake/gmtime_test.c b/cmake/gmtime_test.c
new file mode 100644
index 000000000..1a490c3f2
--- /dev/null
+++ b/cmake/gmtime_test.c
@@ -0,0 +1,7 @@
+#include <time.h>
+
+int main()
+{
+	time_t time = -1;
+	return gmtime(&time) != NULL;
+}
diff --git a/cmake/iconv_test.c b/cmake/iconv_test.c
new file mode 100644
index 000000000..efa8402ac
--- /dev/null
+++ b/cmake/iconv_test.c
@@ -0,0 +1,13 @@
+#include <iconv.h>
+#include <stdlib.h>
+
+int main()
+{
+    iconv_t cd = NULL;
+    CONST char* in_buf = NULL;
+    size_t in_bytes_left = 0;
+    size_t out_bytes_left = 0;
+    char* out_buf = NULL;
+    iconv(cd, &in_buf, &in_bytes_left, &out_buf, &out_bytes_left);
+	return 0;
+}
diff --git a/cmake/inline_test.c b/cmake/inline_test.c
new file mode 100644
index 000000000..73cdfb444
--- /dev/null
+++ b/cmake/inline_test.c
@@ -0,0 +1,9 @@
+static INLINE void foo()
+{
+}
+
+int main(int argc, char* argv[])
+{
+	foo();
+	return 0;
+}
diff --git a/cmake/mkdir_test.c b/cmake/mkdir_test.c
new file mode 100644
index 000000000..d81d141c3
--- /dev/null
+++ b/cmake/mkdir_test.c
@@ -0,0 +1,7 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int main(int argc, char* argv[])
+{
+	return mkdir(argv[1], S_IRWXO);
+}
diff --git a/cmake/mmap_test.c b/cmake/mmap_test.c
new file mode 100644
index 000000000..208d9a375
--- /dev/null
+++ b/cmake/mmap_test.c
@@ -0,0 +1,35 @@
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, const char **argv)
+{
+	struct stat sb;
+
+	int fd = open(argv[1], O_RDONLY);
+	if (fd == -1) {
+		return EXIT_FAILURE;
+	}
+
+	if (fstat(fd, &sb) == -1) {
+		close(fd);
+		return EXIT_FAILURE;
+	}
+
+	void *addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (addr == MAP_FAILED) {
+		close(fd);
+		return EXIT_FAILURE;
+	}
+
+	int result = remove(argv[1]);
+	munmap(addr, sb.st_size);
+	if (result != 0) {
+		close(fd);
+		return EXIT_FAILURE;
+	}
+	return 0;
+}
diff --git a/cmake/parens_test.c b/cmake/parens_test.c
new file mode 100644
index 000000000..5ec555763
--- /dev/null
+++ b/cmake/parens_test.c
@@ -0,0 +1,6 @@
+int main()
+{
+    static const char s[] = ("FOO");
+    (void) s;
+	return 0;
+}
diff --git a/cmake/snprintf_test.c b/cmake/snprintf_test.c
new file mode 100644
index 000000000..3ad943d62
--- /dev/null
+++ b/cmake/snprintf_test.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+	char buf[1];
+	return snprintf(&buf[0], sizeof(buf), "%d", 16);
+}
diff --git a/cmake/sysctl_test.c b/cmake/sysctl_test.c
new file mode 100644
index 000000000..868cfaff8
--- /dev/null
+++ b/cmake/sysctl_test.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+int main()
+{
+	int mib[2] = { 0, 0 };
+	size_t len = 0;
+	int cpucount = 0;
+	return sysctl(mib, 2, &cpucount, &len, NULL, 0);
+}
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-23  0:16 [RFC PATCH 0/1] Implement CMake build Isaac Hier
  2018-01-23  0:16 ` [RFC PATCH 1/1] " Isaac Hier
@ 2018-01-24 13:45 ` Isaac Hier
  2018-01-24 18:11   ` Jacob Keller
                     ` (2 more replies)
  2018-01-24 19:36 ` Jeff Hostetler
  2 siblings, 3 replies; 18+ messages in thread
From: Isaac Hier @ 2018-01-24 13:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Isaac Hier, git

I realize this is a huge patch, but does anyone have feedback for the
general idea?

On Mon, Jan 22, 2018 at 7:16 PM, Isaac Hier <isaachier@gmail.com> wrote:
> This patch adds a mostly complete (aside from building tests, documentation,
> installation, etc.) CMake build to the git project. I am not sure how much
> interest there is in a CMake build, so please send me feedback one way or
> another. Personally, I believe CMake will help with Windows builds and is
> somewhat easier to read than a Makefile. I considered, adding this to the
> contrib directory, but CMakeLists.txt almost always reside in the original
> directories, and I'm not sure how wise it would be to do otherwise. If you are
> interested in a CMake build, I would be more than happy to finish up the work
> here. Decided to wait until I discussed the issue here to finish the final parts
> of the build.
>
> Isaac Hier (1):
>   Implement CMake build
>
>  CMakeLists.txt              | 1849 +++++++++++++++++++++++++++++++++++++++++++
>  cmake/GenerateCmdlist.cmake |   83 ++
>  cmake/fopen_dir_test.c      |   11 +
>  cmake/fstat_test.c          |   37 +
>  cmake/gmtime_test.c         |    7 +
>  cmake/iconv_test.c          |   13 +
>  cmake/inline_test.c         |    9 +
>  cmake/mkdir_test.c          |    7 +
>  cmake/mmap_test.c           |   35 +
>  cmake/parens_test.c         |    6 +
>  cmake/snprintf_test.c       |    7 +
>  cmake/sysctl_test.c         |   11 +
>  12 files changed, 2075 insertions(+)
>  create mode 100644 CMakeLists.txt
>  create mode 100644 cmake/GenerateCmdlist.cmake
>  create mode 100644 cmake/fopen_dir_test.c
>  create mode 100644 cmake/fstat_test.c
>  create mode 100644 cmake/gmtime_test.c
>  create mode 100644 cmake/iconv_test.c
>  create mode 100644 cmake/inline_test.c
>  create mode 100644 cmake/mkdir_test.c
>  create mode 100644 cmake/mmap_test.c
>  create mode 100644 cmake/parens_test.c
>  create mode 100644 cmake/snprintf_test.c
>  create mode 100644 cmake/sysctl_test.c
>
> --
> 2.14.1
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 13:45 ` [RFC PATCH 0/1] " Isaac Hier
@ 2018-01-24 18:11   ` Jacob Keller
  2018-01-24 18:47   ` Junio C Hamano
  2018-01-24 21:15   ` Stephan Beyer
  2 siblings, 0 replies; 18+ messages in thread
From: Jacob Keller @ 2018-01-24 18:11 UTC (permalink / raw)
  To: Isaac Hier; +Cc: Junio C Hamano, Git mailing list

On Wed, Jan 24, 2018 at 5:45 AM, Isaac Hier <isaachier@gmail.com> wrote:
> I realize this is a huge patch, but does anyone have feedback for the
> general idea?
>

I don't know anything about CMake so I can't comment on the patch
itself. Having additional build systems does not bother me, but it
does mean that someone has to maintain the build system and try to
keep it in sync with changes that occur to the main one in use. That
can be problematic.

Personally, if we added a new build system, I think I'd prefer
something like meson with ninja, but that's only because of the
examples I've seen where build times were improved significantly. I
have no idea what advantages CMake would give on this front.

Thanks,
Jake

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 13:45 ` [RFC PATCH 0/1] " Isaac Hier
  2018-01-24 18:11   ` Jacob Keller
@ 2018-01-24 18:47   ` Junio C Hamano
  2018-01-24 20:53     ` Ævar Arnfjörð Bjarmason
  2018-01-24 21:15   ` Stephan Beyer
  2 siblings, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2018-01-24 18:47 UTC (permalink / raw)
  To: Isaac Hier; +Cc: git

Isaac Hier <isaachier@gmail.com> writes:

> I realize this is a huge patch, but does anyone have feedback for the
> general idea?

I personally am not interested, especially with the justification
given in the cover letter.

Perhaps the one in this patch may be "mostly complete", and I am
sure you can make it "complete" against a frozen target, but it is
unclear to me how you envision keeping the completeness up to date.

Whenever a developer needs to introduce a new build knob, the
support for it needs to be implemented in not just Makefile but now
also in this other thing.  Unless there is an automated
bi-directional gateway to allow those who have been writing and
reading Makefile not to worry about those who wants to build with
CMake, and vice versa, you are forcing everybody to do the same work
twice, no?

Choice of build procedure for a project is like choise of SCM to
store its source file.  If the new system is 10x better to make it
worthwhile to educate everybody to use it, switching to a new system
and ditching the current one *is* a reasonable thing to propose and
consider.

But I do not think you are proposing to switch, and I do not think
you are convincingly arguing that it is 10x better than the current
one, either.  

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-23  0:16 [RFC PATCH 0/1] Implement CMake build Isaac Hier
  2018-01-23  0:16 ` [RFC PATCH 1/1] " Isaac Hier
  2018-01-24 13:45 ` [RFC PATCH 0/1] " Isaac Hier
@ 2018-01-24 19:36 ` Jeff Hostetler
  2018-01-24 19:59   ` Isaac Hier
  2 siblings, 1 reply; 18+ messages in thread
From: Jeff Hostetler @ 2018-01-24 19:36 UTC (permalink / raw)
  To: Isaac Hier, gitster; +Cc: git



On 1/22/2018 7:16 PM, Isaac Hier wrote:
> This patch adds a mostly complete (aside from building tests, documentation,
> installation, etc.) CMake build to the git project. I am not sure how much
> interest there is in a CMake build, so please send me feedback one way or
> another. Personally, I believe CMake will help with Windows builds and is
> somewhat easier to read than a Makefile. I considered, adding this to the
> contrib directory, but CMakeLists.txt almost always reside in the original
> directories, and I'm not sure how wise it would be to do otherwise. If you are
> interested in a CMake build, I would be more than happy to finish up the work
> here. Decided to wait until I discussed the issue here to finish the final parts
> of the build.

On Windows, we use "bash" and "make" from the Git-for-Windows SDK installation
(which gives us a bash shell and most of the usual Unix command line tools) and
the main "Makefile".  We do need a special section in the "config.mak.uname" file
to set some platform compiler options and etc., but that is small enough.

Johannes and I recently added a few new options to let Windows build Git from
the command line with either GCC or MSVC and to synthesize MSVS solution (.sln)
and project (.vcxproj) files to allow you to work with the full MSVS IDE and
full intellisense.  And if necessary download and build third-party libraries
not normally present on a Windows machine.  Most of this work is Windows specific
and may not yet be upstream.   See GfW [1] and VCPKG [2].

The synthesized solution and project files are automatically generated, so we
do not have to separately track changes in the Makefile to the various file lists.
These should be treated as read-only and re-generated in response to changes in
the Makefile.  Using the solution/project files, we can completely build Git in
the IDE or a command prompt and without the SDK.  This further simplifies things
for Windows developers.

So given that, I don't see a need to replace the main Makefile on Windows.

Sorry,
Jeff

[1] https://github.com/git-for-windows/git
[2] https://github.com/Microsoft/vcpkg

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 19:36 ` Jeff Hostetler
@ 2018-01-24 19:59   ` Isaac Hier
  2018-01-24 21:00     ` Jeff Hostetler
  0 siblings, 1 reply; 18+ messages in thread
From: Isaac Hier @ 2018-01-24 19:59 UTC (permalink / raw)
  To: Jeff Hostetler; +Cc: Junio C Hamano, git

Jeff, no worries, fair enough. I know https://github.com/grpc/grpc
uses a shared file to generate code for several build systems instead
of maintaining them individually. I plan on doing the work anyway just
because I have my own reasons to use CMake in Git (for packaging in
https://github.com/ruslo/hunter is my main motive here). Whether or
not it is maintained upstream is not a real concern for me at the
moment.

Junio, in terms of maintainability, yes that is my main concern as
well. I proposed this here knowing that might be the main issue. From
my point of view, CMake is a much better choice than Makefile + uname
overrides, but if no one cares for learning CMake, you are correct
that it will not be maintained.

In terms of the benefits of CMake, let me highlight some examples I
noticed while porting this:

* Makefiles rely on hard-coded paths. CMake does not (uses find,
configs, etc. to alleviate path-related issues). One clear example is
the way the Makefile has to exclude certain package manager paths on
Mac (i.e. fink and ports).
* Makefiles do not have a good way of finding dependencies or checking
versions. Compare these two choices.
   Makefile: curl_check := $(shell (echo 070908; $(CURL_CONFIG)
--vernum | sed -e '/^70[BC]/s/^/0/') 2>/dev/null | sort -r | sed -ne
2p)
   CMakeLists.txt:  if(CURL AND CURL_VERSION_STRING
VERSION_GREATER_EQUAL "7.22.0")
* Makefile cannot use compilation results to drive build.
config.mak.uname needs to be updated each and every time to delineate
acceptable builds.
* CMake can automatically produce a compilation database for clang
tools (iwyu, clang-tidy, etc.).
* CMake is procedural and generates a dataflow Makefile. Procedural
programming is a little more intuitive IMO, especially true for C
programmers :). Case in point, debugging a Makefile is a lot harder
than debugging CMake.
* CMake is compatible with non-Unix/Windows platforms.

My point isn't to convert you, just to explain why CMake has taken
over in many many projects over the last decade. I agree that if there
is no maintainer, do not accept this patch. I'm only offering it in
case there is any interest. It seems like there isn't at the moment.
I'll see how the Windows build currently works and if that makes
sense, maybe I'll try using that build generator here too.

Thanks for the feedback,

Isaac

On Wed, Jan 24, 2018 at 2:36 PM, Jeff Hostetler <git@jeffhostetler.com> wrote:
>
>
> On 1/22/2018 7:16 PM, Isaac Hier wrote:
>>
>> This patch adds a mostly complete (aside from building tests,
>> documentation,
>> installation, etc.) CMake build to the git project. I am not sure how much
>> interest there is in a CMake build, so please send me feedback one way or
>> another. Personally, I believe CMake will help with Windows builds and is
>> somewhat easier to read than a Makefile. I considered, adding this to the
>> contrib directory, but CMakeLists.txt almost always reside in the original
>> directories, and I'm not sure how wise it would be to do otherwise. If you
>> are
>> interested in a CMake build, I would be more than happy to finish up the
>> work
>> here. Decided to wait until I discussed the issue here to finish the final
>> parts
>> of the build.
>
>
> On Windows, we use "bash" and "make" from the Git-for-Windows SDK
> installation
> (which gives us a bash shell and most of the usual Unix command line tools)
> and
> the main "Makefile".  We do need a special section in the "config.mak.uname"
> file
> to set some platform compiler options and etc., but that is small enough.
>
> Johannes and I recently added a few new options to let Windows build Git
> from
> the command line with either GCC or MSVC and to synthesize MSVS solution
> (.sln)
> and project (.vcxproj) files to allow you to work with the full MSVS IDE and
> full intellisense.  And if necessary download and build third-party
> libraries
> not normally present on a Windows machine.  Most of this work is Windows
> specific
> and may not yet be upstream.   See GfW [1] and VCPKG [2].
>
> The synthesized solution and project files are automatically generated, so
> we
> do not have to separately track changes in the Makefile to the various file
> lists.
> These should be treated as read-only and re-generated in response to changes
> in
> the Makefile.  Using the solution/project files, we can completely build Git
> in
> the IDE or a command prompt and without the SDK.  This further simplifies
> things
> for Windows developers.
>
> So given that, I don't see a need to replace the main Makefile on Windows.
>
> Sorry,
> Jeff
>
> [1] https://github.com/git-for-windows/git
> [2] https://github.com/Microsoft/vcpkg

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 18:47   ` Junio C Hamano
@ 2018-01-24 20:53     ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 18+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2018-01-24 20:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Isaac Hier, git


On Wed, Jan 24 2018, Junio C. Hamano jotted:

> Isaac Hier <isaachier@gmail.com> writes:
>
>> I realize this is a huge patch, but does anyone have feedback for the
>> general idea?
>
> I personally am not interested, especially with the justification
> given in the cover letter.
>
> Perhaps the one in this patch may be "mostly complete", and I am
> sure you can make it "complete" against a frozen target, but it is
> unclear to me how you envision keeping the completeness up to date.
>
> Whenever a developer needs to introduce a new build knob, the
> support for it needs to be implemented in not just Makefile but now
> also in this other thing.  Unless there is an automated
> bi-directional gateway to allow those who have been writing and
> reading Makefile not to worry about those who wants to build with
> CMake, and vice versa, you are forcing everybody to do the same work
> twice, no?
>
> Choice of build procedure for a project is like choise of SCM to
> store its source file.  If the new system is 10x better to make it
> worthwhile to educate everybody to use it, switching to a new system
> and ditching the current one *is* a reasonable thing to propose and
> consider.
>
> But I do not think you are proposing to switch, and I do not think
> you are convincingly arguing that it is 10x better than the current
> one, either.

There's more than 400 lines of instructions at the top of our current
Makfile. Most of that is of the form "if your system has/doesn't have
so-and-so, define so-and-so".

For whatever reason we've decided not to make autoconf a hard
dependency. I don't know/remember what those reasons are, but if we
could get *some* build system that could use compilation results to
drive its build that would be worth it.

I don't know if cmake is that system, i.e. if we could waive a magic
wand and replace our current build system with it whether we'd still
need a fallback Makefile on some platforms. Is it as portable as GNU
autoconf & make? I don't know.

It would be very nice if git's build system wouldn't require patches
like my fb95e2e38d ("grep: un-break building with PCRE >= 8.32 without
--enable-jit", 2017-06-01), which is only needed because we don't have a
way to run a small C program to determine what the value of something
like NO_LIBPCRE1_JIT should be.

Well, we have it *optionally* with autoconf, but as long as it's
optional we don't save ourselves any time, and from packages I've seen
in the wild most people who build git don't use it, so it wouldn't save
them any time either.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 19:59   ` Isaac Hier
@ 2018-01-24 21:00     ` Jeff Hostetler
  2018-01-24 21:17       ` Isaac Hier
  2018-01-26  0:21       ` Isaac Hier
  0 siblings, 2 replies; 18+ messages in thread
From: Jeff Hostetler @ 2018-01-24 21:00 UTC (permalink / raw)
  To: Isaac Hier; +Cc: Junio C Hamano, git



On 1/24/2018 2:59 PM, Isaac Hier wrote:
> Jeff, no worries, fair enough. I know https://github.com/grpc/grpc
> uses a shared file to generate code for several build systems instead
> of maintaining them individually. I plan on doing the work anyway just
> because I have my own reasons to use CMake in Git (for packaging in
> https://github.com/ruslo/hunter is my main motive here). Whether or
> not it is maintained upstream is not a real concern for me at the
> moment.
[...]
> I'll see how the Windows build currently works and if that makes
> sense, maybe I'll try using that build generator here too.
> 
> Thanks for the feedback,
> 
> Isaac

Look at the "vcxproj:" target in config.mak.uname (in the GfW repo).

Jeff

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 13:45 ` [RFC PATCH 0/1] " Isaac Hier
  2018-01-24 18:11   ` Jacob Keller
  2018-01-24 18:47   ` Junio C Hamano
@ 2018-01-24 21:15   ` Stephan Beyer
  2018-01-24 21:19     ` Isaac Hier
  2 siblings, 1 reply; 18+ messages in thread
From: Stephan Beyer @ 2018-01-24 21:15 UTC (permalink / raw)
  To: Isaac Hier; +Cc: Junio C Hamano, git

Hi Isaac,

On 01/24/2018 02:45 PM, Isaac Hier wrote:
> I realize this is a huge patch, but does anyone have feedback for the
> general idea?

Thank you very much. I am *personally* interested in this due to several
reasons (which are mostly that I am used to CMake and when I do
something on the Git codebase, I always end up that its build system
recompiles everything ...which drives me crazy as hell. Using CMake, I
could simply use out-of-source builds and be happy).

I am not sure if it should go into the main Git repo. I'd already be
happy if I could pull it from somewhere (github for example) and rebase
it to use for my local branches.

~Stephan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 21:00     ` Jeff Hostetler
@ 2018-01-24 21:17       ` Isaac Hier
  2018-01-26  0:21       ` Isaac Hier
  1 sibling, 0 replies; 18+ messages in thread
From: Isaac Hier @ 2018-01-24 21:17 UTC (permalink / raw)
  To: Jeff Hostetler; +Cc: Junio C Hamano, git

CMake is very portable (see
https://open.cdash.org/index.php?project=CMake for details). About the
whole autoconf history in Git, I came across this post by Linus while
researching if anyone had done something with CMake in the git project
before:

> NO! At least the Makefile is debuggable and understandable.
>
> If we need a better build system, I'd much rather use something
> higher-level that can generate VC++ project files etc.
>
> In other words, I'd much rather see us using CMake or something like that,
> which actually adds real value-add.
>
> (And no, I've never used cmake, so maybe it has horrors waiting for us
> too, but autoconf is just worthless).
>
> Linus

https://marc.info/?l=git&m=115032515024816&w=2

On Wed, Jan 24, 2018 at 4:00 PM, Jeff Hostetler <git@jeffhostetler.com> wrote:
>
>
> On 1/24/2018 2:59 PM, Isaac Hier wrote:
>>
>> Jeff, no worries, fair enough. I know https://github.com/grpc/grpc
>> uses a shared file to generate code for several build systems instead
>> of maintaining them individually. I plan on doing the work anyway just
>> because I have my own reasons to use CMake in Git (for packaging in
>> https://github.com/ruslo/hunter is my main motive here). Whether or
>> not it is maintained upstream is not a real concern for me at the
>> moment.
>
> [...]
>>
>> I'll see how the Windows build currently works and if that makes
>> sense, maybe I'll try using that build generator here too.
>>
>> Thanks for the feedback,
>>
>> Isaac
>
>
> Look at the "vcxproj:" target in config.mak.uname (in the GfW repo).
>
> Jeff

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 21:15   ` Stephan Beyer
@ 2018-01-24 21:19     ` Isaac Hier
  2018-01-24 22:02       ` Stephan Beyer
  0 siblings, 1 reply; 18+ messages in thread
From: Isaac Hier @ 2018-01-24 21:19 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: Junio C Hamano, git

Thanks for your interest! This patch is based on the cmake-build
branch of https://github.com/isaachier/git, but the full history is on
the cmake branch (squashed it for easier readability). Hope that
helps.

On Wed, Jan 24, 2018 at 4:15 PM, Stephan Beyer <s-beyer@gmx.net> wrote:
> Hi Isaac,
>
> On 01/24/2018 02:45 PM, Isaac Hier wrote:
>> I realize this is a huge patch, but does anyone have feedback for the
>> general idea?
>
> Thank you very much. I am *personally* interested in this due to several
> reasons (which are mostly that I am used to CMake and when I do
> something on the Git codebase, I always end up that its build system
> recompiles everything ...which drives me crazy as hell. Using CMake, I
> could simply use out-of-source builds and be happy).
>
> I am not sure if it should go into the main Git repo. I'd already be
> happy if I could pull it from somewhere (github for example) and rebase
> it to use for my local branches.
>
> ~Stephan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 21:19     ` Isaac Hier
@ 2018-01-24 22:02       ` Stephan Beyer
  2018-01-25  2:16         ` Isaac Hier
  0 siblings, 1 reply; 18+ messages in thread
From: Stephan Beyer @ 2018-01-24 22:02 UTC (permalink / raw)
  To: Isaac Hier; +Cc: Junio C Hamano, git

On 01/24/2018 10:19 PM, Isaac Hier wrote:
> Thanks for your interest! This patch is based on the cmake-build
> branch of https://github.com/isaachier/git, but the full history is on
> the cmake branch (squashed it for easier readability). Hope that
> helps.

Thanks. I use the cmake branch because I prefer "real" history over one
huge commit.

And I already love it. Thanks for all the work!

From a first short glance, I wonder if you should mark a lot more
options as advanced options, like the paths (e.g., SHELL_PATH,
LESS_PATH, GETTEXT_MSGFMT_EXECUTABLE, etc.) and probably also things
like GIT_USER_AGENT. If you use a configuration tool like ccmake, you
see a lot of options and many of them are not relevant to the average user.

I also think some variables have weird names, for example, POLL, PREAD,
MMAP should be USE_POLL, USE_PREAD, USE_MMAP, respectively... or even
USE_*_SYSCALL, I don't know.

By the way, regarding up-to-dateness, you are missing these recent
changes that have been merged to master:

  edb6a17c36 Makefile: NO_OPENSSL=1 should no longer imply BLK_SHA1=1
  3f824e91c8 t/Makefile: introduce TEST_SHELL_PATH

(which is not surprising)

~Stephan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 22:02       ` Stephan Beyer
@ 2018-01-25  2:16         ` Isaac Hier
  0 siblings, 0 replies; 18+ messages in thread
From: Isaac Hier @ 2018-01-25  2:16 UTC (permalink / raw)
  To: Stephan Beyer; +Cc: Junio C Hamano, git

Stephan, I totally agree about the advanced options. At first, I left
them as visible options seeing as the Makefile does not comment which
are advanced and which are basic.

In terms of the up-to-dateness, I find it easier to "fast-forward" all
the changes at once without tangling myself in a load of periodic
updates.

On Wed, Jan 24, 2018 at 5:02 PM, Stephan Beyer <s-beyer@gmx.net> wrote:
> On 01/24/2018 10:19 PM, Isaac Hier wrote:
>> Thanks for your interest! This patch is based on the cmake-build
>> branch of https://github.com/isaachier/git, but the full history is on
>> the cmake branch (squashed it for easier readability). Hope that
>> helps.
>
> Thanks. I use the cmake branch because I prefer "real" history over one
> huge commit.
>
> And I already love it. Thanks for all the work!
>
> From a first short glance, I wonder if you should mark a lot more
> options as advanced options, like the paths (e.g., SHELL_PATH,
> LESS_PATH, GETTEXT_MSGFMT_EXECUTABLE, etc.) and probably also things
> like GIT_USER_AGENT. If you use a configuration tool like ccmake, you
> see a lot of options and many of them are not relevant to the average user.
>
> I also think some variables have weird names, for example, POLL, PREAD,
> MMAP should be USE_POLL, USE_PREAD, USE_MMAP, respectively... or even
> USE_*_SYSCALL, I don't know.
>
> By the way, regarding up-to-dateness, you are missing these recent
> changes that have been merged to master:
>
>   edb6a17c36 Makefile: NO_OPENSSL=1 should no longer imply BLK_SHA1=1
>   3f824e91c8 t/Makefile: introduce TEST_SHELL_PATH
>
> (which is not surprising)
>
> ~Stephan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-24 21:00     ` Jeff Hostetler
  2018-01-24 21:17       ` Isaac Hier
@ 2018-01-26  0:21       ` Isaac Hier
  2018-01-26 17:34         ` Jeff Hostetler
  2018-02-20 16:28         ` Robert Dailey
  1 sibling, 2 replies; 18+ messages in thread
From: Isaac Hier @ 2018-01-26  0:21 UTC (permalink / raw)
  To: Jeff Hostetler
  Cc: Junio C Hamano, git, Ævar Arnfjörð Bjarmason

Hi Jeff,

I have been looking at the build generator, which looks promising, but
I have one concern. Assuming I can generate a CMakeLists.txt that
appropriately updates the library sources, etc. how do you suggest I
handle new portability macros? For example, assume someone adds a
macro HAVE_X to indicate the availability of some platform-specific
function x. In the current Makefile, a comment would be added to the
top indicating when HAVE_X or NO_X should be set, and that option
would toggle the HAVE_X C macro. But CMake can test for the
availability of x, which is one of the main motives for adding a CMake
build. The current build generator uses the output of make, so all it
would know is whether or not HAVE_X is defined on the platform that
ran the Makefile, but not the entire list of platform that git
supports.

Bottom line: should I add the portability tests as they are now,
without accounting for future portability macros? One good alternative
might be to suggest the authors of new portability macros include a
small sample C program to test it. That would allow me to easily patch
the CMake tests whenever that came up. In a best case scenario, a
practice could be established to write the test in a specific
directory with a certain name so that I could automatically update the
CMake tests from the build generator.

Thanks for the help,

Isaac

On Wed, Jan 24, 2018 at 4:00 PM, Jeff Hostetler <git@jeffhostetler.com> wrote:
>
>
> On 1/24/2018 2:59 PM, Isaac Hier wrote:
>>
>> Jeff, no worries, fair enough. I know https://github.com/grpc/grpc
>> uses a shared file to generate code for several build systems instead
>> of maintaining them individually. I plan on doing the work anyway just
>> because I have my own reasons to use CMake in Git (for packaging in
>> https://github.com/ruslo/hunter is my main motive here). Whether or
>> not it is maintained upstream is not a real concern for me at the
>> moment.
>
> [...]
>>
>> I'll see how the Windows build currently works and if that makes
>> sense, maybe I'll try using that build generator here too.
>>
>> Thanks for the feedback,
>>
>> Isaac
>
>
> Look at the "vcxproj:" target in config.mak.uname (in the GfW repo).
>
> Jeff

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-26  0:21       ` Isaac Hier
@ 2018-01-26 17:34         ` Jeff Hostetler
  2018-02-20 16:28         ` Robert Dailey
  1 sibling, 0 replies; 18+ messages in thread
From: Jeff Hostetler @ 2018-01-26 17:34 UTC (permalink / raw)
  To: Isaac Hier; +Cc: Junio C Hamano, git, Ævar Arnfjörð Bjarmason



On 1/25/2018 7:21 PM, Isaac Hier wrote:
> Hi Jeff,
> 
> I have been looking at the build generator, which looks promising, but
> I have one concern. Assuming I can generate a CMakeLists.txt that
> appropriately updates the library sources, etc. how do you suggest I
> handle new portability macros? For example, assume someone adds a
> macro HAVE_X to indicate the availability of some platform-specific
> function x. In the current Makefile, a comment would be added to the
> top indicating when HAVE_X or NO_X should be set, and that option
> would toggle the HAVE_X C macro. But CMake can test for the
> availability of x, which is one of the main motives for adding a CMake
> build. The current build generator uses the output of make, so all it
> would know is whether or not HAVE_X is defined on the platform that
> ran the Makefile, but not the entire list of platform that git
> supports.
> 
> Bottom line: should I add the portability tests as they are now,
> without accounting for future portability macros? One good alternative
> might be to suggest the authors of new portability macros include a
> small sample C program to test it. That would allow me to easily patch
> the CMake tests whenever that came up. In a best case scenario, a
> practice could be established to write the test in a specific
> directory with a certain name so that I could automatically update the
> CMake tests from the build generator.
> 
> Thanks for the help,
> 
> Isaac

It's been years since I've used cmake as anything other than
a casual (downstream) consumer, so I'm not sure I can answer
your questions.

The vcxproj target we have is a bit of a hack to automatically
capture the set of source files and target libraries and executables.
We don't try to capture the spirit of all of the HAVE_ and NO_ flags
when we build the *.vcxproj files.  And we make some assumptions in
the generation template for the usual VC/VS settings.  But then
Windows is a single target and we don't have to worry about some
things (like whether or not qsort is present).

I don't want to discourage you from attempting this.  (And I realize
that my initial response might have given that impression -- I mainly
wanted to say that we don't currently have a problem on Windows with
the current Makefile situation.)

A full cmake system would let us simplify some things, but it also
complicates some things.  So we might be trading one set of problems
for another.  For example, the libgit2 project uses cmake.  Not to
pick on them, but when I look at it, I see a lot of the same issues
(but perhaps with better syntax than the makefile).

     https://github.com/libgit2/libgit2/blob/master/CMakeLists.txt

As to your portability test questions, I'm afraid I don't know.
Sorry,
Jeff



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-01-26  0:21       ` Isaac Hier
  2018-01-26 17:34         ` Jeff Hostetler
@ 2018-02-20 16:28         ` Robert Dailey
  2018-02-23 18:48           ` Isaac Hier
  1 sibling, 1 reply; 18+ messages in thread
From: Robert Dailey @ 2018-02-20 16:28 UTC (permalink / raw)
  To: Isaac Hier
  Cc: Jeff Hostetler, Junio C Hamano, Git,
	Ævar Arnfjörð Bjarmason

On Thu, Jan 25, 2018 at 6:21 PM, Isaac Hier <isaachier@gmail.com> wrote:
> Hi Jeff,
>
> I have been looking at the build generator, which looks promising, but
> I have one concern. Assuming I can generate a CMakeLists.txt that
> appropriately updates the library sources, etc. how do you suggest I
> handle new portability macros? For example, assume someone adds a
> macro HAVE_X to indicate the availability of some platform-specific
> function x. In the current Makefile, a comment would be added to the
> top indicating when HAVE_X or NO_X should be set, and that option
> would toggle the HAVE_X C macro. But CMake can test for the
> availability of x, which is one of the main motives for adding a CMake
> build. The current build generator uses the output of make, so all it
> would know is whether or not HAVE_X is defined on the platform that
> ran the Makefile, but not the entire list of platform that git
> supports.
>
> Bottom line: should I add the portability tests as they are now,
> without accounting for future portability macros? One good alternative
> might be to suggest the authors of new portability macros include a
> small sample C program to test it. That would allow me to easily patch
> the CMake tests whenever that came up. In a best case scenario, a
> practice could be established to write the test in a specific
> directory with a certain name so that I could automatically update the
> CMake tests from the build generator.

Isaac,

I'm very happy that you have started support for CMake. I have a lot
of experience with it. I'd love to help contribute. Do you have a fork
on github where this code is? I'd have to figure out how to apply a
patch from email, I haven't done it before. I think the goal should be
to replace the existing build system (this can be a transition that
happens slowly). I've been in situations where multiple build systems
are supported in parallel, worst case because of split personal
preferences on a project. That is more counterproductive than asking
the team to just compromise and take the initial hit on learning
curve. Ultimately that's up to the Git community, but that would be my
recommendation. But I think making CMake as complete as possible will
help build that confidence and trust. I can completely understand the
complexities and concerns they have.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC PATCH 0/1] Implement CMake build
  2018-02-20 16:28         ` Robert Dailey
@ 2018-02-23 18:48           ` Isaac Hier
  0 siblings, 0 replies; 18+ messages in thread
From: Isaac Hier @ 2018-02-23 18:48 UTC (permalink / raw)
  To: Robert Dailey
  Cc: Jeff Hostetler, Junio C Hamano, Git,
	Ævar Arnfjörð Bjarmason

Yes I think I mentioned earlier that I have it hosted at
https://github.com/isaachier/git. I have been busy with a few things
so have not continued much since I started this conversation, but it
covers a large part of the Makefile if not all the significant
portions.

On Tue, Feb 20, 2018 at 11:28 AM, Robert Dailey
<rcdailey.lists@gmail.com> wrote:
> On Thu, Jan 25, 2018 at 6:21 PM, Isaac Hier <isaachier@gmail.com> wrote:
>> Hi Jeff,
>>
>> I have been looking at the build generator, which looks promising, but
>> I have one concern. Assuming I can generate a CMakeLists.txt that
>> appropriately updates the library sources, etc. how do you suggest I
>> handle new portability macros? For example, assume someone adds a
>> macro HAVE_X to indicate the availability of some platform-specific
>> function x. In the current Makefile, a comment would be added to the
>> top indicating when HAVE_X or NO_X should be set, and that option
>> would toggle the HAVE_X C macro. But CMake can test for the
>> availability of x, which is one of the main motives for adding a CMake
>> build. The current build generator uses the output of make, so all it
>> would know is whether or not HAVE_X is defined on the platform that
>> ran the Makefile, but not the entire list of platform that git
>> supports.
>>
>> Bottom line: should I add the portability tests as they are now,
>> without accounting for future portability macros? One good alternative
>> might be to suggest the authors of new portability macros include a
>> small sample C program to test it. That would allow me to easily patch
>> the CMake tests whenever that came up. In a best case scenario, a
>> practice could be established to write the test in a specific
>> directory with a certain name so that I could automatically update the
>> CMake tests from the build generator.
>
> Isaac,
>
> I'm very happy that you have started support for CMake. I have a lot
> of experience with it. I'd love to help contribute. Do you have a fork
> on github where this code is? I'd have to figure out how to apply a
> patch from email, I haven't done it before. I think the goal should be
> to replace the existing build system (this can be a transition that
> happens slowly). I've been in situations where multiple build systems
> are supported in parallel, worst case because of split personal
> preferences on a project. That is more counterproductive than asking
> the team to just compromise and take the initial hit on learning
> curve. Ultimately that's up to the Git community, but that would be my
> recommendation. But I think making CMake as complete as possible will
> help build that confidence and trust. I can completely understand the
> complexities and concerns they have.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2018-02-23 19:44 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-23  0:16 [RFC PATCH 0/1] Implement CMake build Isaac Hier
2018-01-23  0:16 ` [RFC PATCH 1/1] " Isaac Hier
2018-01-24 13:45 ` [RFC PATCH 0/1] " Isaac Hier
2018-01-24 18:11   ` Jacob Keller
2018-01-24 18:47   ` Junio C Hamano
2018-01-24 20:53     ` Ævar Arnfjörð Bjarmason
2018-01-24 21:15   ` Stephan Beyer
2018-01-24 21:19     ` Isaac Hier
2018-01-24 22:02       ` Stephan Beyer
2018-01-25  2:16         ` Isaac Hier
2018-01-24 19:36 ` Jeff Hostetler
2018-01-24 19:59   ` Isaac Hier
2018-01-24 21:00     ` Jeff Hostetler
2018-01-24 21:17       ` Isaac Hier
2018-01-26  0:21       ` Isaac Hier
2018-01-26 17:34         ` Jeff Hostetler
2018-02-20 16:28         ` Robert Dailey
2018-02-23 18:48           ` Isaac Hier

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).