Skip to content

Commit 8b0e03f

Browse files
committed
Inline setup_external_build into setupext.
Also: - use tarfile to extract the FreeType tarball on all platforms. - less batch script, more Python. - more pathlib, less shell=True.
1 parent 9ec4b95 commit 8b0e03f

File tree

3 files changed

+51
-121
lines changed

3 files changed

+51
-121
lines changed

pytest.ini

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pep8ignore =
1313
tools/boilerplate.py E501
1414
setup.py E402
1515
setupext.py E301 E302 E501
16-
setup_external_compile.py E302 E711
1716

1817
versioneer.py ALL # External file.
1918
tools/gh_api.py ALL # External file.

setup_external_compile.py

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

setupext.py

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import shutil
1515
import subprocess
1616
import sys
17+
import tarfile
1718
import textwrap
1819
import urllib.request
1920
import warnings
@@ -1045,6 +1046,8 @@ def add_flags(self, ext):
10451046
ext.define_macros.append(('FREETYPE_BUILD_TYPE', 'system'))
10461047

10471048
def do_custom_build(self):
1049+
from pathlib import Path
1050+
10481051
# We're using a system freetype
10491052
if not options.get('local_freetype'):
10501053
return
@@ -1058,7 +1061,7 @@ def do_custom_build(self):
10581061
else:
10591062
libfreetype = 'libfreetype.a'
10601063

1061-
if os.path.isfile(os.path.join(src_path, 'objs', '.libs', libfreetype)):
1064+
if Path(src_path, "objs", ".libs", libfreetype).is_file():
10621065
return
10631066

10641067
tarball = 'freetype-{0}.tar.gz'.format(LOCAL_FREETYPE_VERSION)
@@ -1097,21 +1100,20 @@ def do_custom_build(self):
10971100
tarball_url = url_fmt.format(
10981101
version=LOCAL_FREETYPE_VERSION, tarball=tarball)
10991102

1100-
print("Downloading {0}".format(tarball_url))
1103+
print("Downloading {}".format(tarball_url))
11011104
try:
11021105
urllib.request.urlretrieve(tarball_url, tarball_path)
1103-
except IOError: # URLError (a subclass) on Py3.
1104-
print("Failed to download {0}".format(tarball_url))
1106+
except IOError:
1107+
print("Failed to download {}".format(tarball_url))
11051108
else:
11061109
if get_file_hash(tarball_path) != LOCAL_FREETYPE_HASH:
11071110
print("Invalid hash.")
11081111
else:
11091112
break
11101113
else:
1111-
raise IOError("Failed to download freetype. "
1112-
"You can download the file by "
1113-
"alternative means and copy it "
1114-
" to '{0}'".format(tarball_path))
1114+
raise IOError("Failed to download freetype; you can "
1115+
"download the file by alternative means and "
1116+
"copy it to '{}'".format(tarball_path))
11151117
os.makedirs(tarball_cache_dir, exist_ok=True)
11161118
try:
11171119
shutil.copy(tarball_path, tarball_cache_path)
@@ -1122,55 +1124,55 @@ def do_custom_build(self):
11221124

11231125
if get_file_hash(tarball_path) != LOCAL_FREETYPE_HASH:
11241126
raise IOError(
1125-
"{0} does not match expected hash.".format(tarball))
1127+
"{} does not match expected hash".format(tarball))
1128+
1129+
print("Building {}".format(tarball))
1130+
with tarfile.open(tarball_path, "r:gz") as tgz:
1131+
tgz.extractall("build")
11261132

1127-
print("Building {0}".format(tarball))
11281133
if sys.platform != 'win32':
11291134
# compilation on all other platforms than windows
1130-
cflags = 'CFLAGS="{0} -fPIC" '.format(os.environ.get('CFLAGS', ''))
1131-
1132-
subprocess.check_call(
1133-
['tar', 'zxf', tarball], cwd='build')
1134-
subprocess.check_call(
1135-
[cflags + './configure --with-zlib=no --with-bzip2=no '
1136-
'--with-png=no --with-harfbuzz=no'], shell=True, cwd=src_path)
1135+
env={**os.environ,
1136+
"CFLAGS": "{} -fPIC".format(os.environ.get("CFLAGS", ""))}
11371137
subprocess.check_call(
1138-
[cflags + 'make'], shell=True, cwd=src_path)
1138+
["./configure", "--with-zlib=no", "--with-bzip2=no",
1139+
"--with-png=no", "--with-harfbuzz=no"],
1140+
env=env, cwd=src_path)
1141+
subprocess.check_call(["make"], env=env, cwd=src_path)
11391142
else:
11401143
# compilation on windows
1141-
FREETYPE_BUILD_CMD = """\
1142-
call "%ProgramFiles%\\Microsoft SDKs\\Windows\\v7.0\\Bin\\SetEnv.Cmd" /Release /{xXX} /xp
1144+
FREETYPE_BUILD_CMD = r"""
1145+
call "%ProgramFiles%\Microsoft SDKs\Windows\v7.0\Bin\SetEnv.Cmd" ^
1146+
/Release /{xXX} /xp
11431147
call "{vcvarsall}" {xXX}
1144-
set MSBUILD=C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\MSBuild.exe
1145-
rd /S /Q %FREETYPE%\\objs
1146-
%MSBUILD% %FREETYPE%\\builds\\windows\\{vc20xx}\\freetype.sln /t:Clean;Build /p:Configuration="{config}";Platform={WinXX}
1147-
echo Build completed, moving result"
1148-
:: move to the "normal" path for the unix builds...
1149-
mkdir %FREETYPE%\\objs\\.libs
1150-
:: REMINDER: fix when changing the version
1151-
copy %FREETYPE%\\objs\\{vc20xx}\\{xXX}\\freetype261.lib %FREETYPE%\\objs\\.libs\\libfreetype.lib
1152-
if errorlevel 1 (
1153-
rem This is a py27 version, which has a different location for the lib file :-/
1154-
copy %FREETYPE%\\objs\\win32\\{vc20xx}\\freetype261.lib %FREETYPE%\\objs\\.libs\\libfreetype.lib
1155-
)
1148+
set MSBUILD=C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
1149+
%MSBUILD% "builds\windows\{vc20xx}\freetype.sln" ^
1150+
/t:Clean;Build /p:Configuration="{config}";Platform={WinXX}
11561151
"""
1157-
from setup_external_compile import fixproj, prepare_build_cmd, VS2010, X64, tar_extract
1158-
# Note: freetype has no build profile for 2014, so we don't bother...
1159-
vc = 'vc2010' if VS2010 else 'vc2008'
1160-
WinXX = 'x64' if X64 else 'Win32'
1161-
tar_extract(tarball_path, "build")
1162-
# This is only false for py2.7, even on py3.5...
1163-
if not VS2010:
1164-
fixproj(os.path.join(src_path, 'builds', 'windows', vc, 'freetype.sln'), WinXX)
1165-
fixproj(os.path.join(src_path, 'builds', 'windows', vc, 'freetype.vcproj'), WinXX)
1166-
1167-
cmdfile = os.path.join("build", 'build_freetype.cmd')
1168-
with open(cmdfile, 'w') as cmd:
1169-
cmd.write(prepare_build_cmd(FREETYPE_BUILD_CMD, vc20xx=vc, WinXX=WinXX,
1170-
config='Release' if VS2010 else 'LIB Release'))
1171-
1172-
os.environ['FREETYPE'] = src_path
1173-
subprocess.check_call([cmdfile], shell=True)
1152+
import distutils.msvc9compiler as msvc
1153+
# FreeType 2.6.1 has no build profile for 2014.
1154+
vcvarsall = msvc.find_vcvarsall(10.0)
1155+
if vcvarsall is None:
1156+
raise RuntimeError("Microsoft VS 2010 required")
1157+
X64 = sys.maxsize > 2 ** 32
1158+
vc20xx = "vc2010"
1159+
WinXX="x64" if X64 else "Win32"
1160+
xXX="x64" if X64 else "x86"
1161+
cmd_file = Path("build", "build_freetype.cmd")
1162+
cmd_file.write_text(FREETYPE_BUILD_CMD.format(
1163+
vcvarsall=msvc.find_vcvarsall(10.0),
1164+
vc20xx=vc20xx, WinXX=WinXX, xXX=xXX, config="Release"))
1165+
shutil.rmtree(Path(src_path, "objs"), ignore_errors=True)
1166+
subprocess.check_call(cmdfile, shell=True, cwd=src_path)
1167+
# Move to the corresponding Unix build path.
1168+
Path(src_path, "objs/.libs").mkdir()
1169+
# Be robust against change of FreeType version.
1170+
lib_path, = (Path(src_path, "objs", vc20xx, xXX).glob()
1171+
.glob("freetype*.lib"))
1172+
shutil.copy2(
1173+
str(lib_path),
1174+
str(Path(src_path, "objs", ".libs", "libfreetype.lib"))
1175+
)
11741176

11751177

11761178
class FT2Font(SetupPackage):

0 commit comments

Comments
 (0)