From c9f31b5db3cb133daa5ee416e692eafb954b075c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roman=20W=C3=BCger?= <roman.wueger@gmx.at>
Date: Tue, 19 Apr 2016 07:59:06 +0200
Subject: [PATCH] BundleUtilities: Add optional parameter to ignore specified
 files

---
 Modules/BundleUtilities.cmake | 152 ++++++++++++++++++++++++++++++++----------
 1 file changed, 115 insertions(+), 37 deletions(-)

diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 4b52afa..cfb6450 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -52,6 +52,9 @@
 # Then clear all the keys and call verify_app on the final bundle to
 # ensure that it is truly standalone.
 #
+# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+#
 # ::
 #
 #   COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
@@ -67,6 +70,9 @@
 # analysis tools on it.  Calls "message(FATAL_ERROR" if the application
 # is not verified.
 #
+# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+#
 # ::
 #
 #   GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
@@ -140,6 +146,9 @@
 # all of them and copy prerequisite libs into the bundle and then do
 # appropriate install_name_tool fixups.
 #
+# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+#
 # ::
 #
 #   COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
@@ -196,6 +205,9 @@
 # bundle are contained within the bundle or are "system" libraries,
 # presumed to exist everywhere.
 #
+# As an optional parameter (IGNORE_ITEM) a list of file names can be passed,
+# which are then ignored (e.g. IGNORE_ITEM "vcredist_x86.exe;vcredist_x64.exe")
+#
 # ::
 #
 #   VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
@@ -525,6 +537,11 @@ endfunction()
 function(get_bundle_keys app libs dirs keys_var)
   set(${keys_var} PARENT_SCOPE)
 
+  set(options)
+  set(oneValueArgs)
+  set(multiValueArgs IGNORE_ITEM)
+  cmake_parse_arguments(CFG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
   get_bundle_and_executable("${app}" bundle executable valid)
   if(valid)
     # Always use the exepath of the main bundle executable for @executable_path
@@ -554,10 +571,24 @@ function(get_bundle_keys app libs dirs keys_var)
       set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
 
       set(prereqs "")
-      get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}" "${main_rpaths}")
-      foreach(pr ${prereqs})
-        set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1 "${main_rpaths}")
-      endforeach()
+      set(ignoreFile FALSE)
+      get_filename_component(prereq_filename ${lib} NAME)
+      if(NOT "${CFG_IGNORE_ITEM}" STREQUAL "" )
+        foreach(item ${CFG_IGNORE_ITEM})
+            if("${item}" STREQUAL "${prereq_filename}")
+              set(ignoreFile TRUE)
+            endif()
+        endforeach()
+      endif()
+
+      if(NOT ignoreFile)
+        get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}" "${main_rpaths}")
+        foreach(pr ${prereqs})
+          set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1 "${main_rpaths}")
+        endforeach()
+      else()
+        message(STATUS "Ignoring file: ${prereq_filename}")
+      endif()
     endforeach()
 
     # For each executable found in the bundle, accumulate keys as we go.
@@ -583,10 +614,24 @@ function(get_bundle_keys app libs dirs keys_var)
       # Add each prerequisite to the keys:
       #
       set(prereqs "")
-      get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}" "${exe_rpaths}")
-      foreach(pr ${prereqs})
-        set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1 "${exe_rpaths}")
-      endforeach()
+      set(ignoreFile FALSE)
+      get_filename_component(prereq_filename ${exe} NAME)
+      if(NOT "${CFG_IGNORE_ITEM}" STREQUAL "" )
+        foreach(item ${CFG_IGNORE_ITEM})
+            if("${item}" STREQUAL "${prereq_filename}")
+              set(ignoreFile TRUE)
+            endif()
+        endforeach()
+      endif()
+
+      if(NOT ignoreFile)
+        get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}" "${exe_rpaths}")
+        foreach(pr ${prereqs})
+          set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1 "${exe_rpaths}")
+        endforeach()
+      else()
+        message(STATUS "Ignoring file: ${prereq_filename}")
+      endif()
     endforeach()
 
     # Propagate values to caller's scope:
@@ -798,12 +843,19 @@ function(fixup_bundle app libs dirs)
   message(STATUS "  libs='${libs}'")
   message(STATUS "  dirs='${dirs}'")
 
+  set(options)
+  set(oneValueArgs)
+  set(multiValueArgs IGNORE_ITEM)
+  cmake_parse_arguments(CFG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
+  message(STATUS "  ignoreItems='${CFG_IGNORE_ITEM}'")
+
   get_bundle_and_executable("${app}" bundle executable valid)
   if(valid)
     get_filename_component(exepath "${executable}" PATH)
 
     message(STATUS "fixup_bundle: preparing...")
-    get_bundle_keys("${app}" "${libs}" "${dirs}" keys)
+    get_bundle_keys("${app}" "${libs}" "${dirs}" keys IGNORE_ITEM "${CFG_IGNORE_ITEM}")
 
     message(STATUS "fixup_bundle: copying...")
     list(LENGTH keys n)
@@ -857,7 +909,7 @@ function(fixup_bundle app libs dirs)
     clear_bundle_keys(keys)
 
     message(STATUS "fixup_bundle: verifying...")
-    verify_app("${app}")
+    verify_app("${app}" IGNORE_ITEM "${CFG_IGNORE_ITEM}")
   else()
     message(SEND_ERROR "error: fixup_bundle: not a valid bundle")
   endif()
@@ -877,6 +929,11 @@ function(verify_bundle_prerequisites bundle result_var info_var)
   set(info "")
   set(count 0)
 
+  set(options)
+  set(oneValueArgs)
+  set(multiValueArgs IGNORE_ITEM)
+  cmake_parse_arguments(CFG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
   get_bundle_main_executable("${bundle}" main_bundle_exe)
 
   get_bundle_all_executables("${bundle}" file_list)
@@ -887,37 +944,53 @@ function(verify_bundle_prerequisites bundle result_var info_var)
       message(STATUS "executable file ${count}: ${f}")
 
       set(prereqs "")
-      get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
+      set(ignoreFile FALSE)
+      get_filename_component(prereq_filename ${f} NAME)
+
+      if(NOT "${CFG_IGNORE_ITEM}" STREQUAL "" )
+        foreach(item ${CFG_IGNORE_ITEM})
+            if("${item}" STREQUAL "${prereq_filename}")
+              set(ignoreFile TRUE)
+            endif()
+        endforeach()
+      endif()
 
-      # On the Mac,
-      # "embedded" and "system" prerequisites are fine... anything else means
-      # the bundle's prerequisites are not verified (i.e., the bundle is not
-      # really "standalone")
-      #
-      # On Windows (and others? Linux/Unix/...?)
-      # "local" and "system" prereqs are fine...
-      #
-      set(external_prereqs "")
+      if(NOT ignoreFile)
+        get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
 
-      foreach(p ${prereqs})
-        set(p_type "")
-        gp_file_type("${f}" "${p}" p_type)
+        # On the Mac,
+        # "embedded" and "system" prerequisites are fine... anything else means
+        # the bundle's prerequisites are not verified (i.e., the bundle is not
+        # really "standalone")
+        #
+        # On Windows (and others? Linux/Unix/...?)
+        # "local" and "system" prereqs are fine...
+        #
 
-        if(APPLE)
-          if(NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
-            set(external_prereqs ${external_prereqs} "${p}")
-          endif()
-        else()
-          if(NOT "${p_type}" STREQUAL "local" AND NOT "${p_type}" STREQUAL "system")
-            set(external_prereqs ${external_prereqs} "${p}")
+        set(external_prereqs "")
+
+        foreach(p ${prereqs})
+          set(p_type "")
+          gp_file_type("${f}" "${p}" p_type)
+
+          if(APPLE)
+            if(NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
+              set(external_prereqs ${external_prereqs} "${p}")
+            endif()
+          else()
+            if(NOT "${p_type}" STREQUAL "local" AND NOT "${p_type}" STREQUAL "system")
+              set(external_prereqs ${external_prereqs} "${p}")
+            endif()
           endif()
-        endif()
-      endforeach()
+        endforeach()
 
-      if(external_prereqs)
-        # Found non-system/somehow-unacceptable prerequisites:
-        set(result 0)
-        set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
+        if(external_prereqs)
+          # Found non-system/somehow-unacceptable prerequisites:
+          set(result 0)
+          set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
+        endif()
+      else()
+        message(STATUS "Ignoring file: ${prereq_filename}")
       endif()
   endforeach()
 
@@ -947,6 +1020,11 @@ function(verify_app app)
   set(verified 0)
   set(info "")
 
+  set(options)
+  set(oneValueArgs)
+  set(multiValueArgs IGNORE_ITEM)
+  cmake_parse_arguments(CFG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
+
   get_bundle_and_executable("${app}" bundle executable valid)
 
   message(STATUS "===========================================================================")
@@ -957,7 +1035,7 @@ function(verify_app app)
 
   # Verify that the bundle does not have any "external" prerequisites:
   #
-  verify_bundle_prerequisites("${bundle}" verified info)
+  verify_bundle_prerequisites("${bundle}" verified info IGNORE_ITEM "${CFG_IGNORE_ITEM}")
   message(STATUS "verified='${verified}'")
   message(STATUS "info='${info}'")
   message(STATUS "")
-- 
2.7.4.windows.1

