-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.py
124 lines (108 loc) · 4.61 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from setuptools import setup, Extension, find_packages
from setuptools.command.build_ext import build_ext
from setuptools.command.install import install
import sys
import os
import subprocess
import shutil
class BuildExt(build_ext):
def run(self):
for ext in self.extensions:
self.build_extension(ext)
self.copy_executable()
def build_extension(self, ext):
sources = ext.sources or []
for source in sources:
if source.endswith('.cpp'):
self.compile_cpp(source)
def compile_cpp(self, source):
# Ensure g++ version is >= 4.8 (which supports C++11)
min_gcc_version = (4, 8)
# Check g++ version
try:
output = subprocess.check_output(['g++', '--version']).decode()
version_line = output.splitlines()[0]
version_str = version_line.split()[-1]
version_parts = version_str.split('.')
gcc_version = tuple(map(int, version_parts[:2]))
except (subprocess.CalledProcessError, IndexError, ValueError):
raise RuntimeError('Failed to determine g++ version')
if gcc_version < min_gcc_version:
raise RuntimeError(f'g++ version {gcc_version[0]}.{gcc_version[1]} is too old. '
f'Please update to g++ >= {min_gcc_version[0]}.{min_gcc_version[1]}.')
# Compile using g++ with C++11 standard
object_file = source.replace('.cpp', '.o')
include_dirs = ['src/BigphASE/delta2hap/include']
compile_cmd = ['g++', '-std=c++11', '-c', source, '-o', object_file] + \
[f'-I{dir}' for dir in include_dirs]
print(f'Compiling {source}...')
sys.stdout.flush()
if os.system(' '.join(compile_cmd)) != 0:
raise RuntimeError('Compilation failed')
def copy_executable(self):
# Link the object files and create the executable
object_files = [
'src/BigphASE/delta2hap/src/delta2hap.o',
'src/BigphASE/delta2hap/src/delta.o',
'src/BigphASE/delta2hap/src/tigrinc.o',
'src/BigphASE/delta2hap/src/translate.o'
]
output_executable = 'src/BigphASE/delta2hap/bin/delta2hap'
# Ensure the bin directory exists
os.makedirs(os.path.dirname(output_executable), exist_ok=True)
link_cmd = ['g++', '-o', output_executable] + object_files
print(f'Linking {output_executable}...')
sys.stdout.flush()
if os.system(' '.join(link_cmd)) != 0:
raise RuntimeError('Linking failed')
# Move the executable to the bin directory
if not os.path.exists(output_executable):
raise RuntimeError('Executable not found after compilation')
class InstallCommand(install):
def run(self):
self.run_command('build_ext')
super().run()
self.cleanup()
def cleanup(self):
# Define the directories and files to be removed
cleanup_paths = [
'src/BigphASE/delta2hap/include',
'src/BigphASE/delta2hap/src',
'src/BigphASE/delta2hap/CMakeLists.txt'
]
for path in cleanup_paths:
full_path = os.path.abspath(path)
if os.path.isdir(full_path):
shutil.rmtree(full_path)
print(f'Removed directory {full_path}')
elif os.path.isfile(full_path):
os.remove(full_path)
print(f'Removed file {full_path}')
cpp_extension = Extension('delta2hap',
sources=['src/BigphASE/delta2hap/src/delta2hap.cpp',
'src/BigphASE/delta2hap/src/delta.cpp',
'src/BigphASE/delta2hap/src/tigrinc.cpp',
'src/BigphASE/delta2hap/src/translate.cpp'])
setup(
name='BigphASE',
version='0.1.2',
description='This package was devised to analyze hybrid RNA-seq using bi-parental graph strategy.',
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
author='Yi Jiang, Yi Mu Ran , Zhule Liu',
author_email='[email protected]',
url='https://github.com/yjiang296/BigphASE',
license='GNU GPL v3.0 License',
platforms='any',
ext_modules=[cpp_extension],
cmdclass={'build_ext': BuildExt, 'install': InstallCommand},
packages=['BigphASE'],
scripts=['scripts/BigphASEtools'],
include_package_data=True,
package_dir={'': 'src'},
install_requires=[],
classifiers=[
'Natural Language :: English',
'Programming Language :: Python :: 3.12',
],
)