aboutsummaryrefslogtreecommitdiffstats
path: root/admin
diff options
context:
space:
mode:
authorCorwin Brust2024-12-24 23:55:21 -0600
committerCorwin Brust2024-12-24 23:55:21 -0600
commit8b95549e9087fc54be3d849470652d38ec64cbff (patch)
tree1ff104158520a3b7f0e231fb132165c5b295a2ce /admin
parent8064b2a67988e815c52e289fe2a235ce1008776f (diff)
downloademacs-8b95549e9087fc54be3d849470652d38ec64cbff.tar.gz
emacs-8b95549e9087fc54be3d849470652d38ec64cbff.zip
* admin/nt/dist-build/build-dep-zips.py: (deps src) handle zst
This patch fixes various problems preventing this script from working. The job of this script is to collect Emacs' dependanicies and the (MSYS2/MinGW64) source archives for dependancies (including 2nd etc. order dependancies) into zip archives. GPL requires distributing such archives (along with Emacs' own sources) when distributing GPL binaries. Most principle of the changes is support for MSYS2 "w64" source archives in zst format; previously this script assumed all sources were available as tar.gz files. Additionaly several DLLs are added to list of required, including sqllite3 and tree-sitter. In general this is a maintaince fix to ensure others have access to the code used to create pretest (and, presumably release) version of Emacs 30. Additional changes are required to progmatically identify changes in Emacs' dependancies (e.g. after building a new Emacs binary for distribution). There is commented out code to this effect in the changes I've installed which did work, for a brief period in time; I suspect some changes in MSYS2 made it more difficult (or impossible?) to invoke the MSYS2 shell (under which this python script must run) from the MINGW64 (under which Emacs is built). I may resort to a powershell script as a way to orchistrate/invoke both MSYS2 and MING64 but I'm currently still messing with a Makefile based approach (which would run under MINGW64), in any event I believe we're all agreed this script must interigate Emacs to create the "starting list" of dependancies to include as a way to resolve this issue (missing/incorrect deps are frequent source of broken binary releases). (bug#65206)
Diffstat (limited to 'admin')
-rwxr-xr-xadmin/nt/dist-build/build-dep-zips.py280
1 files changed, 213 insertions, 67 deletions
diff --git a/admin/nt/dist-build/build-dep-zips.py b/admin/nt/dist-build/build-dep-zips.py
index 0b1cc4d8695..c145cd3fc00 100755
--- a/admin/nt/dist-build/build-dep-zips.py
+++ b/admin/nt/dist-build/build-dep-zips.py
@@ -1,6 +1,6 @@
1#!/usr/bin/python3 1#!/usr/bin/python3
2 2
3## Copyright (C) 2017-2024 Free Software Foundation, Inc. 3## Copyright (C) 2017-2023 Free Software Foundation, Inc.
4 4
5## This file is part of GNU Emacs. 5## This file is part of GNU Emacs.
6 6
@@ -20,41 +20,56 @@ import argparse
20import os 20import os
21import shutil 21import shutil
22import re 22import re
23import functools 23import subprocess
24import operator
25 24
26from subprocess import check_output 25from subprocess import check_output
27 26
28## Constants 27## Constants
29EMACS_MAJOR_VERSION="28" 28EMACS_MAJOR_VERSION= os.getenv('EMACS_MAJOR_VERSION') or "30"
30 29
31# This list derives from the features we want Emacs to compile with. 30# Base URI for the package sources mapped in PKG_REQ
31SRC_REPO="https://repo.msys2.org/mingw/sources"
32
33# Map items in `dynamic-library-alist' to source pakages
32PKG_REQ='''mingw-w64-x86_64-giflib 34PKG_REQ='''mingw-w64-x86_64-giflib
33mingw-w64-x86_64-gnutls 35mingw-w64-x86_64-gnutls
34mingw-w64-x86_64-harfbuzz 36mingw-w64-x86_64-harfbuzz
37mingw-w64-x86_64-jansson
35mingw-w64-x86_64-lcms2 38mingw-w64-x86_64-lcms2
36mingw-w64-x86_64-libjpeg-turbo 39mingw-w64-x86_64-libjpeg-turbo
37mingw-w64-x86_64-libpng 40mingw-w64-x86_64-libpng
38mingw-w64-x86_64-librsvg 41mingw-w64-x86_64-librsvg
42mingw-w64-x86_64-libwebp
39mingw-w64-x86_64-libtiff 43mingw-w64-x86_64-libtiff
40mingw-w64-x86_64-libxml2 44mingw-w64-x86_64-libxml2
41mingw-w64-x86_64-xpm-nox'''.split() 45mingw-w64-x86_64-gmp
42 46mingw-w64-x86_64-xpm-nox
43DLL_REQ='''libgif 47mingw-w64-x86_64-tree-sitter
44libgnutls 48mingw-w64-x86_64-sqlite3'''.split()
45libharfbuzz 49
46liblcms2 50# Emacs style path to dependancy DLLs on build system
47libturbojpeg 51DLL_SRC="c:/msys64/mingw64/bin"
48libpng 52
49librsvg 53# libraries we never include
50libtiff 54DLL_SKIP=["libgccjit-0.dll"]
51libxml 55
52libXpm'''.split() 56# Report first existing file for entries in dynamic-library-alist
53 57# ELISP_PROG="""
58# (message "%s" (mapconcat 'identity (remove nil
59# (mapcar (lambda(lib)
60# (seq-find
61# (lambda(file)
62# (file-exists-p
63# (file-name-concat "{}"
64# file)))
65# (cdr lib)))
66# dynamic-library-alist)
67# ) "\\n"))
68# """.format(DLL_SRC)
54 69
55## Options 70## Options
56DRY_RUN=False 71DRY_RUN=False
57 72# NEW_EMACS="bin/emacs.exe"
58 73
59def check_output_maybe(*args,**kwargs): 74def check_output_maybe(*args,**kwargs):
60 if(DRY_RUN): 75 if(DRY_RUN):
@@ -62,31 +77,76 @@ def check_output_maybe(*args,**kwargs):
62 else: 77 else:
63 return check_output(*args,**kwargs) 78 return check_output(*args,**kwargs)
64 79
80####################
65## DLL Capture 81## DLL Capture
82
83# entry point
66def gather_deps(): 84def gather_deps():
67 85
68 os.mkdir("x86_64") 86 os.mkdir("x86_64")
69 os.chdir("x86_64") 87 os.chdir("x86_64")
70 88
71 for dep in full_dll_dependency(): 89 #full=full_dll_dependency(init_deps())
72 check_output_maybe(["cp /mingw64/bin/{}*.dll .".format(dep)], 90 #filtered=filter(lambda x: x not in DLL_SKIP, full)
73 shell=True) 91 #print("full:",full.len(), " filtered:",filtered.len())
74 92 #exit
75 print("Zipping") 93
76 check_output_maybe("zip -9r ../emacs-{}-{}deps.zip *" 94 for dep in full_dll_dependency(init_deps()):
77 .format(EMACS_MAJOR_VERSION, DATE), 95 if dep not in DLL_SKIP:
78 shell=True) 96 if args.l != True:
97 print("Adding dep", dep)
98 check_output_maybe(["cp /mingw64/bin/{} .".format(dep)], shell=True)
99 else:
100 if args.l != True:
101 print("Skipping dep", dep)
102
103 zipfile="../emacs-{}-{}deps.zip".format(EMACS_MAJOR_VERSION, DATE)
104 tmpfile="{}.tmp".format(zipfile)
105 print("Zipping deps in", os.getcwd(), "as", tmpfile)
106 check_output_maybe("zip -9vr {} *.dll".format(tmpfile), shell=True)
107 if os.path.isfile(zipfile):
108 os.remove(zipfile)
109 os.rename(tmpfile, zipfile)
110 print("Deps updated in", os.getcwd(), "as", zipfile)
79 os.chdir("../") 111 os.chdir("../")
80 112
81## Return all Emacs dependencies 113# Return dependancies listed in Emacs
82def full_dll_dependency(): 114def init_deps():
83 deps = [dll_dependency(dep) for dep in DLL_REQ] 115 return '''libXpm-nox4.dll
84 return set(sum(deps, []) + DLL_REQ) 116libpng16-16.dll
85 117libjpeg-8.dll
86## Dependencies for a given DLL 118libgif-7.dll
119librsvg-2-2.dll
120libwebp-7.dll
121libwebpdemux-2.dll
122libsqlite3-0.dll
123libgdk_pixbuf-2.0-0.dll
124libglib-2.0-0.dll
125libgio-2.0-0.dll
126libgobject-2.0-0.dll
127libgnutls-30.dll
128libxml2-2.dll
129zlib1.dll
130liblcms2-2.dll
131libgccjit-0.dll
132libtree-sitter.dll'''.split()
133 # job_args=[NEW_EMACS, "--batch", "--eval", ELISP_PROG]
134 # #print("args: ", job_args)
135 # return subprocess.check_output(job_args, stderr=subprocess.STDOUT
136 # ).decode('utf-8').splitlines()
137
138# Return all second order dependencies
139def full_dll_dependency(dlls):
140 deps = [dll_dependency(dep) for dep in dlls]
141 return set(sum(deps, []) + dlls)
142
143#xs = filter(lambda x: x.attribute == value, xs)
144
145# Dependencies for a given DLL
87def dll_dependency(dll): 146def dll_dependency(dll):
88 output = check_output(["/mingw64/bin/ntldd", "--recursive", 147 output = check_output(["/mingw64/bin/ntldd", "--recursive",
89 "/mingw64/bin/{}*.dll".format(dll)]).decode("utf-8") 148 "/mingw64/bin/{}".format(dll)]
149 ).decode("utf-8")
90 ## munge output 150 ## munge output
91 return ntldd_munge(output) 151 return ntldd_munge(output)
92 152
@@ -101,9 +161,8 @@ def ntldd_munge(out):
101 161
102 ## if it's the former, we want it, if its the later we don't 162 ## if it's the former, we want it, if its the later we don't
103 splt = dep.split() 163 splt = dep.split()
104 if len(splt) > 2 and "msys64" in splt[2]: 164 if len(splt) > 2 and "mingw64" in splt[2]:
105 print("Adding dep", splt[0]) 165 rtn.append(splt[0])
106 rtn.append(splt[0].split(".")[0])
107 166
108 return rtn 167 return rtn
109 168
@@ -112,26 +171,92 @@ def ntldd_munge(out):
112## Packages to fiddle with 171## Packages to fiddle with
113## Source for gcc-libs is part of gcc 172## Source for gcc-libs is part of gcc
114SKIP_SRC_PKGS=["mingw-w64-gcc-libs"] 173SKIP_SRC_PKGS=["mingw-w64-gcc-libs"]
115SKIP_DEP_PKGS=frozenset(["mingw-w64-x86_64-glib2"]) 174SKIP_DEP_PKGS=["mingw-w64-glib2", "mingw-w64-ca-certificates-20211016-3"]
116MUNGE_SRC_PKGS={"mingw-w64-libwinpthread-git":"mingw-w64-winpthreads-git"} 175MUNGE_SRC_PKGS={
176 "mingw-w64-libwinpthread-git":"mingw-w64-winpthreads-git",
177 "mingw-w64-gettext-runtime":"mingw-w64-gettext"
178}
117MUNGE_DEP_PKGS={ 179MUNGE_DEP_PKGS={
118 "mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git", 180 "mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git",
119 "mingw-w64-x86_64-libtre": "mingw-w64-x86_64-libtre-git", 181 "mingw-w64-x86_64-libtre": "mingw-w64-x86_64-libtre-git",
120} 182}
183SRC_EXT={
184 "mingw-w64-freetype": ".src.tar.zst",
185 "mingw-w64-fribidi": ".src.tar.zst",
186 "mingw-w64-glib2": ".src.tar.zst",
187 "mingw-w64-harfbuzz": ".src.tar.zst",
188 "mingw-w64-libunistring": ".src.tar.zst",
189 "mingw-w64-winpthreads-git": ".src.tar.zst",
190 "mingw-w64-ca-certificates": ".src.tar.zst",
191 "mingw-w64-libxml2": ".src.tar.zst",
192 "mingw-w64-ncurses": ".src.tar.zst",
193 "mingw-w64-openssl": ".src.tar.zst",
194 "mingw-w64-pango": ".src.tar.zst",
195 "mingw-w64-python": ".src.tar.zst",
196 "mingw-w64-sqlite3": ".src.tar.zst",
197 "mingw-w64-xpm-nox": ".src.tar.zst",
198 "mingw-w64-xz": ".src.tar.zst",
199 "mingw-w64-bzip2": ".src.tar.zst",
200 "mingw-w64-cairo": ".src.tar.zst",
201 "mingw-w64-expat": ".src.tar.zst",
202 "mingw-w64-fontconfig": ".src.tar.zst",
203 "mingw-w64-gdk-pixbuf2": ".src.tar.zst",
204 "mingw-w64-giflib": ".src.tar.zst",
205 "mingw-w64-gmp": ".src.tar.zst",
206 "mingw-w64-gnutls": ".src.tar.zst",
207 "mingw-w64-graphite2": ".src.tar.zst",
208 "mingw-w64-jbigkit": ".src.tar.zst",
209 "mingw-w64-lcms2": ".src.tar.zst",
210 "mingw-w64-lerc": ".src.tar.zst",
211 "mingw-w64-libdatrie": ".src.tar.zst",
212 "mingw-w64-libffi": ".src.tar.zst",
213 "mingw-w64-libiconv": ".src.tar.zst",
214 "mingw-w64-libiconv": ".src.tar.zst",
215 "mingw-w64-libpng": ".src.tar.zst",
216 "mingw-w64-librsvg": ".src.tar.zst",
217 "mingw-w64-libsystre": ".src.tar.zst",
218 "mingw-w64-libtasn": ".src.tar.zst",
219 "mingw-w64-libthai": ".src.tar.zst",
220 "mingw-w64-libtiff": ".src.tar.zst",
221 "mingw-w64-libtre-git": ".src.tar.zst",
222 "mingw-w64-libwebp": ".src.tar.zst",
223 "mingw-w64-mpdecimal": ".src.tar.zst",
224 "mingw-w64-nettle": ".src.tar.zst",
225 "mingw-w64-p11-kit": ".src.tar.zst",
226 "mingw-w64-pcre": ".src.tar.zst",
227 "mingw-w64-pixman": ".src.tar.zst",
228 "mingw-w64-python-packaging": ".src.tar.zst",
229 "mingw-w64-readline": ".src.tar.zst",
230 "mingw-w64-tcl": ".src.tar.zst",
231 "mingw-w64-termcap": ".src.tar.zst",
232 "mingw-w64-tk": ".src.tar.zst",
233 "mingw-w64-tree-sitter": ".src.tar.zst",
234 "mingw-w64-tzdata": ".src.tar.zst",
235 "mingw-w64-wineditline": ".src.tar.zst",
236 "mingw-w64-zlib": ".src.tar.zst",
237 "mingw-w64-zstd": ".src.tar.zst",
238 "mingw-w64-brotli": ".src.tar.zst",
239 "mingw-w64-gettext": ".src.tar.zst",
240 "mingw-w64-libdeflate": ".src.tar.zst",
241 "mingw-w64-libidn2": ".src.tar.zst",
242 "mingw-w64-libjpeg-turbo": ".src.tar.zst",
243 "mingw-w64-libtasn1": ".src.tar.zst",
244 "mingw-w64-pcre2": ".src.tar.zst",
245}
121 246
122## Currently no packages seem to require this! 247## Currently no packages seem to require this!
123ARCH_PKGS=[] 248ARCH_PKGS=[]
124SRC_REPO="https://repo.msys2.org/mingw/sources"
125 249
250def immediate_deps(pkg):
251 package_info = check_output(["pacman", "-Si", pkg]).decode("utf-8").split("\n")
126 252
127def immediate_deps(pkgs): 253 ## Extract the "Depends On" line
128 package_info = check_output(["pacman", "-Si"] + pkgs).decode("utf-8").splitlines() 254 depends_on = [x for x in package_info if x.startswith("Depends On")][0]
255 ## Remove "Depends On" prefix
256 dependencies = depends_on.split(":")[1]
129 257
130 ## Extract the packages listed for "Depends On:" lines. 258 ## Split into dependencies
131 dependencies = [line.split(":")[1].split() for line in package_info 259 dependencies = dependencies.strip().split(" ")
132 if line.startswith("Depends On")]
133 ## Flatten dependency lists from multiple packages into one list.
134 dependencies = functools.reduce(operator.iconcat, dependencies, [])
135 260
136 ## Remove > signs TODO can we get any other punctuation here? 261 ## Remove > signs TODO can we get any other punctuation here?
137 dependencies = [d.split(">")[0] for d in dependencies if d] 262 dependencies = [d.split(">")[0] for d in dependencies if d]
@@ -147,18 +272,16 @@ def extract_deps():
147 print( "Extracting deps" ) 272 print( "Extracting deps" )
148 273
149 # Get a list of all dependencies needed for packages mentioned above. 274 # Get a list of all dependencies needed for packages mentioned above.
150 pkgs = set(PKG_REQ) 275 pkgs = PKG_REQ[:]
151 newdeps = pkgs 276 n = 0
152 print("adding...") 277 while n < len(pkgs):
153 while True: 278 subdeps = immediate_deps(pkgs[n])
154 subdeps = frozenset(immediate_deps(list(newdeps))) 279 for p in subdeps:
155 newdeps = subdeps - SKIP_DEP_PKGS - pkgs 280 if not (p in pkgs or p in SKIP_DEP_PKGS):
156 if not newdeps: 281 pkgs.append(p)
157 break 282 n = n + 1
158 print('\n'.join(newdeps))
159 pkgs |= newdeps
160 283
161 return list(pkgs) 284 return sorted(pkgs)
162 285
163 286
164def download_source(tarball): 287def download_source(tarball):
@@ -206,14 +329,24 @@ def gather_source(deps):
206 ## Switch names if necessary 329 ## Switch names if necessary
207 pkg_name = MUNGE_SRC_PKGS.get(pkg_name,pkg_name) 330 pkg_name = MUNGE_SRC_PKGS.get(pkg_name,pkg_name)
208 331
209 tarball = "{}-{}.src.tar.gz".format(pkg_name,pkg_version) 332 ## src archive is usually a .tar.gz
333 if pkg_name in SRC_EXT.keys():
334 src_ext = SRC_EXT[pkg_name]
335 else:
336 src_ext = ".src.tar.gz"
337
338 tarball = "{}-{}{}".format(pkg_name,pkg_version,src_ext)
210 339
211 download_source(tarball) 340 download_source(tarball)
212 341
213 print("Zipping") 342 srczip="../emacs-{}-{}deps-mingw-w64-src.zip".format(EMACS_MAJOR_VERSION,DATE)
214 check_output_maybe("zip -9 ../emacs-{}-{}deps-mingw-w64-src.zip *" 343 tmpzip="{}.tmp".format(srczip)
215 .format(EMACS_MAJOR_VERSION,DATE), 344 print("Zipping Dsrc in", os.getcwd(), "as", tmpzip)
216 shell=True) 345 check_output_maybe("zip -9 {} *".format(tmpzip), shell=True)
346 if os.path.isfile(srczip):
347 os.remove(srczip)
348 os.rename(tmpzip, srczip)
349 print("Dsrc updated in", os.getcwd(), "as", srczip)
217 350
218 os.chdir("..") 351 os.chdir("..")
219 352
@@ -231,6 +364,9 @@ if(os.environ["MSYSTEM"] != "MSYS"):
231 364
232 365
233parser = argparse.ArgumentParser() 366parser = argparse.ArgumentParser()
367
368#parser.add_argument("emacs", help="emacs executable")
369
234parser.add_argument("-s", help="snapshot build", 370parser.add_argument("-s", help="snapshot build",
235 action="store_true") 371 action="store_true")
236 372
@@ -243,19 +379,29 @@ parser.add_argument("-c", help="clean only",
243parser.add_argument("-d", help="dry run", 379parser.add_argument("-d", help="dry run",
244 action="store_true") 380 action="store_true")
245 381
246parser.add_argument("-l", help="list dependencies only", 382parser.add_argument("-l", help="list dependencies",
383 action="store_true")
384
385parser.add_argument("-e", help="extract direct dependancies",
247 action="store_true") 386 action="store_true")
248 387
249args = parser.parse_args() 388args = parser.parse_args()
250do_all=not (args.c or args.r) 389do_all=not (args.c or args.r)
251 390
252 391#NEW_EMACS=args.emacs
253 392
254DRY_RUN=args.d 393DRY_RUN=args.d
255 394
395if( args.e ):
396 print("\n".join(init_deps()))
397
256if( args.l ): 398if( args.l ):
257 print("List of dependencies") 399 print("List of dependencies:")
258 print( deps ) 400 print(full_dll_dependency(init_deps()))
401 print("List of source packages:")
402 print( extract_deps() )
403
404if( args.e or args.l ):
259 exit(0) 405 exit(0)
260 406
261if args.s: 407if args.s: