From b8fafef188ba8ca96947f7595ecf884941029fb8 Mon Sep 17 00:00:00 2001 From: Jonathan Keane Date: Sun, 22 Feb 2026 11:42:08 -0600 Subject: [PATCH 1/6] use cmake VALIDATOR --- cpp/cmake_modules/BuildUtils.cmake | 45 +++++++++++++++++++----------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake index db760400f7ca..472b81b2e0b5 100644 --- a/cpp/cmake_modules/BuildUtils.cmake +++ b/cpp/cmake_modules/BuildUtils.cmake @@ -91,28 +91,41 @@ function(arrow_create_merged_static_lib output_target) endforeach() if(APPLE) + # Validator function to confirm that the libtool is Apple's libtool. + # The apple-distributed libtool is what we want for bundling, but there is + # a GNU libtool that has a name collision (and happens to be bundled with R, too). + # We are not compatible with GNU libtool, so we need to avoid it. + function(validate_apple_libtool result_var item) + execute_process(COMMAND "${item}" -V + OUTPUT_VARIABLE libtool_version + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if("${libtool_version}" MATCHES ".*cctools-([0-9.]+).*") + set(${result_var} TRUE PARENT_SCOPE) + else() + set(${result_var} FALSE PARENT_SCOPE) + endif() + endfunction() + if(CMAKE_LIBTOOL) set(LIBTOOL_MACOS ${CMAKE_LIBTOOL}) + # Validate that CMAKE_LIBTOOL is Apple's libtool + validate_apple_libtool(is_apple_libtool "${LIBTOOL_MACOS}") + if(NOT is_apple_libtool) + message(FATAL_ERROR "CMAKE_LIBTOOL does not appear to be Apple's libtool: ${LIBTOOL_MACOS}" + ) + endif() else() - # The apple-distributed libtool is what we want for bundling, but there is - # a GNU libtool that has a namecollision (and happens to be bundled with R, too). - # We are not compatible with GNU libtool, so we need to avoid it. - - # check in the obvious places first to find Apple's libtool + # Check in the obvious places first to find Apple's libtool # HINTS is used before system paths and before PATHS, so we use that # even though hard coded paths should go in PATHS - # TODO: use a VALIDATOR when we require cmake >= 3.25 find_program(LIBTOOL_MACOS libtool - HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin) - endif() - - # confirm that the libtool we found is Apple's libtool - execute_process(COMMAND ${LIBTOOL_MACOS} -V - OUTPUT_VARIABLE LIBTOOL_V_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT "${LIBTOOL_V_OUTPUT}" MATCHES ".*cctools-([0-9.]+).*") - message(FATAL_ERROR "libtool found appears not to be Apple's libtool: ${LIBTOOL_MACOS}" - ) + HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin + VALIDATOR validate_apple_libtool) + if(NOT LIBTOOL_MACOS) + message(FATAL_ERROR "Could not find Apple's libtool. GNU libtool is not compatible." + ) + endif() endif() set(BUNDLE_COMMAND ${LIBTOOL_MACOS} "-no_warning_for_no_symbols" "-static" "-o" From b6fa4e78553f9590dd82573b9d240a3edd424778 Mon Sep 17 00:00:00 2001 From: Jonathan Keane Date: Sun, 22 Feb 2026 11:42:37 -0600 Subject: [PATCH 2/6] add a milgnancy to the validator to confirm it works --- cpp/cmake_modules/BuildUtils.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake index 472b81b2e0b5..b4d417fcc547 100644 --- a/cpp/cmake_modules/BuildUtils.cmake +++ b/cpp/cmake_modules/BuildUtils.cmake @@ -100,7 +100,7 @@ function(arrow_create_merged_static_lib output_target) OUTPUT_VARIABLE libtool_version OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) - if("${libtool_version}" MATCHES ".*cctools-([0-9.]+).*") + if("${libtool_version}" MATCHES ".*ccFAKEtools-([0-9.]+).*") set(${result_var} TRUE PARENT_SCOPE) else() set(${result_var} FALSE PARENT_SCOPE) From dcc373dbef1d42fa037f5ee00aff191b8e182651 Mon Sep 17 00:00:00 2001 From: Jonathan Keane Date: Sun, 22 Feb 2026 11:56:08 -0600 Subject: [PATCH 3/6] More flexible rgex, lint --- cpp/cmake_modules/BuildUtils.cmake | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake index b4d417fcc547..fe5e16fa6c91 100644 --- a/cpp/cmake_modules/BuildUtils.cmake +++ b/cpp/cmake_modules/BuildUtils.cmake @@ -98,12 +98,15 @@ function(arrow_create_merged_static_lib output_target) function(validate_apple_libtool result_var item) execute_process(COMMAND "${item}" -V OUTPUT_VARIABLE libtool_version - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET) - if("${libtool_version}" MATCHES ".*ccFAKEtools-([0-9.]+).*") - set(${result_var} TRUE PARENT_SCOPE) + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + if("${libtool_version}" MATCHES ".*cctools.+([0-9.]+).*") + set(${result_var} + TRUE + PARENT_SCOPE) else() - set(${result_var} FALSE PARENT_SCOPE) + set(${result_var} + FALSE + PARENT_SCOPE) endif() endfunction() @@ -120,8 +123,8 @@ function(arrow_create_merged_static_lib output_target) # HINTS is used before system paths and before PATHS, so we use that # even though hard coded paths should go in PATHS find_program(LIBTOOL_MACOS libtool - HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin - VALIDATOR validate_apple_libtool) + HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin VALIDATOR + validate_apple_libtool) if(NOT LIBTOOL_MACOS) message(FATAL_ERROR "Could not find Apple's libtool. GNU libtool is not compatible." ) From fd2af488dac48d455b15f00a4ba113c5175b0f67 Mon Sep 17 00:00:00 2001 From: Jonathan Keane Date: Sun, 22 Feb 2026 12:03:52 -0600 Subject: [PATCH 4/6] more linting --- cpp/cmake_modules/BuildUtils.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake index fe5e16fa6c91..cdcd3b62ca88 100644 --- a/cpp/cmake_modules/BuildUtils.cmake +++ b/cpp/cmake_modules/BuildUtils.cmake @@ -100,13 +100,13 @@ function(arrow_create_merged_static_lib output_target) OUTPUT_VARIABLE libtool_version OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) if("${libtool_version}" MATCHES ".*cctools.+([0-9.]+).*") - set(${result_var} - TRUE + set(${result_var} + TRUE PARENT_SCOPE) else() - set(${result_var} - FALSE - PARENT_SCOPE) + set(${result_var} + FALSE + PARENT_SCOPE) endif() endfunction() @@ -123,7 +123,7 @@ function(arrow_create_merged_static_lib output_target) # HINTS is used before system paths and before PATHS, so we use that # even though hard coded paths should go in PATHS find_program(LIBTOOL_MACOS libtool - HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin VALIDATOR + HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin VALIDATOR validate_apple_libtool) if(NOT LIBTOOL_MACOS) message(FATAL_ERROR "Could not find Apple's libtool. GNU libtool is not compatible." From 6f8ff478d276e4907fb8f85735a556d35b2ade09 Mon Sep 17 00:00:00 2001 From: Jonathan Keane Date: Mon, 23 Feb 2026 08:40:42 -0600 Subject: [PATCH 5/6] Add a bit of output if we don't find libtool --- cpp/cmake_modules/BuildUtils.cmake | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake index cdcd3b62ca88..1ed7fbefad1a 100644 --- a/cpp/cmake_modules/BuildUtils.cmake +++ b/cpp/cmake_modules/BuildUtils.cmake @@ -91,14 +91,22 @@ function(arrow_create_merged_static_lib output_target) endforeach() if(APPLE) + # Get the version string from a libtool binary. + function(get_libtool_version item result_var) + execute_process(COMMAND "${item}" -V + OUTPUT_VARIABLE _version + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + set(${result_var} + "${_version}" + PARENT_SCOPE) + endfunction() + # Validator function to confirm that the libtool is Apple's libtool. # The apple-distributed libtool is what we want for bundling, but there is # a GNU libtool that has a name collision (and happens to be bundled with R, too). # We are not compatible with GNU libtool, so we need to avoid it. function(validate_apple_libtool result_var item) - execute_process(COMMAND "${item}" -V - OUTPUT_VARIABLE libtool_version - OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + get_libtool_version("${item}" libtool_version) if("${libtool_version}" MATCHES ".*cctools.+([0-9.]+).*") set(${result_var} TRUE @@ -115,7 +123,8 @@ function(arrow_create_merged_static_lib output_target) # Validate that CMAKE_LIBTOOL is Apple's libtool validate_apple_libtool(is_apple_libtool "${LIBTOOL_MACOS}") if(NOT is_apple_libtool) - message(FATAL_ERROR "CMAKE_LIBTOOL does not appear to be Apple's libtool: ${LIBTOOL_MACOS}" + get_libtool_version("${LIBTOOL_MACOS}" _libtool_version_output) + message(FATAL_ERROR "CMAKE_LIBTOOL does not appear to be Apple's libtool: ${LIBTOOL_MACOS}\nlibtool -V output: ${_libtool_version_output}" ) endif() else() @@ -126,8 +135,14 @@ function(arrow_create_merged_static_lib output_target) HINTS /usr/bin /Library/Developer/CommandLineTools/usr/bin VALIDATOR validate_apple_libtool) if(NOT LIBTOOL_MACOS) + # Find any libtool (without validation) to show its version in the error + find_program(_any_libtool libtool) + if(_any_libtool) + get_libtool_version("${_any_libtool}" _libtool_version_output) + endif() message(FATAL_ERROR "Could not find Apple's libtool. GNU libtool is not compatible." - ) + "\nFound libtool: ${_any_libtool}" + "\nlibtool -V output: ${_libtool_version_output}") endif() endif() From 7f0f2a6a4cdb6b9b361cd15569142caaec30ff36 Mon Sep 17 00:00:00 2001 From: Jonathan Keane Date: Mon, 23 Feb 2026 19:36:49 -0600 Subject: [PATCH 6/6] Update cpp/cmake_modules/BuildUtils.cmake Co-authored-by: Sutou Kouhei --- cpp/cmake_modules/BuildUtils.cmake | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cpp/cmake_modules/BuildUtils.cmake b/cpp/cmake_modules/BuildUtils.cmake index 1ed7fbefad1a..d9e06b1657bc 100644 --- a/cpp/cmake_modules/BuildUtils.cmake +++ b/cpp/cmake_modules/BuildUtils.cmake @@ -107,11 +107,7 @@ function(arrow_create_merged_static_lib output_target) # We are not compatible with GNU libtool, so we need to avoid it. function(validate_apple_libtool result_var item) get_libtool_version("${item}" libtool_version) - if("${libtool_version}" MATCHES ".*cctools.+([0-9.]+).*") - set(${result_var} - TRUE - PARENT_SCOPE) - else() + if(NOT "${libtool_version}" MATCHES ".*cctools.+([0-9.]+).*") set(${result_var} FALSE PARENT_SCOPE)