|
1 | 1 | import multiprocessing |
| 2 | +import os |
2 | 3 | import platform |
| 4 | +import subprocess |
| 5 | +from contextlib import contextmanager |
3 | 6 | from pathlib import Path |
4 | 7 | from typing import List |
5 | 8 |
|
6 | 9 | from Cython.Build import cythonize |
7 | 10 | from Cython.Distutils.build_ext import new_build_ext as cython_build_ext |
8 | 11 | from setuptools import Extension, Distribution |
9 | 12 |
|
| 13 | +@contextmanager |
| 14 | +def changedir(path): |
| 15 | + save_dir = os.getcwd() |
| 16 | + os.chdir(path) |
| 17 | + try: |
| 18 | + yield |
| 19 | + finally: |
| 20 | + os.chdir(save_dir) |
| 21 | + |
| 22 | +@contextmanager |
| 23 | +def with_patches(): |
| 24 | + patches = sorted([ |
| 25 | + os.path.abspath(patch) |
| 26 | + for patch in Path("patches").iterdir() |
| 27 | + if patch.is_file() and patch.suffix == ".patch" |
| 28 | + ]) |
| 29 | + with changedir("bwa"): |
| 30 | + for patch in patches: |
| 31 | + retcode = subprocess.call(f"git apply {patch}", shell=True) |
| 32 | + if retcode != 0: |
| 33 | + raise RuntimeError(f"Failed to apply patch {patch}") |
| 34 | + try: |
| 35 | + yield |
| 36 | + finally: |
| 37 | + commands = ["git submodule deinit -f .", "git submodule update --init"] |
| 38 | + for command in commands: |
| 39 | + retcode = subprocess.call(command, shell=True) |
| 40 | + if retcode != 0: |
| 41 | + raise RuntimeError(f"Failed to reset submodules: {command}") |
| 42 | + |
10 | 43 | SOURCE_DIR = Path("pybwa") |
11 | 44 | BUILD_DIR = Path("cython_build") |
12 | 45 | compile_args = [] |
@@ -110,46 +143,48 @@ def cythonize_helper(extension_modules: List[Extension]) -> List[Extension]: |
110 | 143 |
|
111 | 144 |
|
112 | 145 | def build(): |
113 | | - # Collect and cythonize all files |
114 | | - extension_modules = cythonize_helper([ |
115 | | - libbwaindex_module, |
116 | | - libbwaaln_module, |
117 | | - libbwamem_module |
118 | | - ]) |
119 | | - |
120 | | - # Use Setuptools to collect files |
121 | | - distribution = Distribution({ |
122 | | - "name": "pybwa", |
123 | | - 'version': '0.0.1', |
124 | | - 'description': 'Python bindings for BWA', |
125 | | - 'long_description': __doc__, |
126 | | - 'long_description_content_type': 'text/x-rst', |
127 | | - 'author': 'Nils Homer', |
128 | | - 'author_email': 'nils@fulcrumgenomics.com', |
129 | | - 'license': 'MIT', |
130 | | - 'platforms': ['POSIX', 'UNIX', 'MacOS'], |
131 | | - 'classifiers': [_f for _f in CLASSIFIERS.split('\n') if _f], |
132 | | - 'url': 'https://github.com/fulcrumgenomics/pybwa', |
133 | | - 'packages': ['pybwa', 'pybwa.include.bwa'], |
134 | | - 'package_dir': {'pybwa': 'pybwa', 'pybwa.include.bwa': 'bwa'}, |
135 | | - 'package_data': {'': ['*.pxd', '*.h', '*.c', 'py.typed', '*.pyi'], }, |
136 | | - "ext_modules": extension_modules, |
137 | | - "cmdclass": { |
138 | | - "build_ext": cython_build_ext, |
139 | | - }, |
140 | | - }) |
141 | | - |
142 | | - # Grab the build_ext command and copy all files back to source dir. |
143 | | - # Done so Poetry grabs the files during the next step in its build. |
144 | | - build_ext_cmd = distribution.get_command_obj("build_ext") |
145 | | - build_ext_cmd.ensure_finalized() |
146 | | - # Set the value to 1 for "inplace", with the goal to build extensions |
147 | | - # in build directory, and then copy all files back to the source dir |
148 | | - # (under the hood, "copy_extensions_to_source" will be called after |
149 | | - # building the extensions). This is done so Poetry grabs the files |
150 | | - # during the next step in its build. |
151 | | - build_ext_cmd.inplace = 1 |
152 | | - build_ext_cmd.run() |
| 146 | + # apply patches to bwa, then revert them after |
| 147 | + with with_patches(): |
| 148 | + # Collect and cythonize all files |
| 149 | + extension_modules = cythonize_helper([ |
| 150 | + libbwaindex_module, |
| 151 | + libbwaaln_module, |
| 152 | + libbwamem_module |
| 153 | + ]) |
| 154 | + |
| 155 | + # Use Setuptools to collect files |
| 156 | + distribution = Distribution({ |
| 157 | + "name": "pybwa", |
| 158 | + 'version': '0.0.1', |
| 159 | + 'description': 'Python bindings for BWA', |
| 160 | + 'long_description': __doc__, |
| 161 | + 'long_description_content_type': 'text/x-rst', |
| 162 | + 'author': 'Nils Homer', |
| 163 | + 'author_email': 'nils@fulcrumgenomics.com', |
| 164 | + 'license': 'MIT', |
| 165 | + 'platforms': ['POSIX', 'UNIX', 'MacOS'], |
| 166 | + 'classifiers': [_f for _f in CLASSIFIERS.split('\n') if _f], |
| 167 | + 'url': 'https://github.com/fulcrumgenomics/pybwa', |
| 168 | + 'packages': ['pybwa', 'pybwa.include.bwa'], |
| 169 | + 'package_dir': {'pybwa': 'pybwa', 'pybwa.include.bwa': 'bwa'}, |
| 170 | + 'package_data': {'': ['*.pxd', '*.h', '*.c', 'py.typed', '*.pyi'], }, |
| 171 | + "ext_modules": extension_modules, |
| 172 | + "cmdclass": { |
| 173 | + "build_ext": cython_build_ext, |
| 174 | + }, |
| 175 | + }) |
| 176 | + |
| 177 | + # Grab the build_ext command and copy all files back to source dir. |
| 178 | + # Done so Poetry grabs the files during the next step in its build. |
| 179 | + build_ext_cmd = distribution.get_command_obj("build_ext") |
| 180 | + build_ext_cmd.ensure_finalized() |
| 181 | + # Set the value to 1 for "inplace", with the goal to build extensions |
| 182 | + # in build directory, and then copy all files back to the source dir |
| 183 | + # (under the hood, "copy_extensions_to_source" will be called after |
| 184 | + # building the extensions). This is done so Poetry grabs the files |
| 185 | + # during the next step in its build. |
| 186 | + build_ext_cmd.inplace = 1 |
| 187 | + build_ext_cmd.run() |
153 | 188 |
|
154 | 189 |
|
155 | 190 | if __name__ == "__main__": |
|
0 commit comments