[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