[cmake-developers] Modules/GetPrequisites.cmake issues

Bill Somerville bill at classdesign.com
Tue Jul 28 18:02:07 EDT 2015


Hi All,

attached is a patch that addresses some issues recently discussed on the 
users list.

I'm no CMake expert so I don't know if I have done things in the best 
way. One area I do not fully understand is how to detect MinGW, If I 
could then objdump could be chosen as the preferred library dependency 
walker over MS dumpbin.exe. See the patch description for details.

Regards
Bill Somerville.
-------------- next part --------------
From 203848c099026c23b5f70d395d0469887f099d23 Mon Sep 17 00:00:00 2001
From: Bill Somerville <bill at classdesign.com>
Date: Tue, 28 Jul 2015 22:40:36 +0100
Subject: [PATCH] For MinGW pre-filter objdump output for performance

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 doesn't 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
dumpbin.exe for library dependency walking.

This  patch  also   adds  command  status  checking   to  the  various
execute_process() invocations  in GetPrerequisites.cmake so  that they
don't fail silently producing invalid install packages.
---
 Modules/GetPrerequisites.cmake | 53 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 4 deletions(-)

diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index 23d486e..bbc1232 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)
 
@@ -709,6 +724,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_filter "^[[: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}'")
@@ -763,10 +783,30 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
 
   # Run gp_cmd on the target:
   #
-  execute_process(
-    COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
-    OUTPUT_VARIABLE gp_cmd_ov
-    )
+  if(gp_cmd_filter)             # filter is for performance
+    execute_process(
+      COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+      COMMAND ${gp_grep_cmd} ${gp_cmd_filter}
+      RESULT_VARIABLE gp_rv
+      OUTPUT_VARIABLE gp_cmd_ov
+      ERROR_VARIABLE gp_ev
+      )
+  else()
+    execute_process(
+      COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+      RESULT_VARIABLE gp_rv
+      OUTPUT_VARIABLE gp_cmd_ov
+      ERROR_VARIABLE gp_ev
+      )
+  endif()
+  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 +831,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



More information about the cmake-developers mailing list