You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2023/06/27 05:53:40 UTC

[arrow] branch main updated: GH-34921: [C++][Python][Java] Require CMake 3.16 or later (#35921)

This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 11b140a734 GH-34921: [C++][Python][Java] Require CMake 3.16 or later (#35921)
11b140a734 is described below

commit 11b140a734a516e436adaddaeb35d23f30dcce44
Author: Sutou Kouhei <ko...@clear-code.com>
AuthorDate: Tue Jun 27 14:53:32 2023 +0900

    GH-34921: [C++][Python][Java] Require CMake 3.16 or later (#35921)
    
    ### Rationale for this change
    
    We need to support Ubuntu 20.04 (CMake 3.16) or later, CentOS 7 (CMake 3.17) or later, and Debian GNU/Linux bullseye (CMake 3.18) or later.
    
    So we can require CMake 3.16 or later.
    
    ### What changes are included in this PR?
    
    Require CMake 3.16 or later.
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    Yes.
    * Closes: #34921
    
    Authored-by: Sutou Kouhei <ko...@clear-code.com>
    Signed-off-by: Sutou Kouhei <ko...@clear-code.com>
---
 ci/docker/linux-apt-jni.dockerfile                |  89 -------
 cpp/CMakeLists.txt                                |  39 ++-
 cpp/cmake_modules/BuildUtils.cmake                |   6 +-
 cpp/cmake_modules/DefineOptions.cmake             |   9 +-
 cpp/cmake_modules/FindNumPy.cmake                 | 106 ---------
 cpp/cmake_modules/FindPython3Alt.cmake            |  17 +-
 cpp/cmake_modules/FindPythonLibsNew.cmake         | 277 ----------------------
 cpp/cmake_modules/ThirdpartyToolchain.cmake       | 255 +++++---------------
 cpp/examples/minimal_build/CMakeLists.txt         |   2 +-
 cpp/examples/parquet/parquet_arrow/CMakeLists.txt |   2 +-
 cpp/examples/tutorial_examples/CMakeLists.txt     |   2 +-
 docs/source/developers/cpp/building.rst           |  11 +-
 docs/source/developers/python.rst                 |   6 -
 java/CMakeLists.txt                               |   2 +-
 python/CMakeLists.txt                             |   2 +-
 15 files changed, 97 insertions(+), 728 deletions(-)

diff --git a/ci/docker/linux-apt-jni.dockerfile b/ci/docker/linux-apt-jni.dockerfile
deleted file mode 100644
index c0f915206b..0000000000
--- a/ci/docker/linux-apt-jni.dockerfile
+++ /dev/null
@@ -1,89 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-ARG arch=amd64
-ARG jdk=8
-ARG maven=3.5.4
-FROM ${arch}/maven:${maven}-jdk-${jdk}
-
-# pipefail is enabled for proper error detection in the `wget | apt-key add`
-# step
-SHELL ["/bin/bash", "-o", "pipefail", "-c"]
-
-ENV DEBIAN_FRONTEND noninteractive
-
-ARG llvm
-RUN apt-get update -y -q && \
-    apt-get install -y -q --no-install-recommends \
-      apt-transport-https \
-      lsb-release \
-      software-properties-common \
-      wget && \
-    code_name=$(lsb_release --codename --short) && \
-    wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
-    apt-add-repository -y \
-      "deb https://apt.llvm.org/${code_name}/ llvm-toolchain-${code_name}-${llvm} main" && \
-    apt-get update -y -q && \
-    apt-get install -y -q --no-install-recommends \
-        ca-certificates \
-        ccache \
-        clang-${llvm} \
-        cmake \
-        git \
-        g++ \
-        gcc \
-        libboost-all-dev \
-        libcurl4-openssl-dev \
-        libgflags-dev \
-        libgoogle-glog-dev \
-        libgtest-dev \
-        liblz4-dev \
-        libre2-dev \
-        libsnappy-dev \
-        libssl-dev \
-        llvm-${llvm}-dev \
-        make \
-        ninja-build \
-        pkg-config \
-        protobuf-compiler \
-        rapidjson-dev \
-        tzdata \
-        zlib1g-dev && \
-    apt-get clean && \
-    rm -rf /var/lib/apt/lists/*
-
-ARG cmake=3.11.4
-RUN wget -nv -O - https://github.com/Kitware/CMake/releases/download/v${cmake}/cmake-${cmake}-Linux-x86_64.tar.gz | tar -xzf - -C /opt
-ENV PATH=/opt/cmake-${cmake}-Linux-x86_64/bin:$PATH
-
-ENV ARROW_ACERO=ON \
-    ARROW_BUILD_TESTS=ON \
-    ARROW_DATASET=ON \
-    ARROW_FLIGHT=OFF \
-    ARROW_GANDIVA=ON \
-    ARROW_HOME=/usr/local \
-    ARROW_JAVA_CDATA=ON \
-    ARROW_JAVA_JNI=ON \
-    ARROW_ORC=ON \
-    ARROW_PARQUET=ON \
-    ARROW_S3=ON \
-    ARROW_USE_CCACHE=ON \
-    CC=gcc \
-    CXX=g++ \
-    ORC_SOURCE=BUNDLED \
-    PATH=/usr/lib/ccache/:$PATH \
-    Protobuf_SOURCE=BUNDLED
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index bd2238789a..301c919667 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.16)
 message(STATUS "Building using CMake version: ${CMAKE_VERSION}")
 
 # Compiler id for Apple Clang is now AppleClang.
@@ -37,15 +37,15 @@ cmake_policy(SET CMP0063 NEW)
 
 # RPATH settings on macOS do not affect install_name.
 # https://cmake.org/cmake/help/latest/policy/CMP0068.html
-if(POLICY CMP0068)
-  cmake_policy(SET CMP0068 NEW)
-endif()
+cmake_policy(SET CMP0068 NEW)
 
 # find_package() uses <PackageName>_ROOT variables.
 # https://cmake.org/cmake/help/latest/policy/CMP0074.html
-if(POLICY CMP0074)
-  cmake_policy(SET CMP0074 NEW)
-endif()
+cmake_policy(SET CMP0074 NEW)
+
+# MSVC runtime library flags are selected by an abstraction.
+# https://cmake.org/cmake/help/latest/policy/CMP0091.html
+cmake_policy(SET CMP0091 NEW)
 
 set(ARROW_VERSION "13.0.0-SNAPSHOT")
 
@@ -166,19 +166,15 @@ if("$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}" STREQUAL "1"
 endif()
 
 # Needed for linting targets, etc.
-if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
-  find_package(PythonInterp)
-else()
-  # Use the first Python installation on PATH, not the newest one
-  set(Python3_FIND_STRATEGY "LOCATION")
-  # On Windows, use registry last, not first
-  set(Python3_FIND_REGISTRY "LAST")
-  # On macOS, use framework last, not first
-  set(Python3_FIND_FRAMEWORK "LAST")
+# Use the first Python installation on PATH, not the newest one
+set(Python3_FIND_STRATEGY "LOCATION")
+# On Windows, use registry last, not first
+set(Python3_FIND_REGISTRY "LAST")
+# On macOS, use framework last, not first
+set(Python3_FIND_FRAMEWORK "LAST")
 
-  find_package(Python3)
-  set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
-endif()
+find_package(Python3)
+set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
 
 # ----------------------------------------------------------------------
 # cmake options
@@ -233,11 +229,6 @@ if(ARROW_USE_CCACHE
   endif()
 endif()
 
-if(ARROW_USE_PRECOMPILED_HEADERS AND ${CMAKE_VERSION} VERSION_LESS "3.16.0")
-  message(WARNING "Precompiled headers need CMake 3.16.0 or later, disabling")
-  set(ARROW_USE_PRECOMPILED_HEADERS OFF)
-endif()
-
 if(ARROW_OPTIONAL_INSTALL)
   # Don't make the "install" target depend on the "all" target
   set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true)
diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake
index 72cb234b4f..9112b836c9 100644
--- a/cpp/cmake_modules/BuildUtils.cmake
+++ b/cpp/cmake_modules/BuildUtils.cmake
@@ -227,16 +227,12 @@ function(ADD_ARROW_LIB LIB_NAME)
   endif()
 
   if(WIN32
-     OR (CMAKE_GENERATOR STREQUAL Xcode)
-     OR CMAKE_VERSION VERSION_LESS 3.12
+     OR CMAKE_GENERATOR STREQUAL Xcode
      OR NOT ARROW_POSITION_INDEPENDENT_CODE)
     # We need to compile C++ separately for each library kind (shared and static)
     # because of dllexport declarations on Windows.
     # The Xcode generator doesn't reliably work with Xcode as target names are not
     # guessed correctly.
-    # We can't use target for object library with CMake 3.11 or earlier.
-    # See also: Object Libraries:
-    # https://cmake.org/cmake/help/latest/command/add_library.html#object-libraries
     set(USE_OBJLIB OFF)
   else()
     set(USE_OBJLIB ON)
diff --git a/cpp/cmake_modules/DefineOptions.cmake b/cpp/cmake_modules/DefineOptions.cmake
index ba784f1517..8601184309 100644
--- a/cpp/cmake_modules/DefineOptions.cmake
+++ b/cpp/cmake_modules/DefineOptions.cmake
@@ -430,11 +430,10 @@ takes precedence over ccache if a storage backend is configured" ON)
   #   one of the other methods, pass -D$NAME_SOURCE=BUNDLED
   # * SYSTEM: Use CMake's find_package and find_library without any custom
   #   paths. If individual packages are on non-default locations, you can pass
-  #   $NAME_ROOT arguments to CMake, or set environment variables for the same
-  #   with CMake 3.11 and higher.  If your system packages are in a non-default
-  #   location, or if you are using a non-standard toolchain, you can also pass
-  #   ARROW_PACKAGE_PREFIX to set the *_ROOT variables to look in that
-  #   directory
+  #   $NAME_ROOT arguments to CMake, or set environment variables for the same.
+  #   If your system packages are in a non-default location, or if you are using
+  #   a non-standard toolchain, you can also pass ARROW_PACKAGE_PREFIX to set
+  #   the *_ROOT variables to look in that directory
   # * CONDA: Same as SYSTEM but set all *_ROOT variables to
   #   ENV{CONDA_PREFIX}. If this is run within an active conda environment,
   #   then ENV{CONDA_PREFIX} will be used for dependencies unless
diff --git a/cpp/cmake_modules/FindNumPy.cmake b/cpp/cmake_modules/FindNumPy.cmake
deleted file mode 100644
index cdca68a5f2..0000000000
--- a/cpp/cmake_modules/FindNumPy.cmake
+++ /dev/null
@@ -1,106 +0,0 @@
-# - Find the NumPy libraries
-# This module finds if NumPy is installed, and sets the following variables
-# indicating where it is.
-#
-# TODO: Update to provide the libraries and paths for linking npymath lib.
-#
-#  NUMPY_FOUND               - was NumPy found
-#  NUMPY_VERSION             - the version of NumPy found as a string
-#  NUMPY_VERSION_MAJOR       - the major version number of NumPy
-#  NUMPY_VERSION_MINOR       - the minor version number of NumPy
-#  NUMPY_VERSION_PATCH       - the patch version number of NumPy
-#  NUMPY_VERSION_DECIMAL     - e.g. version 1.6.1 is 10601
-#  NUMPY_INCLUDE_DIRS        - path to the NumPy include files
-
-#============================================================================
-# Copyright 2012 Continuum Analytics, Inc.
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to permit
-# persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-#
-#============================================================================
-
-# Legacy code for CMake < 3.15.0.  The primary point of entry should be
-# FindPython3Alt.cmake.
-
-if(NOT PYTHONINTERP_FOUND)
-    set(NUMPY_FOUND FALSE)
-    return()
-endif()
-
-execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
-    "import numpy as n; print(n.__version__); print(n.get_include());"
-    RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS
-    OUTPUT_VARIABLE _NUMPY_VALUES_OUTPUT
-    ERROR_VARIABLE _NUMPY_ERROR_VALUE
-    OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-if(NOT _NUMPY_SEARCH_SUCCESS MATCHES 0)
-    if(NumPy_FIND_REQUIRED)
-        message(FATAL_ERROR
-            "NumPy import failure:\n${_NUMPY_ERROR_VALUE}")
-    endif()
-    set(NUMPY_FOUND FALSE)
-    return()
-endif()
-
-# Convert the process output into a list
-string(REGEX REPLACE ";" "\\\\;" _NUMPY_VALUES ${_NUMPY_VALUES_OUTPUT})
-string(REGEX REPLACE "\n" ";" _NUMPY_VALUES ${_NUMPY_VALUES})
-list(GET _NUMPY_VALUES 0 NUMPY_VERSION)
-list(GET _NUMPY_VALUES 1 NUMPY_INCLUDE_DIRS)
-
-string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" _VER_CHECK "${NUMPY_VERSION}")
-if("${_VER_CHECK}" STREQUAL "")
-    # The output from Python was unexpected. Raise an error always
-    # here, because we found NumPy, but it appears to be corrupted somehow.
-    message(FATAL_ERROR
-        "Requested version and include path from NumPy, got instead:\n${_NUMPY_VALUES_OUTPUT}\n")
-    return()
-endif()
-
-# Make sure all directory separators are '/'
-string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIRS})
-
-# Get the major and minor version numbers
-string(REGEX REPLACE "\\." ";" _NUMPY_VERSION_LIST ${NUMPY_VERSION})
-list(GET _NUMPY_VERSION_LIST 0 NUMPY_VERSION_MAJOR)
-list(GET _NUMPY_VERSION_LIST 1 NUMPY_VERSION_MINOR)
-list(GET _NUMPY_VERSION_LIST 2 NUMPY_VERSION_PATCH)
-string(REGEX MATCH "[0-9]*" NUMPY_VERSION_PATCH ${NUMPY_VERSION_PATCH})
-math(EXPR NUMPY_VERSION_DECIMAL
-    "(${NUMPY_VERSION_MAJOR} * 10000) + (${NUMPY_VERSION_MINOR} * 100) + ${NUMPY_VERSION_PATCH}")
-
-find_package_message(NUMPY
-    "Found NumPy: version \"${NUMPY_VERSION}\" ${NUMPY_INCLUDE_DIRS}"
-    "${NUMPY_INCLUDE_DIRS}${NUMPY_VERSION}")
-
-set(NUMPY_FOUND TRUE)
-
-add_library(Python3::NumPy INTERFACE IMPORTED)
-if(CMAKE_VERSION VERSION_LESS 3.11)
-    set_target_properties(Python3::NumPy PROPERTIES
-        INTERFACE_INCLUDE_DIRECTORIES "${NUMPY_INCLUDE_DIRS}"
-        INTERFACE_LINK_LIBRARIES Python3::Module)
-else()
-    target_include_directories(Python3::NumPy INTERFACE ${NUMPY_INCLUDE_DIRS})
-    target_link_libraries(Python3::NumPy INTERFACE Python3::Module)
-endif()
diff --git a/cpp/cmake_modules/FindPython3Alt.cmake b/cpp/cmake_modules/FindPython3Alt.cmake
index 0cc7fba399..cd74bea356 100644
--- a/cpp/cmake_modules/FindPython3Alt.cmake
+++ b/cpp/cmake_modules/FindPython3Alt.cmake
@@ -41,19 +41,10 @@ if(Python3Alt_FIND_QUIETLY)
   list(APPEND Python3Alt_NumPy_FIND_PACKAGE_OPTIONS QUIET)
 endif()
 
-# Need CMake 3.15 or later for Python3_FIND_STRATEGY
-if(${CMAKE_VERSION} VERSION_LESS "3.15.0")
-  find_package(PythonLibsNew ${Python3Alt_FIND_PACKAGE_OPTIONS})
-  find_package(NumPy ${Python3Alt_NumPy_FIND_PACKAGE_OPTIONS})
-  find_package_handle_standard_args(
-    Python3Alt REQUIRED_VARS PYTHON_EXECUTABLE PYTHON_INCLUDE_DIRS NUMPY_INCLUDE_DIRS)
-  return()
-endif()
-
-if(${CMAKE_VERSION} VERSION_LESS "3.18.0" OR ARROW_BUILD_TESTS)
-  # When building arrow-python-test, we need libpython to be present, so ask for
-  # the full "Development" component.  Also ask for it on CMake < 3.18,
-  # where "Development.Module" is not available.
+if(CMAKE_VERSION VERSION_LESS 3.18.0)
+  # We need libpython to be present, so ask for the full "Development"
+  # component on CMake < 3.18, where "Development.Module" is not
+  # available.
   find_package(Python3 ${Python3Alt_FIND_PACKAGE_OPTIONS} COMPONENTS Interpreter
                                                                      Development NumPy)
 else()
diff --git a/cpp/cmake_modules/FindPythonLibsNew.cmake b/cpp/cmake_modules/FindPythonLibsNew.cmake
deleted file mode 100644
index b13cb35c9c..0000000000
--- a/cpp/cmake_modules/FindPythonLibsNew.cmake
+++ /dev/null
@@ -1,277 +0,0 @@
-# - Find python libraries
-# This module finds the libraries corresponding to the Python interpreter
-# FindPythonInterp provides.
-# This code sets the following variables:
-#
-#  PYTHONLIBS_FOUND           - have the Python libs been found
-#  PYTHON_PREFIX              - path to the Python installation
-#  PYTHON_LIBRARIES           - path to the python library
-#  PYTHON_INCLUDE_DIRS        - path to where Python.h is found
-#  PYTHON_SITE_PACKAGES       - path to installation site-packages
-#  PYTHON_IS_DEBUG            - whether the Python interpreter is a debug build
-#  PYTHON_OTHER_LIBS          - third-party libraries (as link flags) needed
-#                               for linking with Python
-#
-#  PYTHON_INCLUDE_PATH        - path to where Python.h is found (deprecated)
-#
-# A function PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is defined
-# to build modules for python.
-#
-# Thanks to talljimbo for the patch adding the 'LDVERSION' config
-# variable usage.
-
-#=============================================================================
-# Copyright 2001-2009 Kitware, Inc.
-# Copyright 2012-2014 Continuum Analytics, Inc.
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# * Neither the names of Kitware, Inc., the Insight Software Consortium,
-# nor the names of their contributors may be used to endorse or promote
-# products derived from this software without specific prior written
-# permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#=============================================================================
-# (To distribute this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-# Legacy code for CMake < 3.15.0.  The primary point of entry should be
-# FindPython3Alt.cmake.
-
-# Use the Python interpreter to find the libs.
-if(PythonLibsNew_FIND_REQUIRED)
-    find_package(PythonInterp REQUIRED)
-else()
-    find_package(PythonInterp)
-endif()
-
-if(NOT PYTHONINTERP_FOUND)
-    set(PYTHONLIBS_FOUND FALSE)
-    return()
-endif()
-
-# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
-# testing whether sys has the gettotalrefcount function is a reliable,
-# cross-platform way to detect a CPython debug interpreter.
-#
-# The library suffix is from the config var LDVERSION sometimes, otherwise
-# VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows.
-#
-# The config var LIBPL is for Linux, and helps on Debian Jessie where the
-# addition of multi-arch support shuffled things around.
-execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
-    "from distutils import sysconfig as s;import sys;import struct;
-print('.'.join(str(v) for v in sys.version_info));
-print(sys.prefix);
-print(s.get_python_inc(plat_specific=True));
-print(s.get_python_lib(plat_specific=True));
-print(s.get_config_var('SO'));
-print(hasattr(sys, 'gettotalrefcount')+0);
-print(struct.calcsize('@P'));
-print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));
-print(s.get_config_var('LIBPL'));
-print(s.get_config_var('LIBS') or '');
-"
-    RESULT_VARIABLE _PYTHON_SUCCESS
-    OUTPUT_VARIABLE _PYTHON_VALUES
-    ERROR_VARIABLE _PYTHON_ERROR_VALUE)
-
-if(NOT _PYTHON_SUCCESS MATCHES 0)
-    if(PythonLibsNew_FIND_REQUIRED)
-        message(FATAL_ERROR
-            "Python config failure:\n${_PYTHON_ERROR_VALUE}")
-    endif()
-    set(PYTHONLIBS_FOUND FALSE)
-    return()
-endif()
-
-# Convert the process output into a list
-string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
-string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
-list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
-list(GET _PYTHON_VALUES 1 PYTHON_PREFIX)
-list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
-list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
-list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
-list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG)
-list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)
-list(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)
-list(GET _PYTHON_VALUES 8 PYTHON_LIBRARY_PATH)
-list(GET _PYTHON_VALUES 9 PYTHON_OTHER_LIBS)
-
-# Make sure the Python has the same pointer-size as the chosen compiler
-# Skip the check on OS X, it doesn't consistently have CMAKE_SIZEOF_VOID_P defined
-if((NOT APPLE) AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}"))
-    if(PythonLibsNew_FIND_REQUIRED)
-        math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8")
-        math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8")
-        message(FATAL_ERROR
-            "Python config failure: Python is ${_PYTHON_BITS}-bit, "
-            "chosen compiler is  ${_CMAKE_BITS}-bit")
-    endif()
-    set(PYTHONLIBS_FOUND FALSE)
-    return()
-endif()
-
-# The built-in FindPython didn't always give the version numbers
-string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})
-list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
-list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)
-list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)
-
-# Make sure all directory separators are '/'
-string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
-string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR})
-string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES})
-
-if(CMAKE_HOST_WIN32)
-  # Appease CMP0054
-  if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
-    set(PYTHON_LIBRARY
-      "${PYTHON_PREFIX}/libs/Python${PYTHON_LIBRARY_SUFFIX}.lib")
-  else()
-    find_library(PYTHON_LIBRARY
-        NAMES "python${PYTHON_LIBRARY_SUFFIX}"
-        PATHS "${PYTHON_PREFIX}" NO_DEFAULT_PATH
-        PATH_SUFFIXES "lib" "libs")
-  endif()
-elseif(APPLE)
-
-  set(PYTHON_LIBRARY "${PYTHON_PREFIX}/lib/libpython${PYTHON_LIBRARY_SUFFIX}.dylib")
-
-  if (NOT EXISTS ${PYTHON_LIBRARY})
-    # In some cases libpythonX.X.dylib is not part of the PYTHON_PREFIX and we
-    # need to call `python-config --prefix` to determine the correct location.
-    find_program(PYTHON_CONFIG python-config
-        NO_CMAKE_SYSTEM_PATH)
-    if (PYTHON_CONFIG)
-      execute_process(
-          COMMAND "${PYTHON_CONFIG}" "--prefix"
-          OUTPUT_VARIABLE PYTHON_CONFIG_PREFIX
-          OUTPUT_STRIP_TRAILING_WHITESPACE)
-      set(PYTHON_LIBRARY "${PYTHON_CONFIG_PREFIX}/lib/libpython${PYTHON_LIBRARY_SUFFIX}.dylib")
-    endif()
-  endif()
-else()
-    if(${PYTHON_SIZEOF_VOID_P} MATCHES 8)
-        set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib64" "${PYTHON_PREFIX}/lib" "${PYTHON_LIBRARY_PATH}")
-    else()
-        set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib" "${PYTHON_LIBRARY_PATH}")
-    endif()
-    message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}")
-    message(STATUS "Looking for python${PYTHON_LIBRARY_SUFFIX}")
-    # Probably this needs to be more involved. It would be nice if the config
-    # information the python interpreter itself gave us were more complete.
-    find_library(PYTHON_LIBRARY
-        NAMES "python${PYTHON_LIBRARY_SUFFIX}"
-        PATHS ${_PYTHON_LIBS_SEARCH}
-        NO_SYSTEM_ENVIRONMENT_PATH
-        NO_CMAKE_SYSTEM_PATH)
-    message(STATUS "Found Python lib ${PYTHON_LIBRARY}")
-endif()
-
-# For backward compatibility, set PYTHON_INCLUDE_PATH, but make it internal.
-SET(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}" CACHE INTERNAL
-          "Path to where Python.h is found (deprecated)")
-
-MARK_AS_ADVANCED(
-  PYTHON_LIBRARY
-  PYTHON_INCLUDE_DIR
-)
-
-# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
-# cache entries because they are meant to specify the location of a single
-# library. We now set the variables listed by the documentation for this
-# module.
-SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
-SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
-SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
-
-
-# Don't know how to get to this directory, just doing something simple :P
-#INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-#FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs DEFAULT_MSG PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS)
-find_package_message(PYTHON
-    "Found PythonLibs: ${PYTHON_LIBRARY}"
-    "${PYTHON_EXECUTABLE}${PYTHON_VERSION}")
-
-add_library(Python3::Module SHARED IMPORTED)
-if(CMAKE_VERSION VERSION_LESS 3.11)
-  set_target_properties(Python3::Module PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-      ${PYTHON_INCLUDE_DIRS})
-else()
-  target_include_directories(Python3::Module INTERFACE ${PYTHON_INCLUDE_DIRS})
-endif()
-set_target_properties(Python3::Module PROPERTIES
-    IMPORTED_LOCATION "${PYTHON_LIBRARIES}"
-    IMPORTED_IMPLIB "${PYTHON_LIBRARIES}")
-
-# PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is used to build modules for python.
-FUNCTION(PYTHON_ADD_MODULE _NAME )
-  GET_PROPERTY(_TARGET_SUPPORTS_SHARED_LIBS
-    GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
-  OPTION(PYTHON_ENABLE_MODULE_${_NAME} "Add module ${_NAME}" TRUE)
-  OPTION(PYTHON_MODULE_${_NAME}_BUILD_SHARED
-    "Add module ${_NAME} shared" ${_TARGET_SUPPORTS_SHARED_LIBS})
-
-  # Mark these options as advanced
-  MARK_AS_ADVANCED(PYTHON_ENABLE_MODULE_${_NAME}
-    PYTHON_MODULE_${_NAME}_BUILD_SHARED)
-
-  IF(PYTHON_ENABLE_MODULE_${_NAME})
-    IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
-      SET(PY_MODULE_TYPE MODULE)
-    ELSE(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
-      SET(PY_MODULE_TYPE STATIC)
-      SET_PROPERTY(GLOBAL  APPEND  PROPERTY  PY_STATIC_MODULES_LIST ${_NAME})
-    ENDIF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
-
-    SET_PROPERTY(GLOBAL  APPEND  PROPERTY  PY_MODULES_LIST ${_NAME})
-    ADD_LIBRARY(${_NAME} ${PY_MODULE_TYPE} ${ARGN})
-    IF(APPLE)
-      # On OS X, linking against the Python libraries causes
-      # segfaults, so do this dynamic lookup instead.
-      SET_TARGET_PROPERTIES(${_NAME} PROPERTIES LINK_FLAGS
-                          "-undefined dynamic_lookup")
-    ELSEIF(MSVC)
-      target_link_libraries(${_NAME} ${PYTHON_LIBRARIES})
-    ELSE()
-      # In general, we should not link against libpython as we do not embed the
-      # Python interpreter. The python binary itself can then define where the
-      # symbols should loaded from. For being manylinux1 compliant, one is not
-      # allowed to link to libpython. Partly because not all systems ship it,
-      # also because the interpreter ABI/API was not stable between patch
-      # releases for Python < 3.5.
-      SET_TARGET_PROPERTIES(${_NAME} PROPERTIES LINK_FLAGS
-        "-Wl,-undefined,dynamic_lookup")
-    ENDIF()
-    IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
-      SET_TARGET_PROPERTIES(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
-      SET_TARGET_PROPERTIES(${_NAME} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
-    ELSE()
-    ENDIF()
-
-  ENDIF(PYTHON_ENABLE_MODULE_${_NAME})
-ENDFUNCTION(PYTHON_ADD_MODULE)
diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake b/cpp/cmake_modules/ThirdpartyToolchain.cmake
index 68d5be8ba4..9f67f1e52f 100644
--- a/cpp/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake
@@ -327,14 +327,8 @@ endmacro()
 set(THIRDPARTY_DIR "${arrow_SOURCE_DIR}/thirdparty")
 
 add_library(arrow::flatbuffers INTERFACE IMPORTED)
-if(CMAKE_VERSION VERSION_LESS 3.11)
-  set_target_properties(arrow::flatbuffers
-                        PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                   "${THIRDPARTY_DIR}/flatbuffers/include")
-else()
-  target_include_directories(arrow::flatbuffers
-                             INTERFACE "${THIRDPARTY_DIR}/flatbuffers/include")
-endif()
+target_include_directories(arrow::flatbuffers
+                           INTERFACE "${THIRDPARTY_DIR}/flatbuffers/include")
 
 # ----------------------------------------------------------------------
 # Some EP's require other EP's
@@ -404,11 +398,6 @@ endif()
 
 macro(set_urls URLS)
   set(${URLS} ${ARGN})
-  if(CMAKE_VERSION VERSION_LESS 3.7)
-    # ExternalProject doesn't support backup URLs;
-    # Feature only available starting in 3.7
-    list(GET ${URLS} 0 ${URLS})
-  endif()
 endmacro()
 
 # Read toolchain versions from cpp/thirdparty/versions.txt
@@ -838,8 +827,27 @@ if(NOT MSVC_TOOLCHAIN)
   string(APPEND EP_C_FLAGS " -fPIC")
 endif()
 
-set(EP_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
-set(EP_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
+# We pass MSVC runtime related options via
+# CMAKE_${LANG}_FLAGS_${CONFIG} explicitly because external projects
+# may not require CMake 3.15 or later. If an external project doesn't
+# require CMake 3.15 or later, CMAKE_MSVC_RUNTIME_LIBRARY is ignored.
+# If CMAKE_MSVC_RUNTIME_LIBRARY is ignored, an external project may
+# use different MSVC runtime. For example, Apache Arrow C++ uses /MTd
+# (multi threaded debug) but an external project uses /MT (multi
+# threaded release). It causes an link error.
+foreach(CONFIG DEBUG MINSIZEREL RELEASE RELWITHDEBINFO)
+  set(EP_CXX_FLAGS_${CONFIG} "${CMAKE_CXX_FLAGS_${CONFIG}}")
+  set(EP_C_FLAGS_${CONFIG} "${CMAKE_C_FLAGS_${CONFIG}}")
+  if(CONFIG STREQUAL DEBUG)
+    set(EP_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL)
+  else()
+    set(EP_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
+  endif()
+  string(APPEND EP_CXX_FLAGS_${CONFIG}
+         " ${CMAKE_CXX_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_${EP_MSVC_RUNTIME_LIBRARY}}")
+  string(APPEND EP_C_FLAGS_${CONFIG}
+         " ${CMAKE_C_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_${EP_MSVC_RUNTIME_LIBRARY}}")
+endforeach()
 if(MSVC_TOOLCHAIN)
   string(REPLACE "/WX" "" EP_CXX_FLAGS_DEBUG "${EP_CXX_FLAGS_DEBUG}")
   string(REPLACE "/WX" "" EP_C_FLAGS_DEBUG "${EP_C_FLAGS_DEBUG}")
@@ -892,15 +900,15 @@ set(EP_COMMON_CMAKE_ARGS
     -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
     -DCMAKE_CXX_FLAGS=${EP_CXX_FLAGS}
     -DCMAKE_CXX_FLAGS_DEBUG=${EP_CXX_FLAGS_DEBUG}
-    -DCMAKE_CXX_FLAGS_MISIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL}
-    -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE}
-    -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
+    -DCMAKE_CXX_FLAGS_MISIZEREL=${EP_CXX_FLAGS_MINSIZEREL}
+    -DCMAKE_CXX_FLAGS_RELEASE=${EP_CXX_FLAGS_RELEASE}
+    -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${EP_CXX_FLAGS_RELWITHDEBINFO}
     -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
     -DCMAKE_C_FLAGS=${EP_C_FLAGS}
     -DCMAKE_C_FLAGS_DEBUG=${EP_C_FLAGS_DEBUG}
-    -DCMAKE_C_FLAGS_MISIZEREL=${CMAKE_C_FLAGS_MINSIZEREL}
-    -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE}
-    -DCMAKE_C_FLAGS_RELWITHDEBINFO=${CMAKE_C_FLAGS_RELWITHDEBINFO}
+    -DCMAKE_C_FLAGS_MISIZEREL=${EP_C_FLAGS_MINSIZEREL}
+    -DCMAKE_C_FLAGS_RELEASE=${EP_C_FLAGS_RELEASE}
+    -DCMAKE_C_FLAGS_RELWITHDEBINFO=${EP_C_FLAGS_RELWITHDEBINFO}
     -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=${CMAKE_EXPORT_NO_PACKAGE_REGISTRY}
     -DCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY=${CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY}
     -DCMAKE_INSTALL_LIBDIR=lib
@@ -1053,12 +1061,7 @@ macro(build_boost)
                         URL_HASH "SHA256=${ARROW_BOOST_BUILD_SHA256_CHECKSUM}")
   endif()
   add_library(Boost::headers INTERFACE IMPORTED)
-  if(CMAKE_VERSION VERSION_LESS 3.11)
-    set_target_properties(Boost::headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                                    "${Boost_INCLUDE_DIR}")
-  else()
-    target_include_directories(Boost::headers INTERFACE "${Boost_INCLUDE_DIR}")
-  endif()
+  target_include_directories(Boost::headers INTERFACE "${Boost_INCLUDE_DIR}")
   add_dependencies(Boost::headers boost_ep)
   # If Boost is found but one of system or filesystem components aren't found,
   # Boost::disable_autolinking and Boost::dynamic_linking are already defined.
@@ -1200,34 +1203,13 @@ if(ARROW_USE_BOOST)
     unset(BUILD_SHARED_LIBS_KEEP)
   endif()
 
-  # For CMake < 3.15
-  if(NOT TARGET Boost::headers)
-    add_library(Boost::headers INTERFACE IMPORTED)
-    if(CMAKE_VERSION VERSION_LESS 3.11)
-      set_target_properties(Boost::headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                                      "${Boost_INCLUDE_DIR}")
-    else()
-      target_include_directories(Boost::headers INTERFACE "${Boost_INCLUDE_DIR}")
-    endif()
-  endif()
-
   foreach(BOOST_LIBRARY Boost::headers Boost::filesystem Boost::system)
     if(NOT TARGET ${BOOST_LIBRARY})
       continue()
     endif()
-    if(CMAKE_VERSION VERSION_LESS 3.11)
-      set_target_properties(${BOOST_LIBRARY} PROPERTIES INTERFACE_LINK_LIBRARIES
-                                                        Boost::disable_autolinking)
-    else()
-      target_link_libraries(${BOOST_LIBRARY} INTERFACE Boost::disable_autolinking)
-    endif()
+    target_link_libraries(${BOOST_LIBRARY} INTERFACE Boost::disable_autolinking)
     if(ARROW_BOOST_USE_SHARED)
-      if(CMAKE_VERSION VERSION_LESS 3.11)
-        set_target_properties(${BOOST_LIBRARY} PROPERTIES INTERFACE_LINK_LIBRARIES
-                                                          Boost::dynamic_linking)
-      else()
-        target_link_libraries(${BOOST_LIBRARY} INTERFACE Boost::dynamic_linking)
-      endif()
+      target_link_libraries(${BOOST_LIBRARY} INTERFACE Boost::dynamic_linking)
     endif()
   endforeach()
 
@@ -1251,15 +1233,6 @@ macro(find_curl)
   if(NOT TARGET CURL::libcurl)
     find_package(CURL REQUIRED)
     list(APPEND ARROW_SYSTEM_DEPENDENCIES CURL)
-    if(NOT TARGET CURL::libcurl)
-      # For CMake 3.11 or older
-      add_library(CURL::libcurl UNKNOWN IMPORTED)
-      set_target_properties(CURL::libcurl
-                            PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                       "${CURL_INCLUDE_DIRS}"
-                                       IMPORTED_LOCATION "${CURL_LIBRARIES}"
-                                       INTERFACE_LINK_LIBRARIES OpenSSL::SSL)
-    endif()
   endif()
 endmacro()
 
@@ -1554,10 +1527,6 @@ endif()
 # Thrift
 
 macro(build_thrift)
-  if(CMAKE_VERSION VERSION_LESS 3.10)
-    message(FATAL_ERROR "Building thrift using ExternalProject requires at least CMake 3.10"
-    )
-  endif()
   message(STATUS "Building Apache Thrift from source")
   set(THRIFT_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/thrift_ep-install")
   set(THRIFT_INCLUDE_DIR "${THRIFT_PREFIX}/include")
@@ -1626,12 +1595,7 @@ macro(build_thrift)
                         PROPERTIES IMPORTED_LOCATION "${THRIFT_LIB}"
                                    INTERFACE_INCLUDE_DIRECTORIES "${THRIFT_INCLUDE_DIR}")
   if(ARROW_USE_BOOST)
-    if(CMAKE_VERSION VERSION_LESS 3.11)
-      set_target_properties(thrift::thrift PROPERTIES INTERFACE_LINK_LIBRARIES
-                                                      Boost::headers)
-    else()
-      target_link_libraries(thrift::thrift INTERFACE Boost::headers)
-    endif()
+    target_link_libraries(thrift::thrift INTERFACE Boost::headers)
   endif()
   add_dependencies(toolchain thrift_ep)
   add_dependencies(thrift::thrift thrift_ep)
@@ -1677,52 +1641,29 @@ macro(build_protobuf)
   set(Protobuf_PROTOC_LIBRARY "${PROTOC_STATIC_LIB}")
   set(PROTOBUF_COMPILER "${PROTOBUF_PREFIX}/bin/protoc")
 
-  if(CMAKE_VERSION VERSION_LESS 3.7)
-    set(PROTOBUF_CONFIGURE_ARGS
-        "AR=${CMAKE_AR}"
-        "RANLIB=${CMAKE_RANLIB}"
-        "CC=${CMAKE_C_COMPILER}"
-        "CXX=${CMAKE_CXX_COMPILER}"
-        "--disable-shared"
-        "--prefix=${PROTOBUF_PREFIX}"
-        "CFLAGS=${EP_C_FLAGS}"
-        "CXXFLAGS=${EP_CXX_FLAGS}")
-    set(PROTOBUF_BUILD_COMMAND ${MAKE} ${MAKE_BUILD_ARGS})
-    if(CMAKE_OSX_SYSROOT)
-      list(APPEND PROTOBUF_CONFIGURE_ARGS "SDKROOT=${CMAKE_OSX_SYSROOT}")
-      list(APPEND PROTOBUF_BUILD_COMMAND "SDKROOT=${CMAKE_OSX_SYSROOT}")
-    endif()
-    set(PROTOBUF_EXTERNAL_PROJECT_ADD_ARGS
-        CONFIGURE_COMMAND
-        "./configure"
-        ${PROTOBUF_CONFIGURE_ARGS}
-        BUILD_COMMAND
-        ${PROTOBUF_BUILD_COMMAND})
-  else()
-    # Strip lto flags (which may be added by dh_auto_configure)
-    # See https://github.com/protocolbuffers/protobuf/issues/7092
-    set(PROTOBUF_C_FLAGS ${EP_C_FLAGS})
-    set(PROTOBUF_CXX_FLAGS ${EP_CXX_FLAGS})
-    string(REPLACE "-flto=auto" "" PROTOBUF_C_FLAGS "${PROTOBUF_C_FLAGS}")
-    string(REPLACE "-ffat-lto-objects" "" PROTOBUF_C_FLAGS "${PROTOBUF_C_FLAGS}")
-    string(REPLACE "-flto=auto" "" PROTOBUF_CXX_FLAGS "${PROTOBUF_CXX_FLAGS}")
-    string(REPLACE "-ffat-lto-objects" "" PROTOBUF_CXX_FLAGS "${PROTOBUF_CXX_FLAGS}")
-    set(PROTOBUF_CMAKE_ARGS
-        ${EP_COMMON_CMAKE_ARGS}
-        "-DCMAKE_CXX_FLAGS=${PROTOBUF_CXX_FLAGS}"
-        "-DCMAKE_C_FLAGS=${PROTOBUF_C_FLAGS}"
-        "-DCMAKE_INSTALL_PREFIX=${PROTOBUF_PREFIX}"
-        -Dprotobuf_BUILD_TESTS=OFF
-        -Dprotobuf_DEBUG_POSTFIX=)
-    if(MSVC AND NOT ARROW_USE_STATIC_CRT)
-      list(APPEND PROTOBUF_CMAKE_ARGS "-Dprotobuf_MSVC_STATIC_RUNTIME=OFF")
-    endif()
-    if(ZLIB_ROOT)
-      list(APPEND PROTOBUF_CMAKE_ARGS "-DZLIB_ROOT=${ZLIB_ROOT}")
-    endif()
-    set(PROTOBUF_EXTERNAL_PROJECT_ADD_ARGS CMAKE_ARGS ${PROTOBUF_CMAKE_ARGS}
-                                           SOURCE_SUBDIR "cmake")
+  # Strip lto flags (which may be added by dh_auto_configure)
+  # See https://github.com/protocolbuffers/protobuf/issues/7092
+  set(PROTOBUF_C_FLAGS ${EP_C_FLAGS})
+  set(PROTOBUF_CXX_FLAGS ${EP_CXX_FLAGS})
+  string(REPLACE "-flto=auto" "" PROTOBUF_C_FLAGS "${PROTOBUF_C_FLAGS}")
+  string(REPLACE "-ffat-lto-objects" "" PROTOBUF_C_FLAGS "${PROTOBUF_C_FLAGS}")
+  string(REPLACE "-flto=auto" "" PROTOBUF_CXX_FLAGS "${PROTOBUF_CXX_FLAGS}")
+  string(REPLACE "-ffat-lto-objects" "" PROTOBUF_CXX_FLAGS "${PROTOBUF_CXX_FLAGS}")
+  set(PROTOBUF_CMAKE_ARGS
+      ${EP_COMMON_CMAKE_ARGS}
+      "-DCMAKE_CXX_FLAGS=${PROTOBUF_CXX_FLAGS}"
+      "-DCMAKE_C_FLAGS=${PROTOBUF_C_FLAGS}"
+      "-DCMAKE_INSTALL_PREFIX=${PROTOBUF_PREFIX}"
+      -Dprotobuf_BUILD_TESTS=OFF
+      -Dprotobuf_DEBUG_POSTFIX=)
+  if(MSVC AND NOT ARROW_USE_STATIC_CRT)
+    list(APPEND PROTOBUF_CMAKE_ARGS "-Dprotobuf_MSVC_STATIC_RUNTIME=OFF")
+  endif()
+  if(ZLIB_ROOT)
+    list(APPEND PROTOBUF_CMAKE_ARGS "-DZLIB_ROOT=${ZLIB_ROOT}")
   endif()
+  set(PROTOBUF_EXTERNAL_PROJECT_ADD_ARGS CMAKE_ARGS ${PROTOBUF_CMAKE_ARGS} SOURCE_SUBDIR
+                                         "cmake")
 
   externalproject_add(protobuf_ep
                       ${EP_COMMON_OPTIONS} ${PROTOBUF_EXTERNAL_PROJECT_ADD_ARGS}
@@ -1783,34 +1724,11 @@ if(ARROW_WITH_PROTOBUF)
   if(TARGET arrow::protobuf::libprotobuf)
     set(ARROW_PROTOBUF_LIBPROTOBUF arrow::protobuf::libprotobuf)
   else()
-    # CMake 3.8 or older don't define the targets
-    if(NOT TARGET protobuf::libprotobuf)
-      add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
-      set_target_properties(protobuf::libprotobuf
-                            PROPERTIES IMPORTED_LOCATION "${PROTOBUF_LIBRARY}"
-                                       INTERFACE_INCLUDE_DIRECTORIES
-                                       "${PROTOBUF_INCLUDE_DIR}")
-    endif()
     set(ARROW_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
   endif()
   if(TARGET arrow::protobuf::libprotoc)
     set(ARROW_PROTOBUF_LIBPROTOC arrow::protobuf::libprotoc)
   else()
-    # CMake 3.8 or older don't define the targets
-    if(NOT TARGET protobuf::libprotoc)
-      if(PROTOBUF_PROTOC_LIBRARY AND NOT Protobuf_PROTOC_LIBRARY)
-        # Old CMake versions have a different casing.
-        set(Protobuf_PROTOC_LIBRARY ${PROTOBUF_PROTOC_LIBRARY})
-      endif()
-      if(NOT Protobuf_PROTOC_LIBRARY)
-        message(FATAL_ERROR "libprotoc was set to ${Protobuf_PROTOC_LIBRARY}")
-      endif()
-      add_library(protobuf::libprotoc UNKNOWN IMPORTED)
-      set_target_properties(protobuf::libprotoc
-                            PROPERTIES IMPORTED_LOCATION "${Protobuf_PROTOC_LIBRARY}"
-                                       INTERFACE_INCLUDE_DIRECTORIES
-                                       "${PROTOBUF_INCLUDE_DIR}")
-    endif()
     set(ARROW_PROTOBUF_LIBPROTOC protobuf::libprotoc)
   endif()
   if(TARGET arrow::protobuf::protoc)
@@ -2180,10 +2098,6 @@ macro(build_gtest)
     set(_GTEST_MAIN_RUNTIME_LIB
         "${_GTEST_RUNTIME_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}gtest_main${_GTEST_RUNTIME_SUFFIX}"
     )
-    if(CMAKE_VERSION VERSION_LESS 3.9)
-      message(FATAL_ERROR "Building GoogleTest from source on Windows requires at least CMake 3.9"
-      )
-    endif()
     get_property(_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
     if(_GENERATOR_IS_MULTI_CONFIG)
       set(_GTEST_RUNTIME_OUTPUT_DIR "${BUILD_OUTPUT_ROOT_DIRECTORY}/${CMAKE_BUILD_TYPE}")
@@ -2271,9 +2185,6 @@ endif()
 
 macro(build_benchmark)
   message(STATUS "Building benchmark from source")
-  if(CMAKE_VERSION VERSION_LESS 3.6)
-    message(FATAL_ERROR "Building gbenchmark from source requires at least CMake 3.6")
-  endif()
 
   set(GBENCHMARK_CMAKE_CXX_FLAGS "${EP_CXX_FLAGS}")
   if(APPLE AND (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID
@@ -2385,12 +2296,7 @@ if(ARROW_WITH_RAPIDJSON)
   endif()
 
   add_library(rapidjson::rapidjson INTERFACE IMPORTED)
-  if(CMAKE_VERSION VERSION_LESS 3.11)
-    set_target_properties(rapidjson::rapidjson PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                                          "${RAPIDJSON_INCLUDE_DIR}")
-  else()
-    target_include_directories(rapidjson::rapidjson INTERFACE "${RAPIDJSON_INCLUDE_DIR}")
-  endif()
+  target_include_directories(rapidjson::rapidjson INTERFACE "${RAPIDJSON_INCLUDE_DIR}")
 endif()
 
 macro(build_xsimd)
@@ -2431,12 +2337,7 @@ if(ARROW_USE_XSIMD)
 
   if(xsimd_SOURCE STREQUAL "BUNDLED")
     add_library(arrow::xsimd INTERFACE IMPORTED)
-    if(CMAKE_VERSION VERSION_LESS 3.11)
-      set_target_properties(arrow::xsimd PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                                    "${XSIMD_INCLUDE_DIR}")
-    else()
-      target_include_directories(arrow::xsimd INTERFACE "${XSIMD_INCLUDE_DIR}")
-    endif()
+    target_include_directories(arrow::xsimd INTERFACE "${XSIMD_INCLUDE_DIR}")
     set(ARROW_XSIMD arrow::xsimd)
   else()
     message(STATUS "xsimd found. Headers: ${xsimd_INCLUDE_DIRS}")
@@ -2488,9 +2389,6 @@ endif()
 
 macro(build_lz4)
   message(STATUS "Building LZ4 from source")
-  if(CMAKE_VERSION VERSION_LESS 3.7)
-    message(FATAL_ERROR "Building LZ4 using ExternalProject requires at least CMake 3.7")
-  endif()
 
   set(LZ4_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/lz4_ep-install")
 
@@ -2531,10 +2429,6 @@ endif()
 
 macro(build_zstd)
   message(STATUS "Building Zstandard from source")
-  if(CMAKE_VERSION VERSION_LESS 3.7)
-    message(FATAL_ERROR "Building Zstandard using ExternalProject requires at least CMake 3.7"
-    )
-  endif()
 
   set(ZSTD_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/zstd_ep-install")
 
@@ -4220,9 +4114,8 @@ macro(build_google_cloud_cpp_storage)
   list(APPEND GOOGLE_CLOUD_CPP_PREFIX_PATH_LIST ${CRC32C_PREFIX})
   list(APPEND GOOGLE_CLOUD_CPP_PREFIX_PATH_LIST ${NLOHMANN_JSON_PREFIX})
 
-  # JOIN is CMake >=3.12 only
-  string(REPLACE ";" ${EP_LIST_SEPARATOR} GOOGLE_CLOUD_CPP_PREFIX_PATH
-                 "${GOOGLE_CLOUD_CPP_PREFIX_PATH_LIST}")
+  string(JOIN ${EP_LIST_SEPARATOR} GOOGLE_CLOUD_CPP_PREFIX_PATH
+         ${GOOGLE_CLOUD_CPP_PREFIX_PATH_LIST})
 
   set(GOOGLE_CLOUD_CPP_INSTALL_PREFIX
       "${CMAKE_CURRENT_BINARY_DIR}/google_cloud_cpp_ep-install")
@@ -4402,12 +4295,7 @@ endif()
 message(STATUS "Found hdfs.h at: ${HDFS_H_PATH}")
 
 add_library(arrow::hadoop INTERFACE IMPORTED)
-if(CMAKE_VERSION VERSION_LESS 3.11)
-  set_target_properties(arrow::hadoop PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                                 "${HADOOP_HOME}/include")
-else()
-  target_include_directories(arrow::hadoop INTERFACE "${HADOOP_HOME}/include")
-endif()
+target_include_directories(arrow::hadoop INTERFACE "${HADOOP_HOME}/include")
 
 # ----------------------------------------------------------------------
 # Apache ORC
@@ -4487,12 +4375,7 @@ macro(build_orc)
     endif()
     list(APPEND ORC_LINK_LIBRARIES ${CMAKE_DL_LIBS})
   endif()
-  if(CMAKE_VERSION VERSION_LESS 3.11)
-    set_target_properties(orc::liborc PROPERTIES INTERFACE_LINK_LIBRARIES
-                                                 "${ORC_LINK_LIBRARIES}")
-  else()
-    target_link_libraries(orc::liborc INTERFACE ${ORC_LINK_LIBRARIES})
-  endif()
+  target_link_libraries(orc::liborc INTERFACE ${ORC_LINK_LIBRARIES})
 
   add_dependencies(toolchain orc_ep)
   add_dependencies(orc::liborc orc_ep)
@@ -4621,9 +4504,8 @@ macro(build_opentelemetry)
   add_dependencies(opentelemetry_dependencies nlohmann_json::nlohmann_json
                    opentelemetry_proto_ep ${ARROW_PROTOBUF_LIBPROTOBUF})
 
-  # JOIN is CMake >=3.12 only
-  string(REPLACE ";" "${EP_LIST_SEPARATOR}" OPENTELEMETRY_PREFIX_PATH
-                 "${OPENTELEMETRY_PREFIX_PATH_LIST}")
+  string(JOIN "${EP_LIST_SEPARATOR}" OPENTELEMETRY_PREFIX_PATH
+         ${OPENTELEMETRY_PREFIX_PATH_LIST})
   list(APPEND OPENTELEMETRY_CMAKE_ARGS "-DCMAKE_PREFIX_PATH=${OPENTELEMETRY_PREFIX_PATH}")
 
   if(CMAKE_SYSTEM_PROCESSOR STREQUAL "s390x")
@@ -5179,15 +5061,8 @@ endmacro()
 if(ARROW_WITH_UCX)
   resolve_dependency(ucx PC_PACKAGE_NAMES ucx)
   add_library(ucx::ucx INTERFACE IMPORTED)
-  if(CMAKE_VERSION VERSION_LESS 3.11)
-    set_target_properties(ucx::ucx PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
-                                              "${UCX_INCLUDE_DIRS}")
-    set_property(TARGET ucx::ucx PROPERTY INTERFACE_LINK_LIBRARIES ucx::ucp ucx::uct
-                                          ucx::ucs)
-  else()
-    target_include_directories(ucx::ucx INTERFACE "${UCX_INCLUDE_DIRS}")
-    target_link_libraries(ucx::ucx INTERFACE ucx::ucp ucx::uct ucx::ucs)
-  endif()
+  target_include_directories(ucx::ucx INTERFACE "${UCX_INCLUDE_DIRS}")
+  target_link_libraries(ucx::ucx INTERFACE ucx::ucp ucx::uct ucx::ucs)
 endif()
 
 message(STATUS "All bundled static libraries: ${ARROW_BUNDLED_STATIC_LIBS}")
diff --git a/cpp/examples/minimal_build/CMakeLists.txt b/cpp/examples/minimal_build/CMakeLists.txt
index b98f725a4a..b4a7cde938 100644
--- a/cpp/examples/minimal_build/CMakeLists.txt
+++ b/cpp/examples/minimal_build/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.16)
 
 project(ArrowMinimalExample)
 
diff --git a/cpp/examples/parquet/parquet_arrow/CMakeLists.txt b/cpp/examples/parquet/parquet_arrow/CMakeLists.txt
index 84f9d16e40..0480391e38 100644
--- a/cpp/examples/parquet/parquet_arrow/CMakeLists.txt
+++ b/cpp/examples/parquet/parquet_arrow/CMakeLists.txt
@@ -16,7 +16,7 @@
 # under the License.
 
 # Require cmake that supports BYPRODUCTS in add_custom_command, ExternalProject_Add [1].
-cmake_minimum_required(VERSION 3.2.0)
+cmake_minimum_required(VERSION 3.16)
 
 project(parquet_arrow_example)
 
diff --git a/cpp/examples/tutorial_examples/CMakeLists.txt b/cpp/examples/tutorial_examples/CMakeLists.txt
index ed399edbd6..7758af90fb 100644
--- a/cpp/examples/tutorial_examples/CMakeLists.txt
+++ b/cpp/examples/tutorial_examples/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.16)
 
 project(ArrowTutorialExamples)
 
diff --git a/docs/source/developers/cpp/building.rst b/docs/source/developers/cpp/building.rst
index aa5dbe2086..dfd0f6ceec 100644
--- a/docs/source/developers/cpp/building.rst
+++ b/docs/source/developers/cpp/building.rst
@@ -41,9 +41,9 @@ Building requires:
 
 * A C++17-enabled compiler. On Linux, gcc 7.1 and higher should be
   sufficient. For Windows, at least Visual Studio VS2017 is required.
-* CMake 3.5 or higher
+* CMake 3.16 or higher
 * On Linux and macOS, either ``make`` or ``ninja`` build utilities
-* At least 1GB of RAM for a minimal build, 4GB for a minimal  
+* At least 1GB of RAM for a minimal build, 4GB for a minimal
   debug build with tests and 8GB for a full build using
   :ref:`docker <docker-builds>`.
 
@@ -446,12 +446,7 @@ several times with different options if you want to exercise all of them.
 CMake version requirements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-While we support CMake 3.5 and higher, some features require a newer version of
-CMake:
-
-* Building the benchmarks requires 3.6 or higher
-* Building zstd from source requires 3.7 or higher
-* Building Gandiva JNI bindings requires 3.11 or higher
+We support CMake 3.16 and higher.
 
 LLVM and Clang Tools
 ~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/source/developers/python.rst b/docs/source/developers/python.rst
index 2df3297f76..23bbb835a3 100644
--- a/docs/source/developers/python.rst
+++ b/docs/source/developers/python.rst
@@ -374,12 +374,6 @@ Python executable which you are using.
    :ref:`here <cpp-build-dependency-management>`)
    to explicitly tell CMake not to use conda.
 
-.. note::
-
-   With older versions of CMake (<3.15) you might need to pass ``-DPYTHON_EXECUTABLE``
-   instead of ``-DPython3_EXECUTABLE``. See `cmake documentation <https://cmake.org/cmake/help/latest/module/FindPython3.html#artifacts-specification>`_
-   for more details.
-
 For any other C++ build challenges, see :ref:`cpp-development`.
 
 In case you may need to rebuild the C++ part due to errors in the process it is
diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt
index f2a518ac1c..04fa51ff98 100644
--- a/java/CMakeLists.txt
+++ b/java/CMakeLists.txt
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-cmake_minimum_required(VERSION 3.11)
+cmake_minimum_required(VERSION 3.16)
 message(STATUS "Building using CMake version: ${CMAKE_VERSION}")
 
 # find_package() uses <PackageName>_ROOT variables.
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index cefb371130..21a2ace521 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -18,7 +18,7 @@
 # Includes code assembled from BSD/MIT/Apache-licensed code from some 3rd-party
 # projects, including Kudu, Impala, and libdynd. See python/LICENSE.txt
 
-cmake_minimum_required(VERSION 3.5)
+cmake_minimum_required(VERSION 3.16)
 project(pyarrow)
 
 set(PYARROW_VERSION "13.0.0-SNAPSHOT")