|
| 1 | +import os |
| 2 | +import sys |
| 3 | +import struct |
| 4 | +import platform |
| 5 | + |
| 6 | +from setuptools import setup, Extension |
| 7 | +from setuptools.command.build_ext import build_ext as _build_ext |
| 8 | +from distutils import log |
| 9 | +from distutils.errors import DistutilsSetupError |
| 10 | +from distutils.dep_util import newer_group |
| 11 | + |
| 12 | +COMPILE_FLAGS = ['-flto', '-std=gnu++11', '-g', '-Wall', |
| 13 | + '-Werror', '-DRENDERER_PROCESS', '-static'] |
| 14 | +LINK_FLAGS = ['-flto', '-Wl,-rpath,.'] |
| 15 | + |
| 16 | +if len(sys.argv) > 1 and "--fast" in sys.argv: |
| 17 | + sys.argv.remove("--fast") |
| 18 | + # Fast mode disables optimization flags |
| 19 | + FAST = True |
| 20 | + print("FAST mode On") |
| 21 | +else: |
| 22 | + FAST = False |
| 23 | + # Fix "ImportError ... undefined symbol ..." caused by CEF's include/base/ |
| 24 | + # headers by adding the -flto flag (Issue #230). Unfortunately -flto |
| 25 | + # prolongs compilation time significantly. |
| 26 | + # More on the other flags: https://stackoverflow.com/questions/6687630/ |
| 27 | + COMPILE_FLAGS += ['-fdata-sections', '-ffunction-sections'] |
| 28 | + LINK_FLAGS += ['-Wl,--gc-sections'] |
| 29 | + |
| 30 | + |
| 31 | +# Architecture and OS postfixes |
| 32 | +ARCH32 = (8 * struct.calcsize('P') == 32) |
| 33 | +ARCH64 = (8 * struct.calcsize('P') == 64) |
| 34 | +OS_POSTFIX = ("win" if platform.system() == "Windows" else |
| 35 | + "linux" if platform.system() == "Linux" else |
| 36 | + "mac" if platform.system() == "Darwin" else "unknown") |
| 37 | +OS_POSTFIX2 = "unknown" |
| 38 | +if OS_POSTFIX == "win": |
| 39 | + OS_POSTFIX2 = "win32" if ARCH32 else "win64" |
| 40 | +elif OS_POSTFIX == "mac": |
| 41 | + OS_POSTFIX2 = "mac32" if ARCH32 else "mac64" |
| 42 | +elif OS_POSTFIX == "linux": |
| 43 | + OS_POSTFIX2 = "linux32" if ARCH32 else "linux64" |
| 44 | + |
| 45 | +# Directories |
| 46 | +SUBPROCESS_DIR = os.path.abspath(os.path.dirname(__file__)) |
| 47 | +SRC_DIR = os.path.abspath(os.path.join(SUBPROCESS_DIR, "..")) |
| 48 | +CEFPYTHON_DIR = os.path.abspath(os.path.join(SRC_DIR, "..")) |
| 49 | +BUILD_DIR = os.path.abspath(os.path.join(CEFPYTHON_DIR, "build")) |
| 50 | +CEF_BINARY = os.path.abspath(os.path.join(BUILD_DIR, "cef_"+OS_POSTFIX2)) |
| 51 | +CEFPYTHON_BINARY = os.path.abspath(os.path.join(BUILD_DIR, |
| 52 | + "cefpython_"+OS_POSTFIX2)) |
| 53 | + |
| 54 | +# Python version string: "27" or "32". |
| 55 | +PYTHON_VERSION = str(sys.version_info.major) + str(sys.version_info.minor) |
| 56 | + |
| 57 | +class build_ext(_build_ext): |
| 58 | + |
| 59 | + def build_extension(self, ext): |
| 60 | + sources = ext.sources |
| 61 | + if sources is None or not isinstance(sources, (list, tuple)): |
| 62 | + raise DistutilsSetupError( |
| 63 | + "in 'ext_modules' option (extension '%s'), " |
| 64 | + "'sources' must be present and must be " |
| 65 | + "a list of source filenames" % ext.name) |
| 66 | + sources = list(sources) |
| 67 | + |
| 68 | + ext_path = ext.name |
| 69 | + depends = sources + ext.depends |
| 70 | + if not (self.force or newer_group(depends, ext_path, 'newer')): |
| 71 | + log.debug("skipping '%s' extension (up-to-date)", ext.name) |
| 72 | + return |
| 73 | + else: |
| 74 | + log.info("building '%s' extension", ext.name) |
| 75 | + |
| 76 | + # First, scan the sources for SWIG definition files (.i), run |
| 77 | + # SWIG on 'em to create .c files, and modify the sources list |
| 78 | + # accordingly. |
| 79 | + sources = self.swig_sources(sources, ext) |
| 80 | + |
| 81 | + # Next, compile the source code to object files. |
| 82 | + |
| 83 | + # XXX not honouring 'define_macros' or 'undef_macros' -- the |
| 84 | + # CCompiler API needs to change to accommodate this, and I |
| 85 | + # want to do one thing at a time! |
| 86 | + |
| 87 | + # Two possible sources for extra compiler arguments: |
| 88 | + # - 'extra_compile_args' in Extension object |
| 89 | + # - CFLAGS environment variable (not particularly |
| 90 | + # elegant, but people seem to expect it and I |
| 91 | + # guess it's useful) |
| 92 | + # The environment variable should take precedence, and |
| 93 | + # any sensible compiler will give precedence to later |
| 94 | + # command line args. Hence we combine them in order: |
| 95 | + extra_args = ext.extra_compile_args or [] |
| 96 | + |
| 97 | + macros = ext.define_macros[:] |
| 98 | + for undef in ext.undef_macros: |
| 99 | + macros.append((undef,)) |
| 100 | + |
| 101 | + objects = self.compiler.compile(sources, |
| 102 | + output_dir=self.build_temp, |
| 103 | + macros=macros, |
| 104 | + include_dirs=ext.include_dirs, |
| 105 | + debug=self.debug, |
| 106 | + extra_postargs=extra_args, |
| 107 | + depends=ext.depends) |
| 108 | + |
| 109 | + # XXX outdated variable, kept here in case third-part code |
| 110 | + # needs it. |
| 111 | + self._built_objects = objects[:] |
| 112 | + |
| 113 | + # Now link the object files together into a "shared object" -- |
| 114 | + # of course, first we have to figure out all the other things |
| 115 | + # that go into the mix. |
| 116 | + if ext.extra_objects: |
| 117 | + objects.extend(ext.extra_objects) |
| 118 | + extra_args = ext.extra_link_args or [] |
| 119 | + |
| 120 | + # Detect target language, if not provided |
| 121 | + language = ext.language or self.compiler.detect_language(sources) |
| 122 | + |
| 123 | + self.compiler.link_executable( |
| 124 | + objects, ext_path, |
| 125 | + libraries=self.get_libraries(ext), |
| 126 | + library_dirs=ext.library_dirs, |
| 127 | + runtime_library_dirs=ext.runtime_library_dirs, |
| 128 | + extra_postargs=extra_args, |
| 129 | + debug=self.debug, |
| 130 | + target_lang=language) |
| 131 | + |
| 132 | +libcefpython_src = [ |
| 133 | + 'cefpython_app.cpp', |
| 134 | + 'v8function_handler.cpp', |
| 135 | + 'v8utils.cpp', |
| 136 | + 'javascript_callback.cpp', |
| 137 | + 'main_message_loop/main_message_loop.cpp', |
| 138 | + 'main_message_loop/main_message_loop_std.cpp', |
| 139 | + 'main_message_loop/main_message_loop_external_pump.cpp' |
| 140 | +] |
| 141 | + |
| 142 | +subprocess_src = [ |
| 143 | + 'main.cpp', |
| 144 | + # 'cefpython_app.cpp', |
| 145 | + # 'v8function_handler.cpp', |
| 146 | + # 'v8utils.cpp', |
| 147 | + 'javascript_callback.cpp' |
| 148 | +] |
| 149 | + |
| 150 | +libs = [ |
| 151 | + 'glib-2.0', |
| 152 | + 'gtk-x11-2.0', |
| 153 | + 'cef', |
| 154 | + 'cef_dll_wrapper' |
| 155 | +] |
| 156 | + |
| 157 | +if OS_POSTFIX.startswith('linux'): |
| 158 | + libs.insert(0, 'gobject-2.0') |
| 159 | + subprocess_src.append('print_handler_gtk.cpp') |
| 160 | + libcefpython_src.extend(['print_handler_gtk.cpp', |
| 161 | + 'main_message_loop/main_message_loop_external_pump_linux.cpp']) |
| 162 | + |
| 163 | +elif OS_POSTFIX.startswith('mac'): |
| 164 | + libcefpython_src.append('main_message_loop/main_message_loop_external_pump_mac.mm') |
| 165 | + |
| 166 | +ext_modules = [ |
| 167 | + Extension( |
| 168 | + "subprocess", |
| 169 | + [os.path.join(SUBPROCESS_DIR, src) for src in |
| 170 | + (subprocess_src + libcefpython_src)], |
| 171 | + |
| 172 | + language='c++', |
| 173 | + include_dirs=[ |
| 174 | + r'./../', |
| 175 | + r'./../common/', |
| 176 | + r'/usr/include/python2.7', |
| 177 | + r'/usr/include/gtk-2.0', |
| 178 | + r'/usr/include/gtk-unix-print-2.0', |
| 179 | + r'/usr/include/glib-2.0', |
| 180 | + r'/usr/include/cairo', |
| 181 | + r'/usr/include/pango-1.0', |
| 182 | + r'/usr/include/gdk-pixbuf-2.0', |
| 183 | + r'/usr/include/atk-1.0', |
| 184 | + r'/usr/lib/x86_64-linux-gnu/gtk-2.0/include', |
| 185 | + r'/usr/lib/x86_64-linux-gnu/gtk-unix-print-2.0', |
| 186 | + r'/usr/lib/x86_64-linux-gnu/glib-2.0/include', |
| 187 | + r'/usr/lib/i386-linux-gnu/gtk-2.0/include', |
| 188 | + r'/usr/lib/i386-linux-gnu/gtk-unix-print-2.0', |
| 189 | + r'/usr/lib/i386-linux-gnu/glib-2.0/include', |
| 190 | + r'/usr/lib64/gtk-2.0/include', |
| 191 | + r'/usr/lib64/gtk-unix-print-2.0', |
| 192 | + r'/usr/lib64/glib-2.0/include', |
| 193 | + r'/usr/lib/gtk-2.0/include', |
| 194 | + r'/usr/lib/gtk-2.0/gtk-unix-print-2.0', |
| 195 | + r'/usr/lib/glib-2.0/include', |
| 196 | + ], |
| 197 | + |
| 198 | + library_dirs=[ |
| 199 | + os.path.join(CEF_BINARY,'bin'), |
| 200 | + os.path.join(CEF_BINARY,'lib'), |
| 201 | + ], |
| 202 | + |
| 203 | + # Static libraries only. Order is important, if library A depends on B, |
| 204 | + # then B must be included before A. |
| 205 | + libraries=libs, |
| 206 | + |
| 207 | + extra_compile_args=COMPILE_FLAGS, |
| 208 | + extra_link_args=LINK_FLAGS, |
| 209 | +)] |
| 210 | + |
| 211 | +setup( |
| 212 | + name='subprocess_%s' % PYTHON_VERSION, |
| 213 | + cmdclass={'build_ext': build_ext}, |
| 214 | + ext_modules=ext_modules |
| 215 | +) |
0 commit comments