Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a0abb44

Browse files
committed
Issue #15037: Build OS X installers with local copy of ncurses 5.9 libraries
to avoid curses.unget_wch bug present in older versions of ncurses such as those shipped with OS X.
1 parent dfca8c9 commit a0abb44

3 files changed

Lines changed: 93 additions & 105 deletions

File tree

Mac/BuildScript/build-installer.py

Lines changed: 89 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,43 @@ def library_recipes():
198198
configure_pre=[
199199
'--disable-dependency-tracking',
200200
]
201-
)
201+
),
202+
dict(
203+
name="NCurses 5.9",
204+
url="http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz",
205+
checksum='8cb9c412e5f2d96bc6f459aa8c6282a1',
206+
configure_pre=[
207+
"--enable-widec",
208+
"--without-cxx",
209+
"--without-cxx-binding",
210+
"--without-ada",
211+
"--without-curses-h",
212+
"--enable-shared",
213+
"--with-shared",
214+
"--without-debug",
215+
"--without-normal",
216+
"--without-termlib",
217+
"--without-ticlib",
218+
"--without-tests",
219+
"--without-manpages",
220+
"--datadir=/usr/share",
221+
"--sysconfdir=/etc",
222+
"--sharedstatedir=/usr/com",
223+
"--with-terminfo-dirs=/usr/share/terminfo",
224+
"--with-default-terminfo-dir=/usr/share/terminfo",
225+
"--libdir=/Library/Frameworks/Python.framework/Versions/%s/lib"%(getVersion(),),
226+
],
227+
patchscripts=[
228+
("ftp://invisible-island.net/ncurses//5.9/ncurses-5.9-20120616-patch.sh.bz2",
229+
"f54bf02a349f96a7c4f0d00922f3a0d4"),
230+
],
231+
useLDFlags=False,
232+
install='make && make install DESTDIR=%s && cd %s/usr/local/lib && ln -fs ../../../Library/Frameworks/Python.framework/Versions/%s/lib/lib* .'%(
233+
shellQuote(os.path.join(WORKDIR, 'libraries')),
234+
shellQuote(os.path.join(WORKDIR, 'libraries')),
235+
getVersion(),
236+
),
237+
),
202238
])
203239

204240
if DEPTARGET < '10.5':
@@ -236,8 +272,10 @@ def library_recipes():
236272
patches=[
237273
# The readline maintainers don't do actual micro releases, but
238274
# just ship a set of patches.
239-
'http://ftp.gnu.org/pub/gnu/readline/readline-6.1-patches/readline61-001',
240-
'http://ftp.gnu.org/pub/gnu/readline/readline-6.1-patches/readline61-002',
275+
('http://ftp.gnu.org/pub/gnu/readline/readline-6.1-patches/readline61-001',
276+
'c642f2e84d820884b0bf9fd176bc6c3f'),
277+
('http://ftp.gnu.org/pub/gnu/readline/readline-6.1-patches/readline61-002',
278+
'1a76781a1ea734e831588285db7ec9b1'),
241279
]
242280
),
243281
dict(
@@ -258,36 +296,6 @@ def library_recipes():
258296
'--disable-dependency-tracking',
259297
]
260298
),
261-
dict(
262-
name="NCurses 5.5",
263-
url="http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.5.tar.gz",
264-
checksum='e73c1ac10b4bfc46db43b2ddfd6244ef',
265-
configure_pre=[
266-
"--enable-widec",
267-
"--without-cxx",
268-
"--without-ada",
269-
"--without-progs",
270-
"--without-curses-h",
271-
"--enable-shared",
272-
"--with-shared",
273-
"--datadir=/usr/share",
274-
"--sysconfdir=/etc",
275-
"--sharedstatedir=/usr/com",
276-
"--with-terminfo-dirs=/usr/share/terminfo",
277-
"--with-default-terminfo-dir=/usr/share/terminfo",
278-
"--libdir=/Library/Frameworks/Python.framework/Versions/%s/lib"%(getVersion(),),
279-
"--enable-termcap",
280-
],
281-
patches=[
282-
"ncurses-5.5.patch",
283-
],
284-
useLDFlags=False,
285-
install='make && make install DESTDIR=%s && cd %s/usr/local/lib && ln -fs ../../../Library/Frameworks/Python.framework/Versions/%s/lib/lib* .'%(
286-
shellQuote(os.path.join(WORKDIR, 'libraries')),
287-
shellQuote(os.path.join(WORKDIR, 'libraries')),
288-
getVersion(),
289-
),
290-
),
291299
])
292300

293301
if not PYTHON_3:
@@ -660,23 +668,10 @@ def extractArchive(builddir, archiveName):
660668
finally:
661669
os.chdir(curdir)
662670

663-
KNOWNSIZES = {
664-
"http://ftp.gnu.org/pub/gnu/readline/readline-5.1.tar.gz": 7952742,
665-
"http://downloads.sleepycat.com/db-4.4.20.tar.gz": 2030276,
666-
}
667-
668671
def downloadURL(url, fname):
669672
"""
670673
Download the contents of the url into the file.
671674
"""
672-
try:
673-
size = os.path.getsize(fname)
674-
except OSError:
675-
pass
676-
else:
677-
if KNOWNSIZES.get(url) == size:
678-
print("Using existing file for", url)
679-
return
680675
fpIn = urllib_request.urlopen(url)
681676
fpOut = open(fname, 'wb')
682677
block = fpIn.read(10240)
@@ -692,6 +687,24 @@ def downloadURL(url, fname):
692687
except:
693688
pass
694689

690+
def verifyThirdPartyFile(url, checksum, fname):
691+
"""
692+
Download file from url to filename fname if it does not already exist.
693+
Abort if file contents does not match supplied md5 checksum.
694+
"""
695+
name = os.path.basename(fname)
696+
if os.path.exists(fname):
697+
print("Using local copy of %s"%(name,))
698+
else:
699+
print("Did not find local copy of %s"%(name,))
700+
print("Downloading %s"%(name,))
701+
downloadURL(url, fname)
702+
print("Archive for %s stored as %s"%(name, fname))
703+
if os.system(
704+
'MD5=$(openssl md5 %s) ; test "${MD5##*= }" = "%s"'
705+
% (shellQuote(fname), checksum) ):
706+
fatal('MD5 checksum mismatch for file %s' % fname)
707+
695708
def buildRecipe(recipe, basedir, archList):
696709
"""
697710
Build software using a recipe. This function does the
@@ -712,16 +725,7 @@ def buildRecipe(recipe, basedir, archList):
712725
if not os.path.exists(DEPSRC):
713726
os.mkdir(DEPSRC)
714727

715-
716-
if os.path.exists(sourceArchive):
717-
print("Using local copy of %s"%(name,))
718-
719-
else:
720-
print("Did not find local copy of %s"%(name,))
721-
print("Downloading %s"%(name,))
722-
downloadURL(url, sourceArchive)
723-
print("Archive for %s stored as %s"%(name, sourceArchive))
724-
728+
verifyThirdPartyFile(url, recipe['checksum'], sourceArchive)
725729
print("Extracting archive for %s"%(name,))
726730
buildDir=os.path.join(WORKDIR, '_bld')
727731
if not os.path.exists(buildDir):
@@ -732,18 +736,31 @@ def buildRecipe(recipe, basedir, archList):
732736
if 'buildDir' in recipe:
733737
os.chdir(recipe['buildDir'])
734738

735-
736-
for fn in recipe.get('patches', ()):
737-
if fn.startswith('http://'):
738-
# Download the patch before applying it.
739-
path = os.path.join(DEPSRC, os.path.basename(fn))
740-
downloadURL(fn, path)
741-
fn = path
742-
743-
fn = os.path.join(curdir, fn)
739+
for patch in recipe.get('patches', ()):
740+
if isinstance(patch, tuple):
741+
url, checksum = patch
742+
fn = os.path.join(DEPSRC, os.path.basename(url))
743+
verifyThirdPartyFile(url, checksum, fn)
744+
else:
745+
# patch is a file in the source directory
746+
fn = os.path.join(curdir, patch)
744747
runCommand('patch -p%s < %s'%(recipe.get('patchlevel', 1),
745748
shellQuote(fn),))
746749

750+
for patchscript in recipe.get('patchscripts', ()):
751+
if isinstance(patchscript, tuple):
752+
url, checksum = patchscript
753+
fn = os.path.join(DEPSRC, os.path.basename(url))
754+
verifyThirdPartyFile(url, checksum, fn)
755+
else:
756+
# patch is a file in the source directory
757+
fn = os.path.join(curdir, patchscript)
758+
if fn.endswith('.bz2'):
759+
runCommand('bunzip2 -fk %s' % shellQuote(fn))
760+
fn = fn[:-4]
761+
runCommand('sh %s' % shellQuote(fn))
762+
os.unlink(fn)
763+
747764
if configure is not None:
748765
configure_args = [
749766
"--prefix=/usr/local",
@@ -762,25 +779,28 @@ def buildRecipe(recipe, basedir, archList):
762779

763780
if recipe.get('useLDFlags', 1):
764781
configure_args.extend([
765-
"CFLAGS=-arch %s -isysroot %s -I%s/usr/local/include"%(
782+
"CFLAGS=-mmacosx-version-min=%s -arch %s -isysroot %s -I%s/usr/local/include"%(
783+
DEPTARGET,
766784
' -arch '.join(archList),
767785
shellQuote(SDKPATH)[1:-1],
768786
shellQuote(basedir)[1:-1],),
769-
"LDFLAGS=-syslibroot,%s -L%s/usr/local/lib -arch %s"%(
787+
"LDFLAGS=-mmacosx-version-min=%s -syslibroot,%s -L%s/usr/local/lib -arch %s"%(
788+
DEPTARGET,
770789
shellQuote(SDKPATH)[1:-1],
771790
shellQuote(basedir)[1:-1],
772791
' -arch '.join(archList)),
773792
])
774793
else:
775794
configure_args.extend([
776-
"CFLAGS=-arch %s -isysroot %s -I%s/usr/local/include"%(
795+
"CFLAGS=-mmacosx-version-min=%s -arch %s -isysroot %s -I%s/usr/local/include"%(
796+
DEPTARGET,
777797
' -arch '.join(archList),
778798
shellQuote(SDKPATH)[1:-1],
779799
shellQuote(basedir)[1:-1],),
780800
])
781801

782802
if 'configure_post' in recipe:
783-
configure_args = configure_args = list(recipe['configure_post'])
803+
configure_args = configure_args + list(recipe['configure_post'])
784804

785805
configure_args.insert(0, configure)
786806
configure_args = [ shellQuote(a) for a in configure_args ]

Mac/BuildScript/ncurses-5.5.patch

Lines changed: 0 additions & 36 deletions
This file was deleted.

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ Tests
304304
Build
305305
-----
306306

307+
- Issue #15037: Build OS X installers with local copy of ncurses 5.9 libraries
308+
to avoid curses.unget_wch bug present in older versions of ncurses such as
309+
those shipped with OS X.
310+
307311
- Issue #15560: Fix building _sqlite3 extension on OS X with an SDK.
308312

309313
- Issue #8847: Disable COMDAT folding in Windows PGO builds.

0 commit comments

Comments
 (0)