Skip to content

Commit bcdafc3

Browse files
Marcel Plchasottile
authored andcommitted
System sass (#219)
Use env var to allow system libsass
1 parent 8efb498 commit bcdafc3

File tree

1 file changed

+150
-98
lines changed

1 file changed

+150
-98
lines changed

setup.py

Lines changed: 150 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -14,76 +14,13 @@
1414

1515
from setuptools import Extension, setup
1616

17-
LIBSASS_SOURCE_DIR = os.path.join('libsass', 'src')
18-
19-
if (
20-
not os.path.isfile(os.path.join('libsass', 'Makefile')) and
21-
os.path.isdir('.git')
22-
):
23-
print(file=sys.stderr)
24-
print('Missing the libsass sumbodule. Try:', file=sys.stderr)
25-
print(' git submodule update --init', file=sys.stderr)
26-
print(file=sys.stderr)
27-
exit(1)
28-
29-
30-
# Determine the libsass version from the git checkout
31-
if os.path.exists(os.path.join('libsass', '.git')):
32-
proc = subprocess.Popen(
33-
(
34-
'git', '-C', 'libsass', 'describe',
35-
'--abbrev=4', '--dirty', '--always', '--tags',
36-
),
37-
stdout=subprocess.PIPE,
38-
)
39-
out, _ = proc.communicate()
40-
assert not proc.returncode, proc.returncode
41-
with open('.libsass-upstream-version', 'wb') as libsass_version_file:
42-
libsass_version_file.write(out)
43-
44-
# The version file should always exist at this point
45-
with open('.libsass-upstream-version', 'rb') as libsass_version_file:
46-
libsass_version = libsass_version_file.read().decode('UTF-8').strip()
47-
if sys.platform == 'win32':
48-
# This looks wrong, but is required for some reason :(
49-
version_define = r'/DLIBSASS_VERSION="\"{0}\""'.format(libsass_version)
50-
else:
51-
version_define = '-DLIBSASS_VERSION="{0}"'.format(libsass_version)
17+
system_sass = os.environ.get('SYSTEM_SASS', False)
5218

5319
sources = ['pysass.cpp']
5420
headers = []
55-
for directory in (
56-
os.path.join('libsass', 'src'),
57-
os.path.join('libsass', 'include')
58-
):
59-
for pth, _, filenames in os.walk(directory):
60-
for filename in filenames:
61-
filename = os.path.join(pth, filename)
62-
if filename.endswith(('.c', '.cpp')):
63-
sources.append(filename)
64-
elif filename.endswith('.h'):
65-
headers.append(filename)
66-
67-
if sys.platform == 'win32':
68-
from distutils.msvc9compiler import get_build_version
69-
vscomntools_env = 'VS{0}{1}COMNTOOLS'.format(
70-
int(get_build_version()),
71-
int(get_build_version() * 10) % 10
72-
)
73-
try:
74-
os.environ[vscomntools_env] = os.environ['VS140COMNTOOLS']
75-
except KeyError:
76-
distutils.log.warn('You probably need Visual Studio 2015 (14.0) '
77-
'or higher')
78-
from distutils import msvccompiler, msvc9compiler
79-
if msvccompiler.get_build_version() < 14.0:
80-
msvccompiler.get_build_version = lambda: 14.0
81-
if get_build_version() < 14.0:
82-
msvc9compiler.get_build_version = lambda: 14.0
83-
msvc9compiler.VERSION = 14.0
84-
flags = ['/Od', '/EHsc', '/MT']
85-
link_flags = []
86-
else:
21+
version_define = ''
22+
23+
if system_sass:
8724
flags = [
8825
'-fPIC', '-std=gnu++0x', '-Wall', '-Wno-parentheses', '-Werror=switch',
8926
]
@@ -104,51 +41,166 @@ def customize_compiler(compiler):
10441
flags.append('-stdlib=libc++')
10542
if platform.system() == 'Darwin':
10643
flags.append('-mmacosx-version-min=10.7',)
107-
if tuple(map(int, platform.mac_ver()[0].split('.'))) >= (10, 9):
44+
macver = tuple(map(int, platform.mac_ver()[0].split('.')))
45+
if macver >= (10, 9):
10846
flags.append(
109-
'-Wno-error=unused-command-line-argument-hard-error-in-future', # noqa
47+
'-Wno-error=unused-command-line-' +
48+
'argument-hard-error-in-future', # noqa
11049
)
111-
# Dirty workaround to avoid link error...
112-
# Python distutils doesn't provide any way to configure different
113-
# flags for each cc and c++.
114-
cencode_path = os.path.join(LIBSASS_SOURCE_DIR, 'cencode.c')
115-
cencode_body = ''
116-
with open(cencode_path) as f:
117-
cencode_body = f.read()
118-
with open(cencode_path, 'w') as f:
119-
f.write('''
120-
#ifdef __cplusplus
121-
extern "C" {
122-
#endif
123-
''')
124-
f.write(cencode_body)
125-
f.write('''
126-
#ifdef __cplusplus
127-
}
128-
#endif
129-
''')
130-
131-
@atexit.register
132-
def restore_cencode():
133-
if os.path.isfile(cencode_path):
134-
with open(cencode_path, 'w') as f:
135-
f.write(cencode_body)
136-
137-
flags = ['-c', '-O3'] + flags
50+
51+
flags = ['-c', '-O3'] + flags
13852

13953
if platform.system() == 'FreeBSD':
14054
link_flags = ['-fPIC', '-lc++']
14155
else:
14256
link_flags = ['-fPIC', '-lstdc++']
57+
libraries = ['sass']
58+
include_dirs = []
59+
extra_compile_args = flags
60+
extra_link_args = link_flags
61+
else:
62+
LIBSASS_SOURCE_DIR = os.path.join('libsass', 'src')
63+
64+
if (
65+
not os.path.isfile(os.path.join('libsass', 'Makefile')) and
66+
os.path.isdir('.git')
67+
):
68+
print(file=sys.stderr)
69+
print('Missing the libsass sumbodule. Try:', file=sys.stderr)
70+
print(' git submodule update --init', file=sys.stderr)
71+
print(file=sys.stderr)
72+
exit(1)
73+
74+
# Determine the libsass version from the git checkout
75+
if os.path.exists(os.path.join('libsass', '.git')):
76+
proc = subprocess.Popen(
77+
(
78+
'git', '-C', 'libsass', 'describe',
79+
'--abbrev=4', '--dirty', '--always', '--tags',
80+
),
81+
stdout=subprocess.PIPE,
82+
)
83+
out, _ = proc.communicate()
84+
assert not proc.returncode, proc.returncode
85+
with open('.libsass-upstream-version', 'wb') as libsass_version_file:
86+
libsass_version_file.write(out)
87+
88+
# The version file should always exist at this point
89+
with open('.libsass-upstream-version', 'rb') as libsass_version_file:
90+
libsass_version = libsass_version_file.read().decode('UTF-8').strip()
91+
if sys.platform == 'win32':
92+
# This looks wrong, but is required for some reason :(
93+
version_define = r'/DLIBSASS_VERSION="\"{0}\""'.format(
94+
libsass_version)
95+
else:
96+
version_define = '-DLIBSASS_VERSION="{0}"'.format(libsass_version)
97+
98+
for directory in (
99+
os.path.join('libsass', 'src'),
100+
os.path.join('libsass', 'include')
101+
):
102+
for pth, _, filenames in os.walk(directory):
103+
for filename in filenames:
104+
filename = os.path.join(pth, filename)
105+
if filename.endswith(('.c', '.cpp')):
106+
sources.append(filename)
107+
elif filename.endswith('.h'):
108+
headers.append(filename)
109+
110+
if sys.platform == 'win32':
111+
from distutils.msvc9compiler import get_build_version
112+
vscomntools_env = 'VS{0}{1}COMNTOOLS'.format(
113+
int(get_build_version()),
114+
int(get_build_version() * 10) % 10
115+
)
116+
try:
117+
os.environ[vscomntools_env] = os.environ['VS140COMNTOOLS']
118+
except KeyError:
119+
distutils.log.warn('You probably need Visual Studio 2015 (14.0) '
120+
'or higher')
121+
from distutils import msvccompiler, msvc9compiler
122+
if msvccompiler.get_build_version() < 14.0:
123+
msvccompiler.get_build_version = lambda: 14.0
124+
if get_build_version() < 14.0:
125+
msvc9compiler.get_build_version = lambda: 14.0
126+
msvc9compiler.VERSION = 14.0
127+
flags = ['/Od', '/EHsc', '/MT']
128+
link_flags = []
129+
else:
130+
flags = [
131+
'-fPIC', '-std=gnu++0x', '-Wall',
132+
'-Wno-parentheses', '-Werror=switch',
133+
]
134+
platform.mac_ver()
135+
if platform.system() in ['Darwin', 'FreeBSD']:
136+
os.environ.setdefault('CC', 'clang')
137+
os.environ.setdefault('CXX', 'clang++')
138+
orig_customize_compiler = distutils.sysconfig.customize_compiler
139+
140+
def customize_compiler(compiler):
141+
orig_customize_compiler(compiler)
142+
compiler.compiler[0] = os.environ['CC']
143+
compiler.compiler_so[0] = os.environ['CXX']
144+
compiler.compiler_cxx[0] = os.environ['CXX']
145+
compiler.linker_so[0] = os.environ['CXX']
146+
return compiler
147+
distutils.sysconfig.customize_compiler = customize_compiler
148+
flags.append('-stdlib=libc++')
149+
if platform.system() == 'Darwin':
150+
flags.append('-mmacosx-version-min=10.7',)
151+
macver = tuple(map(int, platform.mac_ver()[0].split('.')))
152+
if macver >= (10, 9):
153+
flags.append(
154+
'-Wno-error=unused-command-line-' +
155+
'argument-hard-error-in-future', # noqa
156+
)
157+
# Dirty workaround to avoid link error...
158+
# Python distutils doesn't provide any way
159+
# to configure different flags for each cc and c++.
160+
cencode_path = os.path.join(LIBSASS_SOURCE_DIR, 'cencode.c')
161+
cencode_body = ''
162+
with open(cencode_path) as f:
163+
cencode_body = f.read()
164+
with open(cencode_path, 'w') as f:
165+
f.write('''
166+
#ifdef __cplusplus
167+
extern "C" {
168+
#endif
169+
''')
170+
f.write(cencode_body)
171+
f.write('''
172+
#ifdef __cplusplus
173+
}
174+
#endif
175+
''')
176+
177+
@atexit.register
178+
def restore_cencode():
179+
if os.path.isfile(cencode_path):
180+
with open(cencode_path, 'w') as f:
181+
f.write(cencode_body)
182+
183+
flags = ['-c', '-O3'] + flags
184+
185+
if platform.system() == 'FreeBSD':
186+
link_flags = ['-fPIC', '-lc++']
187+
else:
188+
link_flags = ['-fPIC', '-lstdc++']
189+
190+
libraries = []
191+
include_dirs = [os.path.join('.', 'libsass', 'include')]
192+
extra_compile_args = flags + [version_define]
193+
extra_link_args = link_flags
143194

144195
sources.sort()
145196
sass_extension = Extension(
146197
'_sass',
147198
sources,
148-
include_dirs=[os.path.join('.', 'libsass', 'include')],
199+
include_dirs=include_dirs,
149200
depends=headers,
150-
extra_compile_args=flags + [version_define],
201+
extra_compile_args=extra_compile_args,
151202
extra_link_args=link_flags,
203+
libraries=libraries
152204
)
153205

154206
install_requires = ['six']

0 commit comments

Comments
 (0)