[cmake-developers] Modules/GetPrequisites.cmake issues
Bill Somerville
bill at classdesign.com
Wed Jul 29 12:51:45 EDT 2015
On 29/07/2015 14:37, Brad King wrote:
Hi Brad,
> On 07/28/2015 06:02 PM, Bill Somerville wrote:
>> attached is a patch that addresses some issues recently discussed on the
>> users list.
...
> If you're comfortable enough with Git, please split this part out into
> a preceding patch with its own explanation in its commit message. That
> will clarify which hunks in the patch belong to which change.
...
>
> This can be simplified as:
>
> execute_process(
> COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
> ${gp_cmd_maybe_filter}
> RESULT_VARIABLE gp_rv
> OUTPUT_VARIABLE gp_cmd_ov
> ERROR_VARIABLE gp_ev
> )
>
> where ``gp_cmd_maybe_filter`` is initialized to empty and later
> possibly set as:
>
> if(gp_grep_cmd)
> set(gp_cmd_maybe_filter
> COMMAND ${gp_grep_cmd} "^[[:blank:]]*DLL Name: "
> )
> endif()
Revised patches attached.
>
> Thanks,
> -Brad
>
Regards
Bill Somerville.
-------------- next part --------------
>From 0332d20411f62d865b5a84d8e0f78f68a49d1a0b Mon Sep 17 00:00:00 2001
From: Bill Somerville <bill at classdesign.com>
Date: Wed, 29 Jul 2015 17:05:51 +0100
Subject: [PATCH 1/2] Add error checks for execute_process() calls
Return status checks added to external command invocations so that
they do not fail silently producing incomplete install packages.
---
Modules/GetPrerequisites.cmake | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 23d486e..a359d2c 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -229,9 +229,14 @@ function(is_file_executable file result_var)
if(file_cmd)
execute_process(COMMAND "${file_cmd}" "${file_full}"
+ RESULT_VARIABLE file_rv
OUTPUT_VARIABLE file_ov
+ ERROR_VARIABLE file_ev
OUTPUT_STRIP_TRAILING_WHITESPACE
)
+ if(NOT file_rv STREQUAL "0")
+ message(FATAL_ERROR "${file_cmd} failed: ${file_rv}\n${file_ev}")
+ endif()
# Replace the name of the file in the output with a placeholder token
# (the string " _file_full_ ") so that just in case the path name of
@@ -543,11 +548,21 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
if(CYGPATH_EXECUTABLE)
execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
+ RESULT_VARIABLE env_rv
OUTPUT_VARIABLE env_windir
+ ERROR_VARIABLE env_ev
OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT env_rv STREQUAL "0")
+ message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -W failed: ${env_rv}\n${env_ev}")
+ endif()
execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
+ RESULT_VARIABLE env_rv
OUTPUT_VARIABLE env_sysdir
+ ERROR_VARIABLE env_ev
OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(NOT env_rv STREQUAL "0")
+ message(FATAL_ERROR "${CYGPATH_EXECUTABLE} -S failed: ${env_rv}\n${env_ev}")
+ endif()
string(TOLOWER "${env_windir}" windir)
string(TOLOWER "${env_sysdir}" sysroot)
@@ -765,8 +780,18 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
#
execute_process(
COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+ RESULT_VARIABLE gp_rv
OUTPUT_VARIABLE gp_cmd_ov
+ ERROR_VARIABLE gp_ev
)
+ if(NOT gp_rv STREQUAL "0")
+ if(gp_tool STREQUAL "dumpbin")
+ # dumpbin error messages seem to go to stdout
+ message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}\n${gp_cmd_ov}")
+ else()
+ message(FATAL_ERROR "${gp_cmd} failed: ${gp_rv}\n${gp_ev}")
+ endif()
+ endif()
if(gp_tool STREQUAL "ldd")
set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
@@ -791,8 +816,13 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
if(gp_tool STREQUAL "otool")
execute_process(
COMMAND otool -D ${target}
+ RESULT_VARIABLE otool_rv
OUTPUT_VARIABLE gp_install_id_ov
+ ERROR_VARIABLE otool_ev
)
+ if(NOT otool_rv STREQUAL "0")
+ message(FATAL_ERROR "otool -D failed: ${otool_rv}\n${otool_ev}")
+ endif()
# second line is install name
string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
if(gp_install_id)
--
1.9.5.msysgit.0
-------------- next part --------------
>From 85c1785af125f18581e69b492409339d074ec18e Mon Sep 17 00:00:00 2001
From: Bill Somerville <bill at classdesign.com>
Date: Wed, 29 Jul 2015 17:36:38 +0100
Subject: [PATCH 2/2] Optional filter for dependency walker & use it for
objdump on MinGW
As dumpbin.exe is no longer reliable for gcc libraries on MinGW
because it crashes on many common libraries like libgcc_s and
libgfortran it is now necessary too resort to using objdump for DLL
dependency walking. Using objdump has a secondary problem in that it
generates a lot of output for large libraries and causes
fixup_bundle() to take many minutes to process what took fractions of
a second with dumpbin.exe /dependents.
This patch includes a grep pre-filter in the execute_process() command
pipeline to reduce this output to a minimum for a several orders of
magnitude speed up. If grep isn't available the full output is used.
As there does not seem to be a reliable way of detecting MinGW,
callers of fixup_bundle() may have to set the variable gp_tool to
"objdump" if dumpbin.exe is installed on the build machine to stop it
using the broken MS dumpbin.exe for library dependency walking.
---
Modules/GetPrerequisites.cmake | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index a359d2c..e4018b6 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -700,6 +700,8 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
return()
endif()
+ set(gp_cmd_maybe_filter) # optional command to pre-filter gp_tool results
+
if(gp_tool STREQUAL "ldd")
set(gp_cmd_args "")
set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
@@ -724,6 +726,11 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
set(gp_regex_error "")
set(gp_regex_fallback "")
set(gp_regex_cmp_count 1)
+ # objdump generaates copious output so we create a grep filter to pre-filter results
+ find_program(gp_grep_cmd grep)
+ if(gp_grep_cmd)
+ set(gp_cmd_maybe_filter COMMAND ${gp_grep_cmd} "^[[:blank:]]*DLL Name: ")
+ endif()
else()
message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
@@ -780,6 +787,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
#
execute_process(
COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+ ${gp_cmd_maybe_filter}
RESULT_VARIABLE gp_rv
OUTPUT_VARIABLE gp_cmd_ov
ERROR_VARIABLE gp_ev
--
1.9.5.msysgit.0
More information about the cmake-developers
mailing list