diff --git a/build/windows/2_bundle-gimp-uni_base.py b/build/windows/2_bundle-gimp-uni_base.py index 4f3148478e..b3bd76a795 100644 --- a/build/windows/2_bundle-gimp-uni_base.py +++ b/build/windows/2_bundle-gimp-uni_base.py @@ -204,7 +204,7 @@ for dir in ["bin", "lib"]: for ext in ("*.dll", "*.exe"): for dep in search_dir.rglob(ext): subprocess.run([ - sys.executable, f"{GIMP_SOURCE}/build/windows/2_bundle-gimp-uni_dep.py", + sys.executable, f"{GIMP_SOURCE}/tools/lib_bundle.py", str(dep), f"{GIMP_PREFIX}/", f"{MSYSTEM_PREFIX}/", str(GIMP_DISTRIB), "--output-dll-list", done_dll.as_posix() ], check=True) diff --git a/build/windows/installer/3_dist-gimp-inno.ps1 b/build/windows/installer/3_dist-gimp-inno.ps1 index 9b4d97d14d..0a46e248ee 100644 --- a/build/windows/installer/3_dist-gimp-inno.ps1 +++ b/build/windows/installer/3_dist-gimp-inno.ps1 @@ -195,7 +195,7 @@ if (Test-Path "$X86_BUNDLE") Write-Output "$([char]27)[0Ksection_start:$(Get-Date -UFormat %s -Millisecond 0):installer_files[collapsed=true]$([char]13)$([char]27)[0KGenerating 32-bit TWAIN dependencies list" $twain_list_file = 'build\windows\installer\base_twain32on64.list' Copy-Item $twain_list_file "$twain_list_file.bak" - $twain_list = (python build\windows\2_bundle-gimp-uni_dep.py --debug debug-only $(Resolve-Path $X86_BUNDLE/lib/gimp/*/plug-ins/twain/twain.exe) $env:MSYS_ROOT/mingw32/ $X86_BUNDLE/ 32 | + $twain_list = (python tools\lib_bundle.py --debug debug-only $(Resolve-Path $X86_BUNDLE/lib/gimp/*/plug-ins/twain/twain.exe) $env:MSYS_ROOT/mingw32/ $X86_BUNDLE/ 32 | Select-String 'Installed' -CaseSensitive -Context 0,1000) -replace " `t- ",'bin\' (Get-Content $twain_list_file) | Foreach-Object {$_ -replace "@DEPS_GENLIST@","$twain_list"} | Set-Content $twain_list_file (Get-Content $twain_list_file) | Select-string 'Installed' -notmatch | Set-Content $twain_list_file diff --git a/build/windows/2_bundle-gimp-uni_dep.py b/tools/lib_bundle.py similarity index 58% rename from build/windows/2_bundle-gimp-uni_dep.py rename to tools/lib_bundle.py index 154cbbb44a..4f5871bb25 100644 --- a/build/windows/2_bundle-gimp-uni_dep.py +++ b/tools/lib_bundle.py @@ -1,17 +1,23 @@ #!/usr/bin/python3 ################################################################################ -# Small python script to retrieve DLL dependencies with objdump +# Small python script to retrieve DLL or DYLIB dependencies with object dumper ################################################################################ ################################################################################ # Usage example # -# python3 2_bundle-gimp-uni_dep.py /path/to/run.exe /winenv/ /path/install +# python3 lib_bundle.py /path/to/run.exe /winenv/ /path/install # # In this case, the DLL dependencies for executable run.exe will be extracted # and copied into /path/install/bin folder. To copy the DLL, the root path to -# Windows environnment should be passed, here /winenv/. +# Windows environnment should be passed, here /winenv/ (usually MSYSTEM_PREFIX). +# +# python3 lib_bundle.py /path/to/run /macOSenv/ /path/install +# +# In this case, the DYLIB dependencies for executable run will be extracted +# and copied into /path/install/Contents/Resources/lib folder. To copy the DYLIB, +# the root path to macOS environnment should be passed, here /macOSenv/ (usually /opt/local). import argparse import os @@ -24,22 +30,26 @@ import struct ################################################################################ # Global variables -# Sets for executable and system DLL +# Sets for executable and system DLL/DYLIB dlls = set() sys_dlls = set() -# Previously done DLLs in previous runs +# Previously done DLLs/DYLIBs in previous runs done_dlls = set() # Common paths bindir = 'bin' +# Platform mode (detected at runtime) +is_macos = False + ################################################################################ # Functions # Main function def main(binary, srcdirs, destdir, debug, dll_file): global done_dlls + global is_macos try: if dll_file is not None: with open(dll_file, 'r') as f: @@ -52,26 +62,26 @@ def main(binary, srcdirs, destdir, debug, dll_file): find_dependencies(os.path.abspath(binary), srcdirs) if debug in ['debug-only', 'debug-run']: if debug == 'debug-only': - print("Running in debug-only mode (no DLL moved) for '{}'".format(binary)) + print("Running in debug-only mode (no DLL/DYLIB moved) for '{}'".format(binary)) else: print("Running with debug output for '{}'".format(binary)) if len(dlls) > 0: - sys.stdout.write("Needed DLLs:\n\t- ") + sys.stdout.write("Needed DLLs/DYLIBs:\n\t- ") sys.stdout.write("\n\t- ".join(list(dlls))) print() if len(sys_dlls) > 0: - sys.stdout.write('System DLLs:\n\t- ') + sys.stdout.write('System DLLs/DYLIBs:\n\t- ') sys.stdout.write("\n\t- ".join(sys_dlls)) print() removed_dlls = sys_dlls & dlls if len(removed_dlls) > 0: - sys.stdout.write('Non installed DLLs:\n\t- ') + sys.stdout.write('Non installed DLLs/DYLIBs:\n\t- ') sys.stdout.write("\n\t- ".join(removed_dlls)) print() installed_dlls = dlls - sys_dlls if len(installed_dlls) > 0: - sys.stdout.write('Installed DLLs:\n\t- ') + sys.stdout.write('Installed DLLs/DYLIBs:\n\t- ') sys.stdout.write("\n\t- ".join(installed_dlls)) print() @@ -86,8 +96,9 @@ def main(binary, srcdirs, destdir, debug, dll_file): def find_dependencies(obj, srcdirs): ''' - List DLLs of an object file in a recursive way. + List DLLs/DYLIBs of an object file in a recursive way. ''' + global is_macos if obj in set.union(done_dlls, sys_dlls): # Already processed, either in a previous run of the script # (done_dlls) or in this one. @@ -95,16 +106,19 @@ def find_dependencies(obj, srcdirs): if not os.path.isabs(obj): for srcdir in srcdirs: + bindir = 'bin' + if is_macos: + bindir = 'lib' abs_dll = os.path.join(srcdir, bindir, obj) abs_dll = os.path.abspath(abs_dll) if find_dependencies(abs_dll, srcdirs): return True else: - # Found in none of the srcdirs: consider it a system DLL + # Found in none of the srcdirs: consider it a system DLL/DYLIB sys_dlls.add(os.path.basename(obj)) return False elif os.path.exists(obj): - # If DLL exists, extract dependencies. + # If DLL/DYLIB exists, extract dependencies. objdump = None try: @@ -113,18 +127,28 @@ def find_dependencies(obj, srcdirs): pe_offset = struct.unpack('