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.
From 203848c099026c23b5f70d395d0469887f099d23 Mon Sep 17 00:00:00 2001
From: Bill Somerville <[email protected]>
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

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to