mirror of
https://github.com/fastogt/pyfastogt
synced 2025-03-09 23:38:55 +00:00
409 lines
17 KiB
Python
409 lines
17 KiB
Python
import os
|
|
import shutil
|
|
import stat
|
|
import subprocess
|
|
|
|
from pyfastogt import system_info, utils
|
|
|
|
|
|
class BuildSystem:
|
|
def __init__(self, name: str, cmd_line: list, cmake_generator_arg: str):
|
|
self.name_ = name
|
|
self.cmd_line_ = cmd_line
|
|
self.cmake_generator_arg_ = cmake_generator_arg
|
|
|
|
def cmake_generator_arg(self) -> str:
|
|
return self.cmake_generator_arg_
|
|
|
|
def name(self) -> str:
|
|
return self.name_
|
|
|
|
def cmd_line(self) -> list: # cmd + args
|
|
return self.cmd_line_
|
|
|
|
|
|
SUPPORTED_BUILD_SYSTEMS = [BuildSystem('ninja', ['ninja'], 'Ninja'),
|
|
BuildSystem('single_make', ['make'], 'Unix Makefiles'),
|
|
BuildSystem('make', ['make', '-j2'], 'Unix Makefiles'),
|
|
BuildSystem('gmake', ['gmake', '-j2'], 'Unix Makefiles')]
|
|
|
|
|
|
def get_supported_build_system_by_name(name) -> BuildSystem:
|
|
return next((x for x in SUPPORTED_BUILD_SYSTEMS if x.name() == name), None)
|
|
|
|
|
|
class BuildError(Exception):
|
|
def __init__(self, value):
|
|
self.value_ = value
|
|
|
|
def __str__(self):
|
|
return self.value_
|
|
|
|
|
|
# must be in cmake folder
|
|
def build_command_cmake(prefix_path: str, cmake_flags: list, build_type='RELEASE', cmake_project_root_abs_path='..',
|
|
build_system=get_supported_build_system_by_name('ninja')):
|
|
if not os.path.exists(cmake_project_root_abs_path):
|
|
raise BuildError('invalid cmake_project_root_path: %s' % cmake_project_root_abs_path)
|
|
|
|
abs_prefix_path = os.path.expanduser(prefix_path)
|
|
cmake_line = ['cmake', cmake_project_root_abs_path, '-G', build_system.cmake_generator_arg(),
|
|
'-DCMAKE_BUILD_TYPE=%s' % build_type]
|
|
cmake_line.extend(cmake_flags)
|
|
cmake_line.extend(['-DCMAKE_INSTALL_PREFIX=%s' % abs_prefix_path])
|
|
try:
|
|
build_dir_name = 'build_cmake_%s' % build_type.lower()
|
|
if os.path.exists(build_dir_name):
|
|
shutil.rmtree(build_dir_name)
|
|
|
|
os.mkdir(build_dir_name)
|
|
os.chdir(build_dir_name)
|
|
subprocess.call(cmake_line)
|
|
make_line = build_system.cmd_line()
|
|
subprocess.call(make_line)
|
|
make_line.append('install')
|
|
subprocess.call(make_line)
|
|
if hasattr(shutil, 'which') and shutil.which('ldconfig'):
|
|
subprocess.call(['ldconfig'])
|
|
except Exception as ex:
|
|
ex_str = str(ex)
|
|
raise BuildError(ex_str)
|
|
|
|
|
|
# must be in configure folder
|
|
def build_command_configure(compiler_flags: list, prefix_path, executable='./configure',
|
|
build_system=get_supported_build_system_by_name('make')):
|
|
# +x for exec file
|
|
st = os.stat(executable)
|
|
os.chmod(executable, st.st_mode | stat.S_IEXEC)
|
|
|
|
abs_prefix_path = os.path.expanduser(prefix_path)
|
|
compile_cmd = [executable, '--prefix={0}'.format(abs_prefix_path)]
|
|
compile_cmd.extend(compiler_flags)
|
|
subprocess.call(compile_cmd)
|
|
make_line = build_system.cmd_line()
|
|
subprocess.call(make_line)
|
|
make_line.append('install')
|
|
subprocess.call(make_line)
|
|
if hasattr(shutil, 'which') and shutil.which('ldconfig'):
|
|
subprocess.call(['ldconfig'])
|
|
|
|
|
|
def generate_fastogt_github_path(repo_name) -> str:
|
|
return 'https://github.com/fastogt/%s' % repo_name
|
|
|
|
|
|
def generate_fastogt_gitlab_path(repo_name) -> str:
|
|
return 'https://gitlab.com/fastogt/%s' % repo_name
|
|
|
|
|
|
class BuildRequest(object):
|
|
OPENSSL_SRC_ROOT = "https://www.openssl.org/source/"
|
|
ARCH_OPENSSL_COMP = "gz"
|
|
ARCH_OPENSSL_EXT = "tar." + ARCH_OPENSSL_COMP
|
|
|
|
CMAKE_SRC_ROOT = "https://github.com/Kitware/CMake/releases/download"
|
|
ARCH_CMAKE_COMP = "gz"
|
|
ARCH_CMAKE_EXT = "tar." + ARCH_CMAKE_COMP
|
|
|
|
MESON_SRC_ROOT = "https://github.com/mesonbuild/meson/releases/download"
|
|
MESON_ARCH_COMP = "gz"
|
|
MESON_ARCH_EXT = "tar." + MESON_ARCH_COMP
|
|
|
|
def __init__(self, platform: str, arch_name: str, dir_path: str, prefix_path: str):
|
|
platform_or_none = system_info.get_supported_platform_by_name(platform)
|
|
if not platform_or_none:
|
|
raise BuildError('invalid platform')
|
|
|
|
arch_or_none = platform_or_none.get_architecture_by_arch_name(arch_name)
|
|
if not arch_or_none:
|
|
raise BuildError('invalid arch')
|
|
|
|
if not prefix_path:
|
|
prefix_path = arch_or_none.default_install_prefix_path()
|
|
abs_prefix_path = os.path.expanduser(prefix_path)
|
|
|
|
packages_types = platform_or_none.package_types()
|
|
build_platform = platform_or_none.make_platform_by_arch(arch_or_none, packages_types)
|
|
|
|
env_pkg_path = os.environ.get('PKG_CONFIG_PATH')
|
|
add_env_pkg_path = '%s/lib/pkgconfig/' % abs_prefix_path
|
|
os.environ['PKG_CONFIG_PATH'] = '{0}:{1}'.format(env_pkg_path,
|
|
add_env_pkg_path) if env_pkg_path else add_env_pkg_path
|
|
env_ld_library_path = os.environ.get('LD_LIBRARY_PATH')
|
|
add_env_ld_library_path = '%s/lib' % abs_prefix_path
|
|
os.environ['LD_LIBRARY_PATH'] = '{0}:{1}'.format(env_ld_library_path,
|
|
add_env_ld_library_path) if env_ld_library_path else add_env_ld_library_path
|
|
env_path = os.environ.get('PATH')
|
|
add_env_path = '%s/bin' % abs_prefix_path
|
|
os.environ['PATH'] = '{0}:{1}'.format(env_path, add_env_path) if env_path else add_env_path
|
|
env = build_platform.env_variables()
|
|
for key, value in env.items():
|
|
os.environ[key] = value
|
|
|
|
self.platform_ = build_platform
|
|
build_dir_path = os.path.abspath(dir_path)
|
|
if os.path.exists(build_dir_path):
|
|
shutil.rmtree(build_dir_path)
|
|
|
|
os.mkdir(build_dir_path)
|
|
os.chdir(build_dir_path)
|
|
|
|
self.build_dir_path_ = build_dir_path
|
|
self.prefix_path_ = abs_prefix_path
|
|
print("Build request for platform: {0}({1}) created".format(build_platform.name(), arch_or_none.name()))
|
|
|
|
def platform(self):
|
|
return self.platform_
|
|
|
|
def platform_name(self) -> str:
|
|
return self.platform_.name()
|
|
|
|
def build_dir_path(self):
|
|
return self.build_dir_path_
|
|
|
|
def prefix_path(self):
|
|
return self.prefix_path_
|
|
|
|
def upgrade_pip(self):
|
|
pip3_upgrade = ['pip3', 'install', '-U', 'pip']
|
|
subprocess.call(pip3_upgrade)
|
|
|
|
def build_snappy(self):
|
|
self._clone_and_build_via_cmake(generate_fastogt_github_path('snappy'),
|
|
['-DBUILD_SHARED_LIBS=OFF', '-DSNAPPY_BUILD_TESTS=OFF'])
|
|
|
|
def build_jsonc(self):
|
|
self._clone_and_build_via_cmake(generate_fastogt_github_path('json-c'), ['-DBUILD_SHARED_LIBS=OFF', '-DDISABLE_STATIC_FPIC=OFF'])
|
|
|
|
def build_libev(self):
|
|
libev_compiler_flags = ['--with-pic', '--disable-shared', '--enable-static']
|
|
self._clone_and_build_via_autogen(generate_fastogt_github_path('libev'), libev_compiler_flags)
|
|
|
|
def update_pyfastogt(self):
|
|
self._clone_and_build_via_python3(generate_fastogt_github_path('pyfastogt'))
|
|
|
|
def update_pyfastostream(self):
|
|
self._clone_and_build_via_python3(generate_fastogt_github_path('pyfastostream'))
|
|
|
|
def build_common(self, with_qt=False):
|
|
cmake_flags = []
|
|
if with_qt:
|
|
cmake_flags.append('-DQT_ENABLED=ON')
|
|
|
|
self._clone_and_build_via_cmake(generate_fastogt_github_path('common'), cmake_flags)
|
|
|
|
def build_fastotv_cpp(self):
|
|
cmake_flags = []
|
|
self._clone_and_build_via_cmake(generate_fastogt_github_path('fastotv_cpp'), cmake_flags)
|
|
|
|
def build_fastoplayer(self):
|
|
cmake_flags = []
|
|
self._clone_and_build_via_cmake(generate_fastogt_github_path('fastoplayer'), cmake_flags)
|
|
|
|
def build_cmake(self, version):
|
|
compiler_flags = []
|
|
url = '{0}/v{1}/cmake-{1}.{2}'.format(self.CMAKE_SRC_ROOT, version, self.ARCH_CMAKE_EXT)
|
|
self._download_and_build_via_configure(url, compiler_flags)
|
|
|
|
def build_meson(self, version):
|
|
url = '{0}/{1}/meson-{1}.{2}'.format(self.MESON_SRC_ROOT, version, self.MESON_ARCH_EXT)
|
|
self._download_and_build_via_python3(url)
|
|
|
|
def build_openssl(self, version, have_shared=False):
|
|
compiler_flags = ['no-tests']
|
|
if not have_shared:
|
|
compiler_flags.append('no-shared')
|
|
|
|
platform = self.platform()
|
|
if platform.name() == 'android':
|
|
compiler_flags.append('no-asm')
|
|
|
|
# compiler_flags.append('--openssldir={0}'.format(self.prefix_path_))
|
|
compiler_flags.append('--libdir=lib')
|
|
|
|
url = '{0}openssl-{1}.{2}'.format(self.OPENSSL_SRC_ROOT, version, self.ARCH_OPENSSL_EXT)
|
|
# download
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
build_command_configure(compiler_flags, self.prefix_path_, './config',
|
|
get_supported_build_system_by_name('single_make'))
|
|
os.chdir(pwd)
|
|
|
|
def build_ffmpeg(self, ffmpeg_specific_compile_flags=None):
|
|
if ffmpeg_specific_compile_flags is None:
|
|
ffmpeg_specific_compile_flags = []
|
|
|
|
ffmpeg_platform_args = ['--enable-static', '--enable-pic', '--disable-doc', '--enable-openssl',
|
|
'--disable-avdevice', '--disable-postproc', '--disable-swscale',
|
|
'--disable-encoder=flac', '--disable-devices', '--disable-dxva2', '--disable-vdpau',
|
|
'--disable-filters', '--enable-filter=yadif', '--disable-doc', '--disable-d3d11va',
|
|
'--disable-audiotoolbox', '--disable-videotoolbox', '--disable-vaapi',
|
|
'--disable-crystalhd', '--disable-mediacodec', '--disable-nvenc', '--disable-mmal',
|
|
'--disable-cuda', '--disable-cuvid', '--disable-libmfx', '--disable-libnpp',
|
|
'--disable-iconv', '--disable-jni', '--disable-v4l2_m2m',
|
|
'--enable-optimizations']
|
|
platform = self.platform()
|
|
platform_name = platform.name()
|
|
if platform_name == 'linux':
|
|
ffmpeg_platform_args.extend(['--disable-libxcb'])
|
|
elif platform_name == 'windows':
|
|
ffmpeg_platform_args = ffmpeg_platform_args
|
|
elif platform_name == 'macosx':
|
|
ffmpeg_platform_args.extend(['--cc=clang', '--cxx=clang++', '--disable-libxcb'])
|
|
elif platform_name == 'android':
|
|
ffmpeg_platform_args = ffmpeg_platform_args
|
|
ffmpeg_platform_args.extend(['--cc=%s' % os.environ['CC']])
|
|
|
|
compiler_flags = ffmpeg_specific_compile_flags
|
|
compiler_flags.extend(ffmpeg_platform_args)
|
|
self._clone_and_build_via_configure(generate_fastogt_github_path('ffmpeg'), compiler_flags,
|
|
use_platform_flags=False, branch='n4.3.1')
|
|
|
|
# install packages
|
|
def _install_package(self, name: str):
|
|
self.platform_.install_package(name)
|
|
|
|
def _install_via_python3(self, name: str):
|
|
python3_line = ['pip3', 'install', name]
|
|
subprocess.call(python3_line)
|
|
|
|
# clone
|
|
def _clone_and_build_via_cmake(self, url: str, cmake_flags: list, branch=None, remove_dot_git=True):
|
|
pwd = os.getcwd()
|
|
cloned_dir = utils.git_clone(url, branch, remove_dot_git)
|
|
os.chdir(cloned_dir)
|
|
self._build_via_cmake(cmake_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _clone_and_build_via_meson(self, url: str, meson_flags: list, branch=None, remove_dot_git=True):
|
|
pwd = os.getcwd()
|
|
cloned_dir = utils.git_clone(url, branch, remove_dot_git)
|
|
os.chdir(cloned_dir)
|
|
self._build_via_meson(meson_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _clone_and_build_via_configure(self, url: str, compiler_flags: list, executable='./configure',
|
|
use_platform_flags=True, branch=None, remove_dot_git=True):
|
|
pwd = os.getcwd()
|
|
cloned_dir = utils.git_clone(url, branch, remove_dot_git)
|
|
os.chdir(cloned_dir)
|
|
self._build_via_configure(compiler_flags, executable, use_platform_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _clone_and_build_via_autogen(self, url: str, compiler_flags: list, executable='./configure',
|
|
use_platform_flags=True, branch=None,
|
|
remove_dot_git=True):
|
|
pwd = os.getcwd()
|
|
cloned_dir = utils.git_clone(url, branch, remove_dot_git)
|
|
os.chdir(cloned_dir)
|
|
self._build_via_autogen(compiler_flags, executable, use_platform_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _clone_and_build_via_python3(self, url: str, branch=None,
|
|
remove_dot_git=True):
|
|
pwd = os.getcwd()
|
|
cloned_dir = utils.git_clone(url, branch, remove_dot_git)
|
|
os.chdir(cloned_dir)
|
|
python3_line = ['python3', 'setup.py', 'install']
|
|
subprocess.call(python3_line)
|
|
os.chdir(pwd)
|
|
|
|
# download
|
|
def _download_and_build_via_cmake(self, url: str, cmake_flags: list):
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
self._build_via_cmake(cmake_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _download_and_build_via_bootstrap(self, url: str, compiler_flags: list, executable='./configure',
|
|
use_platform_flags=True):
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
self._build_via_bootstrap(compiler_flags, executable, use_platform_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _download_and_build_via_autogen(self, url: str, compiler_flags: list, executable='./configure',
|
|
use_platform_flags=True):
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
self._build_via_autogen(compiler_flags, executable, use_platform_flags)
|
|
os.chdir(pwd)
|
|
|
|
def _download_and_build_via_python3(self, url: str):
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
python3_line = ['python3', 'setup.py', 'install']
|
|
subprocess.call(python3_line)
|
|
os.chdir(pwd)
|
|
|
|
def _download_and_build_via_meson(self, url: str, compiler_flags: list,
|
|
build_system=get_supported_build_system_by_name('ninja')):
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
self._build_via_meson(compiler_flags, build_system)
|
|
os.chdir(pwd)
|
|
|
|
def _download_and_build_via_configure(self, url: str, compiler_flags: list, executable='./configure',
|
|
use_platform_flags=True):
|
|
pwd = os.getcwd()
|
|
file_path = utils.download_file(url)
|
|
extracted_folder = utils.extract_file(file_path)
|
|
os.chdir(extracted_folder)
|
|
self._build_via_configure(compiler_flags, executable, use_platform_flags)
|
|
os.chdir(pwd)
|
|
|
|
# build
|
|
def _build_via_autogen(self, compiler_flags: list, executable='./configure', use_platform_flags=True):
|
|
autogen_line = ['sh', 'autogen.sh']
|
|
subprocess.call(autogen_line)
|
|
self._build_via_configure(compiler_flags, executable, use_platform_flags)
|
|
|
|
def _build_via_bootstrap(self, compiler_flags: list, executable='./configure', use_platform_flags=True):
|
|
autogen_line = ['sh', 'bootstrap']
|
|
subprocess.call(autogen_line)
|
|
self._build_via_configure(compiler_flags, executable, use_platform_flags)
|
|
|
|
def _build_via_meson(self, compiler_flags: list, build_system=get_supported_build_system_by_name('ninja')):
|
|
build_dir_name = 'build_meson'
|
|
os.mkdir(build_dir_name)
|
|
os.chdir(build_dir_name)
|
|
abs_prefix_path = os.path.expanduser(self.prefix_path_)
|
|
meson_line = ['meson', '--prefix', abs_prefix_path, '--libdir', abs_prefix_path + '/lib']
|
|
meson_line.extend(compiler_flags)
|
|
subprocess.call(meson_line)
|
|
make_line = build_system.cmd_line()
|
|
subprocess.call(make_line)
|
|
make_line.append('install')
|
|
subprocess.call(make_line)
|
|
|
|
# raw build
|
|
def _build_via_cmake(self, cmake_flags: list, build_type='RELEASE', use_platform_flags=True):
|
|
cmake_flags_extended = cmake_flags
|
|
if use_platform_flags:
|
|
cmake_flags_extended.extend(self.platform_.cmake_specific_flags())
|
|
build_command_cmake(self.prefix_path_, cmake_flags, build_type)
|
|
|
|
def _build_via_cmake_double(self, cmake_flags: list, build_type='RELEASE', use_platform_flags=True):
|
|
cmake_flags_extended = cmake_flags
|
|
if use_platform_flags:
|
|
cmake_flags_extended.extend(self.platform_.cmake_specific_flags())
|
|
build_command_cmake(self.prefix_path_, cmake_flags, build_type, '../../..')
|
|
|
|
def _build_via_configure(self, compiler_flags: list, executable='./configure', use_platform_flags=True):
|
|
compiler_flags_extended = compiler_flags
|
|
if use_platform_flags:
|
|
compiler_flags_extended.extend(self.platform_.configure_specific_flags())
|
|
build_command_configure(compiler_flags_extended, self.prefix_path_, executable)
|